def _set_xh_vect(self, spin_line, col, spin, spin_id1=None, spin_id2=None, verbosity=1): """Set the unit vectors. @param spin_line: The line of data for a single spin. @type spin_line: list of str @param col: The column indices. @type col: dict of int @param spin: The spin container. @type spin: SpinContainer instance @keyword spin_id1: The ID string of the first spin. @type spin_id1: str @keyword spin_id2: The ID string of the second spin. @type spin_id2: str @keyword verbosity: A variable specifying the amount of information to print. The higher the value, the greater the verbosity. @type verbosity: int """ # Get the interatomic data container. interatom = return_interatom(spin_id1=spin_id1, spin_id2=spin_id2) if interatom == None: raise RelaxError("No interatomic interaction between spins '%s' and '%s' could be found." (spin_id1, spin_id2)) # The vector. vector = eval(spin_line[col['xh_vect']]) if vector: # numpy array format. try: vector = array(vector, float64) except: raise RelaxError("The XH unit vector " + spin_line[col['xh_vect']] + " is invalid.") # Set the vector. interatom.vector = vector
def return_error(self, data_id): """Return the RDC or PCS error structure. @param data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @return: The array of RDC or PCS error values. @rtype: list of float """ # Initialise the MC data structure. mc_errors = [] # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_hash1, spin_hash2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_hash1=spin_hash1, spin_hash2=spin_hash2) # Do errors exist? if not hasattr(interatom, 'rdc_err'): raise RelaxError( "The RDC errors are missing for interatomic data container between spins '%s' and '%s'." % (spin_id1, spin_id2)) # Handle missing data. if align_id not in interatom.rdc_err: mc_errors.append(None) # Append the data. else: mc_errors.append(interatom.rdc_err[align_id]) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id=spin_id) # Do errors exist? if not hasattr(spin, 'pcs_err'): raise RelaxError("The PCS errors are missing for spin '%s'." % spin_id) # Handle missing data. if align_id not in spin.pcs_err: mc_errors.append(None) # Append the data. else: mc_errors.append(spin.pcs_err[align_id]) # Return the errors. return mc_errors
def create_mc_data(self, data_id=None): """Create the Monte Carlo data by back calculating the RDCs or PCSs. @keyword data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @return: The Monte Carlo simulation data. @rtype: list of floats """ # Initialise the MC data structure. mc_data = [] # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_hash1, spin_hash2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_hash1=spin_hash1, spin_hash2=spin_hash2) # Does back-calculated data exist? if not hasattr(interatom, 'rdc_bc'): self.calculate() # The data. if not hasattr(interatom, 'rdc_bc') or align_id not in interatom.rdc_bc: data = None else: data = interatom.rdc_bc[align_id] # Append the data. mc_data.append(data) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id=spin_id) # Does back-calculated data exist? if not hasattr(spin, 'pcs_bc'): self.calculate() # The data. if not hasattr(spin, 'pcs_bc') or align_id not in spin.pcs_bc: data = None else: data = spin.pcs_bc[align_id] # Append the data. mc_data.append(data) # Return the data. return mc_data
def create_mc_data(self, data_id=None): """Create the Monte Carlo data by back calculating the RDCs or PCSs. @keyword data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @return: The Monte Carlo simulation data. @rtype: list of floats """ # Initialise the MC data structure. mc_data = [] # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_id1, spin_id2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_id1, spin_id2) # Does back-calculated data exist? if not hasattr(interatom, 'rdc_bc'): self.calculate() # The data. if not hasattr(interatom, 'rdc_bc') or align_id not in interatom.rdc_bc: data = None else: data = interatom.rdc_bc[align_id] # Append the data. mc_data.append(data) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id) # Does back-calculated data exist? if not hasattr(spin, 'pcs_bc'): self.calculate() # The data. if not hasattr(spin, 'pcs_bc') or align_id not in spin.pcs_bc: data = None else: data = spin.pcs_bc[align_id] # Append the data. mc_data.append(data) # Return the data. return mc_data
def return_error(self, data_id): """Return the RDC or PCS error structure. @param data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @return: The array of RDC or PCS error values. @rtype: list of float """ # Initialise the MC data structure. mc_errors = [] # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_id1, spin_id2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_id1, spin_id2) # Do errors exist? if not hasattr(interatom, 'rdc_err'): raise RelaxError("The RDC errors are missing for interatomic data container between spins '%s' and '%s'." % (spin_id1, spin_id2)) # Handle missing data. if align_id not in interatom.rdc_err: mc_errors.append(None) # Append the data. else: mc_errors.append(interatom.rdc_err[align_id]) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id) # Do errors exist? if not hasattr(spin, 'pcs_err'): raise RelaxError("The PCS errors are missing for spin '%s'." % spin_id) # Handle missing data. if align_id not in spin.pcs_err: mc_errors.append(None) # Append the data. else: mc_errors.append(spin.pcs_err[align_id]) # Return the errors. return mc_errors
def set_xh_vect(spin_line, col, spin, spin_id1=None, spin_id2=None, spin_hash1=None, spin_hash2=None, verbosity=1): """Set the unit vectors. @param spin_line: The line of data for a single spin. @type spin_line: list of str @param col: The column indices. @type col: dict of int @param spin: The spin container. @type spin: SpinContainer instance @keyword spin_id1: The ID string of the first spin. @type spin_id1: str @keyword spin_id2: The ID string of the second spin. @type spin_id2: str @keyword spin_hash1: The unique hash of the first spin. @type spin_hash1: str @keyword spin_hash2: The unique hash of the second spin. @type spin_hash2: str @keyword verbosity: A variable specifying the amount of information to print. The higher the value, the greater the verbosity. @type verbosity: int """ # Get the interatomic data container. interatom = return_interatom(spin_hash1=spin_hash1, spin_hash2=spin_hash2) if interatom == None: raise RelaxError( "No interatomic interaction between spins '%s' and '%s' could be found." ( spin_id1, spin_id2)) # The vector. vector = eval(spin_line[col['xh_vect']]) if vector: # numpy array format. try: vector = array(vector, float64) except: raise RelaxError("The XH unit vector " + spin_line[col['xh_vect']] + " is invalid.") # Set the vector. interatom.vector = vector
def sim_pack_data(self, data_id, sim_data): """Pack the Monte Carlo simulation data. @param data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @param sim_data: The Monte Carlo simulation data. @type sim_data: list of float """ # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_hash1, spin_hash2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_hash1=spin_hash1, spin_hash2=spin_hash2) # Initialise. if not hasattr(interatom, 'rdc_sim'): interatom.rdc_sim = {} # Store the data structure. interatom.rdc_sim[align_id] = [] for i in range(cdp.sim_number): interatom.rdc_sim[align_id].append(sim_data[i][0]) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id=spin_id) # Initialise. if not hasattr(spin, 'pcs_sim'): spin.pcs_sim = {} # Store the data structure. spin.pcs_sim[data_id[2]] = [] for i in range(cdp.sim_number): spin.pcs_sim[data_id[2]].append(sim_data[i][0])
def setup_pseudoatom_rdc(): """Make sure that the interatom system is properly set up for pseudo-atoms and RDCs. Interatomic data containers between the non-pseudo-atom and the pseudo-atom members will be deselected. """ # Loop over all interatomic data containers. for interatom in interatomic_loop(): # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # Checks. flag1 = is_pseudoatom(spin1) flag2 = is_pseudoatom(spin2) # No pseudo-atoms, so do nothing. if not (flag1 or flag2): continue # Both are pseudo-atoms. if flag1 and flag2: warn(RelaxWarning("Support for both spins being in a dipole pair being pseudo-atoms is not implemented yet, deselecting the interatomic data container for the spin pair '%s' and '%s'." % (interatom.spin_id1, interatom.spin_id2))) interatom.select = False # Alias the pseudo and normal atoms. pseudospin = spin1 base_spin_id = interatom.spin_id2 pseudospin_id = interatom.spin_id1 if flag2: pseudospin = spin2 base_spin_id = interatom.spin_id1 pseudospin_id = interatom.spin_id2 # Loop over the atoms of the pseudo-atom. 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) # Deselect if needed. if pseudo_interatom.select: warn(RelaxWarning("Deselecting the interatomic data container for the spin pair '%s' and '%s' as it is part of the pseudo-atom system of the spin pair '%s' and '%s'." % (pseudo_interatom.spin_id1, pseudo_interatom.spin_id2, base_spin_id, pseudospin_id))) pseudo_interatom.select = False
def sim_pack_data(self, data_id, sim_data): """Pack the Monte Carlo simulation data. @param data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @param sim_data: The Monte Carlo simulation data. @type sim_data: list of float """ # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_id1, spin_id2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_id1, spin_id2) # Initialise. if not hasattr(interatom, 'rdc_sim'): interatom.rdc_sim = {} # Store the data structure. interatom.rdc_sim[align_id] = [] for i in range(cdp.sim_number): interatom.rdc_sim[align_id].append(sim_data[i][0]) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id) # Initialise. if not hasattr(spin, 'pcs_sim'): spin.pcs_sim = {} # Store the data structure. spin.pcs_sim[data_id[2]] = [] for i in range(cdp.sim_number): spin.pcs_sim[data_id[2]].append(sim_data[i][0])
if file[:3] == 'pcs': # Load the original file. pcs.read(align_id=file, file='%s.txt'%file, dir='../free_rotor/', mol_name_col=1, res_num_col=2, res_name_col=3, spin_num_col=4, spin_name_col=5, data_col=6, error_col=7) # Delete the data. for spin_id in missing_pcs[file]: # Get the container. spin = return_spin(spin_id) # Delete the data. del spin.pcs[file] # Write data to file. pcs.write(align_id=file, file='%s.txt'%file, dir='.', force=True) # RDC data. elif file[:3] == 'rdc': # Load the original file. rdc.read(align_id=file, file='%s.txt'%file, dir='../free_rotor/', data_col=3, error_col=4) # Delete the data. for spin_id1, spin_id2 in missing_rdc[file]: # Get the container. interatom = return_interatom(spin_id1, spin_id2) # Delete the data. del interatom.rdc[file] # Write data to file. rdc.write(align_id=file, file='%s.txt'%file, dir='.', force=True)
def read(file=None, dir=None, file_data=None, spin_id1_col=None, spin_id2_col=None, data_col=None, error_col=None, sign_col=None, sep=None): """Read the J coupling data from file. @keyword file: The name of the file to open. @type file: str @keyword dir: The directory containing the file (defaults to the current directory if None). @type dir: str or None @keyword file_data: An alternative to opening a file, if the data already exists in the correct format. The format is a list of lists where the first index corresponds to the row and the second the column. @type file_data: list of lists @keyword spin_id1_col: The column containing the spin ID strings of the first spin. @type spin_id1_col: int @keyword spin_id2_col: The column containing the spin ID strings of the second spin. @type spin_id2_col: int @keyword data_col: The column containing the J coupling data in Hz. @type data_col: int or None @keyword error_col: The column containing the J coupling errors. @type error_col: int or None @keyword sign_col: The optional column containing the sign of the J coupling. @type sign_col: int or None @keyword sep: The column separator which, if None, defaults to whitespace. @type sep: str or None """ # Check the pipe setup. check_pipe_setup(sequence=True) # Either the data or error column must be supplied. if data_col == None and error_col == None: raise RelaxError("One of either the data or error column must be supplied.") # Extract the data from the file, and remove comments and blank lines. file_data = extract_data(file, dir, sep=sep) file_data = strip(file_data, comments=True) # Loop over the J coupling data. data = [] for line in file_data: # Invalid columns. if spin_id1_col > len(line): warn(RelaxWarning("The data %s is invalid, no first spin ID column can be found." % line)) continue if spin_id2_col > len(line): warn(RelaxWarning("The data %s is invalid, no second spin ID column can be found." % line)) continue if data_col and data_col > len(line): warn(RelaxWarning("The data %s is invalid, no data column can be found." % line)) continue if error_col and error_col > len(line): warn(RelaxWarning("The data %s is invalid, no error column can be found." % line)) continue if sign_col and sign_col > len(line): warn(RelaxWarning("The data %s is invalid, no sign column can be found." % line)) continue # Unpack. spin_id1 = line[spin_id1_col-1] spin_id2 = line[spin_id2_col-1] value = None if data_col: value = line[data_col-1] error = None if error_col: error = line[error_col-1] sign = None if sign_col: sign = line[sign_col-1] # Convert the spin IDs. if spin_id1[0] in ["\"", "\'"]: spin_id1 = eval(spin_id1) if spin_id2[0] in ["\"", "\'"]: spin_id2 = eval(spin_id2) # Convert and check the value. if value == 'None': value = None if value != None: try: value = float(value) except ValueError: warn(RelaxWarning("The J coupling value of the line %s is invalid." % line)) continue # The sign data. if sign == 'None': sign = None if sign != None: try: sign = float(sign) except ValueError: warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line)) continue if sign not in [1.0, -1.0]: warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line)) continue # Convert and check the error. if error == 'None': error = None if error != None: try: error = float(error) except ValueError: warn(RelaxWarning("The error value of the line %s is invalid." % line)) continue # Get the spins. spin1 = return_spin(spin_id=spin_id1) spin2 = return_spin(spin_id=spin_id2) # Check the spin IDs. if not spin1: warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id1, line))) continue if not spin2: warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id2, line))) continue # Test the error value (cannot be 0.0). if error == 0.0: raise RelaxError("An invalid error value of zero has been encountered.") # Get the interatomic data container. interatom = return_interatom(spin_hash1=spin1._hash, spin_hash2=spin2._hash) # Create the container if needed. if interatom == None: interatom = create_interatom(spin_id1=spin_id1, spin_id2=spin_id2) # Add the data. if data_col: # Sign conversion. if sign != None: value = value * sign # Add the value. interatom.j_coupling = value # Add the error. if error_col: interatom.j_coupling_err = error # Append the data for printout. data.append([spin_id1, spin_id2]) if is_float(value): data[-1].append("%20.15f" % value) else: data[-1].append("%20s" % value) if is_float(error): data[-1].append("%20.15f" % error) else: data[-1].append("%20s" % error) # No data, so fail hard! if not len(data): raise RelaxError("No J coupling data could be extracted.") # Print out. print("The following J coupling have been loaded into the relax data store:\n") write_data(out=sys.stdout, headings=["Spin_ID1", "Spin_ID2", "Value", "Error"], data=data)
def read(file=None, dir=None, file_data=None, spin_id1_col=None, spin_id2_col=None, data_col=None, error_col=None, sign_col=None, sep=None): """Read the J coupling data from file. @keyword file: The name of the file to open. @type file: str @keyword dir: The directory containing the file (defaults to the current directory if None). @type dir: str or None @keyword file_data: An alternative to opening a file, if the data already exists in the correct format. The format is a list of lists where the first index corresponds to the row and the second the column. @type file_data: list of lists @keyword spin_id1_col: The column containing the spin ID strings of the first spin. @type spin_id1_col: int @keyword spin_id2_col: The column containing the spin ID strings of the second spin. @type spin_id2_col: int @keyword data_col: The column containing the J coupling data in Hz. @type data_col: int or None @keyword error_col: The column containing the J coupling errors. @type error_col: int or None @keyword sign_col: The optional column containing the sign of the J coupling. @type sign_col: int or None @keyword sep: The column separator which, if None, defaults to whitespace. @type sep: str or None """ # Check the pipe setup. check_pipe_setup(sequence=True) # Either the data or error column must be supplied. if data_col == None and error_col == None: raise RelaxError("One of either the data or error column must be supplied.") # Extract the data from the file, and remove comments and blank lines. file_data = extract_data(file, dir, sep=sep) file_data = strip(file_data, comments=True) # Loop over the J coupling data. data = [] for line in file_data: # Invalid columns. if spin_id1_col > len(line): warn(RelaxWarning("The data %s is invalid, no first spin ID column can be found." % line)) continue if spin_id2_col > len(line): warn(RelaxWarning("The data %s is invalid, no second spin ID column can be found." % line)) continue if data_col and data_col > len(line): warn(RelaxWarning("The data %s is invalid, no data column can be found." % line)) continue if error_col and error_col > len(line): warn(RelaxWarning("The data %s is invalid, no error column can be found." % line)) continue if sign_col and sign_col > len(line): warn(RelaxWarning("The data %s is invalid, no sign column can be found." % line)) continue # Unpack. spin_id1 = line[spin_id1_col-1] spin_id2 = line[spin_id2_col-1] value = None if data_col: value = line[data_col-1] error = None if error_col: error = line[error_col-1] sign = None if sign_col: sign = line[sign_col-1] # Convert the spin IDs. if spin_id1[0] in ["\"", "\'"]: spin_id1 = eval(spin_id1) if spin_id2[0] in ["\"", "\'"]: spin_id2 = eval(spin_id2) # Convert and check the value. if value == 'None': value = None if value != None: try: value = float(value) except ValueError: warn(RelaxWarning("The J coupling value of the line %s is invalid." % line)) continue # The sign data. if sign == 'None': sign = None if sign != None: try: sign = float(sign) except ValueError: warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line)) continue if sign not in [1.0, -1.0]: warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line)) continue # Convert and check the error. if error == 'None': error = None if error != None: try: error = float(error) except ValueError: warn(RelaxWarning("The error value of the line %s is invalid." % line)) continue # Get the spins. spin1 = return_spin(spin_id1) spin2 = return_spin(spin_id2) # Check the spin IDs. if not spin1: warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id1, line))) continue if not spin2: warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id2, line))) continue # Test the error value (cannot be 0.0). if error == 0.0: raise RelaxError("An invalid error value of zero has been encountered.") # Get the interatomic data container. interatom = return_interatom(spin_id1, spin_id2) # Create the container if needed. if interatom == None: interatom = create_interatom(spin_id1=spin_id1, spin_id2=spin_id2) # Add the data. if data_col: # Sign conversion. if sign != None: value = value * sign # Add the value. interatom.j_coupling = value # Add the error. if error_col: interatom.j_coupling_err = error # Append the data for printout. data.append([spin_id1, spin_id2]) if is_float(value): data[-1].append("%20.15f" % value) else: data[-1].append("%20s" % value) if is_float(error): data[-1].append("%20.15f" % error) else: data[-1].append("%20s" % error) # No data, so fail hard! if not len(data): raise RelaxError("No J coupling data could be extracted.") # Print out. print("The following J coupling have been loaded into the relax data store:\n") write_data(out=sys.stdout, headings=["Spin_ID1", "Spin_ID2", "Value", "Error"], data=data)
spin = return_spin(spin_id=spin_id) # Delete the data. del spin.pcs[file] # Write data to file. pcs.write(align_id=file, file='%s.txt' % file, dir='.', force=True) # RDC data. elif file[:3] == 'rdc': # Load the original file. rdc.read(align_id=file, file='%s.txt' % file, dir='../free_rotor/', data_col=3, error_col=4) # Delete the data. for spin_id1, spin_id2 in missing_rdc[file]: # Get the container. spin1 = return_spin(spin_id=spin_id1) spin2 = return_spin(spin_id=spin_id2) interatom = return_interatom(spin_hash1=spin1._hash, spin_hash1=spin2._hash) # Delete the data. del interatom.rdc[file] # Write data to file. rdc.write(align_id=file, file='%s.txt' % file, dir='.', force=True)
def bmrb_read(star, sample_conditions=None): """Read the relaxation data from the NMR-STAR dictionary object. @param star: The NMR-STAR dictionary object. @type star: NMR_STAR instance @keyword sample_conditions: The sample condition label to read. Only one sample condition can be read per data pipe. @type sample_conditions: None or str """ # Get the relaxation data. for data in star.relaxation.loop(): # Sample conditions do not match (remove the $ sign). if 'sample_cond_list_label' in data and sample_conditions and data[ 'sample_cond_list_label'].replace('$', '') != sample_conditions: continue # Create the labels. ri_type = data['data_type'] frq = float(data['frq']) * 1e6 # Round the label to the nearest factor of 10. frq_label = create_frq_label(float(data['frq']) * 1e6) # The ID string. ri_id = "%s_%s" % (ri_type, frq_label) # The number of spins. N = bmrb.num_spins(data) # No data in the saveframe. if N == 0: continue # The molecule names. mol_names = bmrb.molecule_names(data, N) # Generate the sequence if needed. bmrb.generate_sequence(N, spin_names=data['atom_names'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names, isotopes=data['isotope'], elements=data['atom_types']) # The attached protons. if 'atom_names_2' in data: # Generate the proton spins. bmrb.generate_sequence(N, spin_names=data['atom_names_2'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names, isotopes=data['isotope_2'], elements=data['atom_types_2']) # Define the dipolar interaction. for i in range(len(data['atom_names'])): # The spin IDs. spin_id1 = generate_spin_id_unique( spin_name=data['atom_names'][i], res_num=data['res_nums'][i], res_name=data['res_names'][i], mol_name=mol_names[i]) spin_id2 = generate_spin_id_unique( spin_name=data['atom_names_2'][i], res_num=data['res_nums'][i], res_name=data['res_names'][i], mol_name=mol_names[i]) # Check if the container exists. spin1 = return_spin(spin_id=spin_id1) spin2 = return_spin(spin_id=spin_id2) if return_interatom(spin_hash1=spin1._hash, spin_hash2=spin2._hash): continue # Define. define_dipole_pair(spin_id1=spin_id1, spin_id2=spin_id2, spin1=spin1, spin2=spin2, verbose=False) # The data and error. vals = data['data'] errors = data['errors'] if vals == None: vals = [None] * N if errors == None: errors = [None] * N # Data transformation. if vals != None and 'units' in data: # Scaling. if data['units'] == 'ms': # Loop over the data. for i in range(N): # The value. if vals[i] != None: vals[i] = vals[i] / 1000 # The error. if errors[i] != None: errors[i] = errors[i] / 1000 # Invert. if data['units'] in ['s', 'ms']: # Loop over the data. for i in range(len(vals)): # The value. if vals[i] != None: vals[i] = 1.0 / vals[i] # The error. if vals[i] != None and errors[i] != None: errors[i] = errors[i] * vals[i]**2 # Pack the data. pack_data(ri_id, ri_type, frq, vals, errors, mol_names=mol_names, res_nums=data['res_nums'], res_names=data['res_names'], spin_nums=None, spin_names=data['atom_names'], gen_seq=True, verbose=False) # Store the temperature calibration and control. if data['temp_calibration']: temp_calibration(ri_id=ri_id, method=data['temp_calibration']) if data['temp_control']: temp_control(ri_id=ri_id, method=data['temp_control']) # Peak intensity type. if data['peak_intensity_type']: peak_intensity_type(ri_id=ri_id, type=data['peak_intensity_type'])
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 read(align_id=None, file=None, dir=None, file_data=None, data_type='D', spin_id1_col=None, spin_id2_col=None, data_col=None, error_col=None, sep=None, neg_g_corr=False, absolute=False): """Read the RDC data from file. @keyword align_id: The alignment tensor ID string. @type align_id: str @keyword file: The name of the file to open. @type file: str @keyword dir: The directory containing the file (defaults to the current directory if None). @type dir: str or None @keyword file_data: An alternative to opening a file, if the data already exists in the correct format. The format is a list of lists where the first index corresponds to the row and the second the column. @type file_data: list of lists @keyword data_type: A string which is set to 'D' means that the splitting in the aligned sample was assumed to be J + D, or if set to '2D' then the splitting was taken as J + 2D. If set to 'T', then the data will be marked as being J+D values. @keyword spin_id1_col: The column containing the spin ID strings of the first spin. @type spin_id1_col: int @keyword spin_id2_col: The column containing the spin ID strings of the second spin. @type spin_id2_col: int @keyword data_col: The column containing the RDC data in Hz. @type data_col: int or None @keyword error_col: The column containing the RDC errors. @type error_col: int or None @keyword sep: The column separator which, if None, defaults to whitespace. @type sep: str or None @keyword neg_g_corr: A flag which is used to correct for the negative gyromagnetic ratio of 15N. If True, a sign inversion will be applied to all RDC values to be loaded. @type neg_g_corr: bool @keyword absolute: A flag which if True indicates that the RDCs to load are signless. All RDCs will then be converted to positive values. @type absolute: bool """ # Check the pipe setup. check_pipe_setup(sequence=True) # Either the data or error column must be supplied. if data_col == None and error_col == None: raise RelaxError("One of either the data or error column must be supplied.") # Check the data types. rdc_types = ['D', '2D', 'T'] if data_type not in rdc_types: raise RelaxError("The RDC data type '%s' must be one of %s." % (data_type, rdc_types)) # Spin specific data. ##################### # Extract the data from the file, and remove comments and blank lines. file_data = extract_data(file, dir, sep=sep) file_data = strip(file_data, comments=True) # Loop over the RDC data. data = [] for line in file_data: # Invalid columns. if spin_id1_col > len(line): warn(RelaxWarning("The data %s is invalid, no first spin ID column can be found." % line)) continue if spin_id2_col > len(line): warn(RelaxWarning("The data %s is invalid, no second spin ID column can be found." % line)) continue if data_col and data_col > len(line): warn(RelaxWarning("The data %s is invalid, no data column can be found." % line)) continue if error_col and error_col > len(line): warn(RelaxWarning("The data %s is invalid, no error column can be found." % line)) continue # Unpack. spin_id1 = line[spin_id1_col-1] spin_id2 = line[spin_id2_col-1] value = None if data_col: value = line[data_col-1] error = None if error_col: error = line[error_col-1] # Convert the spin IDs. if spin_id1[0] in ["\"", "\'"]: spin_id1 = eval(spin_id1) if spin_id2[0] in ["\"", "\'"]: spin_id2 = eval(spin_id2) # Convert and check the value. if value == 'None': value = None if value != None: try: value = float(value) except ValueError: warn(RelaxWarning("The RDC value of the line %s is invalid." % line)) continue # Convert and check the error. if error == 'None': error = None if error != None: try: error = float(error) except ValueError: warn(RelaxWarning("The error value of the line %s is invalid." % line)) continue # Get the spins. spin1 = return_spin(spin_id1) spin2 = return_spin(spin_id2) # Check the spin IDs. if not spin1: warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id1, line))) continue if not spin2: warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id2, line))) continue # Get the interatomic data container. interatom = return_interatom(spin_id1, spin_id2) # Create the container if needed. if interatom == None: interatom = create_interatom(spin_id1=spin_id1, spin_id2=spin_id2) # Test the error value (a value of 0.0 will cause the interatomic container to be deselected). if error == 0.0: interatom.select = False warn(RelaxWarning("An error value of zero has been encountered, deselecting the interatomic container between spin '%s' and '%s'." % (spin_id1, spin_id2))) continue # Store the data type as global data (need for the conversion of RDC data). if not hasattr(interatom, 'rdc_data_types'): interatom.rdc_data_types = {} if not align_id in interatom.rdc_data_types: interatom.rdc_data_types[align_id] = data_type # Convert and add the data. if data_col: # Data conversion. value = convert(value, data_type, align_id, to_intern=True) # Correction for the negative gyromagnetic ratio of 15N. if neg_g_corr and value != None: value = -value # Absolute values. if absolute: # Force the value to be positive. value = abs(value) # Initialise. if not hasattr(interatom, 'rdc'): interatom.rdc = {} # Add the value. interatom.rdc[align_id] = value # Store the absolute value flag. if not hasattr(interatom, 'absolute_rdc'): interatom.absolute_rdc = {} interatom.absolute_rdc[align_id] = absolute # Convert and add the error. if error_col: # Data conversion. error = convert(error, data_type, align_id, to_intern=True) # Initialise. if not hasattr(interatom, 'rdc_err'): interatom.rdc_err = {} # Append the error. interatom.rdc_err[align_id] = error # Append the data for printout. data.append([spin_id1, spin_id2]) if is_float(value): data[-1].append("%20.15f" % value) else: data[-1].append("%20s" % value) if is_float(error): data[-1].append("%20.15f" % error) else: data[-1].append("%20s" % error) # No data, so fail hard! if not len(data): raise RelaxError("No RDC data could be extracted.") # Print out. print("The following RDCs have been loaded into the relax data store:\n") write_data(out=sys.stdout, headings=["Spin_ID1", "Spin_ID2", "Value", "Error"], data=data) # Initialise some global structures. if not hasattr(cdp, 'align_ids'): cdp.align_ids = [] if not hasattr(cdp, 'rdc_ids'): cdp.rdc_ids = [] # Add the RDC id string. if align_id not in cdp.align_ids: cdp.align_ids.append(align_id) if align_id not in cdp.rdc_ids: cdp.rdc_ids.append(align_id)
def check_rdcs(interatom): """Check if all data required for calculating the RDC is present. @param interatom: The interatomic data container. @type interatom: InteratomContainer instance @return: True if all data required for calculating the RDC is present, False otherwise. @rtype: bool """ # Skip deselected interatomic data containers. if not interatom.select: return False # Only use interatomic data containers with RDC data. if not hasattr(interatom, 'rdc'): return False # Only use interatomic data containers with RDC and J coupling data. if opt_uses_j_couplings() and not hasattr(interatom, 'j_coupling'): return False # Get the spins. spin1 = return_spin(interatom.spin_id1) spin2 = return_spin(interatom.spin_id2) # Spin information checks. if not hasattr(spin1, 'isotope'): warn(RelaxSpinTypeWarning(interatom.spin_id1)) return False if not hasattr(spin2, 'isotope'): warn(RelaxSpinTypeWarning(interatom.spin_id2)) return False if is_pseudoatom(spin1) and is_pseudoatom(spin2): warn(RelaxWarning("Support for both spins being in a dipole pair being pseudo-atoms is not implemented yet.")) return False # Pseudo-atom checks. if is_pseudoatom(spin1) or is_pseudoatom(spin2): # Alias the pseudo and normal atoms. pseudospin = spin1 base_spin_id = interatom.spin_id2 pseudospin_id = interatom.spin_id1 if is_pseudoatom(spin2): pseudospin = spin2 base_spin_id = interatom.spin_id1 pseudospin_id = interatom.spin_id2 # Loop over the atoms of the pseudo-atom. 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) # Unit vector check. if not hasattr(pseudo_interatom, 'vector'): warn(RelaxWarning("The interatomic vector is missing for the spin pair '%s' and '%s' of the pseudo-atom '%s', skipping the RDC for the spin pair '%s' and '%s'." % (pseudo_interatom.spin_id1, pseudo_interatom.spin_id2, pseudospin_id, base_spin_id, pseudospin_id))) return False # Check. if not hasattr(pseudo_interatom, 'r'): warn(RelaxWarning("The averaged interatomic distance between spins '%s' and '%s' for the pseudo-atom '%s' has not been set yet." % (spin_id, base_spin_id, pseudospin_id))) return False # Normal atoms checks. else: # Unit vector check. if not hasattr(interatom, 'vector'): warn(RelaxWarning("The interatomic vector is missing, skipping the spin pair '%s' and '%s'." % (interatom.spin_id1, interatom.spin_id2))) return False # Distance information check. if not hasattr(interatom, 'r'): warn(RelaxWarning("The averaged interatomic distance between spins '%s' and '%s' has not been set yet." % (interatom.spin_id1, interatom.spin_id2))) return False # Everything is ok. return True
def bmrb_read(star, sample_conditions=None): """Read the relaxation data from the NMR-STAR dictionary object. @param star: The NMR-STAR dictionary object. @type star: NMR_STAR instance @keyword sample_conditions: The sample condition label to read. Only one sample condition can be read per data pipe. @type sample_conditions: None or str """ # Get the relaxation data. for data in star.relaxation.loop(): # Store the keys. keys = list(data.keys()) # Sample conditions do not match (remove the $ sign). if 'sample_cond_list_label' in keys and sample_conditions and data['sample_cond_list_label'].replace('$', '') != sample_conditions: continue # Create the labels. ri_type = data['data_type'] frq = float(data['frq']) * 1e6 # Round the label to the nearest factor of 10. frq_label = create_frq_label(float(data['frq']) * 1e6) # The ID string. ri_id = "%s_%s" % (ri_type, frq_label) # The number of spins. N = bmrb.num_spins(data) # No data in the saveframe. if N == 0: continue # The molecule names. mol_names = bmrb.molecule_names(data, N) # Generate the sequence if needed. bmrb.generate_sequence(N, spin_names=data['atom_names'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names, isotopes=data['isotope'], elements=data['atom_types']) # The attached protons. if 'atom_names_2' in data: # Generate the proton spins. bmrb.generate_sequence(N, spin_names=data['atom_names_2'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names, isotopes=data['isotope_2'], elements=data['atom_types_2']) # Define the dipolar interaction. for i in range(len(data['atom_names'])): # The spin IDs. spin_id1 = generate_spin_id_unique(spin_name=data['atom_names'][i], res_num=data['res_nums'][i], res_name=data['res_names'][i], mol_name=mol_names[i]) spin_id2 = generate_spin_id_unique(spin_name=data['atom_names_2'][i], res_num=data['res_nums'][i], res_name=data['res_names'][i], mol_name=mol_names[i]) # Check if the container exists. if return_interatom(spin_id1=spin_id1, spin_id2=spin_id2): continue # Define. define(spin_id1=spin_id1, spin_id2=spin_id2, verbose=False) # The data and error. vals = data['data'] errors = data['errors'] if vals == None: vals = [None] * N if errors == None: errors = [None] * N # Data transformation. if vals != None and 'units' in keys: # Scaling. if data['units'] == 'ms': # Loop over the data. for i in range(N): # The value. if vals[i] != None: vals[i] = vals[i] / 1000 # The error. if errors[i] != None: errors[i] = errors[i] / 1000 # Invert. if data['units'] in ['s', 'ms']: # Loop over the data. for i in range(len(vals)): # The value. if vals[i] != None: vals[i] = 1.0 / vals[i] # The error. if vals[i] != None and errors[i] != None: errors[i] = errors[i] * vals[i]**2 # Pack the data. pack_data(ri_id, ri_type, frq, vals, errors, mol_names=mol_names, res_nums=data['res_nums'], res_names=data['res_names'], spin_nums=None, spin_names=data['atom_names'], gen_seq=True, verbose=False) # Store the temperature calibration and control. if data['temp_calibration']: temp_calibration(ri_id=ri_id, method=data['temp_calibration']) if data['temp_control']: temp_control(ri_id=ri_id, method=data['temp_control']) # Peak intensity type. if data['peak_intensity_type']: peak_intensity_type(ri_id=ri_id, type=data['peak_intensity_type'])