1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23  """Module for handling all types of structural statistics.""" 
 24   
 25   
 26  from numpy import array, float64, mean, ones, sqrt, std, zeros 
 27  from numpy.linalg import norm 
 28   
 29   
 31      """Determine the RMSD for the given atomic coordinates. 
 32   
 33      This is the per atom RMSD to the mean structure. 
 34   
 35   
 36      @keyword coord:     The array of molecular coordinates.  The first dimension corresponds to the model, the second the atom, the third the coordinate. 
 37      @type coord:        rank-3 numpy array 
 38      @return:            The RMSD value. 
 39      @rtype:             float 
 40      """ 
 41   
 42       
 43      M = len(coord) 
 44      N = len(coord[0]) 
 45      model_rmsd = zeros(M, float64) 
 46      mean_str = zeros((N, 3), float64) 
 47   
 48       
 49      calc_mean_structure(coord, mean_str) 
 50   
 51       
 52      for i in range(M): 
 53           
 54          for j in range(N): 
 55               
 56              vect = mean_str[j] - coord[i][j] 
 57   
 58               
 59              model_rmsd[i] += norm(vect)**2 
 60   
 61           
 62          model_rmsd[i] = sqrt(model_rmsd[i] / N) 
 63   
 64           
 65          if verbosity: 
 66              print("Model %2s RMSD:  %s" % (i, model_rmsd[i])) 
 67   
 68       
 69      rmsd_mean = sqrt(mean(model_rmsd**2)) 
 70   
 71       
 72      try: 
 73          rmsd_sd = sqrt(std(model_rmsd**2, ddof=1)) 
 74   
 75       
 76      except TypeError: 
 77          rmsd_sd = sqrt(std(model_rmsd**2) * sqrt(M / (M - 1.0))) 
 78   
 79       
 80      if verbosity: 
 81          print("\nGlobal RMSD:  %s +/- %s" % (rmsd_mean, rmsd_sd)) 
 82   
 83       
 84      return rmsd_mean 
  85   
 86   
 88      """Average the coordinates. 
 89   
 90      @keyword coord:     The list of coordinates of all models to superimpose.  The first index is the models, the second is the atomic positions, and the third is the xyz coordinates. 
 91      @type coord:        list of numpy rank-2, Nx3 arrays 
 92      @keyword weights:   The weights for each structure. 
 93      @type weights:      list of float 
 94      @keyword mean:      The data storage for the mean structure. 
 95      @type mean:         numpy rank-2, Nx3 array 
 96      """ 
 97   
 98       
 99      N = len(coord[0]) 
100      M = len(coord) 
101      if weights == None: 
102          weights = ones(M, float64) 
103      else: 
104          weights = array(weights, float64) 
105   
106       
107      for i in range(N): 
108          mean[i] = [0.0, 0.0, 0.0] 
109   
110       
111      for i in range(N): 
112           
113          for j in range(M): 
114              mean[i] += weights[j] * coord[j][i] 
115   
116           
117          mean[i] = mean[i] / weights.sum() 
 118   
119   
121      """Determine the per-atom RMSDs for the given atomic coordinates. 
122   
123      This is the per atom RMSD to the mean structure. 
124   
125   
126      @keyword coord:     The array of molecular coordinates.  The first dimension corresponds to the model, the second the atom, the third the coordinate. 
127      @type coord:        rank-3 numpy array 
128      @return:            The list of RMSD values for each atom. 
129      @rtype:             rank-1 numpy float64 array 
130      """ 
131   
132       
133      M = len(coord) 
134      N = len(coord[0]) 
135      model_rmsd = zeros(M, float64) 
136      mean_str = zeros((N, 3), float64) 
137      rmsd = zeros(N, float64) 
138   
139       
140      calc_mean_structure(coord, mean_str) 
141   
142       
143      for j in range(N): 
144           
145          for i in range(M): 
146               
147              vect = mean_str[j] - coord[i][j] 
148   
149               
150              rmsd[j] += norm(vect)**2 
151   
152           
153          rmsd[j] = sqrt(rmsd[j] / M) 
154   
155       
156      return rmsd 
 157