def __getattr__(self, attr): """Return the value of an attribute Note: The values are calculated on-the-fly. You may want to store the value in a variable if you repeatedly access the same attribute. """ # This function is not accessed in the case of OBMol if attr == "atoms": # Create an atoms attribute on-the-fly return [ Atom(self.OBMol.GetAtom(i+1)) for i in range(self.OBMol.NumAtoms()) ] elif attr == "data": # Create a data attribute on-the-fly return MoleculeData(self.OBMol) elif attr == "unitcell": # Create a unitcell attribute on-the-fly unitcell = self.OBMol.GetData(ob.UnitCell) if unitcell: return ob.toUnitCell(unitcell) else: raise AttributeError, "Molecule has no attribute 'unitcell'" elif attr in self._getmethods: # Call the OB Method to find the attribute value return getattr(self.OBMol, self._getmethods[attr])() elif attr == "_exchange": if self.OBMol.HasNonZeroCoords(): return (1, self.write("mol")) else: return (0, self.write("can").split()[0]) else: raise AttributeError, "Molecule has no attribute '%s'" % attr
def __getattr__(self, attr): """Return the value of an attribute Note: The values are calculated on-the-fly. You may want to store the value in a variable if you repeatedly access the same attribute. """ # This function is not accessed in the case of OBMol if attr == "atoms": # Create an atoms attribute on-the-fly return [ Atom(self.OBMol.GetAtom(i + 1), i + 1) for i in range(self.OBMol.NumAtoms()) ] elif attr == "data": # Create a data attribute on-the-fly return MoleculeData(self.OBMol) elif attr == "unitcell": # Create a unitcell attribute on-th-fly unitcell = self.OBMol.GetData(ob.UnitCell) if unitcell: return ob.toUnitCell(unitcell) else: raise AttributeError, "Molecule has no attribute 'unitcell'" elif attr in self._getmethods: # Call the OB Method to find the attribute value return getattr(self.OBMol, self._getmethods[attr])() else: raise AttributeError, "Molecule has no attribute '%s'" % attr
def type_mof(filename, output_dir, ff="uff", output_files=True): obconversion = OBConversion() obconversion.SetInAndOutFormats("cif", "xyz") obmol = OBMol() # Read MOF file and unit cell and write xyz file obconversion.ReadFile(obmol, filename) unitcell = openbabel.toUnitCell(obmol.GetData(openbabel.UnitCell)) uc = [ unitcell.GetA(), unitcell.GetB(), unitcell.GetC(), unitcell.GetAlpha(), unitcell.GetBeta(), unitcell.GetGamma() ] obconversion.WriteFile(obmol, 'mof_tmp.xyz') # Replicate unit cell using angstrom mol = Molecule(read='mof_tmp.xyz') mol.set_cell(uc) n_atoms = len(mol.atoms) mol333 = mol.replicate([3, 3, 3], center=True) print(mol333.cell) mol333.write('mof333.cif', cell=mol333.cell.to_list()) # Type FF obconversion.ReadFile(obmol, 'mof333.cif') ff = OBForceField.FindForceField("UFF") if not ff.Setup(obmol): print("Error: could not setup force field") ff.GetAtomTypes(obmol) # Get atom types for the middle cell types = [] for atom_idx, obatom in enumerate(OBMolAtomIter(obmol)): if atom_idx >= n_atoms * 13 and atom_idx < n_atoms * 14: ff_atom_type = obatom.GetData("FFAtomType").GetValue() types.append(ff_atom_type) if output_files: mof_name = os.path.splitext(os.path.basename(filename))[0] with open(os.path.join(output_dir, mof_name + "-obabel.log"), 'w') as f: f.write("NOTE: types order is the same as the CIF input file.\n") f.write("types= %s" % str(types)) uniq_types = sorted(set(types)) return [str(i) for i in uniq_types]
def unitcell(self): unitcell = self.OBMol.GetData(ob.UnitCell) if unitcell: return ob.toUnitCell(unitcell) else: raise AttributeError("Molecule has no attribute 'unitcell'")
def parse_mol_info(fname, fcharges, axis, buffa, buffo, pbcbonds, printdih, ignorebonds, ignoreimproper): iaxis = {"x": 0, "y": 1, "z": 2} if axis in iaxis: repaxis = iaxis[axis] else: print("Error: invalid axis") sys.exit(0) if fcharges: chargesLabel = {} with open(fcharges, "r") as f: for line in f: chargesLabel[line.split()[0]] = float(line.split()[1]) # set openbabel file format base, ext = os.path.splitext(fname) obConversion = openbabel.OBConversion() obConversion.SetInAndOutFormats(ext[1:], "xyz") # trick to disable ring perception and make the ReadFile waaaay faster # Source: https://sourceforge.net/p/openbabel/mailman/openbabel-discuss/thread/56e1812d-396a-db7c-096d-d378a077853f%40ipcms.unistra.fr/#msg36225392 obConversion.AddOption("b", openbabel.OBConversion.INOPTIONS) # read molecule to OBMol object mol = openbabel.OBMol() obConversion.ReadFile(mol, fname) mol.ConnectTheDots() # necessary because of the 'b' INOPTION # split the molecules molecules = mol.Separate() # detect the molecules types mTypes = {} mapmTypes = {} atomIdToMol = {} nty = 0 for i, submol in enumerate(molecules, start=1): atomiter = openbabel.OBMolAtomIter(submol) atlist = [] for at in atomiter: atlist.append(at.GetAtomicNum()) atomIdToMol[at.GetId()] = i foundType = None for ty in mTypes: # check if there's already a molecule of this type if atlist == mTypes[ty]: foundType = ty # if not, create a new type if not foundType: nty += 1 foundType = nty mTypes[nty] = atlist mapmTypes[i] = foundType # get atomic labels from pdb idToAtomicLabel = {} if ext[1:] == "pdb": for res in openbabel.OBResidueIter(mol): for atom in openbabel.OBResidueAtomIter(res): if (atomIdToMol[atom.GetId()] > 1) and (len(mTypes) > 1): idToAtomicLabel[ atom.GetId()] = res.GetAtomID(atom).strip() + str( mapmTypes[atomIdToMol[atom.GetId()]]) else: idToAtomicLabel[atom.GetId()] = res.GetAtomID(atom).strip() else: if not ob3: etab = openbabel.OBElementTable() for atom in openbabel.OBMolAtomIter(mol): if (atomIdToMol[atom.GetId()] > 1) and (len(mTypes) > 1): if ob3: idToAtomicLabel[atom.GetId()] = openbabel.GetSymbol( atom.GetAtomicNum()) + str( mapmTypes[atomIdToMol[atom.GetId()]]) else: idToAtomicLabel[atom.GetId()] = etab.GetSymbol( atom.GetAtomicNum()) + str( mapmTypes[atomIdToMol[atom.GetId()]]) else: if ob3: idToAtomicLabel[atom.GetId()] = openbabel.GetSymbol( atom.GetAtomicNum()) else: idToAtomicLabel[atom.GetId()] = etab.GetSymbol( atom.GetAtomicNum()) # print(idToAtomicLabel) # identify atom types and get masses outMasses = "Masses\n\n" massTypes = {} mapTypes = {} nmassTypes = 0 atomIterator = openbabel.OBMolAtomIter(mol) for atom in atomIterator: i = atom.GetId() if idToAtomicLabel[i] not in massTypes: nmassTypes += 1 mapTypes[nmassTypes] = idToAtomicLabel[i] massTypes[idToAtomicLabel[i]] = nmassTypes outMasses += "\t%d\t%.3f\t# %s\n" % ( nmassTypes, atom.GetAtomicMass(), idToAtomicLabel[i]) # create atoms list outAtoms = "Atoms # full\n\n" xmin = float("inf") xmax = float("-inf") ymin = float("inf") ymax = float("-inf") zmin = float("inf") zmax = float("-inf") natoms = 0 acoords = [] for mnum, imol in enumerate(molecules, start=1): atomIterator = openbabel.OBMolAtomIter(imol) for atom in sorted(atomIterator, key=lambda x: x.GetId()): natoms += 1 i = atom.GetId() apos = (atom.GetX(), atom.GetY(), atom.GetZ()) acoords.append(Atom(atom.GetAtomicNum(), apos)) # look for the maximum and minimum x for the box (improve later with numpy and all coordinates) if apos[0] > xmax: xmax = apos[0] if apos[0] < xmin: xmin = apos[0] if apos[1] > ymax: ymax = apos[1] if apos[1] < ymin: ymin = apos[1] if apos[2] > zmax: zmax = apos[2] if apos[2] < zmin: zmin = apos[2] if fcharges: outAtoms += "\t%d\t%d\t%d\t%.6f\t%.4f\t%.4f\t%.4f\t# %s\n" % ( i + 1, mnum, massTypes[idToAtomicLabel[i]], chargesLabel[idToAtomicLabel[i]], atom.GetX(), atom.GetY(), atom.GetZ(), idToAtomicLabel[i]) else: outAtoms += "\t%d\t%d\t%d\tX.XXXXXX\t%.4f\t%.4f\t%.4f\t# %s\n" % ( i + 1, mnum, massTypes[idToAtomicLabel[i]], atom.GetX(), atom.GetY(), atom.GetZ(), idToAtomicLabel[i]) # define box shape and size try: fromBounds = False rcell = mol.GetData(12) cell = openbabel.toUnitCell(rcell) v1 = [ cell.GetCellVectors()[0].GetX(), cell.GetCellVectors()[0].GetY(), cell.GetCellVectors()[0].GetZ() ] v2 = [ cell.GetCellVectors()[1].GetX(), cell.GetCellVectors()[1].GetY(), cell.GetCellVectors()[1].GetZ() ] v3 = [ cell.GetCellVectors()[2].GetX(), cell.GetCellVectors()[2].GetY(), cell.GetCellVectors()[2].GetZ() ] boxinfo = [v1, v2, v3] orthogonal = True for i, array in enumerate(boxinfo): for j in range(3): if i == j: continue if not math.isclose(0., array[j], abs_tol=1e-6): orthogonal = False except: fromBounds = True v1 = [xmax - xmin, 0., 0.] v2 = [0., ymax - ymin, 0.] v3 = [0., 0., zmax - zmin] orthogonal = True # add buffer if orthogonal: buf = [] boxinfo = [v1, v2, v3] for i, val in enumerate(boxinfo[repaxis]): if i == repaxis: buf.append(val + buffa) else: buf.append(val) boxinfo[repaxis] = buf for i in range(3): if i == repaxis: continue buf = [] for j, val in enumerate(boxinfo[i]): if j == i: buf.append(val + buffo) else: buf.append(val) boxinfo[i] = buf # print(boxinfo) # Duplicate to get the bonds in the PBC. Taken from (method _crd2bond): # https://github.com/tongzhugroup/mddatasetbuilder/blob/66eb0f15e972be0f5534dcda27af253cd8891ff2/mddatasetbuilder/detect.py#L213 if pbcbonds: acoords = Atoms(acoords, cell=boxinfo, pbc=True) repatoms = acoords.repeat( 2 )[natoms:] # repeat the unit cell in each direction (len(repatoms) = 7*natoms) tree = cKDTree(acoords.get_positions()) d = tree.query(repatoms.get_positions(), k=1)[0] nearest = d < 8. ghost_atoms = repatoms[nearest] realnumber = np.where(nearest)[0] % natoms acoords += ghost_atoms write("replicated.xyz", acoords) # write the structure with the replicated atoms # write new mol with new bonds nmol = openbabel.OBMol() nmol.BeginModify() for idx, (num, position) in enumerate( zip(acoords.get_atomic_numbers(), acoords.positions)): a = nmol.NewAtom(idx) a.SetAtomicNum(int(num)) a.SetVector(*position) nmol.ConnectTheDots() # nmol.PerceiveBondOrders() # super slow becauses it looks for rings nmol.EndModify() else: acoords = Atoms(acoords, cell=boxinfo, pbc=False) nmol = openbabel.OBMol() nmol.BeginModify() for idx, (num, position) in enumerate( zip(acoords.get_atomic_numbers(), acoords.positions)): a = nmol.NewAtom(idx) a.SetAtomicNum(int(num)) a.SetVector(*position) nmol.ConnectTheDots() # nmol.PerceiveBondOrders() # super slow becauses it looks for rings nmol.EndModify() # identify bond types and create bond list outBonds = "Bonds # harmonic\n\n" bondTypes = {} mapbTypes = {} nbondTypes = 0 nbonds = 0 bondsToDelete = [] bondIterators = [] if ignorebonds: sepmols = nmol.Separate() for smol in sepmols[1:]: bondIterators.append(openbabel.OBMolBondIter(smol)) else: bondIterators.append(openbabel.OBMolBondIter(nmol)) lastidx = 1 for iterator in bondIterators: for i, bond in enumerate(iterator, lastidx): b1 = bond.GetBeginAtom().GetId() b2 = bond.GetEndAtom().GetId() # check if its a bond of the replica only if (b1 >= natoms) and (b2 >= natoms): bondsToDelete.append(bond) continue # remap to a real atom if needed if b1 >= natoms: b1 = realnumber[b1 - natoms] if b2 >= natoms: b2 = realnumber[b2 - natoms] # identify bond type btype1 = "%s - %s" % (idToAtomicLabel[b1], idToAtomicLabel[b2]) btype2 = "%s - %s" % (idToAtomicLabel[b2], idToAtomicLabel[b1]) if btype1 in bondTypes: bondid = bondTypes[btype1] bstring = btype1 elif btype2 in bondTypes: bondid = bondTypes[btype2] bstring = btype2 else: nbondTypes += 1 mapbTypes[nbondTypes] = btype1 bondid = nbondTypes bondTypes[btype1] = nbondTypes bstring = btype1 nbonds += 1 outBonds += "\t%d\t%d\t%d\t%d\t# %s\n" % (nbonds, bondid, b1 + 1, b2 + 1, bstring) lastidx = i # delete the bonds of atoms from other replicas for bond in bondsToDelete: nmol.DeleteBond(bond) # identify angle types and create angle list angleTypes = {} mapaTypes = {} nangleTypes = 0 nangles = 0 angleIterators = [] if ignorebonds: sepmols = nmol.Separate() for smol in sepmols[1:]: smol.FindAngles() angleIterators.append(openbabel.OBMolAngleIter(smol)) prevnumatoms = sepmols[0].NumAtoms() else: nmol.FindAngles() angleIterators.append(openbabel.OBMolAngleIter(nmol)) outAngles = "Angles # harmonic\n\n" lastidx = 1 for j, iterator in enumerate(angleIterators, 1): for i, angle in enumerate(iterator, lastidx): if ignorebonds: a1 = angle[1] + prevnumatoms a2 = angle[0] + prevnumatoms a3 = angle[2] + prevnumatoms else: a1 = angle[1] a2 = angle[0] a3 = angle[2] # remap to a real atom if needed if a1 >= natoms: a1 = realnumber[a1 - natoms] if a2 >= natoms: a2 = realnumber[a2 - natoms] if a3 >= natoms: a3 = realnumber[a3 - natoms] atype1 = "%s - %s - %s" % ( idToAtomicLabel[a1], idToAtomicLabel[a2], idToAtomicLabel[a3]) atype2 = "%s - %s - %s" % ( idToAtomicLabel[a3], idToAtomicLabel[a2], idToAtomicLabel[a1]) if atype1 in angleTypes: angleid = angleTypes[atype1] astring = atype1 elif atype2 in angleTypes: angleid = angleTypes[atype2] astring = atype2 else: nangleTypes += 1 mapaTypes[nangleTypes] = atype1 angleid = nangleTypes angleTypes[atype1] = nangleTypes astring = atype1 nangles += 1 outAngles += "\t%d\t%d\t%d\t%d\t%d\t# %s\n" % ( nangles, angleid, a1 + 1, a2 + 1, a3 + 1, astring) lastidx = i if ignorebonds: prevnumatoms += sepmols[j].NumAtoms() # identify dihedral types and create dihedral list if printdih: dihedralTypes = {} mapdTypes = {} ndihedralTypes = 0 ndihedrals = 0 dihedralIterators = [] if ignorebonds: sepmols = nmol.Separate() for smol in sepmols[1:]: smol.FindTorsions() dihedralIterators.append(openbabel.OBMolTorsionIter(smol)) else: nmol.FindTorsions() dihedralIterators.append(openbabel.OBMolTorsionIter(nmol)) outDihedrals = "Dihedrals # charmmfsw\n\n" lastidx = 1 for iterator in dihedralIterators: for i, dihedral in enumerate(iterator, lastidx): a1 = dihedral[0] a2 = dihedral[1] a3 = dihedral[2] a4 = dihedral[3] # remap to a real atom if needed if a1 >= natoms: a1 = realnumber[a1 - natoms] if a2 >= natoms: a2 = realnumber[a2 - natoms] if a3 >= natoms: a3 = realnumber[a3 - natoms] if a4 >= natoms: a4 = realnumber[a4 - natoms] dtype1 = "%s - %s - %s - %s" % ( idToAtomicLabel[a1], idToAtomicLabel[a2], idToAtomicLabel[a3], idToAtomicLabel[a4]) dtype2 = "%s - %s - %s - %s" % ( idToAtomicLabel[a4], idToAtomicLabel[a3], idToAtomicLabel[a2], idToAtomicLabel[a1]) if dtype1 in dihedralTypes: dihedralid = dihedralTypes[dtype1] dstring = dtype1 elif dtype2 in dihedralTypes: dihedralid = dihedralTypes[dtype2] dstring = dtype2 else: ndihedralTypes += 1 mapdTypes[ndihedralTypes] = dtype1 dihedralid = ndihedralTypes dihedralTypes[dtype1] = ndihedralTypes dstring = dtype1 ndihedrals += 1 outDihedrals += "\t%d\t%d\t%d\t%d\t%d\t%d\t# %s\n" % ( ndihedrals, dihedralid, a1 + 1, a2 + 1, a3 + 1, a4 + 1, dstring) lastidx = i if not ignoreimproper: # look for the improper dihedrals improperDihedralTypes = {} mapiDTypes = {} niDihedralTypes = 0 niDihedrals = 0 mollist = [] if ignorebonds: sepmols = nmol.Separate() for smol in sepmols[1:]: smol.PerceiveBondOrders() mollist.append(smol) else: nmol.PerceiveBondOrders() mollist.append(nmol) outImpropers = "Impropers # harmonic\n\n" for imol in mollist: atomIterator = openbabel.OBMolAtomIter(imol) for atom in atomIterator: try: # print(atom.GetHyb(), atom.GetAtomicNum(), atom.GetValence()) expDegree = atom.GetValence() except: # print(atom.GetHyb(), atom.GetAtomicNum(), atom.GetExplicitDegree()) expDegree = atom.GetExplicitDegree() # returns impropers for atoms with connected to other 3 atoms and SP2 hybridization if atom.GetHyb() == 2 and expDegree == 3: connectedAtoms = [] for atom2, depth in openbabel.OBMolAtomBFSIter( imol, atom.GetId() + 1): if depth == 2: connectedAtoms.append(atom2) torsional = [ atom.GetId() + 1, connectedAtoms[0].GetId() + 1, connectedAtoms[1].GetId() + 1, connectedAtoms[2].GetId() + 1 ] a1 = torsional[0] - 1 a2 = torsional[1] - 1 a3 = torsional[2] - 1 a4 = torsional[3] - 1 # remap to a real atom if needed if a1 >= natoms: a1 = realnumber[a1 - natoms] if a2 >= natoms: a2 = realnumber[a2 - natoms] if a3 >= natoms: a3 = realnumber[a3 - natoms] if a4 >= natoms: a4 = realnumber[a4 - natoms] dtype1 = "%s - %s - %s - %s" % ( idToAtomicLabel[a1], idToAtomicLabel[a2], idToAtomicLabel[a3], idToAtomicLabel[a4]) dtype2 = "%s - %s - %s - %s" % ( idToAtomicLabel[a4], idToAtomicLabel[a3], idToAtomicLabel[a2], idToAtomicLabel[a1]) if dtype1 in improperDihedralTypes: idihedralid = improperDihedralTypes[dtype1] dstring = dtype1 elif dtype2 in improperDihedralTypes: idihedralid = improperDihedralTypes[dtype2] dstring = dtype2 else: niDihedralTypes += 1 mapiDTypes[niDihedralTypes] = dtype1 idihedralid = niDihedralTypes improperDihedralTypes[dtype1] = niDihedralTypes dstring = dtype1 niDihedrals += 1 outImpropers += "\t%d\t%d\t%d\t%d\t%d\t%d\t# %s\n" % ( niDihedrals, idihedralid, a1 + 1, a2 + 1, a3 + 1, a4 + 1, dstring) # print header if printdih and (ndihedrals > 0): if ignoreimproper or (niDihedrals == 0): header = "LAMMPS topology created from %s using pdb2lmp.py - By Henrique Musseli Cezar, 2020\n\n\t%d atoms\n\t%d bonds\n\t%d angles\n\t%d dihedrals\n\n\t%d atom types\n\t%d bond types\n\t%d angle types\n\t%d dihedral types\n\n" % ( fname, natoms, nbonds, nangles, ndihedrals, nmassTypes, nbondTypes, nangleTypes, ndihedralTypes) else: header = "LAMMPS topology created from %s using pdb2lmp.py - By Henrique Musseli Cezar, 2020\n\n\t%d atoms\n\t%d bonds\n\t%d angles\n\t%d dihedrals\n\t%d impropers\n\n\t%d atom types\n\t%d bond types\n\t%d angle types\n\t%d dihedral types\n\t%d improper types\n\n" % ( fname, natoms, nbonds, nangles, ndihedrals, niDihedrals, nmassTypes, nbondTypes, nangleTypes, ndihedralTypes, niDihedralTypes) else: header = "LAMMPS topology created from %s using pdb2lmp.py - By Henrique Musseli Cezar, 2020\n\n\t%d atoms\n\t%d bonds\n\t%d angles\n\n\t%d atom types\n\t%d bond types\n\t%d angle types\n\n" % ( fname, natoms, nbonds, nangles, nmassTypes, nbondTypes, nangleTypes) # add box info if fromBounds: boxsize = [(xmin, xmax), (ymin, ymax), (zmin, zmax)] boxsize[repaxis] = (boxsize[repaxis][0] - buffa / 2., boxsize[repaxis][1] + buffa / 2.) for i in range(3): if i == repaxis: continue boxsize[i] = (boxsize[i][0] - buffo / 2., boxsize[i][1] + buffo / 2.) header += "\t%.8f\t%.8f\t xlo xhi\n\t%.8f\t%.8f\t ylo yhi\n\t%.8f\t%.8f\t zlo zhi\n" % ( boxsize[0][0], boxsize[0][1], boxsize[1][0], boxsize[1][1], boxsize[2][0], boxsize[2][1]) else: if orthogonal: header += "\t%.8f\t%.8f\t xlo xhi\n\t%.8f\t%.8f\t ylo yhi\n\t%.8f\t%.8f\t zlo zhi\n" % ( 0., boxinfo[0][0], 0., boxinfo[1][1], 0., boxinfo[2][2]) else: header += "\t%.8f\t%.8f\t xlo xhi\n\t%.8f\t%.8f\t ylo yhi\n\t%.8f\t%.8f\t zlo zhi\n\t%.8f\t%.8f\t%.8f\t xy xz yz\n" % ( 0., boxinfo[0][0], 0., boxinfo[1][1], 0., boxinfo[2][2], boxinfo[1][0], boxinfo[2][0], boxinfo[2][1]) # print Coeffs outCoeffs = "Pair Coeffs\n\n" for i in range(1, nmassTypes + 1): outCoeffs += "\t%d\teps\tsig\t# %s\n" % (i, mapTypes[i]) outCoeffs += "\nBond Coeffs\n\n" for i in range(1, nbondTypes + 1): outCoeffs += "\t%d\tK\tr_0\t# %s\n" % (i, mapbTypes[i]) outCoeffs += "\nAngle Coeffs\n\n" for i in range(1, nangleTypes + 1): outCoeffs += "\t%d\tK\ttetha_0 (deg)\t# %s\n" % (i, mapaTypes[i]) if printdih and (ndihedrals > 0): outCoeffs += "\nDihedral Coeffs\n\n" for i in range(1, ndihedralTypes + 1): outCoeffs += "\t%d\tK\tn\tphi_0 (deg)\tw\t# %s\n" % (i, mapdTypes[i]) if not ignoreimproper and (niDihedralTypes > 0): outCoeffs += "\nImproper Coeffs\n\n" for i in range(1, niDihedralTypes + 1): outCoeffs += "\t%d\tK\txi_0 (deg)\t# %s\n" % (i, mapiDTypes[i]) if printdih and (ndihedrals > 0): if ignoreimproper or (niDihedralTypes == 0): return header + "\n" + outMasses + "\n" + outCoeffs + "\n" + outAtoms + "\n" + outBonds + "\n" + outAngles + "\n" + outDihedrals else: return header + "\n" + outMasses + "\n" + outCoeffs + "\n" + outAtoms + "\n" + outBonds + "\n" + outAngles + "\n" + outDihedrals + "\n" + outImpropers else: return header + "\n" + outMasses + "\n" + outCoeffs + "\n" + outAtoms + "\n" + outBonds + "\n" + outAngles
def readstruct(ioa, struct, importers=None): fileadapter = ioadapters.IoAdapterFileReader(ioa) if fileadapter.ext == 'structure': struct.parse(fileadapter) if importers is None: try_importers = ['ase', 'openbabel'] else: try_importers = importers for importer in try_importers: if importer == 'ase': try: import ase.io atoms = ase.io.read(fileadapter.filename_open_workaround()) species = atoms.get_atomic_numbers() coords = atoms.get_positions() basis = atoms.get_cell() return Structure(basis=basis, coords=coords, species=species) except Exception as e: if importers is not None: reraise_from( Exception, "Error while trying ase importer: " + str(info[1]), e) elif importer == 'openbabel': try: import openbabel file = fileadapter.file filename = fileadapter.filename # Use babel to read data from file obConversion = openbabel.OBConversion() obConversion.SetInAndOutFormats( obConversion.FormatFromExt(fileadapter.filename), obConversion.FindFormat("pdb")) obmol = openbabel.OBMol() obConversion.ReadString(obmol, file.read()) unitcell = openbabel.toUnitCell( obmol.GetData(openbabel.UnitCell)) unitcell.FillUnitCell(obmol) basisvecs = unitcell.GetCellVectors() basis = array([[ basisvecs[0].GetX(), basisvecs[0].GetY(), basisvecs[0].GetZ() ], [ basisvecs[1].GetX(), basisvecs[1].GetY(), basisvecs[1].GetZ() ], [ basisvecs[2].GetX(), basisvecs[2].GetY(), basisvecs[2].GetZ() ]]) coords = [] species = [] for obatom in openbabel.OBMolAtomIter(obmol): cart = openbabel.vector3(obatom.GetX(), obatom.GetY(), obatom.GetZ()) coords.append([cart.GetX(), cart.GetY(), cart.GetZ()]) species.append(obatom.GetAtomicNum()) return Structure(basis=basis, coords=coords, species=species) except: if importers is not None: info = sys.exc_info() reraise_from( Exception, "Error while trying openbabel importer: " + str(info[1]), info) raise Exception("Could not figure out a way to read structure") return None
#print args.cuttype #print args.rcut #print args.qm openbabel.obErrorLog.SetOutputLevel(0) mols = pybel.readfile("pdb", args.infile) mols_sep = [] for mol in mols: newm = mol.OBMol.Separate() for m in newm: mols_sep.append(pybel.Molecule(m)) print "\n", len(mols_sep), "molecules found\n" openbabel.obErrorLog.SetOutputLevel(1) unitcell = openbabel.toUnitCell(mol.OBMol.GetData(openbabel.UnitCell)) #print unitcell.GetA() #print unitcell.GetB() #print unitcell.GetC() #print unitcell.GetAlpha() #print unitcell.GetBeta() #print unitcell.GetGamma() a = unitcell.GetA() b = unitcell.GetB() c = unitcell.GetC() cos_a = math.cos(unitcell.GetAlpha() * math.pi / 180) cos_b = math.cos(unitcell.GetBeta() * math.pi / 180) sin_b = math.sin(unitcell.GetBeta() * math.pi / 180) cos_g = math.cos(unitcell.GetGamma() * math.pi / 180) sin_g = math.sin(unitcell.GetGamma() * math.pi / 180)