Package maths_fns :: Module frame_order
[hide private]
[frames] | no frames]

Source Code for Module maths_fns.frame_order

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009-2012 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program 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 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Module containing the target functions of the Frame Order theories.""" 
 24   
 25  # Python module imports. 
 26  from copy import deepcopy 
 27  from numpy import array, dot, float64, ones, transpose, zeros 
 28   
 29  # relax module imports. 
 30  from generic_fns.frame_order import print_frame_order_2nd_degree 
 31  from maths_fns.alignment_tensor import to_5D, to_tensor 
 32  from maths_fns.chi2 import chi2 
 33  from maths_fns.frame_order_matrix_ops import compile_2nd_matrix_free_rotor, compile_2nd_matrix_iso_cone, compile_2nd_matrix_iso_cone_free_rotor, compile_2nd_matrix_iso_cone_torsionless, compile_2nd_matrix_pseudo_ellipse, compile_2nd_matrix_pseudo_ellipse_free_rotor, compile_2nd_matrix_pseudo_ellipse_torsionless, compile_2nd_matrix_rotor, reduce_alignment_tensor 
 34  from maths_fns.rotation_matrix import euler_to_R_zyz as euler_to_R 
 35  from relax_errors import RelaxError 
 36   
 37   
38 -class Frame_order:
39 """Class containing the target function of the optimisation of Frame Order matrix components.""" 40
41 - def __init__(self, model=None, init_params=None, full_tensors=None, red_tensors=None, red_errors=None, full_in_ref_frame=None, frame_order_2nd=None):
42 """Set up the target functions for the Frame Order theories. 43 44 @keyword model: The name of the Frame Order model. 45 @type model: str 46 @keyword init_params: The initial parameter values. 47 @type init_params: numpy float64 array 48 @keyword full_tensors: An array of the {Sxx, Syy, Sxy, Sxz, Syz} values for all full alignment tensors. The format is [Sxx1, Syy1, Sxy1, Sxz1, Syz1, Sxx2, Syy2, Sxy2, Sxz2, Syz2, ..., Sxxn, Syyn, Sxyn, Sxzn, Syzn]. 49 @type full_tensors: numpy nx5D, rank-1 float64 array 50 @keyword red_tensors: An array of the {Sxx, Syy, Sxy, Sxz, Syz} values for all reduced tensors. The array format is the same as for full_tensors. 51 @type red_tensors: numpy nx5D, rank-1 float64 array 52 @keyword red_errors: An array of the {Sxx, Syy, Sxy, Sxz, Syz} errors for all reduced tensors. The array format is the same as for full_tensors. 53 @type red_errors: numpy nx5D, rank-1 float64 array 54 @keyword full_in_ref_frame: An array of flags specifying if the tensor in the reference frame is the full or reduced tensor. 55 @type full_in_ref_frame: numpy rank-1 array 56 @keyword frame_order_2nd: The numerical values of the 2nd degree Frame Order matrix. If supplied, the target functions will optimise directly to these values. 57 @type frame_order_2nd: None or numpy 9D, rank-2 array 58 """ 59 60 # Model test. 61 if not model: 62 raise RelaxError("The type of Frame Order model must be specified.") 63 64 # Store the initial parameter (as a copy). 65 self.params = deepcopy(init_params) 66 67 # Store the agrs. 68 self.model = model 69 self.full_tensors = full_tensors 70 self.red_tensors = red_tensors 71 self.red_errors = red_errors 72 self.full_in_ref_frame = full_in_ref_frame 73 74 # Mix up. 75 if full_tensors != None and frame_order_2nd != None: 76 raise RelaxError("Tensors and Frame Order matrices cannot be supplied together.") 77 if full_tensors == None and frame_order_2nd == None: 78 raise RelaxError("The arguments have been incorrectly supplied, cannot determine the optimisation mode.") 79 80 # Tensor setup. 81 if full_tensors != None: 82 self.__init_tensors() 83 84 # Optimisation to the 2nd degree Frame Order matrix components directly. 85 if model == 'iso cone, free rotor' and frame_order_2nd != None: 86 self.__init_iso_cone_elements(frame_order_2nd) 87 88 # The target function aliases. 89 if model == 'pseudo-ellipse': 90 self.func = self.func_pseudo_ellipse 91 elif model == 'pseudo-ellipse, torsionless': 92 self.func = self.func_pseudo_ellipse_torsionless 93 elif model == 'pseudo-ellipse, free rotor': 94 self.func = self.func_pseudo_ellipse_free_rotor 95 elif model == 'iso cone': 96 self.func = self.func_iso_cone 97 elif model == 'iso cone, torsionless': 98 self.func = self.func_iso_cone_torsionless 99 elif model == 'iso cone, free rotor': 100 self.func = self.func_iso_cone_free_rotor 101 elif model == 'line': 102 self.func = self.func_line 103 elif model == 'line, torsionless': 104 self.func = self.func_line_torsionless 105 elif model == 'line, free rotor': 106 self.func = self.func_line_free_rotor 107 elif model == 'rotor': 108 self.func = self.func_rotor 109 elif model == 'rigid': 110 self.func = self.func_rigid 111 elif model == 'free rotor': 112 self.func = self.func_free_rotor
113 114
115 - def __init_tensors(self):
116 """Set up isotropic cone optimisation against the alignment tensor data.""" 117 118 # Some checks. 119 if self.full_tensors == None or not len(self.full_tensors): 120 raise RelaxError("The full_tensors argument " + repr(self.full_tensors) + " must be supplied.") 121 if self.red_tensors == None or not len(self.red_tensors): 122 raise RelaxError("The red_tensors argument " + repr(self.red_tensors) + " must be supplied.") 123 if self.red_errors == None or not len(self.red_errors): 124 raise RelaxError("The red_errors argument " + repr(self.red_errors) + " must be supplied.") 125 if self.full_in_ref_frame == None or not len(self.full_in_ref_frame): 126 raise RelaxError("The full_in_ref_frame argument " + repr(self.full_in_ref_frame) + " must be supplied.") 127 128 # Tensor set up. 129 self.num_tensors = int(len(self.full_tensors) / 5) 130 self.red_tensors_bc = zeros(self.num_tensors*5, float64) 131 132 # The rotation to the Frame Order eigenframe. 133 self.rot = zeros((3, 3), float64) 134 self.tensor_3D = zeros((3, 3), float64) 135 136 # The cone axis storage and molecular frame z-axis. 137 self.cone_axis = zeros(3, float64) 138 self.z_axis = array([0, 0, 1], float64) 139 140 # Initialise the Frame Order matrices. 141 self.frame_order_2nd = zeros((9, 9), float64)
142 143
144 - def __init_iso_cone_elements(self, frame_order_2nd):
145 """Set up isotropic cone optimisation against the 2nd degree Frame Order matrix elements. 146 147 @keyword frame_order_2nd: The numerical values of the 2nd degree Frame Order matrix. If supplied, the target functions will optimise directly to these values. 148 @type frame_order_2nd: numpy 9D, rank-2 array 149 """ 150 151 # Store the real matrix components. 152 self.data = frame_order_2nd 153 154 # The errors. 155 self.errors = ones((9, 9), float64) 156 157 # The cone axis storage and molecular frame z-axis. 158 self.cone_axis = zeros(3, float64) 159 self.z_axis = array([0, 0, 1], float64) 160 161 # The rotation. 162 self.rot = zeros((3, 3), float64) 163 164 # Initialise the Frame Order matrices. 165 self.frame_order_2nd = zeros((9, 9), float64) 166 167 # Alias the target function. 168 self.func = self.func_iso_cone_elements
169 170
171 - def func_free_rotor(self, params):
172 """Target function for free rotor model optimisation. 173 174 This function optimises against alignment tensors. The Euler angles for the tensor rotation are the first 3 parameters optimised in this model, followed by the polar and azimuthal angles of the cone axis. 175 176 @param params: The vector of parameter values. These are the tensor rotation angles {alpha, beta, gamma, theta, phi}. 177 @type params: list of float 178 @return: The chi-squared or SSE value. 179 @rtype: float 180 """ 181 182 # Unpack the parameters. 183 ave_pos_beta, ave_pos_gamma, axis_theta, axis_phi = params 184 185 # Generate the 2nd degree Frame Order super matrix. 186 frame_order_2nd = compile_2nd_matrix_free_rotor(self.frame_order_2nd, self.rot, self.z_axis, self.cone_axis, axis_theta, axis_phi) 187 188 # Reduce and rotate the tensors. 189 self.reduce_and_rot(0.0, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 190 191 # Return the chi-squared value. 192 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
193 194
195 - def func_iso_cone_elements(self, params):
196 """Target function for isotropic cone model optimisation using the Frame Order matrix. 197 198 This function optimises by directly matching the elements of the 2nd degree Frame Order 199 super matrix. The cone axis spherical angles theta and phi and the cone angle theta are the 200 3 parameters optimised in this model. 201 202 @param params: The vector of parameter values {theta, phi, theta_cone} where the first two are the polar and azimuthal angles of the cone axis theta_cone is the isotropic cone angle. 203 @type params: list of float 204 @return: The chi-squared or SSE value. 205 @rtype: float 206 """ 207 208 # Break up the parameters. 209 theta, phi, theta_cone = params 210 211 # Generate the 2nd degree Frame Order super matrix. 212 self.frame_order_2nd = compile_2nd_matrix_iso_cone_free_rotor(self.frame_order_2nd, self.rot, self.z_axis, self.cone_axis, theta, phi, theta_cone) 213 214 # Make the Frame Order matrix contiguous. 215 self.frame_order_2nd = self.frame_order_2nd.copy() 216 217 # Reshape the numpy arrays for use in the chi2() function. 218 self.data.shape = (81,) 219 self.frame_order_2nd.shape = (81,) 220 self.errors.shape = (81,) 221 222 # Get the chi-squared value. 223 val = chi2(self.data, self.frame_order_2nd, self.errors) 224 225 # Reshape the arrays back to normal. 226 self.data.shape = (9, 9) 227 self.frame_order_2nd.shape = (9, 9) 228 self.errors.shape = (9, 9) 229 230 # Return the chi2 value. 231 return val
232 233
234 - def func_iso_cone(self, params):
235 """Target function for isotropic cone model optimisation. 236 237 This function optimises against alignment tensors. 238 239 @param params: The vector of parameter values {beta, gamma, theta, phi, s1} where the first 2 are the tensor rotation Euler angles, the next two are the polar and azimuthal angles of the cone axis, and s1 is the isotropic cone order parameter. 240 @type params: list of float 241 @return: The chi-squared or SSE value. 242 @rtype: float 243 """ 244 245 # Unpack the parameters. 246 ave_pos_alpha, ave_pos_beta, ave_pos_gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta, sigma_max = params 247 248 # Generate the 2nd degree Frame Order super matrix. 249 frame_order_2nd = compile_2nd_matrix_iso_cone(self.frame_order_2nd, self.rot, eigen_alpha, eigen_beta, eigen_gamma, cone_theta, sigma_max) 250 251 # Reduce and rotate the tensors. 252 self.reduce_and_rot(ave_pos_alpha, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 253 254 # Return the chi-squared value. 255 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
256 257
258 - def func_iso_cone_free_rotor(self, params):
259 """Target function for free rotor isotropic cone model optimisation. 260 261 This function optimises against alignment tensors. 262 263 @param params: The vector of parameter values {beta, gamma, theta, phi, s1} where the first 2 are the tensor rotation Euler angles, the next two are the polar and azimuthal angles of the cone axis, and s1 is the isotropic cone order parameter. 264 @type params: list of float 265 @return: The chi-squared or SSE value. 266 @rtype: float 267 """ 268 269 # Unpack the parameters. 270 ave_pos_beta, ave_pos_gamma, axis_theta, axis_phi, cone_s1 = params 271 272 # Generate the 2nd degree Frame Order super matrix. 273 frame_order_2nd = compile_2nd_matrix_iso_cone_free_rotor(self.frame_order_2nd, self.rot, self.z_axis, self.cone_axis, axis_theta, axis_phi, cone_s1) 274 275 # Reduce and rotate the tensors. 276 self.reduce_and_rot(0.0, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 277 278 # Return the chi-squared value. 279 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
280 281
282 - def func_iso_cone_torsionless(self, params):
283 """Target function for torsionless isotropic cone model optimisation. 284 285 This function optimises against alignment tensors. 286 287 @param params: The vector of parameter values {beta, gamma, theta, phi, cone_theta} where the first 2 are the tensor rotation Euler angles, the next two are the polar and azimuthal angles of the cone axis, and cone_theta is cone opening angle. 288 @type params: list of float 289 @return: The chi-squared or SSE value. 290 @rtype: float 291 """ 292 293 # Unpack the parameters. 294 ave_pos_beta, ave_pos_gamma, axis_theta, axis_phi, cone_theta = params 295 296 # Generate the 2nd degree Frame Order super matrix. 297 frame_order_2nd = compile_2nd_matrix_iso_cone_torsionless(self.frame_order_2nd, self.rot, self.z_axis, self.cone_axis, axis_theta, axis_phi, cone_theta) 298 299 # Reduce and rotate the tensors. 300 self.reduce_and_rot(0.0, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 301 302 # Return the chi-squared value. 303 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
304 305
306 - def func_pseudo_ellipse(self, params):
307 """Target function for pseudo-elliptic cone model optimisation. 308 309 @param params: The vector of parameter values {alpha, beta, gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y, cone_sigma_max} where the first 3 are the average position rotation Euler angles, the next 3 are the Euler angles defining the eigenframe, and the last 3 are the pseudo-elliptic cone geometric parameters. 310 @type params: list of float 311 @return: The chi-squared or SSE value. 312 @rtype: float 313 """ 314 315 # Unpack the parameters. 316 ave_pos_alpha, ave_pos_beta, ave_pos_gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y, cone_sigma_max = params 317 318 # Generate the 2nd degree Frame Order super matrix. 319 frame_order_2nd = compile_2nd_matrix_pseudo_ellipse(self.frame_order_2nd, self.rot, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y, cone_sigma_max) 320 321 # Reduce and rotate the tensors. 322 self.reduce_and_rot(ave_pos_alpha, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 323 324 # Return the chi-squared value. 325 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
326 327
328 - def func_pseudo_ellipse_free_rotor(self, params):
329 """Target function for free_rotor pseudo-elliptic cone model optimisation. 330 331 @param params: The vector of parameter values {alpha, beta, gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y} where the first 3 are the average position rotation Euler angles, the next 3 are the Euler angles defining the eigenframe, and the last 2 are the free_rotor pseudo-elliptic cone geometric parameters. 332 @type params: list of float 333 @return: The chi-squared or SSE value. 334 @rtype: float 335 """ 336 337 # Unpack the parameters. 338 ave_pos_alpha, ave_pos_beta, ave_pos_gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y = params 339 340 # Generate the 2nd degree Frame Order super matrix. 341 frame_order_2nd = compile_2nd_matrix_pseudo_ellipse_free_rotor(self.frame_order_2nd, self.rot, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y) 342 343 # Reduce and rotate the tensors. 344 self.reduce_and_rot(ave_pos_alpha, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 345 346 # Return the chi-squared value. 347 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
348 349
350 - def func_pseudo_ellipse_torsionless(self, params):
351 """Target function for torsionless pseudo-elliptic cone model optimisation. 352 353 @param params: The vector of parameter values {alpha, beta, gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y} where the first 3 are the average position rotation Euler angles, the next 3 are the Euler angles defining the eigenframe, and the last 2 are the torsionless pseudo-elliptic cone geometric parameters. 354 @type params: list of float 355 @return: The chi-squared or SSE value. 356 @rtype: float 357 """ 358 359 # Unpack the parameters. 360 ave_pos_alpha, ave_pos_beta, ave_pos_gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y = params 361 362 # Generate the 2nd degree Frame Order super matrix. 363 frame_order_2nd = compile_2nd_matrix_pseudo_ellipse_torsionless(self.frame_order_2nd, self.rot, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y) 364 365 # Reduce and rotate the tensors. 366 self.reduce_and_rot(ave_pos_alpha, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 367 368 # Return the chi-squared value. 369 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
370 371
372 - def func_rigid(self, params):
373 """Target function for rigid model optimisation. 374 375 This function optimises against alignment tensors. The Euler angles for the tensor rotation are the 3 parameters optimised in this model. 376 377 @param params: The vector of parameter values. These are the tensor rotation angles {alpha, beta, gamma}. 378 @type params: list of float 379 @return: The chi-squared or SSE value. 380 @rtype: float 381 """ 382 383 # Unpack the parameters. 384 ave_pos_alpha, ave_pos_beta, ave_pos_gamma = params 385 386 # Reduce and rotate the tensors. 387 self.reduce_and_rot(ave_pos_alpha, ave_pos_beta, ave_pos_gamma) 388 389 # Return the chi-squared value. 390 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
391 392
393 - def func_rotor(self, params):
394 """Target function for rotor model optimisation. 395 396 This function optimises against alignment tensors. The Euler angles for the tensor rotation are the first 3 parameters optimised in this model, followed by the polar and azimuthal angles of the cone axis and the torsion angle restriction. 397 398 @param params: The vector of parameter values. These are the tensor rotation angles {alpha, beta, gamma, theta, phi, sigma_max}. 399 @type params: list of float 400 @return: The chi-squared or SSE value. 401 @rtype: float 402 """ 403 404 # Unpack the parameters. 405 ave_pos_alpha, ave_pos_beta, ave_pos_gamma, axis_theta, axis_phi, sigma_max = params 406 407 # Generate the 2nd degree Frame Order super matrix. 408 frame_order_2nd = compile_2nd_matrix_rotor(self.frame_order_2nd, self.rot, self.z_axis, self.cone_axis, axis_theta, axis_phi, sigma_max) 409 410 # Reduce and rotate the tensors. 411 self.reduce_and_rot(ave_pos_alpha, ave_pos_beta, ave_pos_gamma, frame_order_2nd) 412 413 # Return the chi-squared value. 414 return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)
415 416
417 - def reduce_and_rot(self, ave_pos_alpha=None, ave_pos_beta=None, ave_pos_gamma=None, daeg=None):
418 """Reduce and rotate the alignments tensors using the frame order matrix and Euler angles. 419 420 @keyword ave_pos_alpha: The alpha Euler angle describing the average domain position, the tensor rotation. 421 @type ave_pos_alpha: float 422 @keyword ave_pos_beta: The beta Euler angle describing the average domain position, the tensor rotation. 423 @type ave_pos_beta: float 424 @keyword ave_pos_gamma: The gamma Euler angle describing the average domain position, the tensor rotation. 425 @type ave_pos_gamma: float 426 @keyword daeg: The 2nd degree frame order matrix. 427 @type daeg: rank-2, 9D array 428 """ 429 430 # Alignment tensor rotation. 431 euler_to_R(ave_pos_alpha, ave_pos_beta, ave_pos_gamma, self.rot) 432 433 # Back calculate the rotated tensors. 434 for i in range(self.num_tensors): 435 # Tensor indices. 436 index1 = i*5 437 index2 = i*5+5 438 439 # Reduction. 440 if daeg != None: 441 # Reduce the tensor. 442 reduce_alignment_tensor(daeg, self.full_tensors[index1:index2], self.red_tensors_bc[index1:index2]) 443 444 # Convert the reduced tensor to 3D, rank-2 form. 445 to_tensor(self.tensor_3D, self.red_tensors_bc[index1:index2]) 446 447 # No reduction: 448 else: 449 # Convert the original tensor to 3D, rank-2 form. 450 to_tensor(self.tensor_3D, self.full_tensors[index1:index2]) 451 452 # Rotate the tensor (normal R.X.RT rotation). 453 if self.full_in_ref_frame[i]: 454 tensor_3D = dot(self.rot, dot(self.tensor_3D, transpose(self.rot))) 455 456 # Rotate the tensor (inverse RT.X.R rotation). 457 else: 458 tensor_3D = dot(transpose(self.rot), dot(self.tensor_3D, self.rot)) 459 460 # Convert the tensor back to 5D, rank-1 form, as the back-calculated reduced tensor. 461 to_5D(self.red_tensors_bc[index1:index2], tensor_3D)
462