def test_to_adjacency_list_for_non_integer_bonds(self): """ Test the adjacency list can be created for molecules with bond orders that don't fit into single, double, triple, or benzene """ from rmgpy.molecule.molecule import Atom, Bond, Molecule atom1 = Atom(element='H', lone_pairs=0) atom2 = Atom(element='H', lone_pairs=0) bond = Bond(atom1, atom2, 0.5) mol = Molecule(multiplicity=1) mol.add_atom(atom1) mol.add_atom(atom2) mol.add_bond(bond) adjlist = mol.to_adjacency_list() self.assertIn('H', adjlist) self.assertIn('{1,0.5}', adjlist)
def get_resonance_hybrid(self): """ Returns a molecule object with bond orders that are the average of all the resonance structures. """ # get labeled resonance isomers self.generate_resonance_structures(keep_isomorphic=True) # only consider reactive molecules as representative structures molecules = [mol for mol in self.molecule if mol.reactive] # return if no resonance if len(molecules) == 1: return molecules[0] # create a sorted list of atom objects for each resonance structure cython.declare( atomsFromStructures=list, oldAtoms=list, newAtoms=list, numResonanceStructures=cython.short, structureNum=cython.short, oldBondOrder=cython.float, index1=cython.short, index2=cython.short, newMol=Molecule, oldMol=Molecule, atom1=Atom, atom2=Atom, bond=Bond, atoms=list, ) atoms_from_structures = [] for new_mol in molecules: new_mol.atoms.sort(key=lambda atom: atom.id) atoms_from_structures.append(new_mol.atoms) num_resonance_structures = len(molecules) # make original structure with no bonds new_mol = Molecule() original_atoms = atoms_from_structures[0] for atom1 in original_atoms: atom = new_mol.add_atom(Atom(atom1.element)) atom.id = atom1.id new_atoms = new_mol.atoms # initialize bonds to zero order for index1, atom1 in enumerate(original_atoms): for atom2 in atom1.bonds: index2 = original_atoms.index(atom2) bond = Bond(new_atoms[index1], new_atoms[index2], 0) new_mol.add_bond(bond) # set bonds to the proper value for structureNum, oldMol in enumerate(molecules): old_atoms = atoms_from_structures[structureNum] for index1, atom1 in enumerate(old_atoms): # make bond orders average of resonance structures for atom2 in atom1.bonds: index2 = old_atoms.index(atom2) new_bond = new_mol.get_bond(new_atoms[index1], new_atoms[index2]) old_bond_order = oldMol.get_bond( old_atoms[index1], old_atoms[index2]).get_order_num() new_bond.apply_action( ('CHANGE_BOND', None, old_bond_order / num_resonance_structures / 2)) # set radicals in resonance hybrid to maximum of all structures if atom1.radical_electrons > 0: new_atoms[index1].radical_electrons = max( atom1.radical_electrons, new_atoms[index1].radical_electrons) new_mol.update_atomtypes(log_species=False, raise_exception=False) return new_mol