def test_kron_prod(self): """Test the Kronecker product function kron_prod().""" # The 3D, rank-2 matrices. R1 = array([[1, 4, 5], [-4, 2, 6], [-5, -6, 3]], float64) R2 = array([[0, 1, 0], [0, 0, 0], [0, 0, 0]], float64) # The Kronecker product. C = kron_prod(R1, R2) # The real Kronecker product! D = array([[0, 1, 0, 0, 4, 0, 0, 5, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, -4, 0, 0, 2, 0, 0, 6, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, -5, 0, 0, -6, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]], float64) # Print outs. print("R1:\n%s" % R1) print("R2:\n%s" % R2) print("C:\n%s" % C) print("D:\n%s" % D) # Checks. self.assertEqual(C.shape, (9, 9)) for i in range(9): for j in range(9): self.assertEqual(C[i, j], D[i, j])
def test_kron_prod(self): """Test the Kronecker product function kron_prod().""" # The 3D, rank-2 matrices. R1 = array([[1, 4, 5], [-4, 2, 6], [-5, -6, 3]], float64) R2 = array([[0, 1, 0], [0, 0, 0], [0, 0, 0]], float64) # The Kronecker product. C = kron_prod(R1, R2) # The real Kronecker product! D = array([ [ 0, 1, 0, 0, 4, 0, 0, 5, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, -4, 0, 0, 2, 0, 0, 6, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, -5, 0, 0, -6, 0, 0, 3, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0]], float64) # Print outs. print("R1:\n%s" % R1) print("R2:\n%s" % R2) print("C:\n%s" % C) print("D:\n%s" % D) # Checks. self.assertEqual(C.shape, (9, 9)) for i in range(9): for j in range(9): self.assertEqual(C[i, j], D[i, j])
def calc_Rx2_eigen_full(self, eigen_alpha, eigen_beta, eigen_gamma): """Calculate the Kronecker product of the eigenframe rotation for the full eigenframe.""" # Average position rotation. euler_to_R_zyz(eigen_alpha, eigen_beta, eigen_gamma, self.R_temp) # The Kronecker product of the eigenframe rotation. return kron_prod(self.R_temp, self.R_temp)
def calc_Rx2_eigen_axis(self, axis_theta, axis_phi): """Calculate the Kronecker product of the eigenframe rotation for the z-axis based frame.""" # Generate the cone axis from the spherical angles. spherical_to_cartesian([1.0, axis_theta, axis_phi], self.cone_axis) # Pre-calculate the eigenframe rotation matrix. two_vect_to_R(self.z_axis, self.cone_axis, self.R_temp) # The Kronecker product of the eigenframe rotation. return kron_prod(self.R_temp, self.R_temp)
# Script for calculating the frame order matrix from the rotation matrices. # Python module imports. from numpy import float64, zeros # relax module imports. from lib.linear_algebra.kronecker_product import kron_prod from lib.frame_order.format import print_frame_order_2nd_degree # Load the matrices. exec(compile(open('rotation_matrices.py').read(), 'rotation_matrices.py', 'exec')) # Init the matrix. matrix = zeros((9, 9), float64) # Loop over the structures. for i in range(len(R)): matrix += kron_prod(R[i], R[i]) # Average. matrix = matrix / len(R) # Print out. print_frame_order_2nd_degree(matrix)
def __init__(self): """Calculate the frame order at infinity. This is when the starting positions are random. """ # Loop over the models. for model_index in range(len(MODELS)): # Aliases. model = MODELS[model_index] model_text = MODEL_TEXT[model_index] # Loop over the tags. for tag in TAGS: # Set up the variables to loop over. if model in ['rotor', 'free_rotor']: vars = ['Z'] elif model in ['iso_cone_free_rotor', 'iso_cone_torsionless']: vars = ['X'] elif model in ['iso_cone']: vars = ['X', 'Z'] elif model in ['double_rotor', 'pseudo-ellipse_free_rotor', 'pseudo-ellipse_torsionless']: vars = ['X', 'Y'] elif model in ['pseudo-ellipse']: vars = ['X', 'Y', 'Z'] else: raise RelaxError("Unknown model '%s'." % model) # Loop over the variables. for var in vars: # The file name. file_name = '_%s_%s_theta_%s_calc.agr' % (model, tag, lower(var)) print("Creating the '*%s' files." % file_name) # Set up the eigenframe. self.setup_eigenframe(tag=tag) # The Kronecker product of the eigenframe rotation. Rx2_eigen = kron_prod(self.eigenframe, self.eigenframe) # Set the initial storage structures. self.init_storage() # Loop over the angle incs. for i in range(INC+1): # Get the angle for the increment. theta = self.get_angle(i-1, model=model, var=var) # Vary X. if var == 'X': theta_x = theta theta_y = THETA_Y theta_z = THETA_Z # Vary Y. elif var == 'Y': theta_x = THETA_X theta_y = theta theta_z = THETA_Z # Vary Z. elif var == 'Z': theta_x = THETA_X theta_y = THETA_Y theta_z = theta # Calculate the frame order matrices. if model == 'rotor': self.first_frame_order[i] = rotor.compile_1st_matrix_rotor(self.first_frame_order[i], self.eigenframe, theta_z) self.second_frame_order[i] = rotor.compile_2nd_matrix_rotor(self.second_frame_order[i], Rx2_eigen, theta_z) elif model == 'free_rotor': self.first_frame_order[i] = free_rotor.compile_1st_matrix_free_rotor(self.first_frame_order[i], self.eigenframe) self.second_frame_order[i] = free_rotor.compile_2nd_matrix_free_rotor(self.second_frame_order[i], Rx2_eigen) elif model == 'iso_cone': self.first_frame_order[i] = iso_cone.compile_1st_matrix_iso_cone(self.first_frame_order[i], self.eigenframe, theta_x, theta_z) self.second_frame_order[i] = iso_cone.compile_2nd_matrix_iso_cone(self.second_frame_order[i], Rx2_eigen, theta_x, theta_z) elif model == 'iso_cone_free_rotor': self.first_frame_order[i] = iso_cone_free_rotor.compile_1st_matrix_iso_cone_free_rotor(self.first_frame_order[i], self.eigenframe, theta_x) self.second_frame_order[i] = iso_cone_free_rotor.compile_2nd_matrix_iso_cone_free_rotor(self.second_frame_order[i], Rx2_eigen, theta_x) elif model == 'iso_cone_torsionless': self.first_frame_order[i] = iso_cone_torsionless.compile_1st_matrix_iso_cone_torsionless(self.first_frame_order[i], self.eigenframe, theta_x) self.second_frame_order[i] = iso_cone_torsionless.compile_2nd_matrix_iso_cone_torsionless(self.second_frame_order[i], Rx2_eigen, theta_x) elif model == 'pseudo-ellipse': self.first_frame_order[i] = pseudo_ellipse.compile_1st_matrix_pseudo_ellipse(self.first_frame_order[i], self.eigenframe, theta_x, theta_y, theta_z) self.second_frame_order[i] = pseudo_ellipse.compile_2nd_matrix_pseudo_ellipse(self.second_frame_order[i], Rx2_eigen, theta_x, theta_y, theta_z) elif model == 'pseudo-ellipse_free_rotor': self.first_frame_order[i] = pseudo_ellipse_free_rotor.compile_1st_matrix_pseudo_ellipse_free_rotor(self.first_frame_order[i], self.eigenframe, theta_x, theta_y) self.second_frame_order[i] = pseudo_ellipse_free_rotor.compile_2nd_matrix_pseudo_ellipse_free_rotor(self.second_frame_order[i], Rx2_eigen, theta_x, theta_y) elif model == 'pseudo-ellipse_torsionless': self.first_frame_order[i] = pseudo_ellipse_torsionless.compile_1st_matrix_pseudo_ellipse_torsionless(self.first_frame_order[i], self.eigenframe, theta_x, theta_y) self.second_frame_order[i] = pseudo_ellipse_torsionless.compile_2nd_matrix_pseudo_ellipse_torsionless(self.second_frame_order[i], Rx2_eigen, theta_x, theta_y) elif model == 'double_rotor': self.first_frame_order[i] = double_rotor.compile_1st_matrix_double_rotor(self.first_frame_order[i], self.eigenframe, theta_y, theta_x) self.second_frame_order[i] = double_rotor.compile_2nd_matrix_double_rotor(self.second_frame_order[i], Rx2_eigen, theta_y, theta_x) else: raise RelaxError("Unknown model '%s'." % model) # Write the data. self.write_data(file_name=file_name, model=model, model_text=model_text, var=var)
def __init__(self): """Calculate the frame order at infinity. This is when the starting positions are random. """ # The file name. file_name = '_%s_%s_theta_%s_ens%s.agr' % (MODEL, TAG, lower(VAR), SAMPLE_SIZE) # Set the initial storage structures. self.init_storage() # Init. index = 0 self.torsion_check = True # Pre-transpose the eigenframe for speed. self.eig_frame_T = transpose(EIG_FRAME) # Generate the angle data structures. self.angles = [] self.angles_deg = [] for i in range(INC): # The angle of one increment. inc_angle = pi / INC # The angle of the increment. self.angles.append(inc_angle * (i+1)) # In degrees for the graphs. self.angles_deg.append(self.angles[-1] / (2.0*pi) * 360.0) # Alias the bound checking methods. if MODEL == 'rotor': self.inside = self.inside_rotor self.rotation = self.rotation_z_axis elif MODEL == 'free_rotor': self.inside = self.inside_free_rotor self.rotation = self.rotation_z_axis elif MODEL == 'iso_cone': self.inside = self.inside_iso_cone self.rotation = self.rotation_hypersphere elif MODEL == 'iso_cone_torsionless': self.inside = self.inside_iso_cone self.rotation = self.rotation_hypersphere_torsionless elif MODEL == 'iso_cone_free_rotor': self.inside = self.inside_iso_cone self.rotation = self.rotation_hypersphere self.torsion_check = False elif MODEL == 'pseudo-ellipse': self.inside = self.inside_pseudo_ellipse self.rotation = self.rotation_hypersphere elif MODEL == 'pseudo-ellipse_torsionless': self.inside = self.inside_pseudo_ellipse self.rotation = self.rotation_hypersphere_torsionless elif MODEL == 'pseudo-ellipse_free_rotor': self.inside = self.inside_pseudo_ellipse self.rotation = self.rotation_hypersphere self.torsion_check = False elif MODEL == 'double_rotor': self.inside = self.inside_double_rotor self.rotation = self.rotation_double_xy_axes else: raise RelaxError("Unknown model '%s'." % MODEL) # Loop over random starting positions. while True: # Printout. progress_meter(index, a=1000, b=100000) # Generate the random rotation. theta, phi, sigma = self.rotation() # Pre-calculate the R Kronecker outer product for speed. Rx2 = kron_prod(self.rot, self.rot) # Loop over the angle incs. for i in range(INC): # The new limits. max_theta_x, max_theta_y, max_theta_z = self.limits(i) # Inside the cone. if not self.full[i] and self.inside(i=i, theta=theta, phi=phi, sigma=sigma, max_theta_x=max_theta_x, max_theta_y=max_theta_y, max_theta_z=max_theta_z): # Sum of rotations and cross products. self.first_frame_order[i] += self.rot self.second_frame_order[i] += Rx2 # Increment the counter. self.count[i] += 1 # Full. if self.count[i] == SAMPLE_SIZE: sys.stdout.write("\b"*100 + "The angle restriction of %s deg is complete.\n" % self.angles_deg[i]) self.full[i] = 1 # Increment the global index. index += 1 # Break out. if sum(self.full) == INC: break # Average. self.first_frame_order = self.first_frame_order / float(SAMPLE_SIZE) self.second_frame_order = self.second_frame_order / float(SAMPLE_SIZE) # Write the data. self.write_data(file_name=file_name) # Final printout. sys.stdout.write("Random rotations required: %i\n\n" % index)
def _create_distribution(self): """Generate the distribution of structures.""" # Create a data pipe. self.interpreter.pipe.create('distribution', 'N-state') # Load the original PDB. self.interpreter.structure.read_pdb('1J7P_1st_NH.pdb', dir=self.path, set_mol_name='C-dom') # Set up the 15N and 1H spins. self.interpreter.structure.load_spins(spin_id='@N', ave_pos=False) self.interpreter.structure.load_spins(spin_id='@H', ave_pos=False) self.interpreter.spin.isotope(isotope='15N', spin_id='@N') self.interpreter.spin.isotope(isotope='1H', spin_id='@H') # Define the magnetic dipole-dipole relaxation interaction. self.interpreter.interatom.define(spin_id1='@N', spin_id2='@H', direct_bond=True) self.interpreter.interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.041 * 1e-10) self.interpreter.interatom.unit_vectors() # Back up the original positional data. self._backup_pos() # Init a rotation matrix and the frame order matrix. self.R = zeros((3, 3), float16) self.daeg = zeros((9, 9), float64) # Open the output files. rot_file = open_write_file('rotations', dir=self.save_path, compress_type=1, force=True) # Printout. sys.stdout.write("\n\nRotating %s states:\n\n" % self.N) # Load N copies of the original C-domain. for i in range(self.N): # Print out. self._progress(i) # Generate the distribution specific rotation. self.rotation(i) # Rotate the atomic position. for spin in spin_loop(): if hasattr(spin, 'pos'): spin.pos[i] = dot(self.R, (spin.orig_pos[0] - self.pivot)) + self.pivot # Rotate the NH vector. for interatom in interatomic_loop(): if hasattr(interatom, 'vector'): interatom.vector[i] = dot(self.R, interatom.orig_vect) # Decompose the rotation into Euler angles and store them. a, b, g = R_to_euler_zyz(self.R) rot_file.write('%10.7f %10.7f %10.7f\n' % (a, b, g)) # The frame order matrix component. self.daeg += kron_prod(self.R, self.R) # Print out. sys.stdout.write('\n\n') # Frame order matrix averaging. self.daeg = self.daeg / self.N # Write out the frame order matrix. file = open(self.save_path+sep+'frame_order_matrix', 'w') print_frame_order_2nd_degree(self.daeg, file=file)
from lib.linear_algebra.kronecker_product import kron_prod # Store the rotation matrices. R = [] exec( compile( open('rotation_matrices.py').read(), 'rotation_matrices.py', 'exec')) R = array(R) # Init the frame order matrix. daeg = zeros((9, 9), float64) # Loop over the structures, and build the frame order matrix. for i in range(len(R)): # Kronecker product. kron = kron_prod(R[i], R[i]) # Sum daeg += kron # Average. daeg = daeg / len(R) # The relax calculated matrix. fo_calc = array([[ 0.3410, -0.0370, 0.0333, -0.0370, 0.3252, 0.0411, 0.0333, 0.0411, 0.3338 ], [ -0.0322, 0.3148, 0.0367, -0.0035, 0.0343, -0.3163, -0.3170, -0.0302, -0.0021 ],
from lib.frame_order.format import print_frame_order_2nd_degree from lib.linear_algebra.kronecker_product import kron_prod # Store the rotation matrices. R = [] exec(compile(open('rotation_matrices.py').read(), 'rotation_matrices.py', 'exec')) R = array(R) # Init the frame order matrix. daeg = zeros((9, 9), float64) # Loop over the structures, and build the frame order matrix. for i in range(len(R)): # Kronecker product. kron = kron_prod(R[i], R[i]) # Sum daeg += kron # Average. daeg = daeg / len(R) # The relax calculated matrix. fo_calc = array( [[ 0.3410, -0.0370, 0.0333, -0.0370, 0.3252, 0.0411, 0.0333, 0.0411, 0.3338], [ -0.0322, 0.3148, 0.0367, -0.0035, 0.0343, -0.3163, -0.3170, -0.0302, -0.0021], [ 0.0264, 0.0490, 0.3115, -0.3046, -0.0282, -0.0166, -0.0813, 0.3011, 0.0017], [ -0.0322, -0.0035, -0.3170, 0.3148, 0.0343, -0.0302, 0.0367, -0.3163, -0.0021], [ 0.3272, 0.0296, -0.0266, 0.0296, 0.3399, -0.0329, -0.0266, -0.0329, 0.3329], [ 0.0327, -0.3010, -0.0166, -0.0150, -0.0349, 0.3044, 0.3011, 0.0474, 0.0022],
def __init__(self): """Calculate the frame order at infinity. This is when the starting positions are random. """ # Loop over the models. for model_index in range(len(MODELS)): # Aliases. model = MODELS[model_index] model_text = MODEL_TEXT[model_index] # Loop over the tags. for tag in TAGS: # Set up the variables to loop over. if model in ['rotor', 'free_rotor']: vars = ['Z'] elif model in ['iso_cone_free_rotor', 'iso_cone_torsionless']: vars = ['X'] elif model in ['iso_cone']: vars = ['X', 'Z'] elif model in [ 'double_rotor', 'pseudo-ellipse_free_rotor', 'pseudo-ellipse_torsionless' ]: vars = ['X', 'Y'] elif model in ['pseudo-ellipse']: vars = ['X', 'Y', 'Z'] else: raise RelaxError("Unknown model '%s'." % model) # Loop over the variables. for var in vars: # The file name. file_name = '_%s_%s_theta_%s_calc.agr' % (model, tag, lower(var)) print("Creating the '*%s' files." % file_name) # Set up the eigenframe. self.setup_eigenframe(tag=tag) # The Kronecker product of the eigenframe rotation. Rx2_eigen = kron_prod(self.eigenframe, self.eigenframe) # Set the initial storage structures. self.init_storage() # Loop over the angle incs. for i in range(INC + 1): # Get the angle for the increment. theta = self.get_angle(i - 1, model=model, var=var) # Vary X. if var == 'X': theta_x = theta theta_y = THETA_Y theta_z = THETA_Z # Vary Y. elif var == 'Y': theta_x = THETA_X theta_y = theta theta_z = THETA_Z # Vary Z. elif var == 'Z': theta_x = THETA_X theta_y = THETA_Y theta_z = theta # Calculate the frame order matrices. if model == 'rotor': self.first_frame_order[ i] = rotor.compile_1st_matrix_rotor( self.first_frame_order[i], self.eigenframe, theta_z) self.second_frame_order[ i] = rotor.compile_2nd_matrix_rotor( self.second_frame_order[i], Rx2_eigen, theta_z) elif model == 'free_rotor': self.first_frame_order[ i] = free_rotor.compile_1st_matrix_free_rotor( self.first_frame_order[i], self.eigenframe) self.second_frame_order[ i] = free_rotor.compile_2nd_matrix_free_rotor( self.second_frame_order[i], Rx2_eigen) elif model == 'iso_cone': self.first_frame_order[ i] = iso_cone.compile_1st_matrix_iso_cone( self.first_frame_order[i], self.eigenframe, theta_x, theta_z) self.second_frame_order[ i] = iso_cone.compile_2nd_matrix_iso_cone( self.second_frame_order[i], Rx2_eigen, theta_x, theta_z) elif model == 'iso_cone_free_rotor': self.first_frame_order[ i] = iso_cone_free_rotor.compile_1st_matrix_iso_cone_free_rotor( self.first_frame_order[i], self.eigenframe, theta_x) self.second_frame_order[ i] = iso_cone_free_rotor.compile_2nd_matrix_iso_cone_free_rotor( self.second_frame_order[i], Rx2_eigen, theta_x) elif model == 'iso_cone_torsionless': self.first_frame_order[ i] = iso_cone_torsionless.compile_1st_matrix_iso_cone_torsionless( self.first_frame_order[i], self.eigenframe, theta_x) self.second_frame_order[ i] = iso_cone_torsionless.compile_2nd_matrix_iso_cone_torsionless( self.second_frame_order[i], Rx2_eigen, theta_x) elif model == 'pseudo-ellipse': self.first_frame_order[ i] = pseudo_ellipse.compile_1st_matrix_pseudo_ellipse( self.first_frame_order[i], self.eigenframe, theta_x, theta_y, theta_z) self.second_frame_order[ i] = pseudo_ellipse.compile_2nd_matrix_pseudo_ellipse( self.second_frame_order[i], Rx2_eigen, theta_x, theta_y, theta_z) elif model == 'pseudo-ellipse_free_rotor': self.first_frame_order[ i] = pseudo_ellipse_free_rotor.compile_1st_matrix_pseudo_ellipse_free_rotor( self.first_frame_order[i], self.eigenframe, theta_x, theta_y) self.second_frame_order[ i] = pseudo_ellipse_free_rotor.compile_2nd_matrix_pseudo_ellipse_free_rotor( self.second_frame_order[i], Rx2_eigen, theta_x, theta_y) elif model == 'pseudo-ellipse_torsionless': self.first_frame_order[ i] = pseudo_ellipse_torsionless.compile_1st_matrix_pseudo_ellipse_torsionless( self.first_frame_order[i], self.eigenframe, theta_x, theta_y) self.second_frame_order[ i] = pseudo_ellipse_torsionless.compile_2nd_matrix_pseudo_ellipse_torsionless( self.second_frame_order[i], Rx2_eigen, theta_x, theta_y) elif model == 'double_rotor': self.first_frame_order[ i] = double_rotor.compile_1st_matrix_double_rotor( self.first_frame_order[i], self.eigenframe, theta_y, theta_x) self.second_frame_order[ i] = double_rotor.compile_2nd_matrix_double_rotor( self.second_frame_order[i], Rx2_eigen, theta_y, theta_x) else: raise RelaxError("Unknown model '%s'." % model) # Write the data. self.write_data(file_name=file_name, model=model, model_text=model_text, var=var)
# # ############################################################################### # Module docstring. """Script for calculating the frame order matrix from the rotation matrices.""" # Python module imports. from numpy import float64, zeros # relax module imports. from lib.linear_algebra.kronecker_product import kron_prod from lib.frame_order.format import print_frame_order_2nd_degree # Load the matrices. exec( compile( open('rotation_matrices.py').read(), 'rotation_matrices.py', 'exec')) # Init the matrix. matrix = zeros((9, 9), float64) # Loop over the structures. for i in range(len(R)): matrix += kron_prod(R[i], R[i]) # Average. matrix = matrix / len(R) # Print out. print_frame_order_2nd_degree(matrix)
def _calculate_rdc(self): """Calculate the averaged RDC for all states.""" # Open the output files. if self.ROT_FILE: rot_file = open_write_file('rotations', dir=self.save_path, compress_type=1, force=True) # Printout. sys.stdout.write("\n\nRotating %s states for the RDC:\n\n" % locale.format("%d", self.N**self.MODES, grouping=True)) # Turn off the relax interpreter echoing to allow the progress meter to be shown correctly. self.interpreter.off() # Set up some data structures for faster calculations. interatoms = [] vectors = [] d = [] for interatom in interatomic_loop(): # Nothing to do. if not hasattr(interatom, 'vector'): continue # Initialise the RDC structure (as a 1D numpy.float128 array for speed and minimising truncation artifacts). interatom.rdc = {} for tag in self._tensors: interatom.rdc[tag] = zeros(1, float128) # Pack the interatomic containers and vectors. interatoms.append(interatom) vectors.append(interatom.vector) # Get the spins. spin1 = return_spin(spin_id=interatom.spin_id1) spin2 = return_spin(spin_id=interatom.spin_id2) # Gyromagnetic ratios. g1 = periodic_table.gyromagnetic_ratio(spin1.isotope) g2 = periodic_table.gyromagnetic_ratio(spin2.isotope) # Calculate the RDC dipolar constant (in Hertz, and the 3 comes from the alignment tensor), and append it to the list. d.append(3.0/(2.0*pi) * dipolar_constant(g1, g2, interatom.r)) # Repackage the data for speed. vectors = transpose(array(vectors, float64)) d = array(d, float64) num_interatoms = len(vectors) # Store the alignment tensors. A = [] for i in range(len(self._tensors)): A.append(cdp.align_tensors[i].A) # Loop over each position. for global_index, mode_indices in self._state_loop(): # The progress meter. self._progress(global_index) # Total rotation matrix (for construction of the frame order matrix). total_R = eye(3) # Data initialisation. new_vect = vectors # Loop over each motional mode. for motion_index in range(self.MODES): # Generate the distribution specific rotation. self.rotation(mode_indices[motion_index], motion_index=motion_index) # Rotate the NH vector. new_vect = dot(self.R, new_vect) # Decompose the rotation into Euler angles and store them. if self.ROT_FILE: a, b, g = R_to_euler_zyz(self.R) rot_file.write('Mode %i: %10.7f %10.7f %10.7f\n' % (motion_index, a, b, g)) # Contribution to the total rotation. total_R = dot(self.R, total_R) # Loop over each alignment. for i in range(len(self._tensors)): # Calculate the RDC as quickly as possible. rdcs = d * tensordot(transpose(new_vect), tensordot(A[i], new_vect, axes=1), axes=1) # Store the values. for j in range(len(interatoms)): interatoms[j].rdc[self._tensors[i]][0] += rdcs[j, j] # The frame order matrix component. self.daeg += kron_prod(total_R, total_R) # Print out. sys.stdout.write('\n\n') # Frame order matrix averaging. self.daeg = self.daeg / self.N**self.MODES # Write out the frame order matrix. file = open(self.save_path+sep+'frame_order_matrix', 'w') print_frame_order_2nd_degree(self.daeg, file=file, places=8) # Reactive the interpreter echoing. self.interpreter.on() # Average the RDC and write the data. for tag in self._tensors: # Average. for interatom in interatomic_loop(): interatom.rdc[tag] = interatom.rdc[tag][0] / self.N**self.MODES # Save. self.interpreter.rdc.write(align_id=tag, file='rdc_%s.txt'%tag, dir=self.save_path, force=True)
def _calculate_rdc(self): """Calculate the averaged RDC for all states.""" # Open the output files. if self.ROT_FILE: rot_file = open_write_file('rotations', dir=self.save_path, compress_type=1, force=True) # Printout. sys.stdout.write("\n\nRotating %s states for the RDC:\n\n" % locale.format("%d", self.N**self.MODES, grouping=True)) # Turn off the relax interpreter echoing to allow the progress meter to be shown correctly. self.interpreter.off() # Set up some data structures for faster calculations. interatoms = [] vectors = [] d = [] for interatom in interatomic_loop(): # Nothing to do. if not hasattr(interatom, 'vector'): continue # Initialise the RDC structure (as a 1D numpy.float128 array for speed and minimising truncation artifacts). interatom.rdc = {} for tag in self._tensors: interatom.rdc[tag] = zeros(1, float128) # Pack the interatomic containers and vectors. interatoms.append(interatom) vectors.append(interatom.vector) # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # Gyromagnetic ratios. g1 = periodic_table.gyromagnetic_ratio(spin1.isotope) g2 = periodic_table.gyromagnetic_ratio(spin2.isotope) # Calculate the RDC dipolar constant (in Hertz, and the 3 comes from the alignment tensor), and append it to the list. d.append(3.0/(2.0*pi) * dipolar_constant(g1, g2, interatom.r)) # Repackage the data for speed. vectors = transpose(array(vectors, float64)) d = array(d, float64) num_interatoms = len(vectors) # Store the alignment tensors. A = [] for i in range(len(self._tensors)): A.append(cdp.align_tensors[i].A) # Loop over each position. for global_index, mode_indices in self._state_loop(): # The progress meter. self._progress(global_index) # Total rotation matrix (for construction of the frame order matrix). total_R = eye(3) # Data initialisation. new_vect = vectors # Loop over each motional mode. for motion_index in range(self.MODES): # Generate the distribution specific rotation. self.rotation(mode_indices[motion_index], motion_index=motion_index) # Rotate the NH vector. new_vect = dot(self.R, new_vect) # Decompose the rotation into Euler angles and store them. if self.ROT_FILE: a, b, g = R_to_euler_zyz(self.R) rot_file.write('Mode %i: %10.7f %10.7f %10.7f\n' % (motion_index, a, b, g)) # Contribution to the total rotation. total_R = dot(self.R, total_R) # Loop over each alignment. for i in range(len(self._tensors)): # Calculate the RDC as quickly as possible. rdcs = d * tensordot(transpose(new_vect), tensordot(A[i], new_vect, axes=1), axes=1) # Store the values. for j in range(len(interatoms)): interatoms[j].rdc[self._tensors[i]][0] += rdcs[j, j] # The frame order matrix component. self.daeg += kron_prod(total_R, total_R) # Print out. sys.stdout.write('\n\n') # Frame order matrix averaging. self.daeg = self.daeg / self.N**self.MODES # Write out the frame order matrix. file = open(self.save_path+sep+'frame_order_matrix', 'w') print_frame_order_2nd_degree(self.daeg, file=file, places=8) # Reactive the interpreter echoing. self.interpreter.on() # Average the RDC and write the data. for tag in self._tensors: # Average. for interatom in interatomic_loop(): interatom.rdc[tag] = interatom.rdc[tag][0] / self.N**self.MODES # Save. self.interpreter.rdc.write(align_id=tag, file='rdc_%s.txt'%tag, dir=self.save_path, force=True)