Author: bugman Date: Wed Jul 21 13:38:29 2010 New Revision: 11328 URL: http://svn.gna.org/viewcvs/relax?rev=11328&view=rev Log: Created the func_pseudo_ellipse() optimisation target fn. for the pseudo-elliptic cone model. The structure of the Frame_order class has been simplified for handling multiple frame order models. Modified: 1.3/maths_fns/frame_order.py Modified: 1.3/maths_fns/frame_order.py URL: http://svn.gna.org/viewcvs/relax/1.3/maths_fns/frame_order.py?rev=11328&r1=11327&r2=11328&view=diff ============================================================================== --- 1.3/maths_fns/frame_order.py (original) +++ 1.3/maths_fns/frame_order.py Wed Jul 21 13:38:29 2010 @@ -31,7 +31,7 @@ from generic_fns.frame_order import print_frame_order_2nd_degree from maths_fns.alignment_tensor import to_5D, to_tensor from maths_fns.chi2 import chi2 -from maths_fns.frame_order_matrix_ops import compile_2nd_matrix_iso_cone, reduce_alignment_tensor +from maths_fns.frame_order_matrix_ops import compile_2nd_matrix_iso_cone, compile_2nd_matrix_pseudo_ellipse, reduce_alignment_tensor from maths_fns.rotation_matrix import euler_to_R_zyz as euler_to_R from relax_errors import RelaxError @@ -65,65 +65,63 @@ # Store the initial parameter (as a copy). self.params = deepcopy(init_params) + # Store the agrs. + self.model = model + self.full_tensors = full_tensors + self.red_tensors = red_tensors + self.red_errors = red_errors + self.full_in_ref_frame = full_in_ref_frame + + # Mix up. + if full_tensors != None and frame_order_2nd != None: + raise RelaxError("Tensors and Frame Order matrices cannot be supplied together.") + if full_tensors == None and frame_order_2nd == None: + raise RelaxError("The arguments have been incorrectly supplied, cannot determine the optimisation mode.") + + # Tensor setup. + if full_tensors != None: + self.__init_tensors() + # The rigid model. if model == 'rigid': - # Tensor optimisation. - self.__init_tensors(full_tensors, red_tensors, red_errors, full_in_ref_frame) - # Alias the target function. self.func = self.func_rigid # Isotropic cone model. if model == 'iso cone': - # Mix up. - if full_tensors != None and frame_order_2nd != None: - raise RelaxError("Tensors and Frame Order matrices cannot be supplied together.") - - # Tensor setup. - if full_tensors != None: - self.__init_tensors(full_tensors, red_tensors, red_errors, full_in_ref_frame) - # Optimisation to the 2nd degree Frame Order matrix components directly. - elif frame_order_2nd != None: + if frame_order_2nd != None: self.__init_iso_cone_elements(frame_order_2nd) - - # Badly supplied arguments. - else: - raise RelaxError("The arguments have been incorrectly supplied, cannot determine the optimisation mode.") # The cone axis storage and molecular frame z-axis. self.cone_axis = zeros(3, float64) self.z_axis = array([0, 0, 1], float64) - - def __init_tensors(self, full_tensors, red_tensors, red_errors, full_in_ref_frame): - """Set up isotropic cone optimisation against the alignment tensor data. - - @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]. - @type full_tensors: numpy nx5D, rank-1 float64 array - @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. - @type red_tensors: numpy nx5D, rank-1 float64 array - @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. - @type red_errors: numpy nx5D, rank-1 float64 array - """ + # Alias the target function. + self.func = self.func_iso_cone + + # Pseudo-ellipse cone model. + elif model == 'pseudo-ellipse': + # Alias the target function. + self.func = self.func_pseudo_ellipse + + + def __init_tensors(self): + """Set up isotropic cone optimisation against the alignment tensor data.""" # Some checks. - if full_tensors == None or not len(full_tensors): - raise RelaxError("The full_tensors argument " + repr(full_tensors) + " must be supplied.") - if red_tensors == None or not len(red_tensors): - raise RelaxError("The red_tensors argument " + repr(red_tensors) + " must be supplied.") - if red_errors == None or not len(red_errors): - raise RelaxError("The red_errors argument " + repr(red_errors) + " must be supplied.") - if full_in_ref_frame == None or not len(full_in_ref_frame): - raise RelaxError("The full_in_ref_frame argument " + repr(full_in_ref_frame) + " must be supplied.") + if self.full_tensors == None or not len(self.full_tensors): + raise RelaxError("The full_tensors argument " + repr(self.full_tensors) + " must be supplied.") + if self.red_tensors == None or not len(self.red_tensors): + raise RelaxError("The red_tensors argument " + repr(self.red_tensors) + " must be supplied.") + if self.red_errors == None or not len(self.red_errors): + raise RelaxError("The red_errors argument " + repr(self.red_errors) + " must be supplied.") + if self.full_in_ref_frame == None or not len(self.full_in_ref_frame): + raise RelaxError("The full_in_ref_frame argument " + repr(self.full_in_ref_frame) + " must be supplied.") # Tensor set up. - self.num_tensors = len(full_tensors) / 5 - self.full_tensors = full_tensors - self.red_tensors = red_tensors - self.red_errors = red_errors + self.num_tensors = len(self.full_tensors) / 5 self.red_tensors_bc = zeros(self.num_tensors*5, float64) - self.full_in_ref_frame = full_in_ref_frame # The rotation to the Frame Order eigenframe. self.rot = zeros((3, 3), float64) @@ -131,9 +129,6 @@ # Initialise the Frame Order matrices. self.frame_order_2nd = zeros((9, 9), float64) - - # Alias the target function. - self.func = self.func_iso_cone def __init_iso_cone_elements(self, frame_order_2nd): @@ -288,3 +283,48 @@ # Return the chi2 value. return val + + + def func_pseudo_ellipse(self, params): + """Target function for pseudo-elliptic cone model optimisation using alignment tensors. + + @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. + @type params: list of float + @return: The chi-squared or SSE value. + @rtype: float + """ + + # Unpack the parameters. + alpha, beta, gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y, cone_sigma_max = params + + # Generate the 2nd degree Frame Order super matrix. + self.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) + + # Average position rotation. + euler_to_R(alpha, beta, gamma, self.rot) + + # Back calculate the reduced tensors. + for i in range(self.num_tensors): + # Tensor indices. + index1 = i*5 + index2 = i*5+5 + + # Reduce the tensor. + reduce_alignment_tensor(self.frame_order_2nd, self.full_tensors[index1:index2], self.red_tensors_bc[index1:index2]) + + # Convert the tensor to 3D, rank-2 form. + to_tensor(self.tensor_3D, self.red_tensors_bc[index1:index2]) + + # Rotate the tensor (normal R.X.RT rotation). + if self.full_in_ref_frame[i]: + self.tensor_3D = dot(self.rot, dot(self.tensor_3D, transpose(self.rot))) + + # Rotate the tensor (inverse RT.X.R rotation). + else: + self.tensor_3D = dot(transpose(self.rot), dot(self.tensor_3D, self.rot)) + + # Convert the tensor back to 5D, rank-1 form. + to_5D(self.red_tensors_bc[index1:index2], self.tensor_3D) + + # Return the chi-squared value. + return chi2(self.red_tensors, self.red_tensors_bc, self.red_errors)