def _mol_from_rdkit(self): """ Using an RDKit Molecule object, extract the name, topology, coordinates and atoms """ if self.name is None: self.name = self.rdkit_mol.GetProp("_Name") atoms = [] self.topology = nx.Graph() # Collect the atom names and bonds for atom in self.rdkit_mol.GetAtoms(): # Collect info about each atom atomic_number = atom.GetAtomicNum() index = atom.GetIdx() try: # PDB file extraction atom_name = atom.GetMonomerInfo().GetName().strip() except AttributeError: try: # Mol2 file extraction atom_name = atom.GetProp("_TriposAtomName") except KeyError: # smiles and mol files have no atom names so generate them here if they are not declared atom_name = f"{atom.GetSymbol()}{index}" qube_atom = Atom(atomic_number, index, atom_name, formal_charge=atom.GetFormalCharge()) # Instance the basic qube_atom qube_atom.atom_type = atom.GetSmarts() # Add the atoms as nodes self.topology.add_node(atom.GetIdx()) # Add the bonds for bonded in atom.GetNeighbors(): self.topology.add_edge(atom.GetIdx(), bonded.GetIdx()) qube_atom.add_bond(bonded.GetIdx()) # Now add the atom to the molecule atoms.append(qube_atom) self.coords = self.rdkit_mol.GetConformer().GetPositions() self.atoms = atoms or None
def _read_mol2(self): """ Internal mol2 reader. Only called when RDKit failed to read the mol2. Extracts the topology, atoms and coords of the molecule. """ coords = [] self.topology = nx.Graph() atoms = [] atom_count = 0 with open(self.mol_input, 'r') as mol2: atom_flag = False bond_flag = False for line in mol2: if '@<TRIPOS>ATOM' in line: atom_flag = True continue elif '@<TRIPOS>BOND' in line: atom_flag = False bond_flag = True continue elif '@<TRIPOS>SUBSTRUCTURE' in line: bond_flag = False continue if atom_flag: # Add the molecule information atomic_symbol = line.split()[1][:2] atomic_symbol = re.sub('[0-9]+', '', atomic_symbol) atomic_symbol = atomic_symbol.strip().title() atomic_number = Element().number(atomic_symbol) coords.append([float(line.split()[2]), float(line.split()[3]), float(line.split()[4])]) # Collect the atom names atom_name = str(line.split()[1]) # Add the nodes to the topology object self.topology.add_node(atom_count) atom_count += 1 # Get the atom types atom_type = line.split()[5] atom_type = atom_type.replace(".", "") # Make the qube_atom qube_atom = Atom(atomic_number, atom_count, atom_name) qube_atom.atom_type = atom_type atoms.append(qube_atom) if bond_flag: # Add edges to the topology network atom_index, bonded_index = int(line.split()[1]) - 1, int(line.split()[2]) - 1 self.topology.add_edge(atom_index, bonded_index) atoms[atom_index].add_bond(bonded_index) atoms[bonded_index].add_bond(atom_index) # put the object back into the correct place self.coords = np.array(coords) self.atoms = atoms or None