def stage6(self, water_type): """ Arrange water atoms and replacements Provided variables: atoms: atomic positions of water molecules. (absolute) """ self.logger.info("Stage6: Atomic positions of water.") # assert audit_name(water_type), "Dubious water name: {0}".format(water_type) # water = importlib.import_module("genice.molecules."+water_type) water = safe_import("molecule", water_type) try: mdoc = water.__doc__.splitlines() except BaseException: mdoc = [] for line in mdoc: self.logger.info(" " + line) self.atoms = arrange_atoms(self.reppositions, self.repcell, self.rotmatrices, water.sites, water.labels, water.name, ignores=set(self.dopants)) self.logger.info("Stage6: end.")
def stage6(self, water_type): """ arrange water atoms and replacements """ self.logger.info("Stage6: Atomic positions of water.") # assert audit_name(water_type), "Dubious water name: {0}".format(water_type) # water = importlib.import_module("genice.molecules."+water_type) water = safe_import("molecule", water_type) self.atoms = arrange_atoms(self.reppositions, self.repcell, self.rotmatrices, water.sites, water.labels, water.name, ignores=set(self.dopants)) self.logger.info("Stage6: end.")
def stage6(self, water_type): """ Arrange water atoms and replacements Provided variables: atoms: atomic positions of water molecules. (absolute) """ self.logger.info("Stage6: Atomic positions of water.") # assert audit_name(water_type), "Dubious water name: {0}".format(water_type) # water = importlib.import_module("genice.molecules."+water_type) water = safe_import("molecule", water_type) self.atoms = arrange_atoms(self.reppositions, self.repcell, self.rotmatrices, water.sites, water.labels, water.name, ignores=set(self.dopants)) self.logger.info("Stage6: end.")
def iterate(filename, oname, hname, filerange, framerange, suffix=None): logger = getLogger() rfile = str2range(filerange) rframe = str2rangevalues(framerange) logger.info( " file number range: {0}:{1}:{2}".format(*str2rangevalues(filerange))) logger.info(" frame number range: {0}:{1}:{2}".format(*rframe)) # test whether filename has a regexp for enumeration logger.info(filename) m = re.search("%[0-9]*d", filename) # prepare file list if m is None: filelist = [ filename, ] else: filelist = [] for num in rfile: fname = filename % num if os.path.exists(fname): filelist.append(fname) logger.debug("File list: {0}".format(filelist)) frame = 0 for fname in filelist: logger.info(" File name: {0}".format(fname)) # single file may contain multiple frames if suffix is None: suffix = Path(fname).suffix[1:] loader = safe_import("loader", suffix) file = open(fname) for oatoms, hatoms, cellmat in loader.load_iter(file, oname=oname, hname=hname): if frame == rframe[0]: logger.info("Frame: {0}".format(frame)) yield oatoms, hatoms, cellmat rframe[0] += rframe[2] if rframe[1] <= rframe[0]: return else: logger.info("Skip frame: {0}".format(frame)) frame += 1
def main(): # Module-loading paths # 1. Look for the modules in the current working directory sys.path.append(".") #prepare user's workarea home = os.path.expanduser("~") if os.path.exists(home + "/Library/Application Support"): #MacOS homegenice = home + "/Library/Application Support/GenIce" else: homegenice = os.path.expanduser(home + "/.genice") #Other unix try: os.makedirs(homegenice + "/formats") os.makedirs(homegenice + "/lattices") os.makedirs(homegenice + "/molecules") except: pass #just ignore when failed. # 2. Look for user's home. sys.path.append(homegenice) #Parse options options = getoptions() #Set verbosity level if options.debug: logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s") elif options.quiet: logging.basicConfig(level=logging.WARN, format="%(levelname)s %(message)s") else: #normal logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") logger = logging.getLogger() logger.debug("Debug mode.") logger.debug(options.Type) water_type = options.water[0] guests = options.guests lattice_type = options.Type[0] file_format = options.format[0] seed = options.seed[0] rep = options.rep density = options.dens[0] depolarize = not options.nodep anions = dict() if options.anions is not None: logger.info(options.anions) for v in options.anions: key, value = v[0].split("=") anions[int(key)] = value cations = dict() if options.cations is not None: for v in options.cations: key, value = v[0].split("=") cations[int(key)] = value spot_guests = dict() if options.spot_guests is not None: for v in options.spot_guests: key, value = v[0].split("=") spot_guests[int(key)] = value groups = dict() if options.groups is not None: for v in options.groups: key, value = v[0].split("=") groups[int(key)] = value del options # Dispose for safety. # Set random seeds random.seed(seed) np.random.seed(seed) logger.debug("Lattice: {0}".format(lattice_type)) # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Format: {0}".format(file_format)) formatter = safe_import("format", file_format) lat = lattice.Lattice( lattice_type, density=density, rep=rep, depolarize=depolarize, cations=cations, anions=anions, spot_guests=spot_guests, spot_groups=groups, ) # These arguments should also be in lattice, not in run() lat.format(water_type=water_type, guests=guests, formatter=formatter)
def main(): # Module-loading paths # 1. Look for the modules in the current working directory sys.path.append(".") #prepare user's workarea home = os.path.expanduser("~") if os.path.exists(home + "/Library/Application Support"): #MacOS homegenice = home + "/Library/Application Support/GenIce" else: homegenice = os.path.expanduser(home + "/.genice") #Other unix try: os.makedirs(homegenice + "/formats") os.makedirs(homegenice + "/lattices") os.makedirs(homegenice + "/molecules") except: pass #just ignore when failed. # 2. Look for user's home. sys.path.append(homegenice) #Parse options if sys.argv[0].find("analice") >= 0: options = getoptions_analice() mode = "analice" else: options = getoptions() mode = "genice" #Set verbosity level if options.debug: logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s") elif options.quiet: logging.basicConfig(level=logging.WARN, format="%(levelname)s %(message)s") else: #normal logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") logger = logging.getLogger() logger.debug("Debug mode.") if mode == "genice": logger.debug(options.Type) water_type = options.water[0] guests = options.guests lattice_type = options.Type[0] file_format = options.format[0] seed = options.seed[0] rep = options.rep density = options.dens[0] depolarize = not options.nodep asis = options.asis anions = dict() if options.anions is not None: logger.info(options.anions) for v in options.anions: key, value = v[0].split("=") anions[int(key)] = value cations = dict() if options.cations is not None: for v in options.cations: key, value = v[0].split("=") cations[int(key)] = value spot_guests = dict() if options.spot_guests is not None: for v in options.spot_guests: key, value = v[0].split("=") spot_guests[int(key)] = value groups = dict() if options.groups is not None: for v in options.groups: key, value = v[0].split("=") groups[int(key)] = value del options # Dispose for safety. # Set random seeds random.seed(seed) np.random.seed(seed) logger.debug("Lattice: {0}".format(lattice_type)) # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Format: {0}".format(file_format)) formatter = safe_import("format", file_format) # Show the document of the module try: doc = formatter.__doc__.splitlines() except: doc = [] for line in doc: logger.info("!!! {0}".format(line)) lat = lattice.Lattice( lattice_type, density=density, rep=rep, depolarize=depolarize, asis=asis, cations=cations, anions=anions, spot_guests=spot_guests, spot_groups=groups, ) lat.generate_ice(water_type=water_type, guests=guests, formatter=formatter) else: #analice logger.debug(options.File) water_type = options.water[0] file_format = options.format[0] oname = options.oatom[0] hname = options.hatom[0] filename = options.File[0] del options # Dispose for safety. # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Format: {0}".format(file_format)) formatter = safe_import("format", file_format) # reuse gromacs plugin to load the file. s = "gromacs[{0}:{1}:{2}]".format(filename, oname, hname) lat = lattice.Lattice(lattice_type=s) lat.analize_ice(water_type=water_type, formatter=formatter)
def stage7(self, guests): """ Arrange guest atoms Provided variables: atoms: atomic positions of all molecules. """ self.logger.info("Stage7: Atomic positions of the guest.") if self.cagepos is not None: # the cages around the dopants. dopants_neighbors = self.dopants_info(self.dopants, self.reppositions, self.repcagepos, self.repcell) # put the (one-off) groups if len(self.spot_groups) > 0: # process the -H option for cage, group_to in self.spot_groups.items(): group, root = group_to.split(":") self.add_group(cage, group, int(root)) molecules = defaultdict(list) if len(self.spot_guests) > 0: # process the -G option for cage, molec in self.spot_guests.items(): molecules[molec].append(cage) self.filled_cages.add(cage) if guests is not None: # process the -g option for arg in guests: self.logger.debug(arg[0]) cagetype, spec = arg[0].split("=") assert cagetype in self.cagetypes, "Nonexistent cage type: {0}".format( cagetype) resident = dict() rooms = list(self.cagetypes[cagetype] - self.filled_cages) for room in rooms: resident[room] = None # spec contains a formula consisting of "+" and "*" contents = spec.split("+") vacant = len(rooms) for content in contents: if "*" in content: molec, frac = content.split("*") frac = float(frac) else: molec = content frac = 1.0 nmolec = int(frac * len(rooms) + 0.5) vacant -= nmolec assert vacant >= 0, "Too many guests." remain = nmolec movedin = [] while remain > 0: r = random.randint(0, len(rooms) - 1) room = rooms[r] if resident[room] is None: resident[room] = molec molecules[molec].append(room) movedin.append(room) remain -= 1 # Now ge got the address book of the molecules. if len(molecules): self.logger.info(" Summary of guest placements:") self.guests_info(self.cagetypes, molecules) if len(self.spot_groups) > 0: self.logger.info(" Summary of groups:") self.groups_info(self.groups) # semi-guests for root, cages in self.groups.items(): assert root in self.dopants name = self.dopants[root] molname = "G{0}".format(root) pos = self.reppositions[root] rot = self.rotmatrices[root] self.atoms.append( [0, molname, name, self.repcell.rel2abs(pos), 0]) del self.dopants[root] # processed. self.logger.debug((root, cages, name, molname, pos, rot)) for cage, group in cages.items(): assert group in self.groups_placer assert cage in dopants_neighbors[root] cpos = self.repcagepos[cage] self.atoms += self.groups_placer[group](cpos, pos, self.repcell, molname) # molecular guests for molec, cages in molecules.items(): gmol = safe_import("molecule", molec) try: mdoc = gmol.__doc__.splitlines() except BaseException: mdoc = [] for line in mdoc: logger.info(" " + line) cpos = [self.repcagepos[i] for i in cages] cmat = [np.identity(3) for i in cages] self.atoms += arrange_atoms(cpos, self.repcell, cmat, gmol.sites, gmol.labels, gmol.name) # Assume the dopant is monatomic and replaces one water molecule atomset = defaultdict(set) for label, name in self.dopants.items(): atomset[name].add(label) for name, labels in atomset.items(): pos = [self.reppositions[i] for i in sorted(labels)] rot = [self.rotmatrices[i] for i in sorted(labels)] self.atoms += arrange_atoms(pos, self.repcell, rot, [ [0., 0., 0.], ], [name], name) self.logger.info("Stage7: end.")
def __init__(self, lattice_type=None, density=0, rep=(1, 1, 1), depolarize=True, asis=False, cations=dict(), anions=dict(), spot_guests=dict(), spot_groups=dict(), ): self.logger = logging.getLogger() self.lattice_type = lattice_type self.rep = rep self.depolarize = depolarize self.asis = asis self.cations = cations self.anions = anions self.spot_guests = spot_guests self.spot_groups = spot_groups if lattice_type is None: return lat = safe_import("lattice", lattice_type) # Show the document of the module try: self.doc = lat.__doc__.splitlines() except: self.doc = [] self.doc.append("") self.doc.append("Command line: {0}".format(" ".join(sys.argv))) for line in self.doc: self.logger.info("!!! {0}".format(line)) # ================================================================ # rotmatrices (analice) # try: self.rotmatrices = lat.rotmat except: self.logger.info("No rotmatrices in lattice") pass # ================================================================ # waters: positions of water molecules # self.waters = load_numbers(lat.waters) self.logger.debug("Waters: {0}".format(len(self.waters))) self.waters = self.waters.reshape((self.waters.size // 3, 3)) # ================================================================ # cell: cell dimension # celltype: symmetry of the cell # see parse_cell for syntax. # self.cell = Cell(lat.cell, lat.celltype) #self.cell = parse_cell(lat.cell, lat.celltype) # ================================================================ # coord: "relative" or "absolute" # Inside genice, molecular positions are always treated as "relative" # if lat.coord == "absolute": self.waters = self.cell.abs2rel(self.waters) self.waters = np.array([w - np.floor(w) for w in self.waters]) # ================================================================ # pairs: specify the pairs of molecules that are connected. # Bond orientation will be shuffled later # unless it is "fixed". # self.pairs = None try: if type(lat.pairs) is str: lines = lat.pairs.split("\n") self.pairs = [] for line in lines: columns = line.split() if len(columns) == 2: i, j = [int(x) for x in columns] self.pairs.append((i, j)) elif type(lat.pairs) is list: self.pairs = lat.pairs # for pair in lat.pairs: # self.pairs.append(pair) except AttributeError: self.logger.info("Graph is not defined.") # ================================================================ # bondlen: specify the bond length threshold. # This is used when "pairs" are not specified. # It is applied to the original positions of molecules (before density setting). # self.bondlen = None try: self.bondlen = lat.bondlen self.logger.info("Bond length (specified): {0}".format(self.bondlen)) except AttributeError: self.bondlen = 1.1 * shortest_distance(self.waters, self.cell) self.logger.info("Bond length (assumed): {0}".format(self.bondlen)) # Set density mass = 18 # water NB = 6.022e23 nmol = self.waters.shape[0] # nmol in a unit cell volume = self.cell.volume() # volume of a unit cell in nm**3 density0 = mass * nmol / (NB * volume * 1e-21) if density <= 0: try: self.density = lat.density except AttributeError: self.logger.info( "Density is not specified. Assume the density from lattice.") dmin = shortest_distance(self.waters, self.cell) self.logger.info( "Closest pair distance: {0} (should be around 0.276 nm)".format(dmin)) self.density = density0 / (0.276 / dmin)**3 # self.density = density0 else: self.density = density self.logger.info("Target Density: {0}".format(self.density)) self.logger.info("Original Density: {0}".format(density0)) # scale the cell according to the (specified) density ratio = (density0 / self.density)**(1.0 / 3.0) self.cell.scale(ratio) if self.bondlen is not None: self.bondlen *= ratio self.logger.info("Bond length (scaled, nm): {0}".format(self.bondlen)) # ================================================================ # double_network: True or False # This is a special option for ices VI and VII that have # interpenetrating double network. # GenIce's fast depolarization algorithm fails in some case. # try: self.double_network = lat.double_network except AttributeError: self.double_network = False # ================================================================ # cages: positions of the centers of cages # In fractional coordinate. # self.cagepos = None self.cagetype = None if "cages" in lat.__dict__: self.cagepos, self.cagetype = parse_cages(lat.cages) # ================================================================ # fixed: specify the bonds whose directions are fixed. # you can specify them in pairs at a time. # You can also leave it undefined. # try: if type(lat.fixed) is str: lines = lat.fixed.split("\n") self.fixed = [] for line in lines: columns = line.split() if len(columns) == 2: i, j = [int(x) for x in columns] self.fixed.append((i, j)) # Is a tuple elif type(lat.fixed) is list: self.fixed = [] for pair in lat.fixed: self.fixed.append(tuple(pair[:2])) # Must be a tuple except AttributeError: self.fixed = [] if "dopeIonsToUnitCell" in lat.__dict__: self.dopeIonsToUnitCell = lat.dopeIonsToUnitCell else: self.dopeIonsToUnitCell = None self.dopants = set() # if asis, make pairs to be fixed. if self.asis and len(self.fixed) == 0: self.fixed = self.pairs # filled cages self.filled_cages = set() # groups info self.groups = defaultdict(dict) # groups for the semi-guest # experimental; there are many variation of semi-guest inclusion. self.groups_placer = {"Bu-": butyl, "Butyl-": butyl, "Pentyl-": pentyl, "Propyl-": propyl, "2,2-dimethylpropyl-": _2_2_dimethylpropyl, "2,3-dimethylbutyl-": _2_3_dimethylbutyl, "3,3-dimethylbutyl-": _3_3_dimethylbutyl, "3-methylbutyl-": _3_methylbutyl, "Ethyl-": ethyl}
def main(): # Module-loading paths # 1. Look for the modules in the current working directory sys.path.append(".") #prepare user's workarea home = os.path.expanduser("~") if os.path.exists(home+"/Library/Application Support"): #MacOS homegenice = home+"/Library/Application Support/GenIce" else: homegenice = os.path.expanduser(home + "/.genice") #Other unix try: os.makedirs(homegenice+"/formats") os.makedirs(homegenice+"/lattices") os.makedirs(homegenice+"/molecules") except: pass #just ignore when failed. # 2. Look for user's home. sys.path.append(homegenice) #Parse options if sys.argv[0].find("analice") >= 0: options = getoptions_analice() mode = "analice" else: options = getoptions() mode = "genice" #Set verbosity level if options.debug: logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s") elif options.quiet: logging.basicConfig(level=logging.WARN, format="%(levelname)s %(message)s") else: #normal logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") logger = logging.getLogger() logger.debug("Debug mode.") if mode == "genice": logger.debug(options.Type) water_type = options.water[0] guests = options.guests lattice_type = options.Type[0] file_format = options.format[0] seed = options.seed[0] rep = options.rep density = options.dens[0] depolarize = not options.nodep asis = options.asis anions = dict() if options.anions is not None: logger.info(options.anions) for v in options.anions: key, value = v[0].split("=") anions[int(key)] = value cations = dict() if options.cations is not None: for v in options.cations: key, value = v[0].split("=") cations[int(key)] = value spot_guests = dict() if options.spot_guests is not None: for v in options.spot_guests: key, value = v[0].split("=") spot_guests[int(key)] = value groups = dict() if options.groups is not None: for v in options.groups: key, value = v[0].split("=") groups[int(key)] = value del options # Dispose for safety. # Set random seeds random.seed(seed) np.random.seed(seed) logger.debug("Lattice: {0}".format(lattice_type)) # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Format: {0}".format(file_format)) formatter = safe_import("format", file_format) # Show the document of the module try: doc = formatter.__doc__.splitlines() except: doc = [] for line in doc: logger.info("!!! {0}".format(line)) lat = lattice.Lattice(lattice_type, density=density, rep=rep, depolarize=depolarize, asis=asis, cations=cations, anions=anions, spot_guests=spot_guests, spot_groups=groups, ) lat.generate_ice(water_type=water_type, guests=guests, formatter=formatter ) else: #analice logger.debug(options.File) water_type = options.water[0] file_format = options.format[0] oname = options.oatom[0] hname = options.hatom[0] filename = options.File[0] del options # Dispose for safety. # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Format: {0}".format(file_format)) formatter = safe_import("format", file_format) # reuse gromacs plugin to load the file. s = "gromacs[{0}:{1}:{2}]".format(filename,oname,hname) lat = lattice.Lattice(lattice_type=s) lat.analize_ice(water_type=water_type, formatter=formatter)
def main(): # Module-loading paths # 1. Look for the modules in the current working directory sys.path.append(".") # Parse options if sys.argv[0].find("analice") >= 0: options = analice.getoptions() mode = "analice" else: options = genice.getoptions() mode = "genice" # Set verbosity level if options.debug: logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s") elif options.quiet: logging.basicConfig(level=logging.WARN, format="%(levelname)s %(message)s") else: # normal logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") logger = logging.getLogger() logger.debug("Debug mode.") if mode == "genice": logger.debug(options.Type) lattice_type = options.Type seed = options.seed rep = options.rep density = options.dens asis = options.asis anions = dict() if options.anions is not None: logger.info(options.anions) for v in options.anions: key, value = v[0].split("=") anions[int(key)] = value cations = dict() if options.cations is not None: for v in options.cations: key, value = v[0].split("=") cations[int(key)] = value spot_guests = dict() if options.spot_guests is not None: for v in options.spot_guests: key, value = v[0].split("=") spot_guests[int(key)] = value groups = dict() if options.groups is not None: for v in options.groups: key, value = v[0].split("=") groups[int(key)] = value # Set random seeds random.seed(seed) np.random.seed(seed) logger.debug("Lattice: {0}".format(lattice_type)) assert lattice_type is not None # Initialize the Lattice class with arguments which are required for plugins. lat = genice.GenIce(safe_import("lattice", lattice_type), sys.argv, density=density, rep=rep, cations=cations, anions=anions, spot_guests=spot_guests, spot_groups=groups, asis=asis, ) water_type = options.water guests = options.guests noise = options.noise depolarize = not options.nodep file_format = options.format # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Output file format: {0}".format(file_format)) formatter = safe_import("format", file_format) if options.visual != "": record_depolarization_path = open(options.visual, "w") else: record_depolarization_path = None del options # Dispose for safety. lat.generate_ice(water_type=water_type, guests=guests, formatter=formatter, record_depolarization_path=record_depolarization_path, noise=noise, depolarize=depolarize, ) else: # analice logger.debug(options.File) water_type = options.water file_format = options.format oname = options.oatom hname = options.hatom filename = options.File noise = options.noise avgspan = options.avgspan filerange = options.filerange framerange = options.framerange suffix = options.suffix if options.output is None: output = None stdout = None else: output = options.output stdout = sys.stdout logger.debug(filerange) logger.debug(framerange) logger.debug(oname) logger.debug(hname) logger.debug(suffix) logger.info("Output:{0}".format(output)) del options # Dispose for safety. for i, (oatoms, hatoms, cellmat) in enumerate(load.average(lambda:load.iterate(filename, oname, hname, filerange, framerange, suffix=suffix), span=avgspan)): # Main part of the program is contained in th Formatter object. (See formats/) logger.debug("Output file format: {0}".format(file_format)) formatter = safe_import("format", file_format) lattice_info = load.make_lattice_info(oatoms, hatoms, cellmat) lat = analice.AnalIce(lattice_info, sys.argv) if output is not None: sys.stdout = open(output % i, "w") lat.analyze_ice(water_type=water_type, formatter=formatter, noise=noise, ) if stdout is not None: # recover stdout sys.stdout = stdout
def stage7(self, guests): """ Arrange guest atoms Provided variables: atoms: atomic positions of all molecules. """ self.logger.info("Stage7: Atomic positions of the guest.") if self.cagepos is not None: # the cages around the dopants. dopants_neighbors = self.dopants_info( self.dopants, self.reppositions, self.repcagepos, self.repcell) # put the (one-off) groups if len(self.spot_groups) > 0: # process the -H option for cage, group_to in self.spot_groups.items(): group, root = group_to.split(":") self.add_group(cage, group, int(root)) molecules = defaultdict(list) if len(self.spot_guests) > 0: # process the -G option for cage, molec in self.spot_guests.items(): molecules[molec].append(cage) self.filled_cages.add(cage) if guests is not None: # process the -g option for arg in guests: cagetype, spec = arg[0].split("=") assert cagetype in self.cagetypes, "Nonexistent cage type: {0}".format( cagetype) resident = dict() rooms = list(self.cagetypes[cagetype] - self.filled_cages) for room in rooms: resident[room] = None # spec contains a formula consisting of "+" and "*" contents = spec.split("+") vacant = len(rooms) for content in contents: if "*" in content: molec, frac = content.split("*") frac = float(frac) else: molec = content frac = 1.0 nmolec = int(frac * len(rooms) + 0.5) vacant -= nmolec assert vacant >= 0, "Too many guests." remain = nmolec movedin = [] while remain > 0: r = random.randint(0, len(rooms) - 1) room = rooms[r] if resident[room] is None: resident[room] = molec molecules[molec].append(room) movedin.append(room) remain -= 1 #self.logger.info( # " {0} * {1} @ {2}".format(molec, nmolec, movedin)) # Now ge got the address book of the molecules. if len(molecules): self.logger.info(" Summary of guest placements:") self.guests_info(self.cagetypes, molecules) if len(self.spot_groups) > 0: self.logger.info(" Summary of groups:") self.groups_info(self.groups) # semi-guests for root, cages in self.groups.items(): assert root in self.dopants name = self.dopants[root] molname = "G{0}".format(root) pos = self.reppositions[root] rot = self.rotmatrices[root] self.atoms.append([0, molname, name, self.repcell.rel2abs(pos), 0]) del self.dopants[root] # processed. self.logger.debug((root,cages,name,molname,pos,rot)) for cage, group in cages.items(): assert group in self.groups_placer assert cage in dopants_neighbors[root] cpos = self.repcagepos[cage] self.atoms += self.groups_placer[group](cpos, pos, self.repcell, molname) # molecular guests for molec, cages in molecules.items(): gmol = safe_import("molecule", molec) cpos = [self.repcagepos[i] for i in cages] cmat = [np.identity(3) for i in cages] self.atoms += arrange_atoms(cpos, self.repcell, cmat, gmol.sites, gmol.labels, gmol.name) # Assume the dopant is monatomic and replaces one water molecule atomset = defaultdict(set) for label, name in self.dopants.items(): atomset[name].add(label) for name, labels in atomset.items(): pos = [self.reppositions[i] for i in sorted(labels)] rot = [self.rotmatrices[i] for i in sorted(labels)] self.atoms += arrange_atoms(pos, self.repcell, rot, [[0., 0., 0.], ], [name], name) self.logger.info("Stage7: end.")