def make_atoms(index, lines, key, cell): """Scan through lines to get the atomic positions.""" atoms = Atoms() if key == 'Cartesian axes': for line in lines[index + 3:]: entries = line.split() if len(entries) == 0: break symbol = entries[1][:-1] x = float(entries[6]) y = float(entries[7]) z = float(entries[8]) atoms.append(Atom(symbol, (x, y, z))) atoms.set_cell(cell) elif key == 'ATOMIC_POSITIONS (crystal)': for line in lines[index + 1:]: entries = line.split() if len(entries) == 0 or (entries[0] == 'End'): break symbol = entries[0][:-1] x = float(entries[1]) y = float(entries[2]) z = float(entries[3]) atoms.append(Atom(symbol, (x, y, z))) atoms.set_cell(cell, scale_atoms=True) # Energy is located after positions. energylines = [ number for number, line in enumerate(lines) if ('!' in line and 'total energy' in line) ] energyline = min([n for n in energylines if n > index]) energy = float(lines[energyline].split()[-2]) * units.Ry # Forces are located after positions. forces = np.zeros((len(atoms), 3)) forcelines = [ number for number, line in enumerate(lines) if 'Forces acting on atoms (Ry/au):' in line ] forceline = min([n for n in forcelines if n > index]) for line in lines[forceline + 4:]: words = line.split() if len(words) == 0: break fx = float(words[-3]) fy = float(words[-2]) fz = float(words[-1]) atom_number = int(words[1]) - 1 forces[atom_number] = (fx, fy, fz) forces *= units.Ry / units.Bohr calc = SinglePointCalculator(atoms, energy=energy, forces=forces) atoms.set_calculator(calc) return atoms
def _read_geometry(content): """Helper to read geometry, returns a list of Atoms""" atom_list = [] for entry in content: entry = entry.split() # Get letters for element symbol el = [char.lower() for char in entry[0] if char.isalpha()] el = "".join(el).capitalize() # Get positions pos = [float(x) for x in entry[1:4]] if el in atomic_numbers.keys(): atom_list.append(Atom(el, pos)) else: atom_list.append(Atom('X', pos)) return atom_list
def read_pdb(fileobj, index=-1): """Read PDB files. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = open(fileobj) images = [] atoms = Atoms() for line in fileobj.readlines(): if line.startswith('ATOM') or line.startswith('HETATM'): try: # Atom name is arbitrary and does not necessarily contain the element symbol. # The specification requires the element symbol to be in columns 77+78. symbol = line[76:78].strip().lower().capitalize() words = line[30:55].split() position = np.array([float(words[0]), float(words[1]), float(words[2])]) atoms.append(Atom(symbol, position)) except: pass if line.startswith('ENDMDL'): images.append(atoms) atoms = Atoms() if len(images) == 0: images.append(atoms) return images[index]
def read_pdb(fileobj, index=-1): """Read PDB files. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = open(fileobj) atoms = Atoms() for line in fileobj.readlines(): if line.startswith('ATOM') or line.startswith('HETATM'): try: symbol = line[12:16].strip() # we assume that the second character is a label # in case that it is upper case if len(symbol) > 1 and symbol[1].isupper(): symbol = symbol[0] words = line[30:55].split() position = np.array( [float(words[0]), float(words[1]), float(words[2])]) atoms.append(Atom(symbol, position)) except: pass return atoms
def build_atoms(positions, method, cell, alat): """Creates the atoms for a quantum espresso in file.""" if method != 'crystal': raise NotImplementedError('Only supported for crystal method of ' 'ATOMIC_POSITIONS, not %s.' % method) atoms = Atoms() for el, (x, y, z) in positions: atoms.append(Atom(el, (x, y, z))) cell *= f2f(alat) * units.Bohr atoms.set_cell(cell, scale_atoms=True) return atoms
def json_to_ase(datarow): """ An extended *mpds_client* static *compile_crystal* method for handling the disordered structures in an oversimplified, very narrow-purpose way """ if not datarow or not datarow[-1]: return None, "No structure found" occs_noneq, cell_abc, sg_n, setting, basis_noneq, els_noneq = \ datarow[-6], datarow[-5], int(datarow[-4]), datarow[-3], datarow[-2], datarow[-1] occ_data = None if any([occ != 1 for occ in occs_noneq]): partial_pos, occ_data = {}, {} for n in range(len(occs_noneq) - 1, -1, -1): if occs_noneq[n] != 1: disordered_pos = basis_noneq.pop(n) disordered_el = els_noneq.pop(n) partial_pos.setdefault(tuple(disordered_pos), {})[disordered_el] = occs_noneq[n] for xyz, occs in partial_pos.items(): index = len(els_noneq) els_noneq.append(sorted(occs.keys())[0]) basis_noneq.append(xyz) occ_data[index] = occs atom_data = [] setting = 2 if setting == '2' else 1 for n, xyz in enumerate(basis_noneq): atom_data.append(Atom(els_noneq[n], tuple(xyz), tag=n)) if not atom_data: return None, "No atoms found" try: return crystal( atom_data, spacegroup=sg_n, cellpar=cell_abc, primitive_cell=True, setting=setting, onduplicates='error', info=dict(disordered=occ_data) if occ_data else {}), None except: return None, "ASE cannot handle structure"
def read_pdb(fileobj, index=-1): """Read PDB files. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect8.html and http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = open(fileobj) images = [] orig = np.identity(3) trans = np.zeros(3) atoms = Atoms() for line in fileobj.readlines(): if line.startswith('CRYST1'): cellpar = [float(word) for word in line[6:54].split()] atoms.set_cell(cellpar_to_cell(cellpar)) for c in range(3): if line.startswith('ORIGX' + '123'[c]): pars = [float(word) for word in line[10:55].split()] orig[c] = pars[:3] trans[c] = pars[3] if line.startswith('ATOM') or line.startswith('HETATM'): try: # Atom name is arbitrary and does not necessarily contain the element symbol. # The specification requires the element symbol to be in columns 77+78. symbol = line[76:78].strip().lower().capitalize() words = line[30:55].split() position = np.array( [float(words[0]), float(words[1]), float(words[2])]) position = np.dot(orig, position) + trans atoms.append(Atom(symbol, position)) except: pass if line.startswith('ENDMDL'): images.append(atoms) atoms = Atoms() if len(images) == 0: images.append(atoms) return images[index]
def read_proteindatabank(fileobj, index=-1): """Read PDB files.""" if isinstance(fileobj, basestring): fileobj = open(fileobj) images = [] orig = np.identity(3) trans = np.zeros(3) atoms = Atoms() for line in fileobj.readlines(): if line.startswith('CRYST1'): cellpar = [float(word) for word in line[6:54].split()] atoms.set_cell(cellpar_to_cell(cellpar)) atoms.pbc = True for c in range(3): if line.startswith('ORIGX' + '123'[c]): pars = [float(word) for word in line[10:55].split()] orig[c] = pars[:3] trans[c] = pars[3] if line.startswith('ATOM') or line.startswith('HETATM'): try: # Atom name is arbitrary and does not necessarily # contain the element symbol. The specification # requires the element symbol to be in columns 77+78. symbol = line[76:78].strip().lower().capitalize() words = line[30:55].split() position = np.array( [float(words[0]), float(words[1]), float(words[2])]) position = np.dot(orig, position) + trans atoms.append(Atom(symbol, position)) except Exception as ex: warnings.warn( 'Discarding atom when reading PDB file: {}'.format(ex)) if line.startswith('ENDMDL'): images.append(atoms) atoms = Atoms() if len(images) == 0: images.append(atoms) return images[index]
def spglib_to_ase(molecule, indices=None): basis = molecule[1] atomic_numbers = molecule[2] if indices == None: indices = range(0, len(atomic_numbers)) lattice = np.transpose(np.asarray(molecule[0])) #print(lattice) ase_molecule = [] for ia in indices: atomic_symbol = an_to_symbol[atomic_numbers[ia]] # Have to store in Cartesian pos = np.matmul(lattice, np.asarray(basis[ia])) # Fractional #print(ia, basis[ia]) ase_molecule.append(Atom(atomic_symbol, pos)) return Atoms(ase_molecule, cell=molecule[0])
def read_log(self, file_path=None): """ A helper method that allows one to easily parse log files """ symbol_dict = { 35: "Br", 17: "Cl", 9: "F", 8: "O", 7: "N", 6: "C", 1: "H", } atoms = [] parser = ccread(file_path) for atom_num, coords in zip(parser.atomnos, parser.atomcoords[-1]): atoms.append(Atom(symbol=symbol_dict[atom_num], position=coords)) return Atoms(atoms)
def get_atoms_from_xml_output(filename, schema=None, output=None): """ Returns an Atoms object constructed from an XML QE file (according to the schema). :param filename: Name of the XML file to read from or a file descriptor. :param schema: Optional XML Schema file to use (for default schema is \ found using the schemaLocation attribute of the XML root). :param output: Optional dictionary containing the output tree of the XML file. \ If provided skips file access and builds Atoms object directly from output dictionary. :return: An Atoms object. """ if output is None: output = xmlschema.to_dict(filename, schema=schema, path="./qes:espresso/output") a1 = np.array(output["atomic_structure"]["cell"]["a1"]) a2 = np.array(output["atomic_structure"]["cell"]["a2"]) a3 = np.array(output["atomic_structure"]["cell"]["a3"]) a_p = (output["atomic_structure"]["atomic_positions"]["atom"]) atoms = Atoms() # First define the unit cell from a1, a2, a3 and alat cell = np.zeros((3, 3)) cell[0] = a1 cell[1] = a2 cell[2] = a3 atoms.set_cell(cell) # Now the atoms in the unit cell for atomx in a_p: # TODO: extend to all possible cases the symbol splitting (for now, only numbering up to 9 work). Not a very common case... symbol = split_atomic_symbol(atomx['@name'])[0] x = float(atomx['$'][0]) y = float(atomx['$'][1]) z = float(atomx['$'][2]) atoms.append(Atom(symbol, (x, y, z))) return atoms
def read_struct_out(fname): """Read a siesta struct file""" from ase.atoms import Atoms, Atom f = fname cell = [] for i in range(3): cell.append([float(x) for x in f.readline().split()]) natoms = int(f.readline()) atoms = Atoms() for atom in f: Z, pos_x, pos_y, pos_z = atom.split()[1:] atoms.append(Atom(int(Z), position=(float(pos_x), float(pos_y), float(pos_z)))) if len(atoms) != natoms: raise IOError('Badly structured input file') atoms.set_cell(cell, scale_atoms=True) return atoms
def lewis2xyz(lewis,f='SMILES',aromatic=False,dim=2,addH=True): # Input # lewis ... smiles format string # aromatic ... is the system aromatic # dim ... 2d == 2 and 3d == 3 # Output # Bonding information # Lewis pictures # sdf and xyz files if f == 'pdb': m = Chem.MolFromPDBFile(lewis) if f == 'xyz': struct = read(lewis) write('lewis.pdb',struct,'proteindatabank') m = Chem.MolFromPDBFile(lewis) if f == 'SMILES': m = Chem.MolFromSmiles(lewis) # Change armatic bonds to alternate single and double bonds if aromatic == True: if m.GetBondWithIdx(0).GetIsAromatic() == True: Chem.Kekulize(m) if addH == True: m=Chem.AddHs(m) if dim == 1 or dim == 2: AllChem.Compute2DCoords(m) if dim == 3: AllChem.EmbedMolecule(m) AllChem.UFFOptimizeMolecule(m) fods = Atoms() # core electrons for atom in m.GetAtoms(): idx = atom.GetIdx() # atomic number N = m.GetAtomWithIdx(idx).GetAtomicNum() # number of valence electrons V = m.GetAtomWithIdx(idx).GetTotalValence() # number of radicals R = atom.GetNumRadicalElectrons() # formal charge of the atom F = atom.GetFormalCharge() # number of core electrons C = N-V-R-F # lone pairs #L = 0 #bonds = atom.GetBonds() #for b in range(len(bonds)): # bond_type = bonds[b].GetBondType() # if str(bond_type) == 'SINGLE': # L = L + 1 # if str(bond_type) == 'DOUBLE': # L = L + 2 # if str(bond_type) == 'TRIPLE': # L = L + 3 #print(V-L) if C > 0: pos = m.GetConformer().GetAtomPosition(idx) offset = 0.002 if C == 1: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) if C == 2: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) if C == 3: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) fods.append(Atom('X',[pos[0]+offset,pos[1]+offset,pos[2]+4*offset])) if C == 4: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) fods.append(Atom('X',[pos[0]+offset,pos[1]+offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]-40*offset])) if C == 5: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) fods.append(Atom('X',[pos[0]+offset,pos[1]+offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]-40*offset])) fods.append(Atom('X',[pos[0]+40*offset,pos[1]+40*offset,pos[2]+offset])) if C == 6: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) fods.append(Atom('X',[pos[0]+40*offset,pos[1]+40*offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+offset,pos[1]-40*offset,pos[2]-40*offset])) fods.append(Atom('X',[pos[0]-40*offset,pos[1]+40*offset,pos[2]-40*offset])) fods.append(Atom('He',[pos[0]-40*offset,pos[1]-40*offset,pos[2]+40*offset])) if C == 7: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) fods.append(Atom('X',[pos[0]+40*offset,pos[1]+40*offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+offset,pos[1]-40*offset,pos[2]-40*offset])) fods.append(Atom('X',[pos[0]-40*offset,pos[1]+40*offset,pos[2]-40*offset])) fods.append(Atom('He',[pos[0]-40*offset,pos[1]-40*offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+42*offset,pos[1]+42*offset,pos[2]+42*offset])) if C == 8: fods.append(Atom('X',[pos[0],pos[1],pos[2]])) fods.append(Atom('He',[pos[0]+offset,pos[1]+offset,pos[2]+offset])) fods.append(Atom('X',[pos[0]+40*offset,pos[1]+40*offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+40*offset,pos[1]-40*offset,pos[2]-40*offset])) fods.append(Atom('X',[pos[0]-40*offset,pos[1]+40*offset,pos[2]-40*offset])) fods.append(Atom('He',[pos[0]-40*offset,pos[1]-40*offset,pos[2]+40*offset])) fods.append(Atom('He',[pos[0]+42*offset,pos[1]+42*offset,pos[2]+42*offset])) fods.append(Atom('X',[pos[0]+42*offset,pos[1]-42*offset,pos[2]-42*offset])) # find radicals for atom in m.GetAtoms(): rad = atom.GetNumRadicalElectrons() #print(rad) if rad == 1: idx = atom.GetIdx() pos = m.GetConformer().GetAtomPosition(idx) bonds = atom.GetBonds() vec_BA_x = 0 vec_BA_y = 0 vec_BA_z = 0 BA = [] for b in range(len(bonds)): ai = bonds[b].GetBeginAtomIdx() aj = bonds[b].GetEndAtomIdx() bond_type = bonds[b].GetBondType() # Positions pos_ai = m.GetConformer().GetAtomPosition(ai) pos_aj = m.GetConformer().GetAtomPosition(aj) # adding bonding vectors for 3d vec_BA_x = vec_BA_x + (pos_aj[0]-pos_ai[0]) vec_BA_y = vec_BA_y + (pos_aj[1]-pos_ai[1]) vec_BA_z = vec_BA_z + (pos_aj[2]-pos_ai[2]) # save bonding vectors for 2d BA.append(np.array([(pos_aj[0]-pos_ai[0]),(pos_aj[1]-pos_ai[1]),(pos_aj[2]-pos_ai[2])])) if dim == 1: fods.append(Atom('X',[-1*BA[0][0],-1*BA[0][1],-1*BA[0][2]])) if dim == 2: vec = np.cross(BA[0],BA[1]) norm = np.sqrt(vec[0]**2 + vec[1]**2 + vec[2]**2) pos = vec/norm fods.append(Atom('X',[pos[0],pos[1],pos[2]])) if dim == 3: norm = np.sqrt(vec_BA_x**2 + vec_BA_y**2 + vec_BA_z**2) pos = np.array([-1*vec_BA_x,-1*vec_BA_y,-1*vec_BA_z])/norm fods.append(Atom('X',[pos[0],pos[1],pos[2]])) bonds = m.GetBonds() for b in range(len(bonds)): ai = bonds[b].GetBeginAtomIdx() aj = bonds[b].GetEndAtomIdx() bond_type = bonds[b].GetBondType() # Positions pos_ai = m.GetConformer().GetAtomPosition(ai) pos_aj = m.GetConformer().GetAtomPosition(aj) # Bondlength #print('%0.5f' % np.linalg.norm([pos_ai[0]-pos_aj[0],pos_ai[1]-pos_aj[1],pos_ai[2]-pos_aj[2]])) # Middle of the vector MP = [(pos_ai[0]+pos_aj[0])/2.,(pos_ai[1]+pos_aj[1])/2.,(pos_ai[2]+pos_aj[2])/2.] #print('%0.5f %0.5f %0.5f' %(MP[0],MP[1],MP[2])) # Print positions #print('%0.5f %0.5f %0.5f' %(pos_ai[0],pos_ai[1],pos_ai[2])) #print('%0.5f %0.5f %0.5f' %(pos_aj[0],pos_aj[1],pos_aj[2])) for spin in ['He','X']: if spin == 'He': offset = 0.000 if spin == 'X': #offset = 0.002 offset = 0.02 if str(bond_type) == 'SINGLE': #print('%s %0.5f %0.5f %0.5f' %(spin,MP[0]+offset,MP[1]+offset,MP[2]+offset)) fods.append(Atom(spin,[MP[0]+offset,MP[1]+offset,MP[2]+offset])) if str(bond_type) == 'DOUBLE': #print('%s %0.5f %0.5f %0.5f' %(spin,MP[0]+offset,MP[1]+offset,MP[2]+0.5+offset)) #print('%s %0.5f %0.5f %0.5f' %(spin,MP[0]+offset,MP[1]+offset,MP[2]-0.5+offset)) fods.append(Atom(spin,[MP[0]+offset,MP[1]+offset,MP[2]+0.5+offset])) fods.append(Atom(spin,[MP[0]+offset,MP[1]+offset,MP[2]-0.5+offset])) if str(bond_type) == 'TRIPLE': #print('%s %0.5f %0.5f %0.5f' %(spin,MP[0]+offset,MP[1]+offset,MP[2]+0.5+offset)) #print('%s %0.5f %0.5f %0.5f' %(spin,MP[0]+offset,MP[1]+offset,MP[2]-0.5+offset)) #print('%s %0.5f %0.5f %0.5f' %(spin,MP[0]-0.5+offset,MP[1]+offset,MP[2]+offset)) fods.append(Atom(spin,[MP[0]+offset,MP[1]+offset,MP[2]+0.5+offset])) fods.append(Atom(spin,[MP[0]+offset,MP[1]+offset,MP[2]-0.5+offset])) fods.append(Atom(spin,[MP[0]-0.5+offset,MP[1]+offset,MP[2]+offset])) w = Chem.SDWriter('%s.sdf' % 'pylewis') w.write(m) w.flush() # sdf2xyz struct = read('%s.sdf' % 'pylewis') struct_fods = Atoms() struct_fods.extend(struct) struct_fods.extend(fods) #print(struct.get_chemical_symbols()) write('%s.xyz' % 'pylewis',struct,'xyz') write('%s_fods.xyz' % 'pylewis',struct_fods,'xyz')
def calculate_rotors(self, conformer, steps=36, step_size=10.0): complete = {} calculators = {} verified = {} if len(conformer.torsions) == 0: logging.info("No torsions to run scans on.") return {} for torsion in conformer.torsions: label = self.submit_rotor(conformer, torsion.index) logging.info(label) complete[label] = False verified[label] = False done = False lowest_energy_label = None conformer_error = False while not done: for label in list(complete.keys()): if not self.check_complete(label): continue if done: continue complete[label] = True lowest_conf, continuous, good_slope, opt_count_check = self.verify_rotor( ################################## conformer, label) if all([lowest_conf, continuous]): verified[label] = True else: verified[label] = False if not lowest_conf: done = True lowest_energy_label = label conformer_error = True continue elif all(complete.values()): done = True if conformer_error: logging.info( "A lower energy conformer was found... Going to optimize this insted" ) for label in list(complete.keys()): subprocess.call("""scancel -n '{}'""".format(label), shell=True) if isinstance(conformer, TS): file_name = os.path.join(self.directory, "ts", conformer.reaction_label, "rotors", lowest_energy_label + ".log") else: file_name = os.path.join(self.directory, "species", conformer.smiles, "rotors", lowest_energy_label + ".log") parser = ccread(file_name) first_is_lowest, min_energy, atomnos, atomcoords = self.check_rotor_lowest_conf( parser=parser) symbol_dict = { 17: "Cl", 9: "F", 8: "O", 7: "N", 6: "C", 1: "H", } atoms = [] for atom_num, coords in zip(parser.atomnos, parser.atomcoords[-1]): atoms.append( Atom(symbol=symbol_dict[atom_num], position=coords)) conformer.ase_molecule = Atoms(atoms) conformer.update_coords_from("ase") for index in ["X", "Y", "Z"]: if index != conformer.index: logging.info("Setting index of {} to {}...".format( conformer, index)) conformer.index = index break label = self.submit_conformer(conformer) while not self.check_complete(label): time.sleep(15) logging.info( "Reoptimization complete... performing hindered rotors scans again" ) return self.calculate_rotors(conformer, steps, step_size) else: for label, boolean in list(verified.items()): if not boolean: try: if isinstance(conformer, TS): file_path = os.path.join(self.directory, "ts", conformer.reaction_label, "rotors") else: file_path = os.path.join(self.directory, "species", conformer.smiles, "rotors") os.mkdirs(os.path.join(file_path, failures)) except: pass move(os.path.join(file_path, label + ".log"), os.path.join(file_path, "failures", label + ".log")) return verified
def calculate_rotors(self, conformer, calculator, steps=36, step_size=10.0): complete = {} calculators = {} verified = {} for torsion in conformer.torsions: calc = calculator.get_rotor_calc( conformer=conformer, torsion=torsion, steps=steps, step_size=step_size, ) label = self.submit_rotor(conformer=conformer, ase_calculator=calc, partition="general") logging.info(label) complete[label] = False calculators[label] = calc verified[label] = False done = False lowest_energy_label = None conformer_error = False if len(conformer.torsions) == 0: logging.info("No torsions to run scans on.") return {} while not done: for label in list(complete.keys()): if not self.check_complete(label): continue if done: continue complete[label] = True ase_calc = calculators[label] lowest_conf, continuous, good_slope, opt_count_check = self.verify_rotor( steps=steps, step_size=step_size, ase_calculator=ase_calc) if all([lowest_conf, continuous]): verified[label] = True else: verified[label] = False if not lowest_conf: done = True lowest_energy_label = label conformer_error = True continue elif all(complete.values()): done = True if conformer_error: logging.info( "A lower energy conformer was found... Going to optimize this insted" ) for label in list(complete.keys()): command = """scancel -n '{}'""".format(label) ase_calculator = calculators[label] file_name = os.path.join(ase_calculator.scratch, lowest_energy_label + ".log") parser = ccread(file_name) first_is_lowest, min_energy, atomnos, atomcoords = self.check_rotor_lowest_conf( parser=parser) symbol_dict = { 17: "Cl", 9: "F", 8: "O", 7: "N", 6: "C", 1: "H", } atoms = [] for atom_num, coords in zip(parser.atomnos, parser.atomcoords[-1]): atoms.append( Atom(symbol=symbol_dict[atom_num], position=coords)) conformer.ase_molecule = Atoms(atoms) conformer.update_coords_from("ase") if isinstance(conformer, TS): calc = calculator.get_overall_calc( conformer, direction=conformer.direction) calc.scratch = calc.scratch.strip("/conformers") conformer.direction = "forward" conformer.index = "X" label = self.submit_transitionstate(transitionstate=conformer, ase_calculator=calc) else: calc = calculator.get_conformer_calc(conformer) calc.scratch = calc.scratch.strip("/conformers") conformer.index = "X" label = self.submit_conformer(conformer, calc, "general") while not self.check_complete(label): os.sleep(15) logging.info( "Reoptimization complete... performing hindered rotors scans again" ) return self.calculate_rotors(conformer, calculator, steps, step_size) else: for label, boolean in list(verified.items()): if not boolean: calc = calculators[label] try: os.mkdir(os.path.join(calc.scratch, "failures")) except: pass move( os.path.join(calc.scratch, calc.label + ".log"), os.path.join(calc.scratch, "failures", calc.label + ".log")) return verified
def read_gpaw_text(fileobj, index=-1): if isinstance(fileobj, str): fileobj = open(fileobj) def index_startswith(lines, string): for i, line in enumerate(lines): if line.startswith(string): return i raise ValueError lines = fileobj.readlines() images = [] while True: try: i = lines.index('Unit Cell:\n') except ValueError: pass else: cell = [] pbc = [] for line in lines[i + 3:i + 6]: words = line.split() if len(words) == 5: # old format cell.append(float(words[2])) pbc.append(words[1] == 'yes') else: # new format with GUC cell.append([float(word) for word in words[3:6]]) pbc.append(words[2] == 'yes') try: i = lines.index('Positions:\n') except ValueError: break atoms = Atoms(cell=cell, pbc=pbc) for line in lines[i + 1:]: words = line.split() if len(words) != 5: break n, symbol, x, y, z = words symbol = symbol.split('.')[0] atoms.append(Atom(symbol, [float(x), float(y), float(z)])) lines = lines[i + 5:] try: i = lines.index('-------------------------\n') except ValueError: e = None else: line = lines[i + 9] assert line.startswith('Zero Kelvin:') e = float(line.split()[-1]) try: ii = index_startswith(lines, 'Fermi Level:') except ValueError: eFermi = None else: try: eFermi = float(lines[ii].split()[2]) except ValueError: # we have two Fermi levels fields = lines[ii].split() def strip(string): for rubbish in '[],': string = string.replace(rubbish, '') return string eFermi = [float(strip(fields[2])), float(strip(fields[3]))] try: ii = index_startswith(lines, 'Total Charge:') except ValueError: q = None else: q = float(lines[ii].split()[2]) try: ii = index_startswith(lines, 'Local Magnetic Moments') except ValueError: magmoms = None else: magmoms = [] for i in range(ii + 1, ii + 1 + len(atoms)): iii, magmom = lines[i].split()[:2] magmoms.append(float(magmom)) try: ii = lines.index('Forces in eV/Ang:\n') except ValueError: f = None else: f = [] for i in range(ii + 1, ii + 1 + len(atoms)): try: x, y, z = lines[i].split()[-3:] f.append((float(x), float(y), float(z))) except (ValueError, IndexError), m: raise IOError('Malformed GPAW log file: %s' % m) if len(images) > 0 and e is None: break if e is not None or f is not None: calc = SinglePointDFTCalculator(e, f, None, magmoms, atoms, eFermi) atoms.set_calculator(calc) if q is not None: n = len(atoms) atoms.set_charges([q / n] * n) images.append(atoms) lines = lines[i:]
def xyz_to_database(xyzfile, num_examples=None, xyz_format='xyz', verbose=True, unit_to_ev=None, restart=False): """ Convert the xyz file to an `ase.db.core.Database`. Args: xyzfile: a `str` as the file to parse. num_examples: a `int` as the maximum number of examples to parse. If None, all examples in the given file will be saved. xyz_format: a `str` representing the format of the given xyz file. verbose: a `bool` indicating whether we should log the parsing progress. unit_to_ev: a `float` as the unit for converting energies to eV. Defaults to None so that default units will be used. restart: a `bool`. If True, the database will be re-built even if already existed. Returns: database: an `ase.db.core.Database`. auxdict: a `dict` as the auxiliary dict for this database. """ if xyz_format.lower() == 'ase': formatter = _ase_xyz else: formatter = _xyz dbfile = "{}.db".format(splitext(xyzfile)[0]) if isfile(dbfile): if restart: remove(dbfile) else: auxdict = _load_auxiliary_dict(dbfile) return connect(name=dbfile), auxdict unit = unit_to_ev or formatter.default_unit parse_forces = formatter.parse_forces count = 0 ai = 0 natoms = 0 stage = 0 atoms = None num_examples = num_examples or 0 natoms_counter = Counter() y_min = np.inf y_max = -np.inf max_occurs = Counter() database = connect(name=dbfile) tic = time.time() if verbose: sys.stdout.write("Extract cartesian coordinates ...\n") with open(xyzfile) as f: for line in f: if num_examples and count == num_examples: break line = line.strip() if line == "": continue if stage == 0: if line.isdigit(): natoms = int(line) atoms = Atoms(calculator=ProvidedCalculator()) if parse_forces: atoms.info['provided_forces'] = np.zeros((natoms, 3)) natoms_counter[natoms] += 1 stage += 1 elif stage == 1: m = formatter.energy_patt.search(line) if m: if xyz_format.lower() == 'extxyz': energy = float(m.group(3)) * unit elif xyz_format.lower() == 'ase': energy = float(m.group(2)) * unit atoms.set_cell( np.reshape([float(x) for x in m.group(1).split()], (3, 3))) atoms.set_pbc([ True if x == "T" else False for x in m.group(3).split() ]) else: energy = float(m.group(1)) * unit atoms.info['provided_energy'] = energy y_min = min(y_min, energy) y_max = max(y_max, energy) stage += 1 elif stage == 2: m = formatter.string_patt.search(line) if m: atoms.append( Atom(symbol=m.group(1), position=[float(v) for v in m.groups()[1:4]])) if parse_forces: atoms.info['provided_forces'][ai, :] = [ float(v) * unit for v in m.groups()[4:7] ] ai += 1 if ai == natoms: atoms.calc.calculate() database.write(atoms) counter = Counter(atoms.get_chemical_symbols()) for symbol, n in counter.items(): max_occurs[symbol] = max(max_occurs[symbol], n) ai = 0 stage = 0 count += 1 if verbose and count % 1000 == 0: sys.stdout.write( "\rProgress: {:7d} / {:7d} | Speed = {:.1f}". format(count, num_examples, count / (time.time() - tic))) if verbose: print("") print("Total time: %.3f s\n" % (time.time() - tic)) # Dump the auxiliary dict. auxdict = { "max_occurs": dict(max_occurs), "y_range": [y_min, y_max], "natoms_counter": dict(natoms_counter) } _save_auxiliary_dict(dbfile, auxdict) return database, auxdict
from espresso import * # First import the module from ase.atoms import Atoms, Atom # Import the atoms object from ASE atoms = Atoms([Atom('H', (0, 0, 0))], cell = (8, 9, 10)) with Espresso('output/H', # With respect to the directory this script # is in, this is the directory where the # calculation will be taking place. The module # will automatically make the folders necessary. # Just assure the folder doesn't exist, and if it # does, that it's empty atoms=atoms, # This is where we put in the atoms object ecutwfc=60.0, ecutrho=600.0, # These are the kinetic energy cutoff parameters # These values determine heavily the convergence # of your calculation and therefore the time and # accuracy of your calculation. You should perform # convergence tests before performing large amounts # of studies. kpts=(1, 1, 1), # This is how many kpoints in the x, y, and z # direction of the unit cell. Similar to ecutwfc # and ecutrho, the more kpoints the more converged # and expensive. Testing is recommended. occupations='smearing', # This is to determing the smearing at electrons # at the fermi level. Typically we do smearing.
def read_proteindatabank(fileobj, index=-1, read_arrays=True): """Read PDB files.""" if isinstance(fileobj, basestring): fileobj = open(fileobj) images = [] orig = np.identity(3) trans = np.zeros(3) atoms = Atoms() occ = [] bfactor = [] for line in fileobj.readlines(): if line.startswith('CRYST1'): cellpar = [ float(line[6:15]), # a float(line[15:24]), # b float(line[24:33]), # c float(line[33:40]), # alpha float(line[40:47]), # beta float(line[47:54]) ] # gamma atoms.set_cell(cellpar_to_cell(cellpar)) atoms.pbc = True for c in range(3): if line.startswith('ORIGX' + '123'[c]): orig[c] = [ float(line[10:20]), float(line[20:30]), float(line[30:40]) ] trans[c] = float(line[45:55]) if line.startswith('ATOM') or line.startswith('HETATM'): try: # Atom name is arbitrary and does not necessarily # contain the element symbol. The specification # requires the element symbol to be in columns 77+78. # Fall back to Atom name for files that do not follow # the spec, e.g. packmol. try: symbol = label_to_symbol(line[76:78].strip()) except (KeyError, IndexError): symbol = label_to_symbol(line[12:16].strip()) # Don't use split() in case there are no spaces position = np.array([ float(line[30:38]), # x float(line[38:46]), # y float(line[46:54]) ]) # z try: occ.append(float(line[54:60])) bfactor.append(float(line[60:66])) except (IndexError, ValueError): pass position = np.dot(orig, position) + trans atoms.append(Atom(symbol, position)) except Exception as ex: warnings.warn( 'Discarding atom when reading PDB file: {}\n{}'.format( line.strip(), ex)) if line.startswith('END'): # End of configuration reached # According to the latest PDB file format (v3.30), # this line should start with 'ENDMDL' (not 'END'), # but in this way PDB trajectories from e.g. CP2K # are supported (also VMD supports this format). if read_arrays and len(occ) == len(atoms): atoms.set_array('occupancy', np.array(occ)) if read_arrays and len(bfactor) == len(atoms): atoms.set_array('bfactor', np.array(bfactor)) images.append(atoms) atoms = Atoms() occ = [] bfactor = [] if len(images) == 0: # Single configuration with no 'END' or 'ENDMDL' if read_arrays and len(occ) == len(atoms): atoms.set_array('occupancy', np.array(occ)) if read_arrays and len(bfactor) == len(atoms): atoms.set_array('bfactor', np.array(bfactor)) images.append(atoms) return images[index]
#!/usr/bin/env python from xcp2k import CP2K from ase.atoms import Atom, Atoms from ase.lattice import bulk import numpy as np from multiprocessing import Pool, Process import os from ase.eos import EquationOfState atoms = Atoms([Atom('Pt', (0, 0, 0))]) atoms.pbc = [True, True, True] datas = [] def run(latt, atoms, datas): calc = CP2K(label = 'relax/{0}/pt-relax-{0}'.format(latt, latt), xc = 'PBE', cpu = 8, cutoff = 500, run_type = 'ENERGY_FORCE', atoms = atoms) atoms.cell=0.5 * latt * np.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]]) atoms = atoms*[2, 2, 2] atoms.set_calculator(calc) e = atoms.get_potential_energy() v = atoms.get_volume() datas.append([latt, v, e]) print('$data {0:1.2f} {1:1.4f} {2:1.4f}'.format(latt, v, e))
def read_gpaw_text(fileobj, index=-1): if isinstance(fileobj, str): fileobj = open(fileobj) def index_startswith(lines, string): for i, line in enumerate(lines): if line.startswith(string): return i raise ValueError lines = fileobj.readlines() images = [] while True: try: i = lines.index('Unit Cell:\n') except ValueError: pass else: cell = [] pbc = [] for line in lines[i + 3:i + 6]: words = line.split() if len(words) == 5: # old format cell.append(float(words[2])) pbc.append(words[1] == 'yes') else: # new format with GUC cell.append([float(word) for word in words[3:6]]) pbc.append(words[2] == 'yes') try: i = lines.index('Positions:\n') except ValueError: break atoms = Atoms(cell=cell, pbc=pbc) for line in lines[i + 1:]: words = line.split() if len(words) != 5: break n, symbol, x, y, z = words symbol = symbol.split('.')[0] atoms.append(Atom(symbol, [float(x), float(y), float(z)])) lines = lines[i + 5:] try: i = lines.index('-------------------------\n') except ValueError: e = None else: line = lines[i + 9] assert line.startswith('Zero Kelvin:') e = float(line.split()[-1]) try: ii = index_startswith(lines, 'Fermi Level:') except ValueError: eFermi = None else: try: eFermi = float(lines[ii].split()[2]) except ValueError: # we have two Fermi levels fields = lines[ii].split() def strip(string): for rubbish in '[],': string = string.replace(rubbish, '') return string eFermi = [float(strip(fields[2])), float(strip(fields[3]))] # read Eigenvalues and occupations ii1 = ii2 = 1e32 try: ii1 = index_startswith(lines, ' Band Eigenvalues Occupancy') except ValueError: pass try: ii2 = index_startswith(lines, ' Band Eigenvalues Occupancy') except ValueError: pass ii = min(ii1, ii2) if ii == 1e32: kpts = None else: ii += 1 words = lines[ii].split() vals = [] while (len(words) > 2): vals.append([float(word) for word in words]) ii += 1 words = lines[ii].split() vals = np.array(vals).transpose() kpts = [SinglePointKPoint(0, 0)] kpts[0].eps_n = vals[1] kpts[0].f_n = vals[2] if vals.shape[0] > 3: kpts.append(SinglePointKPoint(0, 1)) kpts[1].eps_n = vals[3] kpts[1].f_n = vals[4] # read charge try: ii = index_startswith(lines, 'Total Charge:') except ValueError: q = None else: q = float(lines[ii].split()[2]) # read dipole moment try: ii = index_startswith(lines, 'Dipole Moment:') except ValueError: dipole = None else: line = lines[ii].replace(']', '').replace('[', '') dipole = np.array([float(c) for c in line.split()[-3:]]) try: ii = index_startswith(lines, 'Local Magnetic Moments') except ValueError: magmoms = None else: magmoms = [] for i in range(ii + 1, ii + 1 + len(atoms)): iii, magmom = lines[i].split()[:2] magmoms.append(float(magmom)) try: ii = lines.index('Forces in eV/Ang:\n') except ValueError: f = None else: f = [] for i in range(ii + 1, ii + 1 + len(atoms)): try: x, y, z = lines[i].split()[-3:] f.append((float(x), float(y), float(z))) except (ValueError, IndexError), m: raise IOError('Malformed GPAW log file: %s' % m) if len(images) > 0 and e is None: break if e is not None or f is not None: calc = SinglePointDFTCalculator(e, f, None, magmoms, atoms, eFermi) if kpts is not None: calc.kpts = kpts if dipole is not None: calc.set_dipole_moment(dipole) atoms.set_calculator(calc) if q is not None and len(atoms) > 0: n = len(atoms) atoms.set_charges([q / n] * n) images.append(atoms) lines = lines[i:]