def test_ready(self): if not os.path.exists(self.executablePath): raise DependencyError( "Couldn't find MOPAC executable at {0}. Try setting your MOPAC_DIR " "environment variable.".format(self.executablePath)) # Check if MOPAC executable works properly process = Popen(self.executablePath, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() self.expired = False stderr = stderr.decode('utf-8') if 'has expired' in stderr: # The MOPAC executable is expired logging.warning('\n'.join(stderr.split('\n')[2:7])) self.expired = True elif 'To install the MOPAC license' in stderr: # The MOPAC executable exists, but the license has not been installed raise DependencyError('\n'.join(stderr.split('\n')[0:9])) elif 'MOPAC_LICENSE' in stderr: # The MOPAC executable is in the wrong location on Windows; MOPAC_LICENSE must be set raise DependencyError('\n'.join(stderr.split('\n')[0:11]))
def toOBMol(mol, returnMapping=False): """ Convert a molecular structure to an OpenBabel OBMol object. Uses `OpenBabel <http://openbabel.org/>`_ to perform the conversion. """ if not OB_INSTALLED: raise DependencyError( 'OpenBabel is not installed. Please install or use RDKit.') # Sort the atoms to ensure consistent output mol.sortAtoms() atoms = mol.vertices obAtomIds = {} # dictionary of OB atom IDs obmol = openbabel.OBMol() for atom in atoms: a = obmol.NewAtom() a.SetAtomicNum(atom.number) a.SetFormalCharge(atom.charge) obAtomIds[atom] = a.GetId() orders = {1: 1, 2: 2, 3: 3, 1.5: 5} for atom1 in mol.vertices: for atom2, bond in atom1.edges.iteritems(): index1 = atoms.index(atom1) index2 = atoms.index(atom2) if index1 < index2: order = orders[bond.order] obmol.AddBond(index1 + 1, index2 + 1, order) obmol.AssignSpinMultiplicity(True) if returnMapping: return obmol, obAtomIds return obmol
def _rdkit_translator(input_object, identifier_type, mol=None): """ Converts between formats using RDKit. If input is a :class:`Molecule`, the identifier_type is used to determine the output type. If the input is a `str`, then the identifier_type is used to identify the input, and the desired output is assumed to be a :class:`Molecule` object. Args: input_object: either molecule or string identifier identifier_type: format of string identifier 'inchi' -> InChI 'inchikey' -> InChI Key 'sma' -> SMARTS 'smi' -> SMILES mol: molecule object for output (optional) """ if identifier_type == 'inchi' and not Chem.inchi.INCHI_AVAILABLE: raise DependencyError("RDKit installed without InChI. Please reinstall to read and write InChI strings.") if isinstance(input_object, str): # We are converting from a string identifier to a molecule if identifier_type == 'inchi': rdkitmol = Chem.inchi.MolFromInchi(input_object, removeHs=False) elif identifier_type == 'sma': rdkitmol = Chem.MolFromSmarts(input_object) elif identifier_type == 'smi': rdkitmol = Chem.MolFromSmiles(input_object) else: raise ValueError('Identifier type {0} is not supported for reading using RDKit.'.format(identifier_type)) if rdkitmol is None: raise ValueError("Could not interpret the identifier {0!r}".format(input_object)) if mol is None: mol = mm.Molecule() output = fromRDKitMol(mol, rdkitmol) elif isinstance(input_object, mm.Molecule): # We are converting from a molecule to a string identifier if identifier_type == 'smi': rdkitmol = toRDKitMol(input_object, sanitize=False) else: rdkitmol = toRDKitMol(input_object, sanitize=True) if identifier_type == 'inchi': output = Chem.inchi.MolToInchi(rdkitmol, options='-SNon') elif identifier_type == 'inchikey': inchi = toInChI(input_object) output = Chem.inchi.InchiToInchiKey(inchi) elif identifier_type == 'sma': output = Chem.MolToSmarts(rdkitmol) elif identifier_type == 'smi': if input_object.isAromatic(): output = Chem.MolToSmiles(rdkitmol) else: output = Chem.MolToSmiles(rdkitmol, kekuleSmiles=True) else: raise ValueError('Identifier type {0} is not supported for writing using RDKit.'.format(identifier_type)) else: raise ValueError('Unexpected input format. Should be a Molecule or a string.') return output
def from_ob_mol(mol, obmol, raise_atomtype_exception=True): """ Convert a OpenBabel Mol object `obmol` to a molecular structure. Uses `OpenBabel <http://openbabel.org/>`_ to perform the conversion. """ # Below are the declared variables for cythonizing the module # cython.declare(i=cython.int) # cython.declare(radical_electrons=cython.int, charge=cython.int, lone_pairs=cython.int) # cython.declare(atom=mm.Atom, atom1=mm.Atom, atom2=mm.Atom, bond=mm.Bond) if openbabel is None: raise DependencyError( 'OpenBabel is not installed. Please install or use RDKit.') mol.vertices = [] # Add hydrogen atoms to complete molecule if needed obmol.AddHydrogens() # TODO Chem.rdmolops.Kekulize(obmol, clearAromaticFlags=True) # iterate through atoms in obmol for obatom in openbabel.OBMolAtomIter(obmol): # Use atomic number as key for element number = obatom.GetAtomicNum() isotope = obatom.GetIsotope() element = elements.get_element(number, isotope or -1) # Process charge charge = obatom.GetFormalCharge() obatom_multiplicity = obatom.GetSpinMultiplicity() radical_electrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0 atom = mm.Atom(element, radical_electrons, charge, '', 0) mol.vertices.append(atom) # iterate through bonds in obmol for obbond in openbabel.OBMolBondIter(obmol): # Process bond type oborder = obbond.GetBondOrder() if oborder not in [1, 2, 3, 4] and obbond.IsAromatic(): oborder = 1.5 bond = mm.Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1], mol.vertices[obbond.GetEndAtomIdx() - 1], oborder) # python array indices start at 0 mol.add_bond(bond) # Set atom types and connectivity values mol.update_connectivity_values() mol.update_atomtypes(log_species=True, raise_exception=raise_atomtype_exception) mol.update_multiplicity() mol.identify_ring_membership() # Assume this is always true # There are cases where 2 radical_electrons is a singlet, but # the triplet is often more stable, mol.multiplicity = mol.get_radical_count() + 1 return mol
def to_ob_mol(mol, return_mapping=False): """ Convert a molecular structure to an OpenBabel OBMol object. Uses `OpenBabel <http://openbabel.org/>`_ to perform the conversion. """ if openbabel is None: raise DependencyError( 'OpenBabel is not installed. Please install or use RDKit.') # Sort the atoms to ensure consistent output mol.sort_atoms() atoms = mol.vertices ob_atom_ids = {} # dictionary of OB atom IDs obmol = openbabel.OBMol() for atom in atoms: a = obmol.NewAtom() if atom.element.symbol == 'X': a.SetAtomicNum( 78 ) # not sure how to do this with linear scaling when this might not be Pt else: a.SetAtomicNum(atom.number) if atom.element.isotope != -1: a.SetIsotope(atom.element.isotope) a.SetFormalCharge(atom.charge) ob_atom_ids[atom] = a.GetId() orders = {1: 1, 2: 2, 3: 3, 4: 4, 1.5: 5} for atom1 in mol.vertices: for atom2, bond in atom1.edges.items(): if bond.is_hydrogen_bond(): continue index1 = atoms.index(atom1) index2 = atoms.index(atom2) if index1 < index2: order = orders[bond.order] obmol.AddBond(index1 + 1, index2 + 1, order) obmol.AssignSpinMultiplicity(True) if return_mapping: return obmol, ob_atom_ids return obmol