Пример #1
0
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
Пример #2
0
 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
Пример #3
0
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]
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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"
Пример #7
0
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]
Пример #8
0
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]
Пример #9
0
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])
Пример #10
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)
Пример #11
0
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
Пример #12
0
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
Пример #13
0
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')
Пример #14
0
    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
Пример #15
0
    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
Пример #16
0
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:]
Пример #17
0
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
Пример #18
0
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.
Пример #19
0
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]
Пример #20
0
#!/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))
Пример #21
0
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:]