def set_dist(spin_id1=None, spin_id2=None, ave_dist=None, unit='meter'): """Set up the magnetic dipole-dipole interaction. @keyword spin_id1: The spin identifier string of the first spin of the pair. @type spin_id1: str @keyword spin_id2: The spin identifier string of the second spin of the pair. @type spin_id2: str @keyword ave_dist: The r^-3 averaged interatomic distance. @type ave_dist: float @keyword unit: The measurement unit. This can be either 'meter' or 'Angstrom'. @type unit: str """ # Check the units. if unit not in ['meter', 'Angstrom']: raise RelaxError("The measurement unit of '%s' must be one of 'meter' or 'Angstrom'." % unit) # Unit conversion. if unit == 'Angstrom': ave_dist = ave_dist * 1e-10 # Generate the selection objects. sel_obj1 = Selection(spin_id1) sel_obj2 = Selection(spin_id2) # Loop over the interatomic containers. data = [] for interatom in interatomic_loop(): # Get the spin info. mol_name1, res_num1, res_name1, spin1 = return_spin(spin_hash=interatom._spin_hash1, full_info=True) mol_name2, res_num2, res_name2, spin2 = return_spin(spin_hash=interatom._spin_hash2, full_info=True) # No match, either way. if not (sel_obj1.contains_spin(spin_num=spin1.num, spin_name=spin1.name, res_num=res_num1, res_name=res_name1, mol=mol_name1) and sel_obj2.contains_spin(spin_num=spin2.num, spin_name=spin2.name, res_num=res_num2, res_name=res_name2, mol=mol_name2)) and not (sel_obj2.contains_spin(spin_num=spin1.num, spin_name=spin1.name, res_num=res_num1, res_name=res_name1, mol=mol_name1) and sel_obj1.contains_spin(spin_num=spin2.num, spin_name=spin2.name, res_num=res_num2, res_name=res_name2, mol=mol_name2)): continue # Store the averaged distance. interatom.r = ave_dist # Store the data for the printout. data.append([repr(interatom.spin_id1), repr(interatom.spin_id2), repr(ave_dist)]) # No data, so fail! if not len(data): raise RelaxError("No data could be set.") # Print out. print("The following averaged distances have been set:\n") write_data(out=sys.stdout, headings=["Spin_ID_1", "Spin_ID_2", "Ave_distance(meters)"], data=data)
def set_dist(spin_id1=None, spin_id2=None, ave_dist=None, unit='meter'): """Set up the magnetic dipole-dipole interaction. @keyword spin_id1: The spin identifier string of the first spin of the pair. @type spin_id1: str @keyword spin_id2: The spin identifier string of the second spin of the pair. @type spin_id2: str @keyword ave_dist: The r^-3 averaged interatomic distance. @type ave_dist: float @keyword unit: The measurement unit. This can be either 'meter' or 'Angstrom'. @type unit: str """ # Check the units. if unit not in ['meter', 'Angstrom']: raise RelaxError("The measurement unit of '%s' must be one of 'meter' or 'Angstrom'." % unit) # Unit conversion. if unit == 'Angstrom': ave_dist = ave_dist * 1e-10 # Generate the selection objects. sel_obj1 = Selection(spin_id1) sel_obj2 = Selection(spin_id2) # Loop over the interatomic containers. data = [] for interatom in interatomic_loop(): # Get the spin info. mol_name1, res_num1, res_name1, spin1 = return_spin(interatom.spin_id1, full_info=True) mol_name2, res_num2, res_name2, spin2 = return_spin(interatom.spin_id2, full_info=True) # No match, either way. if not (sel_obj1.contains_spin(spin_num=spin1.num, spin_name=spin1.name, res_num=res_num1, res_name=res_name1, mol=mol_name1) and sel_obj2.contains_spin(spin_num=spin2.num, spin_name=spin2.name, res_num=res_num2, res_name=res_name2, mol=mol_name2)) and not (sel_obj2.contains_spin(spin_num=spin1.num, spin_name=spin1.name, res_num=res_num1, res_name=res_name1, mol=mol_name1) and sel_obj1.contains_spin(spin_num=spin2.num, spin_name=spin2.name, res_num=res_num2, res_name=res_name2, mol=mol_name2)): continue # Store the averaged distance. interatom.r = ave_dist # Store the data for the printout. data.append([repr(interatom.spin_id1), repr(interatom.spin_id2), repr(ave_dist)]) # No data, so fail! if not len(data): raise RelaxError("No data could be set.") # Print out. print("The following averaged distances have been set:\n") write_data(out=sys.stdout, headings=["Spin_ID_1", "Spin_ID_2", "Ave_distance(meters)"], data=data)
def pack_data(ri_id, ri_type, frq, values, errors, spin_ids=None, mol_names=None, res_nums=None, res_names=None, spin_nums=None, spin_names=None, spin_id=None, gen_seq=False, verbose=True): """Pack the relaxation data into the data pipe and spin containers. The values, errors, and spin_ids arguments must be lists of equal length or None. Each element i corresponds to a unique spin. @param ri_id: The relaxation data ID string. @type ri_id: str @param ri_type: The relaxation data type, ie 'R1', 'R2', or 'NOE'. @type ri_type: str @param frq: The spectrometer proton frequency in Hz. @type frq: float @keyword values: The relaxation data for each spin. @type values: None or list of float or float array @keyword errors: The relaxation data errors for each spin. @type errors: None or list of float or float array @keyword spin_ids: The list of spin ID strings. If the other spin identifiers are given, i.e. mol_names, res_nums, res_names, spin_nums, and/or spin_names, then this argument is not necessary. @type spin_ids: None or list of str @keyword mol_names: The list of molecule names used for creating the spin IDs (if not given) or for generating the sequence data. @type mol_names: None or list of str @keyword res_nums: The list of residue numbers used for creating the spin IDs (if not given) or for generating the sequence data. @type res_nums: None or list of str @keyword res_names: The list of residue names used for creating the spin IDs (if not given) or for generating the sequence data. @type res_names: None or list of str @keyword spin_nums: The list of spin numbers used for creating the spin IDs (if not given) or for generating the sequence data. @type spin_nums: None or list of str @keyword spin_names: The list of spin names used for creating the spin IDs (if not given) or for generating the sequence data. @type spin_names: None or list of str @keyword gen_seq: A flag which if True will cause the molecule, residue, and spin sequence data to be generated. @type gen_seq: bool @keyword verbose: A flag which if True will cause all relaxation data loaded to be printed out. @type verbose: bool """ # The number of spins. N = len(values) # Test the data. if errors != None and len(errors) != N: raise RelaxError( "The length of the errors arg (%s) does not match that of the value arg (%s)." % (len(errors), N)) if spin_ids and len(spin_ids) != N: raise RelaxError( "The length of the spin ID strings arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N)) if mol_names and len(mol_names) != N: raise RelaxError( "The length of the molecule names arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N)) if res_nums and len(res_nums) != N: raise RelaxError( "The length of the residue numbers arg (%s) does not match that of the value arg (%s)." % (len(res_nums), N)) if res_names and len(res_names) != N: raise RelaxError( "The length of the residue names arg (%s) does not match that of the value arg (%s)." % (len(res_names), N)) if spin_nums and len(spin_nums) != N: raise RelaxError( "The length of the spin numbers arg (%s) does not match that of the value arg (%s)." % (len(spin_nums), N)) if spin_names and len(spin_names) != N: raise RelaxError( "The length of the spin names arg (%s) does not match that of the value arg (%s)." % (len(spin_names), N)) # Generate some empty lists. if not mol_names: mol_names = [None] * N if not res_nums: res_nums = [None] * N if not res_names: res_names = [None] * N if not spin_nums: spin_nums = [None] * N if not spin_names: spin_names = [None] * N if errors == None: errors = [None] * N # Generate the spin IDs. if not spin_ids: spin_ids = [] for i in range(N): spin_ids.append( generate_spin_id_unique(spin_num=spin_nums[i], spin_name=spin_names[i], res_num=res_nums[i], res_name=res_names[i], mol_name=mol_names[i])) # Initialise the global data for the current pipe if necessary. if not hasattr(cdp, 'ri_type'): cdp.ri_type = {} if not hasattr(cdp, 'ri_ids'): cdp.ri_ids = [] # Set the spectrometer frequency. set_frequency(id=ri_id, frq=frq) # Update the global data. cdp.ri_ids.append(ri_id) cdp.ri_type[ri_id] = ri_type # The selection object. select_obj = None if spin_id: select_obj = Selection(spin_id) # Loop over the spin data. data = [] for i in range(N): # A selection union. select_id = spin_ids[i] if spin_id != None: select_id = "%s&%s" % (select_id, spin_id) # Get the corresponding spin container. match_mol_names, match_res_nums, match_res_names, spins = return_spin_from_selection( selection=select_id, full_info=True, multi=True) # No spin. if len(spins) == 0: continue # Check that multiple spins are not present. if len(spins) > 1: # Generate the list of spin IDs. new_ids = [] for j in range(len(spins)): new_ids.append( generate_spin_id_unique(mol_name=match_mol_names[j], res_num=match_res_nums[j], res_name=match_res_names[j], spin_num=spins[j].num, spin_name=spins[j].name)) # Raise the error. raise RelaxMultiSpinIDError(spin_ids[i], new_ids) # Check that at least one spin is present. if len(spins) == 0: raise RelaxNoSpinError(spin_ids[i]) # Loop over the spins. for j in range(len(spins)): # No match to the selection. if select_obj and not select_obj.contains_spin( spin_num=spins[j].num, spin_name=spins[j].name, res_num=res_nums[j], res_name=res_names[j], mol=mol_names[j]): continue # Initialise the spin data if necessary. if not hasattr(spins[j], 'ri_data') or spins[j].ri_data == None: spins[j].ri_data = {} if not hasattr(spins[j], 'ri_data_err') or spins[j].ri_data_err == None: spins[j].ri_data_err = {} # Update all data structures. spins[j].ri_data[ri_id] = values[i] spins[j].ri_data_err[ri_id] = errors[i] # Append the data for printing out. data.append([spin_ids[i], repr(values[i]), repr(errors[i])]) # Print out. if verbose: print( "\nThe following %s MHz %s relaxation data with the ID '%s' has been loaded into the relax data store:\n" % (frq / 1e6, ri_type, ri_id)) write_data(out=sys.stdout, headings=["Spin_ID", "Value", "Error"], data=data)
def interatomic_loop(selection1=None, selection2=None, pipe=None, skip_desel=True): """Generator function for looping over all the interatomic data containers. @keyword selection1: The optional spin ID selection of the first atom. @type selection1: str @keyword selection2: The optional spin ID selection of the second atom. @type selection2: str @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. @type pipe: str @keyword skip_desel: A flag which if True will cause only selected interatomic data containers to be returned. @type skip_desel: bool """ # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Parse the spin ID selection strings. select_obj = None select_obj1 = None select_obj2 = None if selection1 and selection2: select_obj1 = Selection(selection1) select_obj2 = Selection(selection2) elif selection1: select_obj = Selection(selection1) elif selection2: select_obj = Selection(selection2) # Loop over the containers, yielding them. for i in range(len(dp.interatomic)): # Skip deselected containers. if skip_desel and not dp.interatomic[i].select: continue # Aliases. interatom = dp.interatomic[i] mol_index1, res_index1, spin_index1 = dp.mol._spin_hash_lookup[interatom._spin_hash1] mol_index2, res_index2, spin_index2 = dp.mol._spin_hash_lookup[interatom._spin_hash2] mol1 = dp.mol[mol_index1] res1 = dp.mol[mol_index1].res[res_index1] spin1 = dp.mol[mol_index1].res[res_index1].spin[spin_index1] mol2 = dp.mol[mol_index2] res2 = dp.mol[mol_index2].res[res_index2] spin2 = dp.mol[mol_index2].res[res_index2].spin[spin_index2] # The different selection combinations. if select_obj: sel1 = select_obj.contains_spin(spin_name=spin1.name, spin_num=spin1.num, res_name=res1.name, res_num=res1.num, mol=mol1.name) sel2 = select_obj.contains_spin(spin_name=spin2.name, spin_num=spin2.num, res_name=res2.name, res_num=res2.num, mol=mol2.name) if select_obj1: sel11 = select_obj1.contains_spin(spin_name=spin1.name, spin_num=spin1.num, res_name=res1.name, res_num=res1.num, mol=mol1.name) sel12 = select_obj1.contains_spin(spin_name=spin2.name, spin_num=spin2.num, res_name=res2.name, res_num=res2.num, mol=mol2.name) if select_obj2: sel21 = select_obj2.contains_spin(spin_name=spin1.name, spin_num=spin1.num, res_name=res1.name, res_num=res1.num, mol=mol1.name) sel22 = select_obj2.contains_spin(spin_name=spin2.name, spin_num=spin2.num, res_name=res2.name, res_num=res2.num, mol=mol2.name) # Check that the selections are met. if select_obj: if not sel1 and not sel2: continue if select_obj1: if not (sel11 or sel12): continue if select_obj2: if not (sel21 or sel22): continue # Return the container. yield interatom
def pack_data(ri_id, ri_type, frq, values, errors, spin_ids=None, mol_names=None, res_nums=None, res_names=None, spin_nums=None, spin_names=None, spin_id=None, gen_seq=False, verbose=True): """Pack the relaxation data into the data pipe and spin containers. The values, errors, and spin_ids arguments must be lists of equal length or None. Each element i corresponds to a unique spin. @param ri_id: The relaxation data ID string. @type ri_id: str @param ri_type: The relaxation data type, ie 'R1', 'R2', or 'NOE'. @type ri_type: str @param frq: The spectrometer proton frequency in Hz. @type frq: float @keyword values: The relaxation data for each spin. @type values: None or list of float or float array @keyword errors: The relaxation data errors for each spin. @type errors: None or list of float or float array @keyword spin_ids: The list of spin ID strings. If the other spin identifiers are given, i.e. mol_names, res_nums, res_names, spin_nums, and/or spin_names, then this argument is not necessary. @type spin_ids: None or list of str @keyword mol_names: The list of molecule names used for creating the spin IDs (if not given) or for generating the sequence data. @type mol_names: None or list of str @keyword res_nums: The list of residue numbers used for creating the spin IDs (if not given) or for generating the sequence data. @type res_nums: None or list of str @keyword res_names: The list of residue names used for creating the spin IDs (if not given) or for generating the sequence data. @type res_names: None or list of str @keyword spin_nums: The list of spin numbers used for creating the spin IDs (if not given) or for generating the sequence data. @type spin_nums: None or list of str @keyword spin_names: The list of spin names used for creating the spin IDs (if not given) or for generating the sequence data. @type spin_names: None or list of str @keyword gen_seq: A flag which if True will cause the molecule, residue, and spin sequence data to be generated. @type gen_seq: bool @keyword verbose: A flag which if True will cause all relaxation data loaded to be printed out. @type verbose: bool """ # The number of spins. N = len(values) # Test the data. if errors != None and len(errors) != N: raise RelaxError("The length of the errors arg (%s) does not match that of the value arg (%s)." % (len(errors), N)) if spin_ids and len(spin_ids) != N: raise RelaxError("The length of the spin ID strings arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N)) if mol_names and len(mol_names) != N: raise RelaxError("The length of the molecule names arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N)) if res_nums and len(res_nums) != N: raise RelaxError("The length of the residue numbers arg (%s) does not match that of the value arg (%s)." % (len(res_nums), N)) if res_names and len(res_names) != N: raise RelaxError("The length of the residue names arg (%s) does not match that of the value arg (%s)." % (len(res_names), N)) if spin_nums and len(spin_nums) != N: raise RelaxError("The length of the spin numbers arg (%s) does not match that of the value arg (%s)." % (len(spin_nums), N)) if spin_names and len(spin_names) != N: raise RelaxError("The length of the spin names arg (%s) does not match that of the value arg (%s)." % (len(spin_names), N)) # Generate some empty lists. if not mol_names: mol_names = [None] * N if not res_nums: res_nums = [None] * N if not res_names: res_names = [None] * N if not spin_nums: spin_nums = [None] * N if not spin_names: spin_names = [None] * N if errors == None: errors = [None] * N # Generate the spin IDs. if not spin_ids: spin_ids = [] for i in range(N): spin_ids.append(generate_spin_id_unique(spin_num=spin_nums[i], spin_name=spin_names[i], res_num=res_nums[i], res_name=res_names[i], mol_name=mol_names[i])) # Initialise the global data for the current pipe if necessary. if not hasattr(cdp, 'ri_type'): cdp.ri_type = {} if not hasattr(cdp, 'ri_ids'): cdp.ri_ids = [] # Set the spectrometer frequency. set_frequency(id=ri_id, frq=frq) # Update the global data. cdp.ri_ids.append(ri_id) cdp.ri_type[ri_id] = ri_type # The selection object. select_obj = None if spin_id: select_obj = Selection(spin_id) # Loop over the spin data. data = [] for i in range(N): # Get the corresponding spin container. match_mol_names, match_res_nums, match_res_names, spins = return_spin_from_selection(spin_ids[i], full_info=True, multi=True) if spins in [None, []]: raise RelaxNoSpinError(spin_ids[i]) # Remove non-matching spins. if select_obj: new_spins = [] new_mol_names = [] new_res_nums = [] new_res_names = [] new_ids = [] for j in range(len(spins)): if select_obj.contains_spin(spin_num=spins[j].num, spin_name=spins[j].name, res_num=match_res_nums[j], res_name=match_res_names[j], mol=match_mol_names[j]): new_spins.append(spins[j]) new_mol_names.append(match_mol_names[j]) new_res_nums.append(match_res_nums[j]) new_res_names.append(match_res_names[j]) new_ids.append(generate_spin_id_unique(mol_name=mol_names[i], res_num=res_nums[i], res_name=res_names[i], spin_num=spins[j].num, spin_name=spins[j].name)) new_id = new_ids[0] # Aliases for normal operation. else: new_spins = spins new_mol_names = match_mol_names new_res_nums = match_res_nums new_res_names = match_res_names new_id = spin_ids[i] new_ids = None # Check that only a singe spin is present. if len(new_spins) > 1: if new_ids: raise RelaxMultiSpinIDError(spin_ids[i], new_ids) else: raise RelaxMultiSpinIDError(spin_ids[i], new_ids) if len(new_spins) == 0: raise RelaxNoSpinError(spin_ids[i]) # Loop over the spins. for j in range(len(new_spins)): # No match to the selection. if select_obj and not select_obj.contains_spin(spin_num=new_spins[j].num, spin_name=new_spins[j].name, res_num=new_res_nums[j], res_name=new_res_names[j], mol=new_mol_names[j]): continue # Initialise the spin data if necessary. if not hasattr(new_spins[j], 'ri_data') or new_spins[j].ri_data == None: new_spins[j].ri_data = {} if not hasattr(new_spins[j], 'ri_data_err') or new_spins[j].ri_data_err == None: new_spins[j].ri_data_err = {} # Update all data structures. new_spins[j].ri_data[ri_id] = values[i] new_spins[j].ri_data_err[ri_id] = errors[i] # Append the data for printing out. data.append([new_id, repr(values[i]), repr(errors[i])]) # Print out. if verbose: print("\nThe following %s MHz %s relaxation data with the ID '%s' has been loaded into the relax data store:\n" % (frq/1e6, ri_type, ri_id)) write_data(out=sys.stdout, headings=["Spin_ID", "Value", "Error"], data=data)
def interatomic_loop(selection1=None, selection2=None, pipe=None, skip_desel=True): """Generator function for looping over all the interatomic data containers. @keyword selection1: The optional spin ID selection of the first atom. @type selection1: str @keyword selection2: The optional spin ID selection of the second atom. @type selection2: str @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. @type pipe: str @keyword skip_desel: A flag which if True will cause only selected interatomic data containers to be returned. @type skip_desel: bool """ # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Parse the spin ID selection strings. select_obj = None select_obj1 = None select_obj2 = None if selection1 and selection2: select_obj1 = Selection(selection1) select_obj2 = Selection(selection2) elif selection1: select_obj = Selection(selection1) elif selection2: select_obj = Selection(selection2) # Loop over the containers, yielding them. for i in range(len(dp.interatomic)): # Skip deselected containers. if skip_desel and not dp.interatomic[i].select: continue # Aliases. interatom = dp.interatomic[i] mol_index1, res_index1, spin_index1 = cdp.mol._spin_id_lookup[interatom.spin_id1] mol_index2, res_index2, spin_index2 = cdp.mol._spin_id_lookup[interatom.spin_id2] mol1 = cdp.mol[mol_index1] res1 = cdp.mol[mol_index1].res[res_index1] spin1 = cdp.mol[mol_index1].res[res_index1].spin[spin_index1] mol2 = cdp.mol[mol_index2] res2 = cdp.mol[mol_index2].res[res_index2] spin2 = cdp.mol[mol_index2].res[res_index2].spin[spin_index2] # The different selection combinations. if select_obj: sel1 = select_obj.contains_spin(spin_name=spin1.name, spin_num=spin1.num, res_name=res1.name, res_num=res1.num, mol=mol1.name) sel2 = select_obj.contains_spin(spin_name=spin2.name, spin_num=spin2.num, res_name=res2.name, res_num=res2.num, mol=mol2.name) if select_obj1: sel11 = select_obj1.contains_spin(spin_name=spin1.name, spin_num=spin1.num, res_name=res1.name, res_num=res1.num, mol=mol1.name) sel12 = select_obj1.contains_spin(spin_name=spin2.name, spin_num=spin2.num, res_name=res2.name, res_num=res2.num, mol=mol2.name) if select_obj2: sel21 = select_obj2.contains_spin(spin_name=spin1.name, spin_num=spin1.num, res_name=res1.name, res_num=res1.num, mol=mol1.name) sel22 = select_obj2.contains_spin(spin_name=spin2.name, spin_num=spin2.num, res_name=res2.name, res_num=res2.num, mol=mol2.name) # Check that the selections are met. if select_obj: if not sel1 and not sel2: continue if select_obj1: if not (sel11 or sel12): continue if select_obj2: if not (sel21 or sel22): continue # Return the container. yield interatom