def main(in_xyz, in_log, target, output, bonding, thresh, kind): if (in_xyz): mol = rf.mol_from_file(in_xyz) else: mol = rf.mol_from_gauss(in_log) charges = rf.read_g_char(in_log, kind)[0] cluster = rf.mol_from_file(target) mol.set_bonding(bonding=bonding, thresh=thresh) cluster.set_bonding(bonding=bonding, thresh=thresh) for atom, char in zip(mol, charges): atom.q = char assign_charges(mol, cluster) # warning if some atoms have not been assigned or if some original charges # were 0 bad_atoms = [] for atom in cluster: if abs(atom.q) <= 0.000: bad_atoms.append(atom) if len(bad_atoms) > 0: print("WARNING: " + str(len(bad_atoms)) + " atoms have null charge!") print(bad_atoms) out_file = open(output, "w") out_file.write(str(len(cluster)) + "\n\n") for atom in cluster: out_file.write(str(atom) + "\n") out_file.close()
def run(self, atoms): """ Write a DFTB .gen file and return a subprocess.Popen Parameters ---------- atoms : list of Atom objects Atoms to be calculated with DFTB+ Returns ------- proc : subprocess.Popen object the object should have a .wait() method """ dftb_path = os.path.join(self.here, self.calc_name) os.chdir(dftb_path) mol = Mol(atoms) region_2_file = "r2.xyz" if os.path.exists(region_2_file): mol_r2 = rf.mol_from_file(region_2_file) mol += mol_r2 mol.write_xyz("geom.xyz") subprocess.call("xyz2gen geom.xyz", shell=True) # Run DFTB+ proc = subprocess.Popen("dftb+ > dftb_out", shell=True) os.chdir(self.here) return proc
def main(args): in_atoms = args.in_xyz atoms = rf.mol_from_file(in_atoms) out_file = open("volumes", "w") prox_grid = vo.CubeGrid() vdw_grid = vo.CubeGrid() mol = atoms.select(args.atom_label - 1) c_x, c_y, c_z = mol.centroid() x_dim, y_dim, z_dim = args.dimensions[0], args.dimensions[ 1], args.dimensions[2] prox_grid.grid_from_point(c_x, c_y, c_z, res=args.resolution, box=np.array([[x_dim, 0.0, 0.0], [0.0, y_dim, 0.0], [0.0, 0.0, z_dim]])) vdw_grid.grid_from_point(c_x, c_y, c_z, res=100, box=np.array([[x_dim, 0.0, 0.0], [0.0, y_dim, 0.0], [0.0, 0.0, z_dim]])) rest = [] for atom in atoms: if atom not in mol: rest.append(atom) prox_grid.set_grid_coord() vdw_grid.set_grid_coord() prox_grid.proximity(mol, rest) vdw_grid.vdw_vol(mol) prox_grid.out_cube("voro.cube", atoms) out_file.write("Voronoi volume: " + str(prox_grid.volume()) + "\n") vdw_grid.out_cube("vdw.cube", atoms) out_file.write("VDW volume: " + str(vdw_grid.volume()) + "\n") prox_grid.add_grid(vdw_grid.grid) out_file.write("Union volume: " + str(prox_grid.volume()) + "\n") prox_grid.out_cube("add.cube", atoms) out_file.close()
def picker(in_name, out_name, labels, bonding, thresh, reverse=False): """ Pick out molecules from an xyz file Parameters ---------- in_name : str Name of the .xyz input file out_name : str Name of the .xyz output file labels : list of ints Labels of the atoms in the molecules to select (array starts at 0) max_bl : float Maximun distance in Angstrom that constitutes a bond """ atoms = rf.mol_from_file(in_name) if thresh == 999: thresh = None atoms.set_bonding(bonding=bonding, thresh=thresh) # if the label does not exist if max(labels) > len(atoms): raise ValueError("One or more atom labels were too high!") selected = atoms.copy() selected.atoms = [] for label in labels: mol = atoms.select(label) # prevent double selecting if mol[0] in selected: raise ValueError("Atom " + str(label) + " was already selected!") selected += mol # to print out the non specified atoms if reverse: to_remove = [copy(i) for i in selected] selected = atoms.copy() selected.atoms = [] for atom in atoms: if atom not in to_remove: selected.append(atom) selected.write_xyz(out_name)
def make_region_2(self): """ Get region 2 Mols with different charges Returns ------- shell_high : Mol object Region 2 molecules with high level of theory charges shell_low : Mole object Region 2 molecules with low level of theory charges """ if self.inputs["target_shell"]: shell_high = rf.mol_from_file(self.inputs["target_shell"]) self.write_out("Outer region read in with " + str(len(shell_high)) + " atoms.\n") high_level_pop_mol = rf.mol_from_gauss( self.inputs["high_pop_file"], pop=self.inputs["high_pop_method"]) shell_high.populate(high_level_pop_mol) else: shell_high = self.cell.make_cluster(self.inputs["clust_rad"], central_mol=self.region_1, mode=self.inputs["clust_mode"]) for atom_i in self.region_1: for atom_j in shell_high: if atom_i.very_close(atom_j): shell_high.remove(atom_j) break self.write_out("Outer region generated with " + str(len(shell_high)) + " atoms.\n") low_level_pop_mol = rf.mol_from_gauss( self.inputs["low_pop_file"], pop=self.inputs["low_pop_method"]) shell_low = shell_high.copy() shell_low.populate(low_level_pop_mol) return shell_low, shell_high
output_file.close() return here = os.getcwd() output_file = open(here + "/prep.out", "w") # print start time start_time = datetime.now() output_file.write("STARTING TIME: " + str(start_time) + "\n") # read config inputs inputs = pcf.parse_inputs("config") # read the input cell cell = rf.mol_from_file(inputs["cell_file"]) cell.vectors = inputs["vectors"] cell.bonding = inputs["bonding"] cell.thresh = inputs["bond_thresh"] cell = cell.confined() output_file.write("Read " + str(len(cell)) + " atoms in cell_file\n") output_file.close() # High level charge assignment populate_cell(cell, inputs["high_pop_program"], inputs["high_pop_file"], inputs["high_pop_method"]) region_1, cell = cell.centered_mols(inputs["atom_label"]) # write useful xyz and new cell region_1.write_xyz("mol.init.xyz")
def hc1_mol(): """HC1 monomer""" mol = rf.mol_from_file(_in_data("hc1_mol.xyz")) return mol
def hc1_array(): """Coordinate array for the HC1 monomer""" mol = rf.mol_from_file(_in_data("hc1_mol.xyz")) arr = mol.coord_array() return arr
def h2o_dim_array(): """Coordinate array for H2O dimer""" mol = rf.mol_from_file(_in_data("h2o_dimer.xyz")) arr = mol.coord_array() return arr
def rectangle_mol(): """Roughly rectangular soup of atoms""" mol = rf.mol_from_file(_in_data("rectangle_atom_soup.xyz")) return mol
def h2o_dup(): """H2O molecule with duplicate atoms""" out_mol = rf.mol_from_file(_in_data("h2o_repeated.xyz")) return out_mol
def h2o_dup(): out_mol = rf.mol_from_file("h2o_repeated.xyz") return out_mol
def pery_cell(): """Return a Mol object of the uncharged perylene cell""" out_cell = rf.mol_from_file("perylene_cell.xyz") out_cell.vectors = rf.read_vectors("perylene_vectors") return out_cell
def benz_clust_char(benz_solo): """Return a Mol object of a charged benzene cluster""" out_char_clust = rf.mol_from_file("benzene_clust.xyz") ac.assign_charges(benz_solo, out_char_clust) return out_char_clust
def main(in_xyz, vectors_file, complete, confine, frac, dupli, output, bonding, thresh, bonding_str, print_mono, trans, clust_rad, inclusivity, center_label): vectors = rf.read_vectors(vectors_file) atoms = rf.mol_from_file(in_xyz, vectors=vectors) if thresh == 999: thresh = None atoms.set_bonding(bonding=bonding, thresh=thresh) # if the bonding is specified all in one string if bonding_str: atoms.set_bonding_str(bonding_str) if print_mono and not complete: print("-c is required for -m") return if sum([complete, confine, frac]) > 1: print("-c, -C and -f are mutually exclusive") return print_now = True centered = False if center_label: central_mol, atoms = atoms.centered_mols(center_label - 1) # -1 for Python index centered = True if complete: # get the modified (uncropped) unit cell mod_cell, mols = atoms.complete_cell() elif confine: # get the cell confined to primitive mod_cell = atoms.confined() elif frac: # get the cell in fractional coordinates mod_cell = atoms.dir_to_frac_pos() elif centered: mod_cell = atoms.copy() else: mod_cell = deepcopy(atoms) print_now = False if dupli: # purge duplicate atoms mod_cell.remove_duplicates() print_now = True if print_now: mod_cell.write_xyz(output) if trans: translation = np.array(trans) new_atoms = mod_cell.supercell(translation) new_vec = (vectors.T * translation.transpose()).T new_atoms.write_xyz("supercell_out.xyz") ef.write_lat_vec("supercell_vectors", new_vec) if clust_rad > 0.0: clust = atoms.make_cluster(clust_rad, mode=inclusivity) clust.write_xyz("cluster_out.xyz") if print_mono: identities = [] # for each molecule of the modified unit cell for mol_i in mols: # get the rest of the molecules rest = [] for mol_j in mols: if mol_j != mol_i: rest.append(mol_j) identity = [] # for each dimer including the selected molecule for mol_j in rest: dimer_distances = [] # get all of the interatomic distances across the dimer using the # shortest lattice distance for at_i in mol_i: for at_j in mol_j: dimer_distances.append(at_i.per_dist(at_j, vectors)) dimer_distances.sort() identity.append(dimer_distances) identity.sort() identities.append(identity) identities = np.array(identities) # list of each molecules paired with its identity # in Python 2 we could just use a zip but for compatibility with Python3 # we need a list of tuples mols_ids = [(mol_i, iden_i) for mol_i, iden_i in zip(mols, identities)] # list of each molecule paired with its identity separated by equivalent # molecule sep_mols_ids = [] while len(mols_ids) > 0: sep_mol_id = [mols_ids[0]] for mol_i, id_i in mols_ids[1:]: comp = compare_id(mols_ids[0][1], id_i) # if the identities being compared don't have the same dimension, # the comparison will return None. This implies that the molecules # are not equivalent. This case only happens in crystals with # different monomers if comp: if comp < 0.001: sep_mol_id.append((mol_i, id_i)) mols_ids.remove((mol_i, id_i)) del mols_ids[0] sep_mols_ids.append(sep_mol_id) for counter, equimols in enumerate(sep_mols_ids): # only the list of lists of atoms i.e. list of molecules which are # equivalent fequimols = [i[0] for i in equimols] # make it a flat list fequimols = [inner for outer in fequimols for inner in outer] ef.write_xyz("mono_" + str(counter + 1) + ".xyz", fequimols) return