def test_from_SMILES_like_string1(self):

        # generate fragment from SMILES like string
        # the atom type is also calculated
        smiles_like = 'C'
        fragment = afm.fragment.Fragment().from_SMILES_like_string(smiles_like)

        # construct fragment manually
        atom_C = Atom(element=getElement('C'),
                      radicalElectrons=0,
                      charge=0,
                      lonePairs=0)

        atom_H1 = Atom(element=getElement('H'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        atom_H2 = Atom(element=getElement('H'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        atom_H3 = Atom(element=getElement('H'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        atom_H4 = Atom(element=getElement('H'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        atom_C.atomType = atomTypes['Cs']
        atom_H1.atomType = atomTypes['H']
        atom_H2.atomType = atomTypes['H']
        atom_H3.atomType = atomTypes['H']
        atom_H4.atomType = atomTypes['H']

        vertices = [atom_C, atom_H1, atom_H2, atom_H3, atom_H4]

        bonds = [
            Bond(atom_C, atom_H1, 1),
            Bond(atom_C, atom_H2, 1),
            Bond(atom_C, atom_H3, 1),
            Bond(atom_C, atom_H4, 1)
        ]

        expected_fragment = afm.fragment.Fragment()
        for vertex in vertices:
            expected_fragment.addVertex(vertex)
        for bond in bonds:
            expected_fragment.addEdge(bond)

        self.assertTrue(expected_fragment.isIsomorphic(fragment))
    def setUp(self):
        """
        A function run before each unit test in this class.
        """

        # construct the first fragment
        atom_C1 = Atom(element=getElement('C'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        cutting_label_R1 = afm.fragment.CuttingLabel('R')
        cutting_label_L1 = afm.fragment.CuttingLabel('L')

        vertices = [atom_C1, cutting_label_R1, cutting_label_L1]

        bonds = [
            Bond(atom_C1, cutting_label_R1),
            Bond(atom_C1, cutting_label_L1)
        ]

        self.fragment1 = afm.fragment.Fragment()
        for vertex in vertices:
            self.fragment1.addVertex(vertex)
        for bond in bonds:
            self.fragment1.addEdge(bond)

        # construct the second fragment
        atom_C2 = Atom(element=getElement('C'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        cutting_label_R2 = afm.fragment.CuttingLabel('R')
        cutting_label_L2 = afm.fragment.CuttingLabel('L')

        vertices = [atom_C2, cutting_label_R2, cutting_label_L2]

        bonds = [
            Bond(atom_C2, cutting_label_R2),
            Bond(atom_C2, cutting_label_L2)
        ]

        self.fragment2 = afm.fragment.Fragment()
        for vertex in vertices:
            self.fragment2.addVertex(vertex)
        for bond in bonds:
            self.fragment2.addEdge(bond)
def generate_isotopomers(spc, N=1):
    """
    Generate all isotopomers of the parameter species by adding max. N carbon isotopes to the
    atoms of the species.
    """

    mol = spc.molecule[0]
    isotope = getElement(6, 13)

    mols = []
    add_isotope(0, N, mol, mols, isotope)

    spcs = []
    for isomol in mols:
        isotopomer = Species(molecule=[isomol], thermo=deepcopy(spc.thermo), transportData=spc.transportData, reactive=spc.reactive)
        isotopomer.generate_resonance_structures(keep_isomorphic=True)
        spcs.append(isotopomer)

    # do not retain identical species:
    filtered = []
    while spcs:
        candidate = spcs.pop()
        unique = True
        for isotopomer in filtered:
            if isotopomer.isIsomorphic(candidate):
                unique = False
                break
        if unique: filtered.append(candidate)

    if spc.thermo:
        for isotopomer in filtered:
            correct_entropy(isotopomer, spc)

    return filtered
示例#4
0
def generate_isotopomers(spc, N=1):
    """
    Generate all isotopomers of the parameter species by adding max. N carbon isotopes to the
    atoms of the species.
    """

    mol = spc.molecule[0]
    isotope = getElement(6, 13)

    mols = []
    add_isotope(0, N, mol, mols, isotope)

    spcs = []
    for isomol in mols:
        isotopomer = Species(molecule=[isomol], thermo=deepcopy(spc.thermo), transportData=spc.transportData, reactive=spc.reactive)
        isotopomer.generate_resonance_structures(keep_isomorphic=True)
        spcs.append(isotopomer)

    # do not retain identical species:
    filtered = []
    while spcs:
        candidate = spcs.pop()
        unique = True
        for isotopomer in filtered:
            if isotopomer.isIsomorphic(candidate):
                unique = False
                break
        if unique: filtered.append(candidate)

    if spc.thermo:
        for isotopomer in filtered:
            correct_entropy(isotopomer, spc)

    return filtered
    def test_update(self):

        atom_C = Atom(element=getElement('C'),
                      radicalElectrons=0,
                      charge=0,
                      lonePairs=0)

        atom_H1 = Atom(element=getElement('H'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        atom_H2 = Atom(element=getElement('H'),
                       radicalElectrons=0,
                       charge=0,
                       lonePairs=0)

        cutting_label_R1 = afm.fragment.CuttingLabel('R')
        cutting_label_R2 = afm.fragment.CuttingLabel('R')

        vertices = [
            atom_C, cutting_label_R1, cutting_label_R2, atom_H1, atom_H2
        ]

        bonds = [
            Bond(atom_C, cutting_label_R1, 1),
            Bond(atom_C, cutting_label_R2, 1),
            Bond(atom_C, atom_H1, 1),
            Bond(atom_C, atom_H2, 1)
        ]

        fragment = afm.fragment.Fragment()
        for vertex in vertices:
            fragment.addVertex(vertex)
        for bond in bonds:
            fragment.addEdge(bond)

        fragment.update()

        for v in fragment.vertices:
            if isinstance(v, Atom) and v.isCarbon():
                break

        self.assertTrue(v.atomType == atomTypes['Cs'])
        self.assertTrue(fragment.getNetCharge() == 0)
        self.assertTrue(fragment.multiplicity == 1)
示例#6
0
def fromOBMol(mol, obmol):
    """
    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(radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int)
    # cython.declare(atom=Atom, atom1=Atom, atom2=Atom, bond=Bond)

    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):
        idx = obatom.GetIdx()  #openbabel idx starts at 1!

        # Use atomic number as key for element
        number = obatom.GetAtomicNum()
        element = elements.getElement(number)
        # Process charge
        charge = obatom.GetFormalCharge()
        obatom_multiplicity = obatom.GetSpinMultiplicity()
        radicalElectrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0

        atom = Atom(element, radicalElectrons, charge, '', 0)
        mol.vertices.append(atom)

    # iterate through bonds in obmol
    for obbond in openbabel.OBMolBondIter(obmol):
        order = 0
        # Process bond type
        oborder = obbond.GetBondOrder()
        if oborder == 1: order = 'S'
        elif oborder == 2: order = 'D'
        elif oborder == 3: order = 'T'
        elif obbond.IsAromatic(): order = 'B'

        bond = Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1],
                    mol.vertices[obbond.GetEndAtomIdx() - 1],
                    order)  #python array indices start at 0
        mol.addBond(bond)

    # Set atom types and connectivity values
    mol.updateConnectivityValues()
    mol.updateAtomTypes()
    mol.updateMultiplicity()
    mol.updateLonePairs()

    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.getRadicalCount() + 1

    return mol
示例#7
0
文件: parser.py 项目: Alborzi/RMG-Py
def fromOBMol(mol, obmol):
    """
    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(radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int)
    # cython.declare(atom=Atom, atom1=Atom, atom2=Atom, bond=Bond)
    
    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):
        idx = obatom.GetIdx()#openbabel idx starts at 1!
        
        # Use atomic number as key for element
        number = obatom.GetAtomicNum()
        element = elements.getElement(number)
        # Process charge
        charge = obatom.GetFormalCharge()
        obatom_multiplicity = obatom.GetSpinMultiplicity()
        radicalElectrons =  obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0
        
        atom = Atom(element, radicalElectrons, charge, '', 0)
        mol.vertices.append(atom)
    
    # iterate through bonds in obmol
    for obbond in openbabel.OBMolBondIter(obmol):
        order = 0
        # Process bond type
        oborder = obbond.GetBondOrder()
        if oborder == 1: order = 'S'
        elif oborder == 2: order = 'D'
        elif oborder == 3: order = 'T'
        elif obbond.IsAromatic() : order = 'B'

        bond = Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1], mol.vertices[obbond.GetEndAtomIdx() - 1], order)#python array indices start at 0
        mol.addBond(bond)

    
    # Set atom types and connectivity values
    mol.updateConnectivityValues()
    mol.updateAtomTypes()
    mol.updateMultiplicity()
    mol.updateLonePairs()
    
    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable, 
    mol.multiplicity = mol.getRadicalCount() + 1
    
    return mol
示例#8
0
 def setUp(self):
     """
     A method called before each unit test in this class.
     """
     self.atom = Atom(element=getElement('C'),
                      radicalElectrons=1,
                      charge=0,
                      label='*1',
                      lonePairs=0)
示例#9
0
def fromOBMol(mol, obmol):
    """
    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(radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int)
    # cython.declare(atom=mm.Atom, atom1=mm.Atom, atom2=mm.Atom, bond=mm.Bond)
    if not OB_INSTALLED:
        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.getElement(number, isotope or -1)
        # Process charge
        charge = obatom.GetFormalCharge()
        obatom_multiplicity = obatom.GetSpinMultiplicity()
        radicalElectrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0

        atom = mm.Atom(element, radicalElectrons, 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] 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.addBond(bond)

    # Set atom types and connectivity values
    mol.updateConnectivityValues()
    mol.updateAtomTypes()
    mol.updateMultiplicity()
    mol.identifyRingMembership()

    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.getRadicalCount() + 1

    return mol
示例#10
0
 def setUp(self):
     """
     A method called before each unit test in this class.
     """
     self.atom = Atom(element=getElement('C'),
                      radicalElectrons=1,
                      spinMultiplicity=2,
                      charge=0,
                      label='*1')
def fromOBMol(mol, obmol):
    """
    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(radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int)
    # cython.declare(atom=mm.Atom, atom1=mm.Atom, atom2=mm.Atom, bond=mm.Bond)
    if not OB_INSTALLED:
        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.getElement(number, isotope or -1)
        # Process charge
        charge = obatom.GetFormalCharge()
        obatom_multiplicity = obatom.GetSpinMultiplicity()
        radicalElectrons =  obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0

        atom = mm.Atom(element, radicalElectrons, 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.addBond(bond)


    # Set atom types and connectivity values
    mol.updateConnectivityValues()
    mol.updateAtomTypes()
    mol.updateMultiplicity()
    mol.identifyRingMembership()

    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.getRadicalCount() + 1

    return mol
示例#12
0
def get_xyz_string(coords, mol=None, numbers=None, symbols=None):
    """
    Convert list of lists xyz form::

        [[0.6616514836, 0.4027481525, -0.4847382281],
        [-0.6039793084, 0.6637270105, 0.0671637135],
        [-1.4226865648, -0.4973210697, -0.2238712255],
        [-0.4993010635, 0.6531020442, 1.0853092315],
        [-2.2115796924, -0.4529256762, 0.4144516252],
        [-1.8113671395, -0.3268900681, -1.1468957003]]

    into a geometry form read by an ESS::

        C    0.6616514836    0.4027481525   -0.4847382281
        N   -0.6039793084    0.6637270105    0.0671637135
        H   -1.4226865648   -0.4973210697   -0.2238712255
        H   -0.4993010635    0.6531020442    1.0853092315
        H   -2.2115796924   -0.4529256762    0.4144516252
        H   -1.8113671395   -0.3268900681   -1.1468957003

    The atom symbols are derived from either an RMG Molecule object, atom numbers, or explicitly given (`symbol`).
    This function isn't defined as a method of ARCSpecies since it is also used when parsing opt geometry in Scheduler.

    Args:
        coords (list): The array-format coordinates to be converted.
        mol (Molecule, optional): An RMG Molecule object.
        numbers (list, optional): Entries are atomic numbers (integers) corresponding to `coords`.
        symbols (list, optional): Entries are atomic symbols (strings) corresponding to `coords`.

    Returns:
        str: A string representation of the coordinates.
    """
    if isinstance(coords, (str, unicode)):
        logger.debug('Cannot convert string format xyz into a string...')
        return coords
    result = ''
    if symbols is not None:
        elements = symbols
    elif numbers is not None:
        elements = []
        for num in numbers:
            elements.append(getElement(int(num)).symbol)
    elif mol is not None:
        elements = []
        for atom in mol.atoms:
            elements.append(atom.element.symbol)
    else:
        raise ValueError("Must have either an RMG:Molecule object input as `mol`, or atomic numbers / symbols.")
    for i, coordinate in enumerate(coords):
        result += elements[i] + ' ' * (4 - len(elements[i]))
        for c in coordinate:
            result += '{0:14.8f}'.format(c)
        result += '\n'
    return result
示例#13
0
文件: mol.py 项目: cgrambow/bac
def pybel_to_rmg(pybelmol, addh=False):
    """ignore charge, multiplicity, and bond orders"""
    mol = molecule.Molecule()
    if addh:
        pybelmol.addh()
    for pybelatom in pybelmol:
        num = pybelatom.atomicnum
        element = elements.getElement(num)
        atom = molecule.Atom(element=element,
                             coords=np.array(pybelatom.coords))
        mol.vertices.append(atom)
    for obbond in pybel.ob.OBMolBondIter(pybelmol.OBMol):
        begin_idx = obbond.GetBeginAtomIdx() - 1
        end_idx = obbond.GetEndAtomIdx() - 1
        bond = molecule.Bond(mol.vertices[begin_idx], mol.vertices[end_idx])
        mol.addBond(bond)
    return mol.toSingleBonds()
def is_enriched(obj):
    """
    Returns True if the species or reaction object has any enriched isotopes.
    """

    if isinstance(obj,Species):
        for atom in obj.molecule[0].atoms:
            if atom.element.isotope != -1 and not np.allclose(atom.element.mass, getElement(atom.element.symbol).mass):
                return True
        return False
    elif isinstance(obj,Reaction):
        enriched = []
        for spec in obj.reactants:
            enriched.append(is_enriched(spec))
        for spec in obj.products:
            enriched.append(is_enriched(spec))
        return any(enriched)
    else:
        raise TypeError('is_enriched only takes species and reaction objects. {} was sent'.format(str(type(obj))))
示例#15
0
文件: converter.py 项目: goldmanm/ARC
def get_xyz_string(xyz, mol=None, number=None, symbol=None):
    """
    Convert list of lists xyz form:
    [[0.6616514836, 0.4027481525, -0.4847382281],
    [-0.6039793084, 0.6637270105, 0.0671637135],
    [-1.4226865648, -0.4973210697, -0.2238712255],
    [-0.4993010635, 0.6531020442, 1.0853092315],
    [-2.2115796924, -0.4529256762, 0.4144516252],
    [-1.8113671395, -0.3268900681, -1.1468957003]]
    into a geometry form read by ESS:
    C    0.6616514836    0.4027481525   -0.4847382281
    N   -0.6039793084    0.6637270105    0.0671637135
    H   -1.4226865648   -0.4973210697   -0.2238712255
    H   -0.4993010635    0.6531020442    1.0853092315
    H   -2.2115796924   -0.4529256762    0.4144516252
    H   -1.8113671395   -0.3268900681   -1.1468957003
    The atom symbols are derived from either an RMG Molecule object (`mol`) or atom numbers ('number`)
    or explicitly given (`symbol`).
    `number` and `symbol` are lists (optional parameters)
    `xyz` is an array of arrays, as shown in the example above.
    This function isn't defined as a method of ARCSpecies since it is also used when parsing opt geometry in Scheduler
    """
    result = ''
    if symbol is not None:
        elements = symbol
    elif number is not None:
        elements = []
        for num in number:
            elements.append(getElement(int(num)).symbol)
    elif mol is not None:
        elements = []
        for atom in mol.atoms:
            elements.append(atom.element.symbol)
    else:
        raise ValueError(
            "Must have either an RMG:Molecule object input as `mol`, or atomic numbers \ symbols."
        )
    for i, coord in enumerate(xyz):
        result += elements[i] + ' ' * (4 - len(elements[i]))
        for c in coord:
            result += '{0:14.8f}'.format(c)
        result += '\n'
    return result
示例#16
0
def is_enriched(obj):
    """
    Returns True if the species or reaction object has any enriched isotopes.
    """

    if isinstance(obj,Species):
        for atom in obj.molecule[0].atoms:
            if atom.element.isotope != -1 and not np.allclose(atom.element.mass, getElement(atom.element.symbol).mass):
                return True
        return False
    elif isinstance(obj,Reaction):
        enriched = []
        for spec in obj.reactants:
            enriched.append(is_enriched(spec))
        for spec in obj.products:
            enriched.append(is_enriched(spec))
        return any(enriched)
    else:
        raise TypeError('is_enriched only takes species and reaction objects. {} was sent'.format(str(type(obj))))
示例#17
0
文件: common.py 项目: yunsiechung/ARC
def determine_symmetry(coords, symbols):
    """
    Determine external symmetry and chirality (optical isomers) of the species.

    Args:
        coords (list): The 3D coordinates of a molecule in array-format.
        symbols (list): Entries are atomic symbols correcponding to coords.

    Returns:
        int: The external symmetry number.
    Returns:
        int: 1 if no chiral centers are present, 2 if chiral centers are present.
    """
    atom_numbers = list()  # List of atomic numbers
    for symbol in symbols:
        atom_numbers.append(getElement(str(symbol)).number)
    coords = np.array(coords,
                      np.float64)  # N x 3 numpy.ndarray of atomic coordinates
    #  in the same order as `atom_numbers`
    unique_id = '0'  # Just some name that the SYMMETRY code gives to one of its jobs
    scr_dir = os.path.join(
        arc_path, str('scratch')
    )  # Scratch directory that the SYMMETRY code writes its files in
    if not os.path.exists(scr_dir):
        os.makedirs(scr_dir)
    symmetry = optical_isomers = 1
    qmdata = QMData(
        groundStateDegeneracy=1,  # Only needed to check if valid QMData
        numberOfAtoms=len(atom_numbers),
        atomicNumbers=atom_numbers,
        atomCoords=(coords, str('angstrom')),
        energy=(0.0, str('kcal/mol'))  # Only needed to avoid error
    )
    settings = type(
        str(''), (),
        dict(symmetryPath=str('symmetry'), scratchDirectory=scr_dir))()
    pgc = PointGroupCalculator(settings, unique_id, qmdata)
    pg = pgc.calculate()
    if pg is not None:
        symmetry = pg.symmetryNumber
        optical_isomers = 2 if pg.chiral else optical_isomers
    return symmetry, optical_isomers
    def get_representative_molecule(self, mode='minimal', update=True):

        if mode == 'minimal':
            # create a molecule from fragment.vertices.copy
            mapping = self.copyAndMap()

            # replace CuttingLabel with H
            atoms = []
            for vertex in self.vertices:

                mapped_vertex = mapping[vertex]
                if isinstance(mapped_vertex, CuttingLabel):

                    # replace cutting label with atom H
                    atom_H = Atom(element=getElement('H'),
                                  radicalElectrons=0,
                                  charge=0,
                                  lonePairs=0)

                    for bondedAtom, bond in mapped_vertex.edges.iteritems():
                        new_bond = Bond(bondedAtom, atom_H, order=bond.order)

                        bondedAtom.edges[atom_H] = new_bond
                        del bondedAtom.edges[mapped_vertex]

                        atom_H.edges[bondedAtom] = new_bond

                    mapping[vertex] = atom_H
                    atoms.append(atom_H)

                else:
                    atoms.append(mapped_vertex)

            # Note: mapping is a dict with
            # key: self.vertex and value: mol_repr.atom
            mol_repr = Molecule()
            mol_repr.atoms = atoms
            if update:
                mol_repr.update()

            return mol_repr, mapping
示例#19
0
def fromRDKitMol(mol, rdkitmol):
    """
    Convert a RDKit Mol object `rdkitmol` to a molecular structure. Uses
    `RDKit <http://rdkit.org/>`_ to perform the conversion.
    This Kekulizes everything, removing all aromatic atom types.
    """
    cython.declare(
        i=cython.int,
        radicalElectrons=cython.int,
        charge=cython.int,
        lonePairs=cython.int,
        number=cython.int,
        order=cython.str,
        atom=Atom,
        atom1=Atom,
        atom2=Atom,
        bond=Bond,
    )

    mol.vertices = []

    # Add hydrogen atoms to complete molecule if needed
    rdkitmol = Chem.AddHs(rdkitmol)
    Chem.rdmolops.Kekulize(rdkitmol, clearAromaticFlags=True)

    # iterate through atoms in rdkitmol
    for i in xrange(rdkitmol.GetNumAtoms()):
        rdkitatom = rdkitmol.GetAtomWithIdx(i)

        # Use atomic number as key for element
        number = rdkitatom.GetAtomicNum()
        element = elements.getElement(number)

        # Process charge
        charge = rdkitatom.GetFormalCharge()
        radicalElectrons = rdkitatom.GetNumRadicalElectrons()

        atom = Atom(element, radicalElectrons, charge, "", 0)
        mol.vertices.append(atom)

        # Add bonds by iterating again through atoms
        for j in xrange(0, i):
            rdkitatom2 = rdkitmol.GetAtomWithIdx(j + 1)
            rdkitbond = rdkitmol.GetBondBetweenAtoms(i, j)
            if rdkitbond is not None:
                order = ""

                # Process bond type
                rdbondtype = rdkitbond.GetBondType()
                if rdbondtype.name == "SINGLE":
                    order = "S"
                elif rdbondtype.name == "DOUBLE":
                    order = "D"
                elif rdbondtype.name == "TRIPLE":
                    order = "T"
                elif rdbondtype.name == "AROMATIC":
                    order = "B"

                bond = Bond(mol.vertices[i], mol.vertices[j], order)
                mol.addBond(bond)

    # Set atom types and connectivity values
    mol.update()
    mol.updateLonePairs()

    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.getRadicalCount() + 1

    return mol
    def fromRDKitMol(self, rdkitmol, atom_replace_dict=None):
        """
        Convert a RDKit Mol object `rdkitmol` to a molecular structure. Uses
        `RDKit <http://rdkit.org/>`_ to perform the conversion.
        This Kekulizes everything, removing all aromatic atom types.
        """

        from rdkit import Chem

        self.vertices = []

        # Add hydrogen atoms to complete molecule if needed
        rdkitmol.UpdatePropertyCache(strict=False)
        rdkitmol = Chem.AddHs(rdkitmol)
        Chem.rdmolops.Kekulize(rdkitmol, clearAromaticFlags=True)

        # iterate through atoms in rdkitmol
        for i in xrange(rdkitmol.GetNumAtoms()):
            rdkitatom = rdkitmol.GetAtomWithIdx(i)

            # Use atomic number as key for element
            number = rdkitatom.GetAtomicNum()
            element = getElement(number)

            # Process charge
            charge = rdkitatom.GetFormalCharge()
            radicalElectrons = rdkitatom.GetNumRadicalElectrons()

            ELE = element.symbol
            if atom_replace_dict.has_key('[' + ELE + ']'):
                cutting_label_name = atom_replace_dict['[' + ELE + ']']
                cutting_label = CuttingLabel(name=cutting_label_name)
                self.vertices.append(cutting_label)
            else:
                atom = Atom(element, radicalElectrons, charge, '', 0)
                self.vertices.append(atom)

            # Add bonds by iterating again through atoms
            for j in xrange(0, i):
                rdkitbond = rdkitmol.GetBondBetweenAtoms(i, j)
                if rdkitbond is not None:
                    order = 0

                    # Process bond type
                    rdbondtype = rdkitbond.GetBondType()
                    if rdbondtype.name == 'SINGLE':
                        order = 1
                    elif rdbondtype.name == 'DOUBLE':
                        order = 2
                    elif rdbondtype.name == 'TRIPLE':
                        order = 3
                    elif rdbondtype.name == 'AROMATIC':
                        order = 1.5

                    bond = Bond(self.vertices[i], self.vertices[j], order)
                    self.addBond(bond)

        # We need to update lone pairs first because the charge was set by RDKit
        self.updateLonePairs()
        # Set atom types and connectivity values
        self.update()

        # Assume this is always true
        # There are cases where 2 radicalElectrons is a singlet, but
        # the triplet is often more stable,
        self.updateMultiplicity()
        # mol.updateAtomTypes()

        return self
def remove_isotope(labeledObj, inplace = False):
    """
    Create a deep copy of the first molecule of the species object and replace
    non-normal Element objects (of special isotopes) by the
    expected isotope.

    If the boolean `inplace` is True, the method remove the isotopic atoms of
    the Species/Reaction
    inplace and returns a list of atom objects & element pairs for adding back
    to the oritinal object. This should significantly improve speed of this method.

    If successful, the non-inplace parts should be removed
    """

    if isinstance(labeledObj,Species2):
        if inplace:
            modifiedAtoms = []
            for mol in labeledObj.molecule:
                for atom in mol.atoms:
                    if atom.element.isotope != -1:
                        modifiedAtoms.append((atom,atom.element))
                        atom.element = getElement(atom.element.symbol)
            return modifiedAtoms
        else:
            stripped = labeledObj.copy(deep=True)

            for atom in stripped.molecule[0].atoms:
                if atom.element.isotope != -1:
                    atom.element = getElement(atom.element.symbol)

        # only do it for the first molecule, generate the other resonance isomers.
            stripped.molecule = [stripped.molecule[0]]
            stripped.generate_resonance_structures(keep_isomorphic=True)

        return stripped

    elif isinstance(labeledObj,Reaction):

        if inplace:

            atomList = []
            for reactant in  labeledObj.reactants:
                removed = remove_isotope(reactant,inplace)
                if removed:
                    atomList += removed
            for product in labeledObj.products:
                removed = remove_isotope(product,inplace)
                if removed:
                    atomList += removed

            return atomList
        else:
            strippedRxn = labeledObj.copy()

            strippedReactants = []
            for reactant in  strippedRxn.reactants:
                strippedReactants.append(remove_isotope(reactant,inplace))
            strippedRxn.reactants = strippedReactants

            strippedProducts = []
            for product in  strippedRxn.products:
                strippedProducts.append(remove_isotope(product,inplace))
            strippedRxn.products = strippedProducts

            return strippedRxn
    elif isinstance(labeledObj,Molecule):
        if inplace:
            modifiedAtoms = []
            for atom in labeledObj.atoms:
                if atom.element.isotope != -1:
                    modifiedAtoms.append((atom,atom.element))
                    atom.element = getElement(atom.element.symbol)
            return modifiedAtoms
        else:
            stripped = labeledObj.copy(deep=True)

            for atom in stripped.atoms:
                if atom.element.isotope != -1:
                    atom.element = getElement(atom.element.symbol)

            return stripped
    else:
        raise TypeError('Only Reaction, Species, and Molecule objects are supported')
示例#22
0
def remove_isotope(labeledObj, inplace=False):
    """
    Create a deep copy of the first molecule of the species object and replace
    non-normal Element objects (of special isotopes) by the
    expected isotope.

    If the boolean `inplace` is True, the method remove the isotopic atoms of
    the Species/Reaction
    inplace and returns a list of atom objects & element pairs for adding back
    to the oritinal object. This should significantly improve speed of this method.

    If successful, the non-inplace parts should be removed
    """

    if isinstance(labeledObj, Species2):
        if inplace:
            modifiedAtoms = []
            for mol in labeledObj.molecule:
                for atom in mol.atoms:
                    if atom.element.isotope != -1:
                        modifiedAtoms.append((atom, atom.element))
                        atom.element = getElement(atom.element.symbol)
            return modifiedAtoms
        else:
            stripped = labeledObj.copy(deep=True)

            for atom in stripped.molecule[0].atoms:
                if atom.element.isotope != -1:
                    atom.element = getElement(atom.element.symbol)

        # only do it for the first molecule, generate the other resonance isomers.
            stripped.molecule = [stripped.molecule[0]]
            stripped.generate_resonance_structures(keep_isomorphic=True)

        return stripped

    elif isinstance(labeledObj, Reaction):

        if inplace:

            atomList = []
            for reactant in labeledObj.reactants:
                removed = remove_isotope(reactant, inplace)
                if removed:
                    atomList += removed
            for product in labeledObj.products:
                removed = remove_isotope(product, inplace)
                if removed:
                    atomList += removed

            return atomList
        else:
            strippedRxn = labeledObj.copy()

            strippedReactants = []
            for reactant in strippedRxn.reactants:
                strippedReactants.append(remove_isotope(reactant, inplace))
            strippedRxn.reactants = strippedReactants

            strippedProducts = []
            for product in strippedRxn.products:
                strippedProducts.append(remove_isotope(product, inplace))
            strippedRxn.products = strippedProducts

            return strippedRxn
    elif isinstance(labeledObj, Molecule):
        if inplace:
            modifiedAtoms = []
            for atom in labeledObj.atoms:
                if atom.element.isotope != -1:
                    modifiedAtoms.append((atom, atom.element))
                    atom.element = getElement(atom.element.symbol)
            return modifiedAtoms
        else:
            stripped = labeledObj.copy(deep=True)

            for atom in stripped.atoms:
                if atom.element.isotope != -1:
                    atom.element = getElement(atom.element.symbol)

            return stripped
    else:
        raise TypeError(
            'Only Reaction, Species, and Molecule objects are supported')
示例#23
0
 def setUp(self):
     """
     A method called before each unit test in this class.
     """
     self.atom = Atom(element=getElement('C'), radicalElectrons=1, spinMultiplicity=2, charge=0, label='*1')
示例#24
0
def fromRDKitMol(mol, rdkitmol):
    """
    Convert a RDKit Mol object `rdkitmol` to a molecular structure. Uses
    `RDKit <http://rdkit.org/>`_ to perform the conversion.
    This Kekulizes everything, removing all aromatic atom types.
    """
    cython.declare(i=cython.int,
                   radicalElectrons=cython.int,
                   charge=cython.int,
                   lonePairs=cython.int,
                   number=cython.int,
                   order=cython.float,
                   atom=mm.Atom,
                   atom1=mm.Atom,
                   atom2=mm.Atom,
                   bond=mm.Bond)

    mol.vertices = []

    # Add hydrogen atoms to complete molecule if needed
    rdkitmol.UpdatePropertyCache(strict=False)
    rdkitmol = Chem.AddHs(rdkitmol)
    Chem.rdmolops.Kekulize(rdkitmol, clearAromaticFlags=True)

    # iterate through atoms in rdkitmol
    for i in xrange(rdkitmol.GetNumAtoms()):
        rdkitatom = rdkitmol.GetAtomWithIdx(i)

        # Use atomic number as key for element
        number = rdkitatom.GetAtomicNum()
        isotope = rdkitatom.GetIsotope()
        element = elements.getElement(number, isotope or -1)

        # Process charge
        charge = rdkitatom.GetFormalCharge()
        radicalElectrons = rdkitatom.GetNumRadicalElectrons()

        atom = mm.Atom(element, radicalElectrons, charge, '', 0)
        mol.vertices.append(atom)

        # Add bonds by iterating again through atoms
        for j in xrange(0, i):
            rdkitbond = rdkitmol.GetBondBetweenAtoms(i, j)
            if rdkitbond is not None:
                order = 0

                # Process bond type
                rdbondtype = rdkitbond.GetBondType()
                if rdbondtype.name == 'SINGLE': order = 1
                elif rdbondtype.name == 'DOUBLE': order = 2
                elif rdbondtype.name == 'TRIPLE': order = 3
                elif rdbondtype.name == 'QUADRUPLE': order = 4
                elif rdbondtype.name == 'AROMATIC': order = 1.5

                bond = mm.Bond(mol.vertices[i], mol.vertices[j], order)
                mol.addBond(bond)

    # We need to update lone pairs first because the charge was set by RDKit
    mol.updateLonePairs()
    # Set atom types and connectivity values
    mol.update()

    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.getRadicalCount() + 1
    # mol.updateAtomTypes()

    return mol
    def assign_representative_molecule(self):

        # create a molecule from fragment.vertices.copy
        mapping = self.copyAndMap()

        # replace CuttingLabel with CC
        atoms = []
        additional_atoms = []
        additional_bonds = []
        for vertex in self.vertices:

            mapped_vertex = mapping[vertex]
            if isinstance(mapped_vertex, CuttingLabel):

                # replace cutting label with atom C
                atom_C1 = Atom(element=getElement('C'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                for bondedAtom, bond in mapped_vertex.edges.iteritems():
                    new_bond = Bond(bondedAtom, atom_C1, order=bond.order)

                    bondedAtom.edges[atom_C1] = new_bond
                    del bondedAtom.edges[mapped_vertex]

                    atom_C1.edges[bondedAtom] = new_bond

                # add hydrogens and carbon to make it CC
                atom_H1 = Atom(element=getElement('H'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                atom_H2 = Atom(element=getElement('H'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                atom_C2 = Atom(element=getElement('C'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                atom_H3 = Atom(element=getElement('H'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                atom_H4 = Atom(element=getElement('H'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                atom_H5 = Atom(element=getElement('H'),
                               radicalElectrons=0,
                               charge=0,
                               lonePairs=0)

                atoms.append(atom_C1)

                additional_atoms.extend(
                    [atom_H1, atom_H2, atom_H3, atom_H4, atom_H5, atom_C2])

                additional_bonds.extend([
                    Bond(atom_C1, atom_H1, 1),
                    Bond(atom_C1, atom_H2, 1),
                    Bond(atom_C2, atom_H3, 1),
                    Bond(atom_C2, atom_H4, 1),
                    Bond(atom_C2, atom_H5, 1),
                    Bond(atom_C1, atom_C2, 1)
                ])

            else:
                atoms.append(mapped_vertex)

        mol_repr = Molecule()
        mol_repr.atoms = atoms
        for atom in additional_atoms:
            mol_repr.addAtom(atom)
        for bond in additional_bonds:
            mol_repr.addBond(bond)
        # update connectivity
        mol_repr.update()

        # create a species object from molecule
        self.mol_repr = mol_repr

        return mapping
    maxSiliconAtoms = speciesConstraints.get("maximumSiliconAtoms", -1)
    if maxSiliconAtoms != -1:
        if struct.getNumAtoms("Si") > maxSiliconAtoms:
            return True

    maxSulfurAtoms = speciesConstraints.get("maximumSulfurAtoms", -1)
    if maxSulfurAtoms != -1:
        if struct.getNumAtoms("S") > maxSulfurAtoms:
            return True

    maxHeavyAtoms = speciesConstraints.get("maximumHeavyAtoms", -1)
    if maxHeavyAtoms != -1:
        if struct.getNumAtoms() - struct.getNumAtoms("H") > maxHeavyAtoms:
            return True

    maxRadicals = speciesConstraints.get("maximumRadicalElectrons", -1)
    if maxRadicals != -1:
        if struct.getNumberOfRadicalElectrons() > maxRadicals:
            return True

    maxIsotopes = speciesConstraints.get("maximumIsotopicAtoms", -1)
    if maxIsotopes != -1:
        counter = 0
        for atom in struct.atoms:
            if not isclose(atom.mass, getElement(atom.symbol).mass, atol=1e-04):
                counter += 1
            if counter > maxIsotopes:
                return True

    return False
示例#27
0
 def setUp(self):
     """
     A method called before each unit test in this class.
     """
     self.atom = Atom(element=getElement('C'), radicalElectrons=1, charge=0, label='*1', lonePairs=0)
示例#28
0
    maxSiliconAtoms = speciesConstraints.get('maximumSiliconAtoms', -1)
    if maxSiliconAtoms != -1:
        if struct.getNumAtoms('Si') > maxSiliconAtoms:
            return True

    maxSulfurAtoms = speciesConstraints.get('maximumSulfurAtoms', -1)
    if maxSulfurAtoms != -1:
        if struct.getNumAtoms('S') > maxSulfurAtoms:
            return True

    maxHeavyAtoms = speciesConstraints.get('maximumHeavyAtoms', -1)
    if maxHeavyAtoms != -1:
        if struct.getNumAtoms() - struct.getNumAtoms('H') > maxHeavyAtoms:
            return True

    maxRadicals = speciesConstraints.get('maximumRadicalElectrons', -1)
    if maxRadicals != -1:
        if (struct.getNumberOfRadicalElectrons() > maxRadicals):
            return True

    maxIsotopes = speciesConstraints.get('maximumIsotopicAtoms', -1)
    if maxIsotopes != -1:
        counter = 0
        for atom in struct.atoms:
            if not isclose(atom.mass, getElement(atom.symbol).mass,
                           atol=1e-04):
                counter += 1
            if counter > maxIsotopes: return True

    return False
wilhoit.fitToData(Tlist, Cplist, Cp0, CpInf, H298, S298, B0=500.0)\

NASA_fit = wilhoit.toNASA(Tlist[0], Tlist[-1], Tint=500.0)

string = ''

f = open('chem.inp', 'a')

# Line 1
string += '{0:<16}        '.format(SpeciesIdentifier)
if len(elementCounts) <= 4:
    # Use the original Chemkin syntax for the element counts
    for key, count in elementCounts.iteritems():
        if isinstance(key, tuple):
            symbol, isotope = key
            chemkinName = getElement(symbol, isotope=isotope).chemkinName
        else:
            chemkinName = key
        string += '{0!s:<2}{1:>3d}'.format(chemkinName, count)
    string += '     ' * (4 - len(elementCounts))
else:
    string += '     ' * 4
string += 'G{0:>10.3f}{1:>10.3f}{2:>8.2f}      1'.format(NASA_fit.polynomials[0].Tmin.value_si,
                                                         NASA_fit.polynomials[1].Tmax.value_si,
                                                         NASA_fit.polynomials[0].Tmax.value_si)
if len(elementCounts) > 4:
    string += '&\n'
    # Use the new-style Chemkin syntax for the element counts
    # This will only be recognized by Chemkin 4 or later
    for key, count in elementCounts.iteritems():
        if isinstance(key, tuple):
示例#30
0
    maxSiliconAtoms = speciesConstraints.get('maximumSiliconAtoms', -1)
    if maxSiliconAtoms != -1:
        if struct.getNumAtoms('Si') > maxSiliconAtoms:
            return True

    maxSulfurAtoms = speciesConstraints.get('maximumSulfurAtoms', -1)
    if maxSulfurAtoms != -1:
        if struct.getNumAtoms('S') > maxSulfurAtoms:
            return True

    maxHeavyAtoms = speciesConstraints.get('maximumHeavyAtoms', -1)
    if maxHeavyAtoms != -1:
        if struct.getNumAtoms() - struct.getNumAtoms('H') > maxHeavyAtoms:
            return True

    maxRadicals = speciesConstraints.get('maximumRadicalElectrons', -1)
    if maxRadicals != -1:
        if (struct.getRadicalCount() > maxRadicals):
            return True

    maxIsotopes = speciesConstraints.get('maximumIsotopicAtoms', -1)
    if maxIsotopes != -1:
        counter = 0
        for atom in struct.atoms:
            if not isclose(atom.mass, getElement(atom.symbol).mass, atol=1e-04):
                counter += 1
            if counter > maxIsotopes: return True

    return False
def failsSpeciesConstraints(species):
    """
    Pass in either a `Species` or `Molecule` object and checks whether it passes 
    the speciesConstraints set by the user.  If not, returns `True` for failing speciesConstraints.
    """

    from rmgpy.rmg.input import getInput

    try:
        speciesConstraints = getInput('speciesConstraints')
    except Exception:
        logging.debug('Species constraints could not be found.')
        speciesConstraints = {}

    if isinstance(species, Species):
        struct = species.molecule[0]
    else:
        # expects a molecule here
        struct = species

    explicitlyAllowedMolecules = speciesConstraints.get(
        'explicitlyAllowedMolecules', [])
    for molecule in explicitlyAllowedMolecules:
        if struct.isIsomorphic(molecule):
            return False

    maxCarbonAtoms = speciesConstraints.get('maximumCarbonAtoms', -1)
    if maxCarbonAtoms != -1:
        if struct.getNumAtoms('C') > maxCarbonAtoms:
            return True

    maxOxygenAtoms = speciesConstraints.get('maximumOxygenAtoms', -1)
    if maxOxygenAtoms != -1:
        if struct.getNumAtoms('O') > maxOxygenAtoms:
            return True

    maxNitrogenAtoms = speciesConstraints.get('maximumNitrogenAtoms', -1)
    if maxNitrogenAtoms != -1:
        if struct.getNumAtoms('N') > maxNitrogenAtoms:
            return True

    maxSiliconAtoms = speciesConstraints.get('maximumSiliconAtoms', -1)
    if maxSiliconAtoms != -1:
        if struct.getNumAtoms('Si') > maxSiliconAtoms:
            return True

    maxSulfurAtoms = speciesConstraints.get('maximumSulfurAtoms', -1)
    if maxSulfurAtoms != -1:
        if struct.getNumAtoms('S') > maxSulfurAtoms:
            return True

    maxHeavyAtoms = speciesConstraints.get('maximumHeavyAtoms', -1)
    if maxHeavyAtoms != -1:
        if struct.getNumAtoms() - struct.getNumAtoms('H') > maxHeavyAtoms:
            return True

    maxRadicals = speciesConstraints.get('maximumRadicalElectrons', -1)
    if maxRadicals != -1:
        if (struct.getRadicalCount() > maxRadicals):
            return True

    maxCarbenes = speciesConstraints.get('maximumSingletCarbenes', 1)
    if maxRadicals != -1:
        if struct.getSingletCarbeneCount() > maxCarbenes:
            return True

    maxCarbeneRadicals = speciesConstraints.get('maximumCarbeneRadicals', 0)
    if maxCarbeneRadicals != -1:
        if struct.getSingletCarbeneCount() > 0 and struct.getRadicalCount(
        ) > maxCarbeneRadicals:
            return True

    maxIsotopes = speciesConstraints.get('maximumIsotopicAtoms', -1)
    if maxIsotopes != -1:
        counter = 0
        for atom in struct.atoms:
            if not isclose(atom.mass, getElement(atom.symbol).mass,
                           atol=1e-04):
                counter += 1
            if counter > maxIsotopes: return True

    return False
示例#32
0
def failsSpeciesConstraints(species):
    """
    Pass in either a `Species` or `Molecule` object and checks whether it passes 
    the speciesConstraints set by the user.  If not, returns `True` for failing speciesConstraints.
    """
    
    from rmgpy.rmg.input import getInput

    try:
        speciesConstraints = getInput('speciesConstraints')
    except Exception:
        logging.debug('Species constraints could not be found.')
        speciesConstraints = {}
    
    if isinstance(species, Species):
        struct = species.molecule[0]
    else:
        # expects a molecule here
        struct = species

    explicitlyAllowedMolecules = speciesConstraints.get('explicitlyAllowedMolecules', [])
    for molecule in explicitlyAllowedMolecules:
        if struct.isIsomorphic(molecule):
            return False  
    
    maxCarbonAtoms = speciesConstraints.get('maximumCarbonAtoms', -1)          
    if maxCarbonAtoms != -1:
        if struct.getNumAtoms('C') > maxCarbonAtoms:
            return True

    maxOxygenAtoms = speciesConstraints.get('maximumOxygenAtoms', -1)
    if maxOxygenAtoms != -1:
        if struct.getNumAtoms('O') > maxOxygenAtoms:
            return True

    maxNitrogenAtoms = speciesConstraints.get('maximumNitrogenAtoms', -1)
    if maxNitrogenAtoms != -1:
        if struct.getNumAtoms('N') > maxNitrogenAtoms:
            return True

    maxSiliconAtoms = speciesConstraints.get('maximumSiliconAtoms', -1)
    if maxSiliconAtoms != -1:
        if struct.getNumAtoms('Si') > maxSiliconAtoms:
            return True

    maxSulfurAtoms = speciesConstraints.get('maximumSulfurAtoms', -1)
    if maxSulfurAtoms != -1:
        if struct.getNumAtoms('S') > maxSulfurAtoms:
            return True

    maxHeavyAtoms = speciesConstraints.get('maximumHeavyAtoms', -1)
    if maxHeavyAtoms != -1:
        if struct.getNumAtoms() - struct.getNumAtoms('H') > maxHeavyAtoms:
            return True

    maxRadicals = speciesConstraints.get('maximumRadicalElectrons', -1)
    if maxRadicals != -1:
        if (struct.getRadicalCount() > maxRadicals):
            return True

    maxCarbenes = speciesConstraints.get('maximumSingletCarbenes', 1)
    if maxRadicals != -1:
        if struct.getSingletCarbeneCount() > maxCarbenes:
            return True

    maxCarbeneRadicals = speciesConstraints.get('maximumCarbeneRadicals', 0)
    if maxCarbeneRadicals != -1:
        if struct.getSingletCarbeneCount() > 0 and struct.getRadicalCount() > maxCarbeneRadicals:
            return True

    maxIsotopes = speciesConstraints.get('maximumIsotopicAtoms', -1)
    if maxIsotopes != -1:
        counter = 0
        for atom in struct.atoms:
            if not isclose(atom.mass, getElement(atom.symbol).mass, atol=1e-04):
                counter += 1
            if counter > maxIsotopes: return True

    return False