Author: bugman Date: Thu Feb 5 14:41:36 2009 New Revision: 8741 URL: http://svn.gna.org/viewcvs/relax?rev=8741&view=rev Log: Massive speed up of the bond_vectors() method. The algorithm used was very, very poorly designed. Now when setting the profile flag to 1 gives the following. Before in one test: 11168736 function calls (10986641 primitive calls) in 76.750 CPU seconds ncalls tottime percall cumtime percall filename:lineno(function) 758954 12.160 0.000 51.060 0.000 /home/edau/relax/relax-1.3/generic_fns/relax_re.py:31(search) 141 0.890 0.006 67.620 0.480 /home/edau/relax/relax-1.3/generic_fns/structure/internal.py:444(bond_vectors) All other function call info lines have been removed. After the changes: 2586419 function calls (2579305 primitive calls) in 21.370 CPU seconds ncalls tottime percall cumtime percall filename:lineno(function) 62803 1.180 0.000 5.020 0.000 /home/edau/relax/relax-1.3/generic_fns/relax_re.py:31(search) 141 0.060 0.000 12.020 0.085 /home/edau/relax/relax-1.3/generic_fns/structure/internal.py:444(bond_vectors) The difference is that the selection object is no longer used, as it is completely unnecessary. Modified: 1.3/generic_fns/structure/internal.py 1.3/generic_fns/structure/main.py Modified: 1.3/generic_fns/structure/internal.py URL: http://svn.gna.org/viewcvs/relax/1.3/generic_fns/structure/internal.py?rev=8741&r1=8740&r2=8741&view=diff ============================================================================== --- 1.3/generic_fns/structure/internal.py (original) +++ 1.3/generic_fns/structure/internal.py Thu Feb 5 14:41:36 2009 @@ -72,7 +72,7 @@ @param attached_atom: The name of the attached atom to return. @type attached_atom: str - @param index: The index of the atom which the attached atom is attached to. + @param index: The index of the atom which the attached atom is attached to. @type index: int @param mol: The molecule container. @type mol: MolContainer instance @@ -441,18 +441,25 @@ break - def bond_vectors(self, atom_id=None, attached_atom=None, model_num=None, return_name=False, return_warnings=False): + def bond_vectors(self, attached_atom=None, model_num=None, mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None, return_name=False, return_warnings=False): """Find the bond vector between the atoms of 'attached_atom' and 'atom_id'. - @keyword atom_id: The molecule, residue, and atom identifier string. This must - correspond to a single atom in the system. - @type atom_id: str @keyword attached_atom: The name of the bonded atom. @type attached_atom: str @keyword model_num: The model of which to return the vectors from. If not supplied and multiple models exist, then vectors from all models will be returned. @type model_num: None or int + @keyword mol_name: The name of the molecule that attached_atom belongs to. + @type mol_name: str + @keyword res_num: The number of the residue that attached_atom belongs to. + @type res_num: str + @keyword res_name: The name of the residue that attached_atom belongs to. + @type res_name: str + @keyword spin_num: The number of the spin that attached_atom is attached to. + @type spin_num: str + @keyword spin_name: The name of the spin that attached_atom is attached to. + @type spin_name: str @keyword return_name: A flag which if True will cause the name of the attached atom to be returned together with the bond vectors. @type return_name: bool @@ -463,9 +470,6 @@ return_warnings are set) """ - # Generate the selection object. - sel_obj = Selection(atom_id) - # Initialise some objects. vectors = [] attached_name = None @@ -480,28 +484,29 @@ # Loop over the molecules. for mol in model.mol: # Skip non-matching molecules. - if sel_obj and not sel_obj.contains_mol(mol.mol_name): + if mol_name and mol_name != mol.mol_name: continue - # Init. - atom_found = False - - # Loop over all atoms. - for i in xrange(len(mol.atom_name)): - # Skip non-matching atoms. - if sel_obj and not sel_obj.contains_spin(mol.atom_num[i], mol.atom_name[i], mol.res_num[i], mol.res_name[i], mol.mol_name): + # Find the atomic index of the base atom. + index = None + for i in range(len(mol.atom_name)): + # Residues don't match. + if (res_num != None and mol.res_num[i] != res_num) or (res_name != None and mol.res_name[i] != res_name): continue + # Atoms don't match. + if (spin_num != None and mol.atom_num[i] != spin_num) or (spin_name != None and mol.atom_name[i] != spin_name): + continue + # More than one matching atom! - if atom_found: + if index != None: raise RelaxError, "The atom_id argument " + `atom_id` + " must correspond to a single atom." - # The atom has been found, so store some info. - atom_found = True + # Update the index. index = i # Found the atom. - if atom_found: + if index != None: # Get the atom bonded to this model/molecule/residue/atom. bonded_num, bonded_name, element, pos, attached_name, warnings = self.__bonded_atom(attached_atom, index, mol) Modified: 1.3/generic_fns/structure/main.py URL: http://svn.gna.org/viewcvs/relax/1.3/generic_fns/structure/main.py?rev=8741&r1=8740&r2=8741&view=diff ============================================================================== --- 1.3/generic_fns/structure/main.py (original) +++ 1.3/generic_fns/structure/main.py Thu Feb 5 14:41:36 2009 @@ -361,7 +361,7 @@ continue # Get the bond info. - bond_vectors, attached_name, warnings = cdp.structure.bond_vectors(atom_id=id, attached_atom=attached, model_num=model, return_name=True, return_warnings=True) + bond_vectors, attached_name, warnings = cdp.structure.bond_vectors(attached_atom=attached, model_num=model, mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin.num, spin_name=spin.name, return_name=True, return_warnings=True) # No attached atom. if not bond_vectors: