def printgeoms(): globs = globalvars() if globs.custom_path: f = globs.custom_path + "/Data/coordinations.dict" else: f = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Data/coordinations.dict") f = open(f, 'r') s = f.read().splitlines() s = [_f for _f in s if _f] f.close() geomnames = [] geomshorts = [] coords = [] for line in s: if (line[0] != '#'): vals = [_f for _f in re.split(',| |:', line) if _f] coords.append(vals[0]) geomnames.append(vals[1]) geomshorts.append(vals[2]) geomgroups = list([] for a in set(coords)) for i, g in enumerate(coords): geomgroups[int(g) - 1].append(geomshorts[i]) for i, g in enumerate(geomnames): print(("Coordination: %s, geometry: %s,\t short name: %s " % (coords[i], g, geomshorts[i]))) print('')
def getgeoms(): globs = globalvars() if globs.custom_path: f = globs.custom_path + "/Data/coordinations.dict" else: f = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Data/coordinations.dict") f = open(f, 'r') s = f.read().splitlines() s = [_f for _f in s if _f] f.close() geomnames = [] geomshorts = [] coords = [] for line in s: if (line[0] != '#'): vals = [_f for _f in re.split(',| |:', line) if _f] coords.append(vals[0]) # get coordination geomnames.append(vals[1]) # get name of geometry geomshorts.append(vals[2]) # get short names geomgroups = list([] for a in set(coords)) # get unique coordinations count = 0 geomgroups[count].append(geomshorts[0]) for i in range(1, len(coords)): if coords[i - 1] != coords[i]: count += 1 geomgroups[count].append(geomshorts[i]) return coords, geomnames, geomshorts, geomgroups
def readfromtxt(mol, txt): # print('!!!!', filename) globs = globalvars() en_dict = globs.endict() mol.graph = [] for line in txt: line_split = line.split() if len(line_split) == 4 and line_split[0]: # this looks for unique atom IDs in files lm = re.search(r'\d+$', line_split[0]) # if the string ends in digits m will be a Match object, or None otherwise. if lm is not None: symb = re.sub('\d+', '', line_split[0]) # number = lm.group() # # print('sym and number ' +str(symb) + ' ' + str(number)) # globs = globalvars() atom = atom3D(symb, [float(line_split[1]), float(line_split[2]), float(line_split[3])], name=line_split[0]) elif line_split[0] in en_dict.keys(): atom = atom3D(line_split[0], [float(line_split[1]), float(line_split[2]), float(line_split[3])]) else: print('cannot find atom type') sys.exit() mol.addAtom(atom) return mol
def readfromtxt(mol, txt): # print('!!!!', filename) globs = globalvars() en_dict = globs.endict() mol.graph = [] for line in txt: line_split = line.split() if len(line_split) == 4 and line_split[0]: # this looks for unique atom IDs in files lm = re.search(r'\d+$', line_split[0]) # if the string ends in digits m will be a Match object, or None otherwise. if lm is not None: symb = re.sub('\d+', '', line_split[0]) # number = lm.group() # # print('sym and number ' +str(symb) + ' ' + str(number)) # globs = globalvars() atom = atom3D(symb, [ float(line_split[1]), float(line_split[2]), float(line_split[3]) ], name=line_split[0]) elif line_split[0] in list(en_dict.keys()): atom = atom3D(line_split[0], [ float(line_split[1]), float(line_split[2]), float(line_split[3]) ]) else: print('cannot find atom type') sys.exit() mol.addAtom(atom) return mol
def __init__(self, Sym='C', xyz=[0.0, 0.0, 0.0], name=False): # Element symbol self.sym = Sym globs = globalvars() amass = globs.amass() if Sym not in amass: # assign default values if not in dictionary print(("We didn't find the atomic mass of %s in the dictionary. Assigning default value of 12!\n" % (Sym))) # Atomic mass self.mass = 12 # default atomic mass # Atomic number self.atno = 6 # default atomic number # Covalent radius self.rad = 0.75 # default atomic radius else: self.mass = amass[Sym][0] self.atno = amass[Sym][1] self.rad = amass[Sym][2] # Flag for freezing in optimization self.frozen = False # Flag for atom name if name: self.name = name else: self.name = Sym # flag for metal self.metal = None # Coordinates self.__xyz = xyz
def check_top_layer_correct(super_cell, atom_type): # remove the layer on # top of the cell if # wrong material is exposed trimmed_cell = mol3D() trimmed_cell.copymol3D(super_cell) globs = globalvars() elements = globs.elementsbynum() print(('chekcing surface for ' + atom_type + '\n')) if not atom_type in elements: print("unkown surface type, unable to trim ") return trimmed_cell else: stop_flag = False counter = 0 # 3 tries max while not stop_flag: atom_type_surf = find_all_surface_atoms( trimmed_cell, tol=1e-3, type_of_atom=atom_type) top_surf = find_all_surface_atoms( trimmed_cell, tol=1e-3, type_of_atom=False) # print("top surf",top_surf) # print("atom top surf",atom_type_surf) if set(atom_type_surf) == set(top_surf): print('match') stop_flag = True else: counter += 1 trimmed_cell = shave_surface_layer(trimmed_cell, 1e-3) if counter == 3: print('unable to find target atom in 3 cuts') stop_flag = True return trimmed_cell
def ismetal(self): if self.metal is None: if self.sym in globalvars().metals(): self.metal = True else: self.metal = False return self.metal
def __init__(self): ## List of atom3D objects self.atoms = [] ## Number of atoms self.natoms = 0 ## Mass of molecule self.mass = 0 ## Size of molecule self.size = 0 ## Charge of molecule self.charge = 0 ## Force field optimization settings self.ffopt = 'BA' ## Name of molecule self.name = '' ## Holder for openbabel molecule self.OBMol = False ## List of connection atoms self.cat = [] ## Denticity self.denticity = 0 ## Identifier self.ident = '' ## Holder for global variables self.globs = globalvars() ## Holder for molecular graph self.graph = []
def ismetal(self): # OUTPUT # flag for metal or not if self.sym in globalvars().metals(): return True else: return False
def getMask(self, mask): globs = globalvars() elements = globs.elementsbynum() # check center of mass ats = [] # loop over entries in mask for entry in mask: # check for center of mass if ('com' in entry.lower()) or ('cm' in entry.lower()): return self.centermass() # check for range elif '-' in entry: at0 = entry.split('-')[0] at1 = entry.split('-')[-1] for i in range(int(at0), int(at1) + 1): ats.append(i - 1) # python indexing elif entry in elements: ats += self.findAtomsbySymbol(entry) else: # try to convert to integer try: t = int(entry) ats.append(t - 1) except: return self.centermass() maux = mol3D() for at in ats: maux.addAtom(self.getAtom(at)) if maux.natoms == 0: return self.centermass() else: return maux.centermass()
def getmcores(): globs = globalvars() if globs.custom_path: # test if a custom path is used: mcores = str(globs.custom_path).rstrip('/') + "/Cores/cores.dict" else: mcores = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Cores/cores.dict") mcores = readdict(mcores) return mcores
def getbcores(): globs = globalvars() if globs.custom_path: # test if a custom path is used: bcores = str(globs.custom_path).rstrip('/') + "/Bind/bind.dict" else: bcores = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Bind/bind.dict") bcores = readdict(bcores) return bcores
def getsubcores(): globs = globalvars() if globs.custom_path: # test if a custom path is used: subcores = str( globs.custom_path).rstrip('/') + "/Substrates/substrates.dict" else: subcores = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Substrates/substrates.dict") subcores = readdict_sub(subcores) return subcores
def getslicores(): globs = globalvars() if globs.custom_path: # test if a custom path is used: slicores = str( globs.custom_path).rstrip('/') + "/Ligands/simple_ligands.dict" else: slicores = resource_filename( Requirement.parse("molSimplify"), "molSimplify/Ligands/simple_ligands.dict") slicores = readdict(slicores) return slicores
def mutate(self, newType): globs = globalvars() amass = globs.amass() if newType not in list(amass.keys()): print(('Error, unknown atom atom type transformation to ' + str(newType))) print('no changes made') else: self.mass = amass[newType][0] self.atno = amass[newType][1] self.rad = amass[newType][2] self.name = newType self.sym = newType
def get_lig_EN(mol,connection_atoms): ## calculate the maximum abs electronegativity ## difference between connection atom an all ## neighbors max_EN = 0 globs =globalvars() for atoms in connection_atoms: this_atoms_neighbors = mol.getBondedAtomsSmart(atoms) for bound_atoms in this_atoms_neighbors: this_EN = float(globs.endict()[mol.getAtom(atoms).symbol()]) - float(globs.endict()[mol.getAtom(bound_atoms).symbol()]) if (abs(this_EN) >= max_EN): max_EN = this_EN return max_EN
def convert2mol3D(self): # initialize again self.initialize() # get elements dictionary elem = globalvars().elementsbynum() # loop over atoms for atom in openbabel.OBMolAtomIter(self.OBMol): # get coordinates pos = [atom.GetX(), atom.GetY(), atom.GetZ()] # get atomic symbol sym = elem[atom.GetAtomicNum() - 1] # add atom to molecule self.addAtom(atom3D(sym, [pos[0], pos[1], pos[2]]))
def construct_property_vector(mol, prop, oct=True): ## assigns the value of property ## for atom i (zero index) in mol ## to position i in returned vector ## can be used to create weighted ## graph representations # oct - bool, if complex is octahedral, will use better bond checks #allowed_strings = ['electronegativity','nulcear_charge','ident','coord'] allowed_strings = [ 'electronegativity', 'nuclear_charge', 'ident', 'topology', 'size' ] ## note that ident just codes every atom as one, this gives ## a purely toplogical index. coord gives the number of ## connecting atom to attom i (similar to Randic index) if not oct: print('NOT using octahedral bonding pattern') globs = globalvars() prop_dict = dict() w = numpy.zeros(mol.natoms) done = False if not prop in allowed_strings: print('error, property ' + str(prop) + ' is not a vaild choice') print(' options are ' + str(allowed_strings)) return False if prop == 'electronegativity': prop_dict = globs.endict() elif prop == 'size': at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][2] prop_dict.update({keys: values}) elif prop == 'nuclear_charge': at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][1] prop_dict.update({keys: values}) elif prop == 'ident': at_keys = globs.amass().keys() for keys in at_keys: prop_dict.update({keys: 1}) elif prop == 'topology': for i, atoms in enumerate(mol.getAtoms()): #print('atom # ' + str(i) + " symbol = " + str(atoms.symbol())) w[i] = len(mol.getBondedAtomsSmart(i, oct=oct)) done = True if not done: for i, atoms in enumerate(mol.getAtoms()): #print('atom # ' + str(i) + " symbol = " + str(atoms.symbol())) w[i] = prop_dict[atoms.symbol()] return (w)
def ismetal(self): """ Identify whether an atom is a metal. Returns ------- metal : bool Bool for whether or not an atom is a metal. """ if self.metal is None: if self.sym in globalvars().metalslist(): self.metal = True else: self.metal = False return self.metal
def get_lig_EN(mol, connection_atoms): # calculate the maximum abs electronegativity # difference between connection atom an all # neighbors max_EN = 0 globs = globalvars() for atoms in connection_atoms: this_atoms_neighbors = mol.getBondedAtomsSmart(atoms) for bound_atoms in this_atoms_neighbors: this_EN = float(globs.endict()[mol.getAtom(atoms).symbol( )]) - float(globs.endict()[mol.getAtom(bound_atoms).symbol()]) if (abs(this_EN) >= max_EN): max_EN = this_EN return max_EN
def __init__(self): globs = globalvars() self.sanity_is_set = False # flag to indicate if properties # have been written to this file self.ANN_is_set = False self.bl_is_set = False self.mol_is_set = False self.sanity = False self.min_dist = False self.ANN_flag = False # ANN value has been set? self.ANN_reason = " not set" # Reason ANN not set self.ANN_attributes = dict() # placeholder for # predicted properties self.dict_bondl = False # stores the ML-dict bond dist self.mol = False # stores a mol3D representation of the mol.
def getlicores(flip=True): globs = globalvars() if globs.custom_path: # test if a custom path is used: licores = str(globs.custom_path).rstrip('/') + "/Ligands/ligands.dict" else: licores = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Ligands/ligands.dict") licores = readdict(licores) if flip: for ligand in list(licores.keys()): if len(licores[ligand][2]) == 2 and type( licores[ligand][2]) == list: licores[ligand + '_flipped'] = copy.deepcopy(licores[ligand]) licores[ligand + '_flipped'][2].reverse() return licores
def getsimilar(smi, nmols, dbselect, finger, squery, args): # get database files [dbsdf, dbfs] = setupdb(dbselect) print(('database set up :' + str(dbsdf) + ' || ' + str(dbfs))) globs = globalvars() print(('Finding results similar, comparing to ' + smi)) obab = 'babel' if dbfs and args.dbfs: com = obab + ' ' + dbfs + ' ' + 'simres.smi -d -xf' + \ finger + ' -s"' + smi + '" -al' + nmols else: mybash(obab + ' -isdf ' + dbsdf + ' -osdf -O tmp.sdf -d') com = obab + ' tmp.sdf simres.smi -xf' + finger + ' -s"' + smi + '"' # perform search using bash commandline print('Performing substructure search:') print(('running: ' + str(com))) res = mybash(com) print(('res = ' + str(res))) print(('number of SMILES returned : ' + str(mybash('cat simres.smi | wc -l')))) if os.path.isfile('tmp.sdf'): os.remove('tmp.sdf') shutil.copy('simres.smi', 'initial.smi') if args.dbmaxsmartsmatches: print('Applying filters: inside get similar') com = obab + " -ismi simres.smi -osmi -O simres.smi -h --filter " + squery print(('running: ' + str(com))) mybash(com) print(('number of lines in simres.smi: ' + str(mybash('cat simres.smi | wc -l')))) # com = obab+" -ismi simres.smi -osmi -O simres.smi -d --filter 'nsmartsmatches<="+args.dbmaxsmartsmatches+"'" # rint('running: '+ str(com)) # res = mybash(com) # print('number of lines in simres.smi after dxbsmartmatches: '+str(mybash('cat simres.smi | wc -l'))) # print res shutil.copy('simres.smi', 'afterfilteringsmarts.smi') # check output and print error if nothing was found if ('errors' in res): ss = 'No matches were found in DB. Log info:\n' + res print(ss) return ss, True else: return 'simres.smi', False
def grabguivarstc(gui): globs = globalvars() # list with arguments args = dict() args['-charge'] = gui.etqctch.text() args['-spin'] = gui.etqctspin.text() args['-runtyp'] = gui.qctcalc.currentText() args['-method'] = gui.etqctmethod.text() args['-basis'] = gui.etqctbasis.text() args['-dispersion'] = gui.qctsel.currentText() args['-qoption'] = gui.qceditor.toPlainText() # extra flag to control duplication prompt args['-rprompt'] = 'True' ### write input file ### writeinputc(args, globs.installdir + '/Data/.tcdefinput.inp') return args
def simple_slope_ann(slope_excitation): globs = globalvars() path_to_file = resource_filename(Requirement.parse("molSimplify"), "molSimplify/python_nn/" + "ms_slope") #print('path to ANN data: ',path_to_file) n = simple_network_builder([24, 50, 50], "ms_slope") ## no alpha value #print(slope_excitation) slope_excitation, sl_center, sl_shift = excitation_standardizer( slope_excitation, 'slope') #print(slope_excitation) result = n.activate(slope_excitation) # print('result is ' + str(result)) # print('center is ' + str(sl_center) + ' shift '+ str(sl_shift)) result = (result * sl_shift) + sl_center #print('result is ' + str(result)) return result
def loadcoord(coord): globs = globalvars() # f = open(installdir+'Data/'+coord+'.dat') if globs.custom_path: f = globs.custom_path + "/Data/" + coord + ".dat" else: f = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Data/" + coord + ".dat") f = open(f) txt = [_f for _f in f.read().splitlines() if _f] f.close() b = [] for line in txt: l = [_f for _f in line.split(None) if _f] b.append([float(l[0]), float(l[1]), float(l[2])]) return b
def simple_splitting_ann(excitation): globs = globalvars() path_to_file = resource_filename(Requirement.parse("molSimplify"), "molSimplify/python_nn/" + "ms_split") #print('path to ANN data: ',path_to_file) n = simple_network_builder([25, 50, 50], "ms_split") excitation, sp_center, sp_shift = excitation_standardizer( excitation, 'split') #print(excitation) #print('center is ' + str(sp_center)) #print('scale is '+ str(sp_shift)) #print(excitation) result = n.activate(excitation) #print('result is ' + str(result)) result = (result * sp_shift) + sp_center #print('result is ' + str(result)) return result, excitation
def grabguivarsqch(gui): globs = globalvars() # list with arguments args = dict() args['-charge'] = gui.etqcQch.text() args['-spin'] = gui.etqcQspin.text() args['-runtyp'] = gui.qcQcalc.currentText() args['-basis'] = gui.etqcQbasis.text() args['-remoption'] = gui.qcQeditor.toPlainText() args['-exchange'] = gui.etqcQex.text() args['-correlation'] = gui.etqcQcor.text() if gui.chQun: args['-unrestricted'] = '1' ### write input file ### # extra flag to control duplication prompt args['-rprompt'] = 'True' writeinputc(args, globs.installdir + '/Data/.qchdefinput.inp') return args
def grabguivarsjob(gui): globs = globalvars() # list with arguments args = dict() args['-jname'] = gui.etjname.text() args['-memory'] = gui.etjmem.text() args['-wtime'] = gui.etjwallt.text() args['-queue'] = gui.etjqueue.text() args['-gpus'] = gui.etjgpus.text() args['-cpus'] = gui.etjcpus.text() args['-modules'] = gui.etjmod.text() args['-joption'] = gui.etjopt.toPlainText() args['-jcommand'] = gui.jcomm.toPlainText() # set prompt option args['-rprompt'] = 'True' ### write input file ### writeinputc(args, globs.installdir + '/Data/.jobdefinput.inp') return args
def __init__(self): globs = globalvars() self.sanity_is_set = False # flag to indicate if properties # have been written to this file self.ANN_is_set = False self.bl_is_set = False self.mol_is_set = False self.catalysis_is_set = False self.sanity = False self.min_dist = False self.ANN_flag = False # ANN value has been set? self.ANN_reason = " not set" # Reason ANN not set self.ANN_attributes = dict() # placeholder for # predicted properties self.catalysis_flag = False self.catalysis_reason = " not activated" self.dict_bondl = False # stores the ML-dict bond dist self.mol = False # stores a mol3D representation of the mol.
def loaddata_ts(path): globs = globalvars() # loads ML data from ML.dat file and # store to dictionary if globs.custom_path: # test if a custom path is used: fname = str(globs.custom_path).rstrip('/') + path else: fname = resource_filename(Requirement.parse("molSimplify"), "molSimplify" + path) d = dict() f = open(fname) txt = f.read() lines = [_f for _f in txt.splitlines() if _f] for line in lines[1:]: if '#' != line[0]: # skip comments l = [_f for _f in line.split(None) if _f] d[(l[0], l[1], l[2], l[3])] = l[4:] # read dictionary f.close() return d
def ismetal(self, transition_metals_only=True): """ Identify whether an atom is a metal. Parameters ---------- transition_metals_only : bool, optional Identify only transition metals. Default is true. Returns ------- metal : bool Bool for whether or not an atom is a metal. """ if self.metal is None: if self.sym in globalvars().metalslist( transition_metals_only=transition_metals_only): self.metal = True else: self.metal = False return self.metal
def mutate(self, newType='C'): """ Mutate an element to another element in the atom3D. Parameters ---------- newType : str, optional Element name for new element. Default is 'C'. """ globs = globalvars() amass = globs.amass() if newType not in list(amass.keys()): print(('Error, unknown atom atom type transformation to ' + str(newType))) print('no changes made') else: self.mass = amass[newType][0] self.atno = amass[newType][1] self.rad = amass[newType][2] self.name = newType self.sym = newType
def construct_property_vector(mol, prop, oct=True,modifier = False): ## assigns the value of property ## for atom i (zero index) in mol ## to position i in returned vector ## can be used to create weighted ## graph representations ## oct - bool, if complex is octahedral, will use better bond checks ## modifier - dict, used to modify prop vector (e.g. for adding ## ONLY used with ox_nuclear_charge ox or charge) ## {"Fe":2, "Co": 3} etc allowed_strings = ['electronegativity', 'nuclear_charge', 'ident', 'topology', 'ox_nuclear_charge', 'size', 'vdwrad', 'effective_nuclear_charge'] ## note that ident just codes every atom as one, this gives ## a purely toplogical index. coord gives the number of ## connecting atom to attom i (similar to Randic index) # if not oct: # print('NOT using octahedral bonding pattern') globs = globalvars() prop_dict = dict() w = numpy.zeros(mol.natoms) done = False if not prop in allowed_strings: print('error, property ' + str(prop) + ' is not a vaild choice') print(' options are ' + str(allowed_strings)) return False if prop == 'electronegativity': prop_dict = globs.endict() elif prop == 'size': at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][2] prop_dict.update({keys: values}) elif prop == 'nuclear_charge': at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][1] prop_dict.update({keys: values}) elif prop == 'effective_nuclear_charge': #Uses number of valence electrons if not modifier: at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][3] prop_dict.update({keys: values}) else: at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][3] if keys in modifier.keys(): values += float(modifier[keys]) prop_dict.update({keys: values}) elif prop == 'ox_nuclear_charge': if not modifier: print('Error, must give modifier with ox_nuclear_charge') return False else: at_keys = globs.amass().keys() for keys in at_keys: values = globs.amass()[keys][1] if keys in modifier.keys(): values += float(modifier[keys]) prop_dict.update({keys: values}) elif prop == 'ident': at_keys = globs.amass().keys() for keys in at_keys: prop_dict.update({keys: 1}) elif prop == 'topology': for i, atoms in enumerate(mol.getAtoms()): # print('atom # ' + str(i) + " symbol = " + str(atoms.symbol())) w[i] = len(mol.getBondedAtomsSmart(i, oct=oct)) done = True elif prop == 'vdwrad': prop_dict = globs.vdwrad() for i, atoms in enumerate(mol.getAtoms()): atom_type = atoms.symbol() if atom_type in globs.metalslist(): w[i] = globs.amass()[atoms.symbol()][2] else: w[i] = prop_dict[atoms.symbol()] done = True # for keys in at_keys: # prop_dict.update({keys: 1}) if not done: for i, atoms in enumerate(mol.getAtoms()): # print('atom # ' + str(i) + " symbol = " + str(atoms.symbol())) w[i] = prop_dict[atoms.symbol()] return (w)
# Written by JP Janet for HJK Group
def write_periodic_mol3d_to_qe(mol,cell_vector,path): psd = {"Ti":'Ti.pbe-sp-van_ak.UPF','O':'O.pbe-van_ak.UPF','Si':'Si.pbe-n-van.UPF'} ## set global properties unique_atoms = mol.getAtomTypes() globs = globalvars() #print(globs) ## start writing this file: with open(path,'w') as f: f.write("&CONTROL\n") f.write('calculation = "relax" \n') f.write('prefix = clean\n') f.write('pseudo_dir = "/opt/espresso-5.1/pseudo"\n') f.write('outdir = "./"\n') f.write('wf_collect = .true\n') f.write('tprnfor = .true.\n') f.write('restart_mode = "from_scratch"\n') f.write('nstep = 1000\n') f.write("/ \n") with open(path,'a') as f: f.write("&SYSTEM\n") f.write("ibrav = 0 \n") f.write("nat = " + str(mol.natoms) + "\n") f.write("ntyp = " + str(len(unique_atoms)) + "\n") f.write("nspin = 1\n") f.write('occupations = "smearing"\n') f.write('degauss = 0.01\n') f.write('ecutwfc = 25.0 \n') f.write('ecutrho = 250.0 \n') f.write("/ \n") with open(path,'a') as f: f.write("&ELECTRONS\n") f.write("mixing_beta = 0.4 \n") f.write("electron_maxstep = 350 \n") f.write("/ \n") with open(path,'a') as f: f.write("&IONS\n") f.write("ion_dynamics = 'bfgs' \n") f.write("/ \n") with open(path,'a') as f: f.write("CELL_PARAMETERS {angstrom}\n") for cv in cell_vector: ss = " ".join(str(e) for e in cv) + "\n" f.write(ss) f.write(" \n") with open(path,'a') as f: f.write("ATOMIC_SPECIES\n") for elements in unique_atoms: ps_info = ".pbe-van_ak.UPF" m_ps = ".pbe-sp-van_ak.UPF" if str(elements) in psd.keys(): ps_info = str(psd[str(elements)]) if len(elements) == 1: f.write(str(elements) + " " + str(globs.amass()[elements][0]) + " " + ps_info + '\n') else: f.write(str(elements) + " " + str(globs.amass()[elements][0]) + " " + ps_info + '\n') with open(path,'a') as f: pos_list =list() write_list = list() f.write("ATOMIC_POSITIONS {angstrom}\n") for atom in mol.atoms: xyz = atom.coords() if atom.frozen: freeze_vect = [0,0,0] else: freeze_vect = [1,1,1] pos_list.append(xyz[2]) write_list.append((atom.sym,xyz[0],xyz[1],xyz[2],freeze_vect[0],freeze_vect[1],freeze_vect[2])) sorted_inds = [i[0] for i in sorted(enumerate(pos_list),key=lambda x:x[1])] for inds in sorted_inds: f.write("%s %f %f %f %f %f %f\n" % write_list[inds]) # f.write("%s %f %f %f %f %f %f\n" % (atom.sym,xyz[0],xyz[1],xyz[2],freeze_vect[0],freeze_vect[1],freeze_vect[2])) with open(path,'a') as f: f.write("K_POINTS {automatic}\n") f.write("4 4 1 0 0 0\n")