def write(file, dir=None, sep=None, mol_name_flag=True, res_num_flag=True, res_name_flag=True, spin_num_flag=True, spin_name_flag=True, force=False): """Write the molecule, residue, and/or sequence data. This calls the lib.io.write_spin_data() function to do most of the work. @param file: The name of the file to write the data to. @type file: str @keyword dir: The directory to contain the file (defaults to the current directory if None). @type dir: str or None @keyword sep: The column seperator which, if None, defaults to whitespace. @type sep: str or None @keyword mol_name_flag: A flag which if True will cause the molecule name column to be written. @type mol_name_flag: bool @keyword res_num_flag: A flag which if True will cause the residue number column to be written. @type res_num_flag: bool @keyword res_name_flag: A flag which if True will cause the residue name column to be written. @type res_name_flag: bool @keyword spin_name_flag: A flag which if True will cause the spin name column to be written. @type spin_name_flag: bool @keyword spin_num_flag: A flag which if True will cause the spin number column to be written. @keyword force: A flag which if True will cause an existing file to be overwritten. @type force: bin """ # Test if the sequence data is loaded. if not count_spins(): raise RelaxNoSequenceError # Init the data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] # Spin loop. for spin, mol_name, res_num, res_name in spin_loop(full_info=True): mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin.num) spin_names.append(spin.name) # Remove unwanted data. if not mol_name_flag: mol_names = None if not res_num_flag: res_nums = None if not res_name_flag: res_names = None if not spin_num_flag: spin_nums = None if not spin_name_flag: spin_names = None # Write the data. write_spin_data(file=file, dir=dir, sep=sep, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, force=force)
def display(sep=None, mol_name_flag=True, res_num_flag=True, res_name_flag=True, spin_num_flag=True, spin_name_flag=True): """Display the current spin selections. @keyword sep: The column seperator which, if None, defaults to whitespace. @type sep: str or None @keyword mol_name_flag: A flag which if True will cause the molecule name column to be written. @type mol_name_flag: bool @keyword res_num_flag: A flag which if True will cause the residue number column to be written. @type res_num_flag: bool @keyword res_name_flag: A flag which if True will cause the residue name column to be written. @type res_name_flag: bool @keyword spin_name_flag: A flag which if True will cause the spin name column to be written. @type spin_name_flag: bool @keyword spin_num_flag: A flag which if True will cause the spin number column to be written. @type spin_num_flag: bool """ # Test if the sequence data is loaded. check_mol_res_spin_data() # Init the data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] selections = [] # Spin loop. for spin, mol_name, res_num, res_name in spin_loop(full_info=True, skip_desel=False): mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin.num) spin_names.append(spin.name) selections.append(spin.select) # Remove unwanted data. if not mol_name_flag: mol_names = None if not res_num_flag: res_nums = None if not res_name_flag: res_names = None if not spin_num_flag: spin_nums = None if not spin_name_flag: spin_names = None # Write the data. write_spin_data(file=sys.stdout, sep=sep, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=selections, data_name="selection")
def read(file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, sep=None, spin_id=None): """Read the molecule, residue, and/or spin sequence data from file. @param file: The name of the file to open. @type file: str @param 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_id_col: The column containing the spin ID strings. If supplied, the mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col arguments must be none. @type spin_id_col: int or None @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None. @type mol_name_col: int or None @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None. @type res_name_col: int or None @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None. @type res_num_col: int or None @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None. @type spin_name_col: int or None @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None. @type spin_num_col: int or None @keyword sep: The column separator which, if None, defaults to whitespace. @type sep: str or None @keyword spin_id: The spin ID string used to restrict data loading to a subset of all spins. @type spin_id: None or str """ # Test if the current data pipe exists. check_pipe() # Test if sequence data already exists. if exists_mol_res_spin_data(): raise RelaxSequenceError # Init the data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] # Generate the sequence. for mol_name, res_num, res_name, spin_num, spin_name in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, sep=sep, spin_id=spin_id): # Add the spin. generate(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) # Append the new spin. mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin_num) spin_names.append(spin_name) # No data, so fail. if not len(spin_names): raise RelaxError("No sequence data could be loaded.") # Write the data. write_spin_data(sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names)
def write_data(param=None, file=None, scaling=1.0, bc=False, return_value=None, return_data_desc=None, comment=None): """The function which actually writes the data. @keyword param: The parameter to write. @type param: str @keyword file: The file to write the data to. @type file: str @keyword scaling: The value to scale the parameter by. @type scaling: float @keyword bc: A flag which if True will cause the back calculated values to be written. @type bc: bool @keyword return_value: An optional function which if supplied will override the default value returning function. @type return_value: None or func @keyword return_data_desc: An optional function which if supplied will override the default parameter description returning function. @type return_data_desc: None or func @keyword comment: Text which will be added to the start of the file as comments. All lines will be prefixed by '# '. @type comment: str """ # The specific analysis API object. api = return_api() # Get the value and error returning function parameter description function if required. if not return_value: return_value = api.return_value if not return_data_desc: return_data_desc = api.return_data_desc # Format string. format = "%-30s%-30s" # Init the data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] values = [] errors = [] # Get the parameter description and add it to the file. desc = return_data_desc(param) if desc: file.write("# Parameter description: %s.\n" % desc) file.write("#\n") # The comments. if comment: # Split up the lines. lines = comment.splitlines() # Write out. for line in lines: file.write("# %s\n" % line) file.write("#\n") # Determine the data type, check the data, and set up the dictionary type data keys. data_names = 'value' error_names = 'error' data_type = None for spin, mol_name, res_num, res_name in spin_loop(full_info=True): # Get the value and error. value, error = return_value(spin, param, bc=bc) # Dictionary type data. if isinstance(value, dict): # Sanity check. if not data_type in [None, 'dict']: raise RelaxError("Mixed data types.") data_type = 'dict' # Initialise the structures. if not isinstance(data_names, list): data_names = [] error_names = [] # Sort the keys. keys = sorted(value.keys()) # Loop over the keys. for key in keys: # Add the data and error names if new. if key not in data_names: data_names.append(key) error_names.append('sd(%s)' % key) # List type data. elif isinstance(value, list): # Sanity check. if not data_type in [None, 'list']: raise RelaxError("Mixed data types.") data_type = 'list' # Initialise the structures. if not isinstance(data_names, list): data_names = [] error_names = [] # Check the length. elif len(data_names) != len(value): raise RelaxError("The list type data has an inconsistent number of elements between different spin systems.") # Loop over the data. for i in range(len(value)): # The data and error names. data_names.append('value_%s' % i) error_names.append('error_%s' % i) # None. elif value == None: pass # Simple values. else: # Sanity check. if not data_type in [None, 'value']: raise RelaxError("Mixed data types.") data_type = 'value' # Pack the data. for spin, mol_name, res_num, res_name in spin_loop(full_info=True): # Get the value and error. value, error = return_value(spin, param, bc=bc) # Append the spin data (scaled). mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin.num) spin_names.append(spin.name) # Dictionary type data. if data_type == 'dict': # Initialise the lists. values.append([]) errors.append([]) # Loop over the keys. for key in data_names: # Append the scaled values and errors. if value == None or key not in value: values[-1].append(None) else: values[-1].append(scale(value[key], scaling)) if error == None or key not in error: errors[-1].append(None) else: errors[-1].append(scale(error[key], scaling)) # List type data. elif data_type == 'list': # Initialise the lists. values.append([]) errors.append([]) # Loop over the data. for i in range(len(data_names)): # Append the scaled values and errors. if value == None: values[-1].append(None) else: values[-1].append(scale(value[i], scaling)) if error == None: errors[-1].append(None) else: errors[-1].append(scale(error[i], scaling)) # Simple values. else: # Append the scaled values and errors. values.append(scale(value, scaling)) errors.append(scale(error, scaling)) # Replace all spaces " " with "_" in data_names list. if isinstance(data_names, list): for i, data_name in enumerate(data_names): data_str = data_name.replace(" ", "_") # Replace string. data_names[i] = data_str # Replace all spaces " " with "_" in error_names list. if isinstance(error_names, list): for i, error_name in enumerate(error_names): error_str = error_name.replace(" ", "_") # Replace string. error_names[i] = error_str # Write the data. write_spin_data(file, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name=data_names, error=errors, error_name=error_names)
def read(param=None, scaling=1.0, file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, data_col=None, error_col=None, sep=None, spin_id=None): """Read spin specific data values from a file. @keyword param: The name of the parameter to read. @type param: str @keyword scaling: A scaling factor by which all read values are multiplied by. @type scaling: float @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_id_col: The column containing the spin ID strings. If supplied, the mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col arguments must be none. @type spin_id_col: int or None @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None. @type mol_name_col: int or None @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None. @type res_name_col: int or None @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None. @type res_num_col: int or None @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None. @type spin_name_col: int or None @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None. @type spin_num_col: int or None @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 spin_id: The spin ID string. @type spin_id: None or str """ # Test if the current pipe exists. check_pipe() # Test if sequence data is loaded. if not exists_mol_res_spin_data(): raise RelaxNoSequenceError # Minimisation statistic flag. min_stat = False # Alias specific analysis API object method. api = return_api() return_value = api.return_value # Specific set function. set_fn = set # Test data corresponding to param already exists. for spin in spin_loop(): # Skip deselected spins. if not spin.select: continue # Get the value and error. value, error = return_value(spin, param) # Data exists. if value != None or error != None: raise RelaxValueError(param) # Loop over the data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] values = [] errors = [] for data in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, data_col=data_col, error_col=error_col, sep=sep, spin_id=spin_id): # Unpack. if data_col and error_col: mol_name, res_num, res_name, spin_num, spin_name, value, error = data elif data_col: mol_name, res_num, res_name, spin_num, spin_name, value = data error = None else: mol_name, res_num, res_name, spin_num, spin_name, error = data value = None # Set the value. id = generate_spin_id_unique(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) set_fn(val=value, error=error, param=param, spin_id=id) # Append the data for printout. mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin_num) spin_names.append(spin_name) values.append(value) errors.append(error) # Print out. write_spin_data(file=sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name=param, error=errors, error_name='%s_error'%param) # Reset the minimisation statistics. if api.set(param) == 'min': minimise.reset_min_stats()
def read(align_id=None, file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, data_col=None, error_col=None, sep=None, spin_id=None): """Read the PCS data from file. @param align_id: The alignment tensor ID string. @type align_id: str @param file: The name of the file to open. @type file: str @param dir: The directory containing the file (defaults to the current directory if None). @type dir: str or None @param file_data: An alternative 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_id_col: The column containing the spin ID strings. If supplied, the mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col arguments must be none. @type spin_id_col: int or None @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None. @type mol_name_col: int or None @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None. @type res_name_col: int or None @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None. @type res_num_col: int or None @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None. @type spin_name_col: int or None @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None. @type spin_num_col: int or None @keyword data_col: The column containing the PCS data in Hz. @type data_col: int or None @keyword error_col: The column containing the PCS errors. @type error_col: int or None @keyword sep: The column separator which, if None, defaults to whitespace. @type sep: str or None @keyword spin_id: The spin ID string used to restrict data loading to a subset of all spins. @type spin_id: None or str """ # Check the pipe setup. check_pipe_setup(sequence=True) # Test if sequence data exists. if not exists_mol_res_spin_data(): raise RelaxNoSequenceError # 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.") # Spin specific data. ##################### # Loop over the PCS data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] values = [] errors = [] for data in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, data_col=data_col, error_col=error_col, sep=sep, spin_id=spin_id): # Unpack. if data_col and error_col: mol_name, res_num, res_name, spin_num, spin_name, value, error = data elif data_col: mol_name, res_num, res_name, spin_num, spin_name, value = data error = None else: mol_name, res_num, res_name, spin_num, spin_name, error = data value = None # 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 corresponding spin container. id = generate_spin_id_unique(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) spin = return_spin(id) if spin == None and spin_id and spin_id[0] == '@': # Allow spin IDs of atom names to be used to specify multi column data. spin = return_spin(id+spin_id) if spin == None: warn(RelaxNoSpinWarning(id)) continue # Add the data. if data_col: # Initialise. if not hasattr(spin, 'pcs'): spin.pcs = {} # Append the value. spin.pcs[align_id] = value # Add the error. if error_col: # Initialise. if not hasattr(spin, 'pcs_err'): spin.pcs_err = {} # Append the error. spin.pcs_err[align_id] = error # Append the data for printout. mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin_num) spin_names.append(spin_name) values.append(value) errors.append(error) # Print out. write_spin_data(file=sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name='PCSs', error=errors, error_name='PCS_error') # Global (non-spin specific) data. ################################## # No data, so return. if not len(values): return # Initialise. if not hasattr(cdp, 'align_ids'): cdp.align_ids = [] if not hasattr(cdp, 'pcs_ids'): cdp.pcs_ids = [] # Add the PCS id string. if align_id not in cdp.align_ids: cdp.align_ids.append(align_id) if align_id not in cdp.pcs_ids: cdp.pcs_ids.append(align_id)
def write(align_id=None, file=None, dir=None, bc=False, force=False): """Display the PCS data corresponding to the alignment ID. @keyword align_id: The alignment tensor ID string. @type align_id: str @keyword file: The file name or object to write to. @type file: str or file object @keyword dir: The name of the directory to place the file into (defaults to the current directory). @type dir: str @keyword bc: The back-calculation flag which if True will cause the back-calculated rather than measured data to be written. @type bc: bool @keyword force: A flag which if True will cause any pre-existing file to be overwritten. @type force: bool """ # Check the pipe setup. check_pipe_setup(sequence=True, pcs_id=align_id, pcs=True) # Open the file for writing. file = open_write_file(file, dir, force) # Loop over the spins and collect the data. mol_names = [] res_nums = [] res_names = [] spin_nums = [] spin_names = [] values = [] errors = [] for spin, mol_name, res_num, res_name in spin_loop(full_info=True): # Skip deselected spins. if not spin.select: continue # Skip spins with no PCSs. if not bc and (not hasattr(spin, 'pcs') or not align_id in spin.pcs): continue elif bc and (not hasattr(spin, 'pcs_bc') or align_id not in spin.pcs_bc): continue # Append the spin data. mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(spin.num) spin_names.append(spin.name) # The value. if bc: values.append(spin.pcs_bc[align_id]) else: values.append(spin.pcs[align_id]) # The error. if hasattr(spin, 'pcs_err') and align_id in spin.pcs_err: errors.append(spin.pcs_err[align_id]) else: errors.append(None) # Write out. write_spin_data(file=file, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name='PCSs', error=errors, error_name='PCS_error')