Package generic_fns :: Package structure :: Module mass
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.structure.mass

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2011 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Python module imports. 
 24  from numpy import float64, zeros 
 25  from warnings import warn 
 26   
 27  # relax module imports. 
 28  from generic_fns.mol_res_spin import return_molecule, return_residue, return_spin 
 29  from physical_constants import return_atomic_mass 
 30  from relax_errors import RelaxError, RelaxNoPdbError 
 31  from relax_warnings import RelaxWarning 
 32   
 33   
 34   
35 -def centre_of_mass(atom_id=None, model=None, return_mass=False):
36 """Calculate and return the centre of mass of the structure. 37 38 @keyword atom_id: The molecule, residue, and atom identifier string. Only atoms matching this selection will be used. 39 @type atom_id: str or None 40 @keyword model: Only use a specific model. 41 @type model: int or None 42 @keyword return_mass: A flag which if False will cause only the centre of mass to be returned, but if True will cause the centre of mass and the mass itself to be returned as a tuple. 43 @type return_mass: bool 44 @return: The centre of mass vector, and additionally the mass. 45 @rtype: list of 3 floats (or tuple of a list of 3 floats and one float) 46 """ 47 48 # Test if a structure has been loaded. 49 if not hasattr(cdp, 'structure'): 50 raise RelaxNoPdbError 51 52 # Print out. 53 print("Calculating the centre of mass.") 54 55 # Initialise the centre of mass. 56 R = zeros(3, float64) 57 58 # Initialise the total mass. 59 M = 0.0 60 61 # Loop over all atoms. 62 for mol_name, res_num, res_name, atom_num, atom_name, element, pos in cdp.structure.atom_loop(atom_id=atom_id, model_num=model, mol_name_flag=True, res_num_flag=True, res_name_flag=True, atom_num_flag=True, atom_name_flag=True, element_flag=True, pos_flag=True): 63 # Initialise the spin id string. 64 id = '' 65 66 # Get the corresponding molecule container. 67 if mol_name == None: 68 mol_cont = cdp.mol[0] 69 else: 70 id = id + '#' + mol_name 71 mol_cont = return_molecule(id) 72 73 # Get the corresponding residue container. 74 if res_name == None and res_num == None: 75 res_cont = mol_cont.res[0] 76 else: 77 id = id + ':' + repr(res_num) 78 res_cont = return_residue(id) 79 80 # Get the corresponding spin container. 81 if atom_name == None and atom_num == None: 82 spin_cont = res_cont.spin[0] 83 else: 84 id = id + '@' + repr(atom_num) 85 spin_cont = return_spin(id) 86 87 # Deselected spins. 88 if spin_cont and not spin_cont.select: 89 continue 90 91 # No element? 92 if element == None: 93 warn(RelaxWarning("Skipping the atom '%s' as the element type cannot be determined." % id)) 94 continue 95 96 # Atomic mass. 97 try: 98 mass = return_atomic_mass(element) 99 except RelaxError: 100 warn(RelaxWarning("Skipping the atom '%s' as the element '%s' is unknown." % (id, element))) 101 102 # Total mass. 103 M = M + mass 104 105 # Sum of mass * position. 106 R = R + mass * pos 107 108 # Normalise. 109 R = R / M 110 111 # Final print out. 112 print((" Total mass: M = " + repr(M))) 113 print((" Centre of mass: R = " + repr(R))) 114 115 # Return the centre of mass. 116 if return_mass: 117 return R, M 118 else: 119 return R
120