def return_rdc_data(sim_index=None): """Set up the data structures for optimisation using RDCs as base data sets. @keyword sim_index: The index of the simulation to optimise. This should be None if normal optimisation is desired. @type sim_index: None or int @return: The assembled data structures for using RDCs as the base data for optimisation. These include: - rdc, the RDC values. - rdc_err, the RDC errors. - rdc_weight, the RDC weights. - vectors, the interatomic vectors (pseudo-atom dependent). - rdc_const, the dipolar constants (pseudo-atom dependent). - absolute, the absolute value flags (as 1's and 0's). - T_flags, the flags for T = J+D type data (as 1's and 0's). - j_couplings, the J coupling values if the RDC data type is set to T = J+D. - pseudo_flags, the list of flags indicating if the interatomic data contains a pseudo-atom (as 1's and 0's). @rtype: tuple of (numpy rank-2 float64 array, numpy rank-2 float64 array, numpy rank-2 float64 array, list of numpy rank-3 float64 arrays, list of lists of floats, numpy rank-2 int32 array, numpy rank-2 int32 array, numpy rank-2 float64 array, numpy rank-1 int32 array) """ # Sort out pseudo-atoms first. This only needs to be called once. setup_pseudoatom_rdc() # Initialise. rdc = [] rdc_err = [] rdc_weight = [] unit_vect = [] rdc_const = [] absolute = [] T_flags = [] j_couplings = [] pseudo_flags = [] # The unit vectors, RDC constants, and J couplings. for interatom in interatomic_loop(): # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # RDC checks. if not check_rdcs(interatom): continue # Gyromagnetic ratios. g1 = return_gyromagnetic_ratio(spin1.isotope) g2 = return_gyromagnetic_ratio(spin2.isotope) # Pseudo atoms. if is_pseudoatom(spin1) and is_pseudoatom(spin2): raise RelaxError("Support for both spins being in a dipole pair being pseudo-atoms is not implemented yet.") if is_pseudoatom(spin1) or is_pseudoatom(spin2): # Set the flag. pseudo_flags.append(1) # Alias the pseudo and normal atoms. if is_pseudoatom(spin1): pseudospin = spin1 base_spin = spin2 pseudospin_id = interatom.spin_id1 base_spin_id = interatom.spin_id2 else: pseudospin = spin2 base_spin = spin1 pseudospin_id = interatom.spin_id2 base_spin_id = interatom.spin_id1 # Loop over the atoms of the pseudo-atom, storing the data. pseudo_unit_vect = [] pseudo_rdc_const = [] for spin, spin_id in pseudoatom_loop(pseudospin, return_id=True): # Get the corresponding interatomic data container. pseudo_interatom = return_interatom(spin_id1=spin_id, spin_id2=base_spin_id) # Check. if pseudo_interatom == None: raise RelaxError("The interatomic data container between the spins '%s' and '%s' for the pseudo-atom '%s' is not defined." % (base_spin_id, spin_id, pseudospin_id)) # Add the vectors. if is_float(interatom.vector[0]): pseudo_unit_vect.append([pseudo_interatom.vector]) else: pseudo_unit_vect.append(pseudo_interatom.vector) # Calculate the RDC dipolar constant (in Hertz, and the 3 comes from the alignment tensor), and append it to the list. pseudo_rdc_const.append(3.0/(2.0*pi) * dipolar_constant(g1, g2, pseudo_interatom.r)) # Reorder the unit vectors so that the structure and pseudo-atom dimensions are swapped. pseudo_unit_vect = transpose(array(pseudo_unit_vect, float64), (1, 0, 2)) # Block append the pseudo-data. unit_vect.append(pseudo_unit_vect) rdc_const.append(pseudo_rdc_const) # Normal atom. else: # Set the flag. pseudo_flags.append(0) # Add the vectors. if is_float(interatom.vector[0]): unit_vect.append([interatom.vector]) else: unit_vect.append(interatom.vector) # Calculate the RDC dipolar constant (in Hertz, and the 3 comes from the alignment tensor), and append it to the list. rdc_const.append(3.0/(2.0*pi) * dipolar_constant(g1, g2, interatom.r)) # Store the measured J coupling. if opt_uses_j_couplings(): j_couplings.append(interatom.j_coupling) # Fix the unit vector data structure. num = None for rdc_index in range(len(unit_vect)): # Convert to numpy structures. unit_vect[rdc_index] = array(unit_vect[rdc_index], float64) # Number of vectors. if num == None: if unit_vect[rdc_index] != None: num = len(unit_vect[rdc_index]) continue # Check. if unit_vect[rdc_index] != None and len(unit_vect[rdc_index]) != num: raise RelaxError("The number of interatomic vectors for all no match:\n%s" % unit_vect[rdc_index]) # Missing unit vectors. if num == None: raise RelaxError("No interatomic vectors could be found.") # Update None entries. for i in range(len(unit_vect)): if unit_vect[i] == None: unit_vect[i] = [[None, None, None]]*num # The RDC data. for i in range(len(cdp.align_ids)): # Alias the ID. align_id = cdp.align_ids[i] # Skip non-optimised data. if not opt_uses_align_data(align_id): continue # Append empty arrays to the RDC structures. rdc.append([]) rdc_err.append([]) rdc_weight.append([]) absolute.append([]) T_flags.append([]) # Interatom loop. for interatom in interatomic_loop(): # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # RDC checks. if not check_rdcs(interatom): continue # T-type data. if align_id in interatom.rdc_data_types and interatom.rdc_data_types[align_id] == 'T': T_flags[-1].append(True) else: T_flags[-1].append(False) # Check for J couplings if the RDC data type is T = J+D. if T_flags[-1][-1] and not hasattr(interatom, 'j_coupling'): continue # Defaults of None. value = None error = None # Normal set up. if align_id in interatom.rdc.keys(): # The RDC. if sim_index != None: value = interatom.rdc_sim[align_id][sim_index] else: value = interatom.rdc[align_id] # The error. if hasattr(interatom, 'rdc_err') and align_id in interatom.rdc_err.keys(): # T values. if T_flags[-1][-1]: error = sqrt(interatom.rdc_err[align_id]**2 + interatom.j_coupling_err**2) # D values. else: error = interatom.rdc_err[align_id] # Append the RDCs to the list. rdc[-1].append(value) # Append the RDC errors. rdc_err[-1].append(error) # Append the weight. if hasattr(interatom, 'rdc_weight') and align_id in interatom.rdc_weight.keys(): rdc_weight[-1].append(interatom.rdc_weight[align_id]) else: rdc_weight[-1].append(1.0) # Append the absolute value flag. if hasattr(interatom, 'absolute_rdc') and align_id in interatom.absolute_rdc.keys(): absolute[-1].append(interatom.absolute_rdc[align_id]) else: absolute[-1].append(False) # Convert to numpy objects. rdc = array(rdc, float64) rdc_err = array(rdc_err, float64) rdc_weight = array(rdc_weight, float64) absolute = array(absolute, int32) T_flags = array(T_flags, int32) if not opt_uses_j_couplings(): j_couplings = None pseudo_flags = array(pseudo_flags, int32) # Return the data structures. return rdc, rdc_err, rdc_weight, unit_vect, rdc_const, absolute, T_flags, j_couplings, pseudo_flags
def back_calc(align_id=None): """Back calculate the RDC from the alignment tensor and unit bond vectors. @keyword align_id: The alignment tensor ID string. @type align_id: str """ # Check the pipe setup. check_pipe_setup(rdc_id=align_id, sequence=True, N=True, tensors=True) # Convert the align IDs to an array, or take all IDs. if align_id: align_ids = [align_id] else: align_ids = cdp.align_ids # Add the ID to the RDC IDs, if needed. for align_id in align_ids: # Init. if not hasattr(cdp, 'rdc_ids'): cdp.rdc_ids = [] # Add the ID. if align_id not in cdp.rdc_ids: cdp.rdc_ids.append(align_id) # The weights. weights = ones(cdp.N, float64) / cdp.N # Unit vector data structure init. unit_vect = zeros((cdp.N, 3), float64) # Loop over the interatomic data. count = 0 for interatom in interatomic_loop(): # Skip containers with no interatomic vectors. if not hasattr(interatom, 'vector'): continue # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # Checks. if not hasattr(spin1, 'isotope'): raise RelaxSpinTypeError(interatom.spin_id1) if not hasattr(spin2, 'isotope'): raise RelaxSpinTypeError(interatom.spin_id2) # Single vector. if is_float(interatom.vector[0]): vectors = [interatom.vector] else: vectors = interatom.vector # Gyromagnetic ratios. g1 = return_gyromagnetic_ratio(spin1.isotope) g2 = return_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. dj = 3.0/(2.0*pi) * dipolar_constant(g1, g2, interatom.r) # Unit vectors. for c in range(cdp.N): unit_vect[c] = vectors[c] / norm(vectors[c]) # Initialise if necessary. if not hasattr(interatom, 'rdc_bc'): interatom.rdc_bc = {} # Calculate the RDCs. for id in align_ids: # The signed value. interatom.rdc_bc[id] = ave_rdc_tensor(dj, unit_vect, cdp.N, cdp.align_tensors[get_tensor_index(align_id=id)].A, weights=weights) # T values. if hasattr(interatom, 'rdc_data_types') and align_id in interatom.rdc_data_types and interatom.rdc_data_types[align_id] == 'T': if not hasattr(interatom, 'j_coupling'): raise RelaxNoJError interatom.rdc_bc[id] += interatom.j_coupling # The absolute value. if hasattr(interatom, 'absolute_rdc') and id in interatom.absolute_rdc.keys() and interatom.absolute_rdc[id]: interatom.rdc_bc[id] = abs(interatom.rdc_bc[id]) # Increment the counter. count += 1 # No RDCs calculated. if not count: warn(RelaxWarning("No RDCs have been back calculated, probably due to missing bond vector information."))
def q_factors(spin_id=None): """Calculate the Q-factors for the RDC data. @keyword spin_id: The spin ID string used to restrict the Q-factor calculation to a subset of all spins. @type spin_id: None or str """ # Check the pipe setup. check_pipe_setup(sequence=True) # No RDCs, so no Q factors can be calculated. if not hasattr(cdp, 'rdc_ids') or not len(cdp.rdc_ids): warn(RelaxWarning("No RDC data exists, Q factors cannot be calculated.")) return # Q-factor dictonaries. cdp.q_factors_rdc = {} cdp.q_factors_rdc_norm2 = {} # Loop over the alignments. for align_id in cdp.rdc_ids: # Init. D2_sum = 0.0 sse = 0.0 # Interatomic data loop. dj = None N = 0 interatom_count = 0 rdc_data = False rdc_bc_data = False norm2_flag = True for interatom in interatomic_loop(): # Increment the counter. interatom_count += 1 # Data checks. if hasattr(interatom, 'rdc') and align_id in interatom.rdc: rdc_data = True if hasattr(interatom, 'rdc_bc') and align_id in interatom.rdc_bc: rdc_bc_data = True j_flag = False if hasattr(interatom, 'rdc_data_types') and align_id in interatom.rdc_data_types and interatom.rdc_data_types[align_id] == 'T': j_flag = True if not hasattr(interatom, 'j_coupling'): raise RelaxNoJError # Skip containers without RDC data. if not hasattr(interatom, 'rdc') or not hasattr(interatom, 'rdc_bc') or not align_id in interatom.rdc or interatom.rdc[align_id] == None or not align_id in interatom.rdc_bc or interatom.rdc_bc[align_id] == None: continue # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # Sum of squares. sse = sse + (interatom.rdc[align_id] - interatom.rdc_bc[align_id])**2 # Sum the RDCs squared (for one type of normalisation). if j_flag: D2_sum = D2_sum + (interatom.rdc[align_id] - interatom.j_coupling)**2 else: D2_sum = D2_sum + interatom.rdc[align_id]**2 # Gyromagnetic ratios. g1 = return_gyromagnetic_ratio(spin1.isotope) g2 = return_gyromagnetic_ratio(spin2.isotope) # Skip the 2Da^2(4 + 3R)/5 normalised Q factor if pseudo-atoms are present. if norm2_flag and (is_pseudoatom(spin1) or is_pseudoatom(spin2)): warn(RelaxWarning("Pseudo-atoms are present, skipping the Q factor normalised with 2Da^2(4 + 3R)/5.")) norm2_flag = False # Calculate the RDC dipolar constant (in Hertz, and the 3 comes from the alignment tensor), and append it to the list. if norm2_flag: dj_new = 3.0/(2.0*pi) * dipolar_constant(g1, g2, interatom.r) if dj != None and dj_new != dj: warn(RelaxWarning("The dipolar constant is not the same for all RDCs, skipping the Q factor normalised with 2Da^2(4 + 3R)/5.")) norm2_flag = False else: dj = dj_new # Increment the number of data sets. N = N + 1 # Warnings (and then exit). if not interatom_count: warn(RelaxWarning("No interatomic data containers have been used in the calculation, skipping the RDC Q factor calculation.")) return if not rdc_data: warn(RelaxWarning("No RDC data can be found for the alignment ID '%s', skipping the RDC Q factor calculation for this alignment." % align_id)) continue if not rdc_bc_data: warn(RelaxWarning("No back-calculated RDC data can be found for the alignment ID '%s', skipping the RDC Q factor calculation for this alignment." % align_id)) continue # Normalisation factor of 2Da^2(4 + 3R)/5. if norm2_flag: D = dj * cdp.align_tensors[cdp.align_ids.index(align_id)].A_diag Da = 1.0/3.0 * (D[2, 2] - (D[0, 0]+D[1, 1])/2.0) Dr = 1.0/3.0 * (D[0, 0] - D[1, 1]) if Da == 0: R = nan else: R = Dr / Da norm = 2.0 * (Da)**2 * (4.0 + 3.0*R**2)/5.0 if Da == 0.0: norm = 1e-15 # The Q-factor for the alignment. cdp.q_factors_rdc[align_id] = sqrt(sse / N / norm) else: cdp.q_factors_rdc[align_id] = 0.0 # The second Q-factor definition. cdp.q_factors_rdc_norm2[align_id] = sqrt(sse / D2_sum) # The total Q-factor. cdp.q_rdc = 0.0 cdp.q_rdc_norm2 = 0.0 for id in cdp.q_factors_rdc: cdp.q_rdc = cdp.q_rdc + cdp.q_factors_rdc[id]**2 for id in cdp.q_factors_rdc_norm2: cdp.q_rdc_norm2 = cdp.q_rdc_norm2 + cdp.q_factors_rdc_norm2[id]**2 cdp.q_rdc = sqrt(cdp.q_rdc / len(cdp.q_factors_rdc)) cdp.q_rdc_norm2 = sqrt(cdp.q_rdc_norm2 / len(cdp.q_factors_rdc_norm2))
def rdc_analysis(self): """Perform the RDC part of the analysis.""" # Redirect STDOUT to a log file. if self.log: sys.stdout = open(self.results_dir+sep+"logs" + sep + "RDC_%s_analysis.log" % self.rdc_name, 'w') # The dipolar constant. d = 0.0 if self.bond_length != None: d = 3.0 / (2.0*pi) * dipolar_constant(g13C, g1H, self.bond_length) # Create a directory for the save files. dir = self.results_dir + sep + "RDC_%s_results" % self.rdc_name mkdir_nofail(dir=dir) # Loop over the configurations. for config in self.configs: # Print out. print("\n"*10 + "# Set up for config " + config + " #" + "\n") # Open the results files. out = open(self.results_dir+sep+"Q_factors_" + config, 'w') out_sorted = open(self.results_dir+sep+"Q_factors_" + config + "_sorted", 'w') out.write("%-20s%20s%20s\n" % ("# Ensemble", "RDC_Q_factor(pales)", "RDC_Q_factor(standard)")) out_sorted.write("%-20s%20s\n" % ("# Ensemble", "RDC_Q_factor(pales)")) # Create the data pipe. self.interpreter.pipe.create("rdc_analysis_%s" % config, "N-state") # Read the first structure. self.interpreter.structure.read_pdb("ensembles_superimposed" + sep + config + "0.pdb", dir=self.results_dir, set_mol_name=config, set_model_num=list(range(1, self.num_models+1))) # Load all spins as the sequence. self.interpreter.structure.load_spins(ave_pos=False) # Create the pseudo-atoms. for i in range(len(self.pseudo)): self.interpreter.spin.create_pseudo(spin_name=self.pseudo[i][0], members=self.pseudo[i][1], averaging="linear") self.interpreter.sequence.display() # Read the RDC data. self.interpreter.rdc.read(align_id=self.rdc_file, file=self.rdc_file, spin_id1_col=self.rdc_spin_id1_col, spin_id2_col=self.rdc_spin_id2_col, data_col=self.rdc_data_col, error_col=self.rdc_error_col) # Define the magnetic dipole-dipole relaxation interaction. if self.bond_length != None: self.interpreter.interatom.set_dist(spin_id1='@C*', spin_id2='@H*', ave_dist=self.bond_length) self.interpreter.interatom.set_dist(spin_id1='@C*', spin_id2='@Q*', ave_dist=self.bond_length) else: self.interpreter.interatom.read_dist(file=self.bond_length_file, spin_id1_col=1, spin_id2_col=2, data_col=3) # Set the nuclear isotope. self.interpreter.spin.isotope(isotope='13C', spin_id='@C*') self.interpreter.spin.isotope(isotope='1H', spin_id='@H*') self.interpreter.spin.isotope(isotope='1H', spin_id='@Q*') # Set up the model. self.interpreter.n_state_model.select_model(model="fixed") # Print out. print("\n"*2 + "# Set up complete #" + "\n"*10) # Loop over each ensemble. q_factors = [] for ens in range(self.num_ens): # Print out the ensemble to both the log and screen. if self.log: sys.stdout.write(config + repr(ens) + "\n") sys.stderr.write(config + repr(ens) + "\n") # Delete the old structures. self.interpreter.structure.delete() # Read the ensemble. self.interpreter.structure.read_pdb("ensembles_superimposed" + sep + config + repr(ens) + ".pdb", dir=self.results_dir, set_mol_name=config, set_model_num=list(range(1, self.num_models+1))) # Get the positional information, then load the CH vectors. self.interpreter.structure.get_pos(ave_pos=False) if self.bond_length != None: self.interpreter.interatom.set_dist(spin_id1='@C*', spin_id2='@H*', ave_dist=self.bond_length) else: self.interpreter.interatom.read_dist(file=self.bond_length_file, spin_id1_col=1, spin_id2_col=2, data_col=3) self.interpreter.interatom.unit_vectors(ave=False) # Minimisation. #grid_search(inc=4) self.interpreter.minimise("simplex", constraints=False) # Store and write out the Q-factors. q_factors.append([cdp.q_rdc, ens]) out.write("%-20i%20.15f%20.15f\n" % (ens, cdp.q_rdc, cdp.q_rdc_norm2)) # Calculate the alignment tensor in Hz, and store it for reference. cdp.align_tensor_Hz = d * cdp.align_tensors[0].A cdp.align_tensor_Hz_5D = d * cdp.align_tensors[0].A_5D # Save the state. self.interpreter.results.write(file="%s_results_%s" % (config, ens), dir=dir, force=True) # Sort the NOE violations. q_factors.sort() # Write the data. for i in range(len(q_factors)): out_sorted.write("%-20i%20.15f\n" % (q_factors[i][1], q_factors[i][0]))
# Load the spins. self._execute_uf(uf_name='structure.load_spins', spin_id='@N', ave_pos=False) self._execute_uf(uf_name='structure.load_spins', spin_id='@H', ave_pos=False) # Define the magnetic dipole-dipole relaxation interaction. self._execute_uf(uf_name='interatom.define', spin_id1='@N', spin_id2='@H', direct_bond=True) self._execute_uf(uf_name='interatom.set_dist', spin_id1='@N', spin_id2='@H', ave_dist=NH_BOND_LENGTH_RDC) self._execute_uf(uf_name='interatom.unit_vectors', ave=True) # Set the nuclear isotope. self._execute_uf(uf_name='spin.isotope', isotope='15N', spin_id='@N') self._execute_uf(uf_name='spin.isotope', isotope='1H', spin_id='@H') # The dipolar constant. const = 3.0 / (2.0*pi) * dipolar_constant(g15N, g1H, NH_BOND_LENGTH_RDC) # The tensor. tensor = 'A' self._execute_uf(uf_name='align_tensor.init', tensor=tensor, params=(4.724/const, 11.856/const, 0, 0, 0), align_id=tensor, param_types=2) # The temperature. self._execute_uf(uf_name='spectrometer.temperature', id=tensor, temp=298) # The frequency. self._execute_uf(uf_name='spectrometer.frequency', id=tensor, frq=900.0 * 1e6) # One state model. self._execute_uf(uf_name='n_state_model.select_model', model='fixed') self._execute_uf(uf_name='n_state_model.number_of_states', N=1)
# Load the spins. self._execute_uf(uf_name='structure.load_spins', spin_id='@N', ave_pos=False) self._execute_uf(uf_name='structure.load_spins', spin_id='@H', ave_pos=False) # Define the magnetic dipole-dipole relaxation interaction. self._execute_uf(uf_name='interatom.define', spin_id1='@N', spin_id2='@H', direct_bond=True) self._execute_uf(uf_name='interatom.set_dist', spin_id1='@N', spin_id2='@H', ave_dist=NH_BOND_LENGTH_RDC) self._execute_uf(uf_name='interatom.unit_vectors', ave=True) # Set the nuclear isotope. self._execute_uf(uf_name='spin.isotope', isotope='15N', spin_id='@N') self._execute_uf(uf_name='spin.isotope', isotope='1H', spin_id='@H') # The dipolar constant. const = 3.0 / (2.0*pi) * dipolar_constant(periodic_table.gyromagnetic_ratio('15N'), periodic_table.gyromagnetic_ratio('1H'), NH_BOND_LENGTH_RDC) # The tensor. tensor = 'A' self._execute_uf(uf_name='align_tensor.init', tensor=tensor, params=(4.724/const, 11.856/const, 0, 0, 0), align_id=tensor, param_types=2) # The temperature. self._execute_uf(uf_name='spectrometer.temperature', id=tensor, temp=298) # The frequency. self._execute_uf(uf_name='spectrometer.frequency', id=tensor, frq=900.0 * 1e6) # One state model. self._execute_uf(uf_name='n_state_model.select_model', model='fixed') self._execute_uf(uf_name='n_state_model.number_of_states', N=1)
def rdc_analysis(self): """Perform the RDC part of the analysis.""" # Redirect STDOUT to a log file. if self.log: sys.stdout = open( self.results_dir + sep + "logs" + sep + "RDC_%s_analysis.log" % self.rdc_name, 'w') # The dipolar constant. d = 0.0 if self.bond_length != None: d = 3.0 / (2.0 * pi) * dipolar_constant( periodic_table.gyromagnetic_ratio('13C'), periodic_table.gyromagnetic_ratio('1H'), self.bond_length) # Create a directory for the save files. dir = self.results_dir + sep + "RDC_%s_results" % self.rdc_name mkdir_nofail(dir=dir) # Loop over the configurations. for config in self.configs: # Print out. print("\n" * 10 + "# Set up for config " + config + " #" + "\n") # Open the results files. out = open(self.results_dir + sep + "Q_factors_" + config, 'w') out_sorted = open( self.results_dir + sep + "Q_factors_" + config + "_sorted", 'w') out.write("%-20s%20s%20s\n" % ("# Ensemble", "RDC_Q_factor(pales)", "RDC_Q_factor(standard)")) out_sorted.write("%-20s%20s\n" % ("# Ensemble", "RDC_Q_factor(pales)")) # Create the data pipe. self.interpreter.pipe.create("rdc_analysis_%s" % config, "N-state") # Read the first structure. self.interpreter.structure.read_pdb( "ensembles_superimposed" + sep + config + "0.pdb", dir=self.results_dir, set_mol_name=config, set_model_num=list(range(1, self.num_models + 1))) # Load all spins as the sequence. self.interpreter.structure.load_spins(ave_pos=False) # Create the pseudo-atoms. for i in range(len(self.pseudo)): self.interpreter.spin.create_pseudo( spin_name=self.pseudo[i][0], members=self.pseudo[i][1], averaging="linear") self.interpreter.sequence.display() # Read the RDC data. self.interpreter.rdc.read(align_id=self.rdc_file, file=self.rdc_file, spin_id1_col=self.rdc_spin_id1_col, spin_id2_col=self.rdc_spin_id2_col, data_col=self.rdc_data_col, error_col=self.rdc_error_col) # Define the magnetic dipole-dipole relaxation interaction. if self.bond_length != None: self.interpreter.interatom.set_dist(spin_id1='@C*', spin_id2='@H*', ave_dist=self.bond_length) self.interpreter.interatom.set_dist(spin_id1='@C*', spin_id2='@Q*', ave_dist=self.bond_length) else: self.interpreter.interatom.read_dist( file=self.bond_length_file, spin_id1_col=1, spin_id2_col=2, data_col=3) # Set the nuclear isotope. self.interpreter.spin.isotope(isotope='13C', spin_id='@C*') self.interpreter.spin.isotope(isotope='1H', spin_id='@H*') self.interpreter.spin.isotope(isotope='1H', spin_id='@Q*') # Set up the model. self.interpreter.n_state_model.select_model(model="fixed") # Print out. print("\n" * 2 + "# Set up complete #" + "\n" * 10) # Loop over each ensemble. q_factors = [] for ens in range(self.num_ens): # Print out the ensemble to both the log and screen. if self.log: sys.stdout.write(config + repr(ens) + "\n") sys.stderr.write(config + repr(ens) + "\n") # Delete the old structures. self.interpreter.structure.delete() # Read the ensemble. self.interpreter.structure.read_pdb( "ensembles_superimposed" + sep + config + repr(ens) + ".pdb", dir=self.results_dir, set_mol_name=config, set_model_num=list(range(1, self.num_models + 1))) # Get the positional information, then load the CH vectors. self.interpreter.structure.get_pos(ave_pos=False) if self.bond_length != None: self.interpreter.interatom.set_dist( spin_id1='@C*', spin_id2='@H*', ave_dist=self.bond_length) else: self.interpreter.interatom.read_dist( file=self.bond_length_file, spin_id1_col=1, spin_id2_col=2, data_col=3) self.interpreter.interatom.unit_vectors(ave=False) # Minimisation. #minimise.grid_search(inc=4) self.interpreter.minimise.execute("simplex", constraints=False) # Store and write out the Q factors. q_factors.append([cdp.q_rdc_norm_squared_sum, ens]) out.write("%-20i%20.15f%20.15f\n" % (ens, cdp.q_rdc_norm_squared_sum, cdp.q_rdc_norm_squared_sum)) # Calculate the alignment tensor in Hz, and store it for reference. cdp.align_tensor_Hz = d * cdp.align_tensors[0].A cdp.align_tensor_Hz_5D = d * cdp.align_tensors[0].A_5D # Save the state. self.interpreter.results.write(file="%s_results_%s" % (config, ens), dir=dir, force=True) # Sort the NOE violations. q_factors.sort() # Write the data. for i in range(len(q_factors)): out_sorted.write("%-20i%20.15f\n" % (q_factors[i][1], q_factors[i][0]))
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)
# Path of the files. str_path = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'structures' # The data pipe. self._execute_uf(uf_name='pipe.create', pipe_name='pcs_back_calc', pipe_type='N-state') # Load the structures. self._execute_uf(uf_name='structure.read_pdb', file='trunc_ubi_pcs.pdb', dir=str_path) # Load the proton spins. self._execute_uf(uf_name='structure.load_spins', spin_id='@H') # The dipolar constant. const = 3.0 / (2.0*pi) * dipolar_constant(periodic_table.gyromagnetic_ratio('15N'), periodic_table.gyromagnetic_ratio('1H'), NH_BOND_LENGTH_RDC) # The tensor. tensor = 'A' align_id = tensor self._execute_uf(uf_name='align_tensor.init', tensor=tensor, params=(4.724/const, 11.856/const, 0, 0, 0), align_id=align_id, param_types=2) # The temperature. self._execute_uf(uf_name='spectrometer.temperature', id=align_id, temp=298) # The frequency. self._execute_uf(uf_name='spectrometer.frequency', id=align_id, frq=900.0 * 1e6) # One state model. self._execute_uf(uf_name='n_state_model.select_model', model='fixed') self._execute_uf(uf_name='n_state_model.number_of_states', N=1)