Source code for httk.external.isotropy_ext

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#    The high-throughput toolkit (httk)
#    Copyright (C) 2012-2015 Rickard Armiento
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import print_function
import sys, os, tempfile

from httk.core import citation, IoAdapterString
citation.add_ext_citation('isotropy', "Harold T. Stokes, Dorian M. Hatch, and Branton J. Campbell, Department of Physics and Astronomy, Brigham Young University, Provo, Utah 84606, USA")

from httk.core.basic import int_to_anonymous_symbol
from httk import config
from httk.external.command import Command
import httk.httkio
import httk.iface

from httk.atomistic.atomisticio.structure_cif_io import cif_to_struct
from httk.atomistic.data.periodictable import atomic_symbol, atomic_number

isotropy_path = None

[docs]def ensure_has_isotropy(): if isotropy_path is None or isotropy_path == "": raise ImportError("httk.external.isotropy_ext imported with no access to isotropy binary")
try: isotropy_path = config.get('paths', 'isotropy') except Exception: pass
[docs]def isotropy(cwd, args, inputstr, timeout=30): ensure_has_isotropy() #p = subprocess.Popen([cif2cell_path]+args, stdout=subprocess.PIPE, # stderr=subprocess.PIPE, cwd=cwd) #print("COMMAND CIF2CELL") out, err, completed = Command(os.path.join(isotropy_path, 'findsym'), args, cwd=cwd, inputstr=inputstr).run(timeout) #print("COMMAND CIF2CELL END") return out, err, completed
#out, err = p.communicate() #return out, err
[docs]def uc_reduced_coordgroups_process_with_isotropy(coordgroup, cell, get_wyckoff=False): #print("GURK",struct.formula,len(struct.uc_reduced_coords)) inputstr = httk.iface.isotropy_if.reduced_coordgroups_to_input(coordgroup, cell) out, err, completed = isotropy("./", [], inputstr) if completed == 0: cif = httk.iface.isotropy_if.out_to_cif(IoAdapterString(string=out), [atomic_symbol(x) for x in range(1, len(coordgroup)+1)]) #print("CIF",cif) newstruct = cif_to_struct(IoAdapterString(string=cif), backends=['cif2cell_reduce']) checkstruct = cif_to_struct(IoAdapterString(string=cif), backends=['cif2cell']) only_rc_struct = cif_to_struct(IoAdapterString(string=cif), backends=['cif_reader_that_can_only_read_isotropy_cif']) # This is an illeelegant hack newstruct.rc_sites.wyckoff_symbols = only_rc_struct.rc_sites.wyckoff_symbols # Cell basis can only be constructed from the cif approximately cell_mismatch = sum(sum((checkstruct.rc_cell.basis - only_rc_struct.rc_cell.basis))).to_float() #print("CELL MISMATCH:",sum(sum((newstruct.cell.maxnorm_basis - only_rc_struct.cell.maxnorm_basis))).to_float()) only_rc_struct._rc_cell = newstruct.rc_cell # Make sure the hexhash is recomputed only_rc_struct.rc_sites._hexhash = None #print("CHECK THIS:", newstruct.rc_sites.hexhash, only_rc_struct.rc_sites.hexhash) #print("CHECK THIS:", newstruct.cell.to_tuple(), only_rc_struct.cell.to_tuple()) if cell_mismatch > 1e-6 or newstruct.rc_sites.hexhash != only_rc_struct.rc_sites.hexhash: print("Cell mismatch:", cell_mismatch) print("Structure hashes:", newstruct.rc_sites.hexhash, only_rc_struct.rc_sites.hexhash) #print("Structures:", newstruct.rc_sites.to_tuple(), only_rc_struct.rc_sites.to_tuple()) raise Exception("isotropy_ext.struct_process_with_isotropy: internal error, structures that absolutely should be the same are not, sorry.") #order = [x.as_integer-1 for x in newstruct.assignments] #print("ORDER:",order) if get_wyckoff: return newstruct.rc_reduced_coordgroups, newstruct.rc_sites.wyckoff_symbols, [[atomic_number(x) for x in y] for y in newstruct.assigments.symbols_list()] else: return newstruct.rc_reduced_coordgroups else: print("ISOTROPY STDERR:") #print(inputstr) print("========") #print(out) #print("========") print(err) print("========") raise Exception("isotropy_ext: isotropy did not complete.")
[docs]def struct_process_with_isotropy(struct): tmpdir = tempfile.mkdtemp(prefix='ht.tmp.isotropy_') inputstr = httk.iface.isotropy_if.struct_to_input(struct) #print("== Running findsym", end="", file=sys.stderr) #print("==================== INPUT\n",inputstr) #print("====================") out, err, completed = isotropy(tmpdir, [], inputstr) # Clean up try: os.unlink(os.path.join(tmpdir, 'findsym.log')) except IOError: pass try: os.rmdir(tmpdir) except (IOError, OSError): pass #print("== Running findsym complete, stderr output follows:", end="", file=sys.stderr) #print(out, end="", file=sys.stderr) #print("============================================", end="", file=sys.stderr) #print(err, end="", file=sys.stderr) #print(float(struct.volume), end="", file=sys.stderr) #print("============================================", end="", file=sys.stderr) #print("=== OUTPUT ====") #print(out) #print("==============") #print("XXX",struct.assignments.symbols) if completed == 0: #print("what?",completed) # TODO: Clean this up with own cif reader that actually reads wyckoff sites out of cif file! cif = httk.iface.isotropy_if.out_to_cif(IoAdapterString(string=out), struct.assignments) newstruct = cif_to_struct(IoAdapterString(string=cif)) #print("Rejected?") newstruct.add_tags(struct.get_tags()) newstruct._refs = struct.get_refs() #print("CHECKING",struct.uc_volume,newstruct.rc_volume) # only_rc_struct = cif_to_struct(IoAdapterString(string=cif), backends=['cif_reader_that_can_only_read_isotropy_cif']) # #newstruct.rc_sites.wyckoff_symbols = only_rc_struct.rc_sites.wyckoff_symbols # #newstruct.rc_sites._multiplicities = only_rc_struct.rc_sites._multiplicities # #print("HERE", only_rc_struct.rc_sites.wyckoff_symbols) # # Cell basis can only be constructed from the cif approximately # cell_mismatch = sum(sum((newstruct.rc_cell.basis - only_rc_struct.rc_cell.basis))).to_float() # #print("CELL MISMATCH:",sum(sum((newstruct.cell.maxnorm_basis - only_rc_struct.cell.maxnorm_basis))).to_float()) # #only_rc_struct._rc_cell = newstruct.rc_cell # # Make sure the hexhash is recomputed # #only_rc_struct.rc_sites._hexhash = None # #print("CHECK THIS:", newstruct.rc_sites.hexhash, only_rc_struct.rc_sites.hexhash) # #print("CHECK THIS:", newstruct.cell.to_tuple(), only_rc_struct.cell.to_tuple()) # if cell_mismatch > 1e-6 or newstruct.rc_sites.hexhash != only_rc_struct.rc_sites.hexhash: # print("Cell mismatch:", cell_mismatch) # print("Structure hashes:", newstruct.rc_sites.hexhash, only_rc_struct.rc_sites.hexhash) # print("======") # print(newstruct.to_tuple()) # print("======") # print(only_rc_struct.to_tuple()) # print("======") # #print("Structures:", newstruct.rc_sites.to_tuple(), only_rc_struct.rc_sites.to_tuple()) # raise Exception("isotropy_ext.struct_process_with_isotropy: internal error, structures that absolutely should be the same are not, sorry.") return newstruct else: print("ISOTROPY STDERR:") print(inputstr) print("========") print(out) print("========") print(err) print("========") raise Exception("isotropy_ext: isotropy did not complete.")