Author: bugman Date: Thu Sep 25 17:52:15 2008 New Revision: 7302 URL: http://svn.gna.org/viewcvs/relax?rev=7302&view=rev Log: Added support to the internal PDB structural object for determining connected atoms. This is for when no CONECT records exist. The method __find_bonded_atom() has been renamed to __bonded_atom(), and the new method __find_bonded_atoms() has been written. This new method connects all atoms located a certain distance from each other. Modified: 1.3/generic_fns/structure/internal.py Modified: 1.3/generic_fns/structure/internal.py URL: http://svn.gna.org/viewcvs/relax/1.3/generic_fns/structure/internal.py?rev=7302&r1=7301&r2=7302&view=diff ============================================================================== --- 1.3/generic_fns/structure/internal.py (original) +++ 1.3/generic_fns/structure/internal.py Thu Sep 25 17:52:15 2008 @@ -24,7 +24,7 @@ """Module containing the internal relax structural object.""" # Python module imports. -from numpy import array, float64, zeros +from numpy import array, float64, linalg, zeros from re import search from string import split, strip from warnings import warn @@ -74,41 +74,7 @@ warn(RelaxWarning("The atom number " + `atom_num` + " from the CONECT record cannot be found within the ATOM and HETATM records.")) - def __fill_object_from_pdb(self, records, struct_index): - """Method for generating a complete Structure_container object from the given PDB records. - - @param records: A list of structural PDB records. - @type records: list of str - @param struct_index: The index of the structural container to add the data to. - @type struct_index: int - """ - - # Loop over the records. - for record in records: - # Parse the record. - record = self.__parse_pdb_record(record) - - # Nothing to do. - if not record: - continue - - # Add the atom. - if record[0] == 'ATOM' or record[0] == 'HETATM': - self.atom_add(pdb_record=record[0], atom_num=record[1], atom_name=record[2], res_name=record[4], chain_id=record[5], res_num=record[6], pos=[record[8], record[9], record[10]], segment_id=record[13], element=record[14], struct_index=struct_index) - - # Connect atoms. - if record[0] == 'CONECT': - # Loop over the atoms of the record. - for i in xrange(len(record)-2): - # Skip if there is no record. - if record[i+2] == None: - continue - - # Make the connection. - self.atom_connect(index1=self.__atom_index(record[1], struct_index), index2=self.__atom_index(record[i+2], struct_index), struct_index=struct_index) - - - def __find_bonded_atom(self, attached_atom, index, struct_index): + def __bonded_atom(self, attached_atom, index, struct_index): """Find the atom named attached_atom directly bonded to the atom located at the index. @param attached_atom: The name of the attached atom to return. @@ -126,6 +92,10 @@ bonded_found = False struct = self.structural_data[struct_index] + # No bonded atoms, so go find everything within 1.2 Angstroms and say they are bonded. + if not struct.bonded[index]: + self.__find_bonded_atoms(index, struct_index) + # Loop over the bonded atoms. matching_list = [] for bonded_index in struct.bonded[index]: @@ -157,6 +127,71 @@ # Return the information. return bonded_num, bonded_name, element, pos, attached_name, None + + + def __fill_object_from_pdb(self, records, struct_index): + """Method for generating a complete Structure_container object from the given PDB records. + + @param records: A list of structural PDB records. + @type records: list of str + @param struct_index: The index of the structural container to add the data to. + @type struct_index: int + """ + + # Loop over the records. + for record in records: + # Parse the record. + record = self.__parse_pdb_record(record) + + # Nothing to do. + if not record: + continue + + # Add the atom. + if record[0] == 'ATOM' or record[0] == 'HETATM': + self.atom_add(pdb_record=record[0], atom_num=record[1], atom_name=record[2], res_name=record[4], chain_id=record[5], res_num=record[6], pos=[record[8], record[9], record[10]], segment_id=record[13], element=record[14], struct_index=struct_index) + + # Connect atoms. + if record[0] == 'CONECT': + # Loop over the atoms of the record. + for i in xrange(len(record)-2): + # Skip if there is no record. + if record[i+2] == None: + continue + + # Make the connection. + self.atom_connect(index1=self.__atom_index(record[1], struct_index), index2=self.__atom_index(record[i+2], struct_index), struct_index=struct_index) + + + def __find_bonded_atoms(self, index, struct_index, radius=1.2): + """Find all atoms within a sphere and say that they are attached to the central atom. + + The found atoms will be added to the 'bonded' data structure. + + + @param index: The index of the central atom. + @type index: int + @param struct_index: The index of the structure. + @type struct_index: int + """ + + # Init. + struct = self.structural_data[struct_index] + + # Central atom info. + centre = array([struct.x[index], struct.y[index], struct.z[index]], float64) + + # Atom loop. + for i in xrange(len(struct.atom_num)): + # The atom's position. + pos = array([struct.x[i], struct.y[i], struct.z[i]], float64) + + # The distance from the centre. + dist = linalg.norm(centre-pos) + + # Connect the atoms if within the radius value. + if dist < radius: + self.atom_connect(index, i) def __get_chemical_name(self, hetID): @@ -698,8 +733,8 @@ # Found the atom. if atom_found: - # Find the atom bonded to this structure/molecule/residue/atom. - bonded_num, bonded_name, element, pos, attached_name, warnings = self.__find_bonded_atom(attached_atom, index, i) + # Get the atom bonded to this structure/molecule/residue/atom. + bonded_num, bonded_name, element, pos, attached_name, warnings = self.__bonded_atom(attached_atom, index, i) # No bonded atom. if (bonded_num, bonded_name, element) == (None, None, None):