Author: bugman Date: Wed Nov 19 16:40:12 2014 New Revision: 26625 URL: http://svn.gna.org/viewcvs/relax?rev=26625&view=rev Log: Added the 'irreducible 5D' basis set option to the align_tensor.matrix_angles user function. This is for the inter-tensor vector angle for the irreducible 5D basis set {S-2, S-1, S0, S1, S2}. Its results match that of the standard tensor angle as well as the 'unitary 9D' basis sets. Modified: trunk/pipe_control/align_tensor.py trunk/user_functions/align_tensor.py Modified: trunk/pipe_control/align_tensor.py URL: http://svn.gna.org/viewcvs/relax/trunk/pipe_control/align_tensor.py?rev=26625&r1=26624&r2=26625&view=diff ============================================================================== --- trunk/pipe_control/align_tensor.py (original) +++ trunk/pipe_control/align_tensor.py Wed Nov 19 16:40:12 2014 @@ -25,7 +25,7 @@ # Python module imports. from copy import deepcopy from math import acos, pi, sqrt -from numpy import arccos, dot, float64, inner, linalg, zeros +from numpy import arccos, complex128, dot, float64, inner, linalg, zeros from numpy.linalg import norm import sys from warnings import warn @@ -35,6 +35,7 @@ from lib.alignment.alignment_tensor import calc_chi_tensor, kappa from lib.errors import RelaxError, RelaxNoTensorError, RelaxTensorError, RelaxUnknownParamCombError, RelaxUnknownParamError from lib.geometry.angles import wrap_angles +from lib.geometry.vectors import vector_angle_complex_conjugate from lib.io import write_data from lib.text.sectioning import section, subsection from lib.warnings import RelaxWarning @@ -888,18 +889,19 @@ The basis set defines how the angles are calculated: - "matrix", the standard inter-matrix angle. The angle is calculated via the Euclidean inner product of the alignment matrices in rank-2, 3D form divided by the Frobenius norm ||A||_F of the matrices. + - "irreducible 5D", the irreducible 5D basis set {S-2, S-1, S0, S1, S2}. - "unitary 5D", the unitary 5D basis set {Sxx, Syy, Sxy, Sxz, Syz}. - "geometric 5D", the geometric 5D basis set {Szz, Sxxyy, Sxy, Sxz, Syz}. This is also the Pales standard notation. - @param basis_set: The basis set to use for calculating the inter-matrix angles. It can be one of "matrix", "unitary 5D", or "geometric 5D". + @param basis_set: The basis set to use for calculating the inter-matrix angles. It can be one of "matrix", "irreducible 5D", "unitary 5D", or "geometric 5D". @type basis_set: str @param tensors: The list of alignment tensor IDs to calculate inter-matrix angles between. If None, all tensors will be used. @type tensors: None or list of str """ # Argument check. - allowed = ['matrix', 'unitary 9D', 'unitary 5D', 'geometric 5D'] + allowed = ['matrix', 'unitary 9D', 'irreducible 5D', 'unitary 5D', 'geometric 5D'] if basis_set not in allowed: raise RelaxError("The basis set of '%s' is not one of %s." % (basis_set, allowed)) @@ -921,6 +923,9 @@ matrix = zeros((tensor_num, 9), float64) elif basis_set in ['unitary 5D', 'geometric 5D']: matrix = zeros((tensor_num, 5), float64) + elif basis_set in ['irreducible 5D']: + matrix = zeros((tensor_num, 5), complex128) + matrix_conj = zeros((tensor_num, 5), complex128) # Loop over the tensors. i = 0 @@ -953,6 +958,21 @@ matrix[i, 3] = tensor.Sxz matrix[i, 4] = tensor.Syz + # 5D irreducible basis set. + if basis_set == 'irreducible 5D': + matrix[i, 0] = tensor.Am2 + matrix[i, 1] = tensor.Am1 + matrix[i, 2] = tensor.A0 + matrix[i, 3] = tensor.A1 + matrix[i, 4] = tensor.A2 + + # The (-1)^mS-m conjugate. + matrix_conj[i, 0] = tensor.A2 + matrix_conj[i, 1] = -tensor.A1 + matrix_conj[i, 2] = tensor.A0 + matrix_conj[i, 3] = -tensor.Am1 + matrix_conj[i, 4] = tensor.Am2 + # 5D geometric basis set. elif basis_set == 'geometric 5D': matrix[i, 0] = tensor.Szz @@ -976,6 +996,8 @@ sys.stdout.write("Standard inter-tensor matrix angles in degress using the Euclidean inner product divided by the Frobenius norms (theta = arccos(<A1,A2>/(||A1||.||A2||)))") elif basis_set == 'unitary 9D': sys.stdout.write("Inter-tensor vector angles in degrees for the unitary 9D vectors {Sxx, Sxy, Sxz, Syx, Syy, Syz, Szx, Szy, Szz}") + elif basis_set == 'irreducible 5D': + sys.stdout.write("Inter-tensor vector angles in degrees for the irreducible 5D vectors {S-2, S-1, S0, S1, S2}") elif basis_set == 'unitary 5D': sys.stdout.write("Inter-tensor vector angles in degrees for the unitary 5D vectors {Sxx, Syy, Sxy, Sxz, Syz}") elif basis_set == 'geometric 5D': @@ -1014,6 +1036,10 @@ # The angle. theta = arccos(delta) + + # The irreducible complex conjugate angles. + if basis_set in ['irreducible 5D']: + theta = vector_angle_complex_conjugate(v1=matrix[i], v2=matrix[j], v1_conj=matrix_conj[i], v2_conj=matrix_conj[j]) # The full matrix angle. elif basis_set in ['matrix']: Modified: trunk/user_functions/align_tensor.py URL: http://svn.gna.org/viewcvs/relax/trunk/user_functions/align_tensor.py?rev=26625&r1=26624&r2=26625&view=diff ============================================================================== --- trunk/user_functions/align_tensor.py (original) +++ trunk/user_functions/align_tensor.py Wed Nov 19 16:40:12 2014 @@ -307,8 +307,8 @@ desc_short = "basis set", desc = "The basis set to operate with.", wiz_element_type = "combo", - wiz_combo_choices = ["Standard matrix angles via the Euclidean inner product", "Unitary 9D {Sxx, Sxy, Sxz, ..., Szz}", "Unitary 5D {Sxx, Syy, Sxy, Sxz, Syz}", "Geometric 5D {Szz, Sxxyy, Sxy, Sxz, Syz}"], - wiz_combo_data = ["matrix", "unitary 9D", "unitary 5D", "geometric 5D"] + wiz_combo_choices = ["Standard matrix angles via the Euclidean inner product", "Irreducible 5D {S-2, S-1, S0, S1, S2}", "Unitary 9D {Sxx, Sxy, Sxz, ..., Szz}", "Unitary 5D {Sxx, Syy, Sxy, Sxz, Syz}", "Geometric 5D {Szz, Sxxyy, Sxy, Sxz, Syz}"], + wiz_combo_data = ["matrix", "irreducible 5D", "unitary 9D", "unitary 5D", "geometric 5D"] ) uf.add_keyarg( name = "tensors", @@ -324,16 +324,43 @@ uf.desc.append(Desc_container()) uf.desc[-1].add_paragraph("This will calculate the inter-matrix angles between all loaded alignment tensors for the current data pipe. For the 5D basis sets, the matrices are first converted to a 5D vector form and then then the inter-vector angles, rather than inter-matrix angles, are calculated. The angles are dependent upon the basis set:") uf.desc[-1].add_item_list_element("'matrix'", "The standard inter-tensor matrix angle. This is the default option. The angle is calculated via the Euclidean inner product of the alignment matrices in rank-2, 3D form divided by the Frobenius norm ||A||_F of the matrices.") +uf.desc[-1].add_item_list_element("'irreducible 5D'", "The inter-tensor vector angle for the irreducible 5D basis set {S-2, S-1, S0, S1, S2}.") uf.desc[-1].add_item_list_element("'unitary 9D'", "The inter-tensor vector angle for the unitary 9D basis set {Sxx, Sxy, Sxz, Syx, Syy, Syz, Szx, Szy, Szz}.") uf.desc[-1].add_item_list_element("'unitary 5D'", "The inter-tensor vector angle for the unitary 5D basis set {Sxx, Syy, Sxy, Sxz, Syz}.") uf.desc[-1].add_item_list_element("'geometric 5D'", "The inter-tensor vector angle for the geometric 5D basis set {Szz, Sxxyy, Sxy, Sxz, Syz}. This is also the Pales standard notation.") -uf.desc[-1].add_paragraph("The full matrix angle via the Euclidean inner product is defined as:") -uf.desc[-1].add_verbatim(""" +uf.desc[-1].add_paragraph("The full matrix angle via the Euclidean inner product is defined as") +uf.desc[-1].add_verbatim("""\ / <A1 , A2> \ theta = arccos | ------------- | , - \ ||A1|| ||A2|| / -""") -uf.desc[-1].add_paragraph("where <a,b> is the Euclidean inner product and ||a|| is the Frobenius norm of the matrix.") + \ ||A1|| ||A2|| / \ +""") +uf.desc[-1].add_paragraph("where <a,b> is the Euclidean inner product and ||a|| is the Frobenius norm of the matrix. For the irreducible basis set, the Sm components are defined as") +uf.desc[-1].add_verbatim("""\ + / 4pi \ 1/2 + S0 = | --- | Szz , + \ 5 / + + / 8pi \ 1/2 + S+/-1 = +/- | --- | (Sxz +/- iSyz) , + \ 15 / + + / 2pi \ 1/2 + S+/-2 = | --- | (Sxx - Syy +/- 2iSxy) , + \ 15 / \ +""") +uf.desc[-1].add_paragraph("and, for this complex notation, the angle is") +uf.desc[-1].add_verbatim("""\ + theta = arccos(Re(<A1|A2>) / (|A1|.|A2|)) , \ +""") +uf.desc[-1].add_paragraph("where the inner product is defined as") +uf.desc[-1].add_verbatim("""\ + ___ + \ 1 2* + <A1|A2> = > Sm . Sm , + /__ + m=-2,2 \ +""") +uf.desc[-1].add_paragraph("and where Sm* = (-1)^m S-m, and the norm is defined as |A1| = Re(sqrt(<A1|A1>)).") uf.desc[-1].add_paragraph("The inner product solution is a linear map and thereby preserves angles, whereas the {Sxx, Syy, Sxy, Sxz, Syz} and {Szz, Sxxyy, Sxy, Sxz, Syz} basis sets are non-linear maps which do not preserve angles. Therefore the angles from all three basis sets will be different.") uf.backend = align_tensor.matrix_angles uf.menu_text = "&matrix_angles"