def test_load_and_modify(self): """The modification of an unpickled and restored relax data storage singleton. This tests the normal operation of the pipe_control.state.load() function. """ # Test the contents of the empty singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y')) # Load the state. self.state.load_state(state='basic_single_pipe', dir=status.install_path + sep + 'test_suite' + sep + 'shared_data' + sep + 'saved_states') # Add a new data pipe and some data to it. ds.add('new', 'jw_mapping') cdp.z = [None, None] # Get the data pipes. dp_orig = pipes.get_pipe('orig') dp_new = pipes.get_pipe('new') # Test the contents of the restored singleton (with subsequent data added). self.assert_('orig' in ds) self.assert_('new' in ds) self.assertEqual(pipes.cdp_name(), 'new') self.assertEqual(dp_orig.x, 1) self.assertEqual(ds.y, 'Hello') self.assertEqual(dp_new.z, [None, None])
def test_load_and_modify(self): """The modification of an unpickled and restored relax data storage singleton. This tests the normal operation of the pipe_control.state.load() function. """ # Test the contents of the empty singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y')) # Load the state. self.state.load_state(state='basic_single_pipe', dir=status.install_path+sep+'test_suite'+sep+'shared_data'+sep+'saved_states') # Add a new data pipe and some data to it. ds.add('new', 'jw_mapping') cdp.z = [None, None] # Get the data pipes. dp_orig = pipes.get_pipe('orig') dp_new = pipes.get_pipe('new') # Test the contents of the restored singleton (with subsequent data added). self.assert_('orig' in ds) self.assert_('new' in ds) self.assertEqual(pipes.cdp_name(), 'new') self.assertEqual(dp_orig.x, 1) self.assertEqual(ds.y, 'Hello') self.assertEqual(dp_new.z, [None, None])
def action_spin_spin_copy(self, event): """Wrapper method. @param event: The wx event. @type event: wx event """ # Launch the user function wizard. uf_store['spin.copy'](wx_parent=self.gui.spin_viewer, pipe_from=cdp_name(), spin_from=self.info['id'], pipe_to=cdp_name())
def exists_data(pipe=None): """Determine if any interatomic data exists. @keyword pipe: The data pipe in which the interatomic data will be checked for. @type pipe: str @return: The answer to the question about the existence of data. @rtype: bool """ # The current data pipe. if pipe == None: pipe = pipes.cdp_name() # Test the data pipe. pipes.test(pipe) # Get the data pipe. dp = pipes.get_pipe(pipe) # The interatomic data structure is empty. if dp.interatomic.is_empty(): return False # Otherwise. return True
def return_interatom_list(spin_id=None, pipe=None): """Return the list of interatomic data containers for the given spin. @keyword spin_id: The spin ID string. @type spin_id: str @keyword pipe: The data pipe holding the container. This defaults to the current data pipe. @type pipe: str or None @return: The list of matching interatomic data containers, if any exist. @rtype: list of data.interatomic.InteratomContainer instances """ # Check. if spin_id == None: raise RelaxError("The spin ID must be supplied.") # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Initialise. interatoms = [] # Find and append all containers. for i in range(len(dp.interatomic)): if id_match(spin_id=spin_id, interatom=dp.interatomic[i], pipe=pipe) or id_match(spin_id=spin_id, interatom=dp.interatomic[i], pipe=pipe): interatoms.append(dp.interatomic[i]) # Return the list of containers. return interatoms
def check_structure_func(pipe_name=None): """Test if structural data is present. @return: The initialised RelaxError object or nothing. @rtype: None or RelaxError instance """ # Defaults. if pipe_name == None: pipe_name = cdp_name() # Get the data pipe. dp = get_pipe(pipe_name) # Test if the structure exists. if not hasattr(dp, 'structure'): return RelaxError( "No structural data is present in the current data pipe.") # Check for models: if not dp.structure.num_models(): return RelaxError( "The structural object in the current data pipe contains no models." ) # Check for molecules. if not dp.structure.num_molecules(): return RelaxError( "The structural object in the current data pipe contains no molecules." )
def pipe_switch(self, pipe=None): """Switch the page to the given or current data pipe. @keyword pipe: The pipe associated with the page to switch to. If not supplied, the current data pipe will be used. @type pipe: str or None """ # The data pipe. if pipe == None: pipe = pipes.cdp_name() # No pipes to switch to. if pipe == None: return # Find the page. index = self.page_index_from_bundle(pipes.get_bundle(pipe)) # No matching page. if index == None: return # The page is already active, so do nothing. if self._current == index: return # Switch to the page. self.switch_page(index) # Notify the observers of the change. status.observers.gui_analysis.notify()
def check_structure_func(pipe_name=None): """Test if structural data is present. @return: The initialised RelaxError object or nothing. @rtype: None or RelaxError instance """ # Defaults. if pipe_name == None: pipe_name = cdp_name() # Get the data pipe. dp = get_pipe(pipe_name) # Test if the structure exists. if not hasattr(dp, 'structure'): return RelaxError("No structural data is present in the current data pipe.") # Check for models: if not dp.structure.num_models(): return RelaxError("The structural object in the current data pipe contains no models.") # Check for molecules. if not dp.structure.num_molecules(): return RelaxError("The structural object in the current data pipe contains no molecules.")
def exists_data(pipe=None): """Determine if any interatomic data exists. @keyword pipe: The data pipe in which the interatomic data will be checked for. @type pipe: str @return: The answer to the question about the existence of data. @rtype: bool """ # The current data pipe. if pipe == None: pipe = pipes.cdp_name() # Test the data pipe. check_pipe(pipe) # Get the data pipe. dp = pipes.get_pipe(pipe) # The interatomic data structure is empty. if dp.interatomic.is_empty(): return False # Otherwise. return True
def return_interatom(spin_hash1=None, spin_hash2=None, pipe=None): """Return the list of interatomic data containers for the two spins. @keyword spin_hash1: The unique spin hash for the first atom. @type spin_hash1: str @keyword spin_hash2: The unique spin hash for the second atom. @type spin_hash2: str @keyword pipe: The data pipe holding the container. Defaults to the current data pipe. @type pipe: str or None @return: The matching interatomic data container, if it exists. @rtype: data.interatomic.InteratomContainer instance or None """ # Checks. if spin_hash1 == None: raise RelaxError("The first spin hash must be supplied.") if spin_hash2 == None: raise RelaxError("The second spin hash must be supplied.") # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Return the matching container. for i in range(len(dp.interatomic)): if spin_hash1 != spin_hash2 and spin_hash1 in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2] and spin_hash2 in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2]: return dp.interatomic[i] # No matchs. return None
def return_interatom_list(spin_hash=None, pipe=None): """Return the list of interatomic data containers for the given spin. @keyword spin_hash: The unique spin hash. @type spin_hash: str @keyword pipe: The data pipe holding the container. This defaults to the current data pipe. @type pipe: str or None @return: The list of matching interatomic data containers, if any exist. @rtype: list of data.interatomic.InteratomContainer instances """ # Check. if spin_hash == None: raise RelaxError("The unique spin hash must be supplied.") # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Initialise. interatoms = [] # Find and append all containers. for i in range(len(dp.interatomic)): if spin_hash in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2]: interatoms.append(dp.interatomic[i]) # Return the list of containers. return interatoms
def return_interatom(spin_id1=None, spin_id2=None, pipe=None): """Return the list of interatomic data containers for the two spins. @keyword spin_id1: The spin ID string of the first atom. @type spin_id1: str @keyword spin_id2: The spin ID string of the second atom. @type spin_id2: str @keyword pipe: The data pipe holding the container. Defaults to the current data pipe. @type pipe: str or None @return: The matching interatomic data container, if it exists. @rtype: data.interatomic.InteratomContainer instance or None """ # Checks. if spin_id1 == None: raise RelaxError("The first spin ID must be supplied.") if spin_id2 == None: raise RelaxError("The second spin ID must be supplied.") # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Return the matching container. for i in range(len(dp.interatomic)): if id_match(spin_id=spin_id1, interatom=dp.interatomic[i], pipe=pipe) and id_match(spin_id=spin_id2, interatom=dp.interatomic[i], pipe=pipe): return dp.interatomic[i] # No matchs. return None
def update_pipes(self, event=None): """Update the spin view data pipe selector. @keyword event: The wx event. @type event: wx event """ # Change the cursor to busy. wx.BeginBusyCursor() # Init. pipe_switch = False # The selected pipe. if event: # The name of the selected pipe. pipe = gui_to_str(self.pipe_name.GetString(event.GetSelection())) # A pipe change. if pipe != cdp_name(): pipe_switch = True else: pipe = cdp_name() if not pipe: pipe = '' # Clear the previous data. self.pipe_name.Clear() # The list of pipe names. for name in pipe_names(): self.pipe_name.Append(str_to_gui(name)) # Switch. if pipe_switch: # Switch data pipes. self.gui.interpreter.apply('pipe.switch', pipe) # Update the tree view. self.tree_panel.update() # Set the pipe name to the cdp. self.pipe_name.SetValue(str_to_gui(pipe)) # Reset the cursor. if wx.IsBusy(): wx.EndBusyCursor()
def __init__(self, pipe_name=None, pipe_bundle=None, file_root='noe', results_dir=None, save_state=True): """Perform relaxation curve fitting. To use this auto-analysis, a data pipe with all the required data needs to be set up. This data pipe should contain the following: - All the spins loaded. - Unresolved spins deselected. - The NOE peak intensities from the saturated and reference spectra. - Either the baseplane noise RMDS values should be set or replicated spectra loaded. @keyword pipe_name: The name of the data pipe containing all of the data for the analysis. @type pipe_name: str @keyword pipe_bundle: The data pipe bundle to associate all spawned data pipes with. @type pipe_bundle: str @keyword file_root: File root of the output filea. @type file_root: str @keyword results_dir: The directory where results files are saved. @type results_dir: str @keyword save_state: A flag which if True will cause a relax save state to be created at the end of the analysis. @type save_state: bool """ # Execution lock. status.exec_lock.acquire(pipe_bundle, mode='auto-analysis') # Set up the analysis status object. status.init_auto_analysis(pipe_bundle, type='noe') status.current_analysis = pipe_bundle # Store the args. self.save_state = save_state self.pipe_name = pipe_name self.pipe_bundle = pipe_bundle self.file_root = file_root self.results_dir = results_dir if self.results_dir: self.grace_dir = results_dir + sep + 'grace' else: self.grace_dir = 'grace' # Data checks. self.check_vars() # Set the data pipe to the current data pipe. if self.pipe_name != cdp_name(): switch(self.pipe_name) # Load the interpreter. self.interpreter = Interpreter(show_script=False, quit=False, raise_relax_error=True) self.interpreter.populate_self() self.interpreter.on(verbose=False) # Execute. self.run() # Finish and unlock execution. status.auto_analysis[self.pipe_bundle].fin = True status.current_analysis = None status.exec_lock.release()
def test_current(self): """Get the current data pipe. The function used is pipe_control.pipes.cdp_name(). """ # Test the current pipe. self.assertEqual(pipes.cdp_name(), 'orig')
def test_switch(self): """Test the switching of the current data pipe. The function tested is pipe_control.pipes.switch(). """ # Switch to the 'orig' data pipe. pipes.switch('orig') # Test the current data pipe. self.assertEqual(pipes.cdp_name(), 'orig') # Switch to the 'empty' data pipe. pipes.switch('empty') # Test the current data pipe. self.assertEqual(pipes.cdp_name(), 'empty')
def copy_frequencies(pipe_from=None, pipe_to=None, id=None): """Copy the frequency information from one data pipe to another. @keyword pipe_from: The data pipe to copy the frequency information from. This defaults to the current data pipe. @type pipe_from: str @keyword pipe_to: The data pipe to copy the frequency information to. This defaults to the current data pipe. @type pipe_to: str @param id: The experiment ID string. @type id: str """ # Defaults. if pipe_from == None and pipe_to == None: raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.") elif pipe_from == None: pipe_from = pipes.cdp_name() elif pipe_to == None: pipe_to = pipes.cdp_name() # Test if the pipe_from and pipe_to data pipes exist. check_pipe(pipe_from) check_pipe(pipe_to) # Get the data pipes. dp_from = pipes.get_pipe(pipe_from) dp_to = pipes.get_pipe(pipe_to) # Test if the pipe_from pipe has frequency data. if not hasattr(dp_from, 'spectrometer_frq'): raise RelaxNoFrqError(pipe_from) elif id not in dp_from.spectrometer_frq: raise RelaxNoFrqError(pipe_from, id=id) # Set up the data structures if missing. if not hasattr(dp_to, 'spectrometer_frq'): dp_to.spectrometer_frq = {} dp_to.spectrometer_frq_list = [] dp_to.spectrometer_frq_count = 0 # Copy the frequency. dp_to.spectrometer_frq[id] = dp_from.spectrometer_frq[id] # New frequency. if dp_to.spectrometer_frq[id] not in dp_to.spectrometer_frq_list: dp_to.spectrometer_frq_list.append(dp_to.spectrometer_frq[id]) dp_to.spectrometer_frq_count += 1
def load_spins_wizard(self, event=None): """The spin loading wizard. @keyword event: The wx event. @type event: wx event """ # No current data pipe. if not cdp_name(): gui_raise(RelaxNoPipeError()) return # Change the cursor to busy. wx.BeginBusyCursor() # Initialise a wizard. self.wizard = Wiz_window(parent=self, size_x=1000, size_y=800, title="Load spins") self.page_indices = {} # The loading method page. self.page_method = Load_method_page(self.wizard) self.page_indices['method'] = self.wizard.add_page(self.page_method, apply_button=True, skip_button=False) self.wizard.set_seq_next_fn(self.page_indices['method'], self.wizard_page_after_load_method) # The sequence.read page. page = uf_store['sequence.read'].create_page(self.wizard) self.page_indices['sequence.read'] = self.wizard.add_page(page, skip_button=True) self.wizard.set_seq_next_fn(self.page_indices['sequence.read'], self.wizard_page_after_sequence_read) # The structure.read_pdb page. page = uf_store['structure.read_pdb'].create_page(self.wizard) self.page_indices['structure.read_pdb'] = self.wizard.add_page(page, skip_button=True) self.wizard.set_seq_next_fn(self.page_indices['structure.read_pdb'], self.wizard_page_after_structure_read) # The structure.read_xyz page. page = uf_store['structure.read_xyz'].create_page(self.wizard) self.page_indices['structure.read_xyz'] = self.wizard.add_page(page, skip_button=True) self.wizard.set_seq_next_fn(self.page_indices['structure.read_xyz'], self.wizard_page_after_structure_read) # The spectrum.read_spins page. page = uf_store['spectrum.read_spins'].create_page(self.wizard) self.page_indices['spectrum.read_spins'] = self.wizard.add_page(page, skip_button=True) self.wizard.set_seq_next_fn(self.page_indices['spectrum.read_spins'], self.wizard_page_after_sequence_read) # The structure.load_spins page. page = uf_store['structure.load_spins'].create_page(self.wizard) self.page_indices['structure.load_spins'] = self.wizard.add_page(page) # The termination page. page = Finish_page(self.wizard) self.page_indices['fin'] = self.wizard.add_page(page, apply_button=False, skip_button=False) # Reset the cursor. if wx.IsBusy(): wx.EndBusyCursor() # Run the wizard. self.wizard.run()
def update_grid_safe(self): """Update the grid with the pipe data.""" # First freeze the grid, so that the GUI element doesn't update until the end. self.grid.Freeze() # Acquire the pipe lock. status.pipe_lock.acquire('pipe editor window') # Delete the rows, leaving a single row. self.grid.DeleteRows(numRows=self.grid.GetNumberRows()-1) # Clear the contents of the first row. for i in range(self.grid.GetNumberCols()): self.grid.SetCellValue(0, i, str_to_gui("")) # The data pipes. pipe_list = pipe_names() n = len(pipe_list) # Append the appropriate number of rows. if n >= 1: self.grid.AppendRows(numRows=n-1) # Loop over the data pipes. for i in range(n): # Set the pipe name. self.grid.SetCellValue(i, 0, str_to_gui(pipe_list[i])) # Set the pipe type. self.grid.SetCellValue(i, 1, str_to_gui(get_type(pipe_list[i]))) # Set the pipe bundle. self.grid.SetCellValue(i, 2, str_to_gui(get_bundle(pipe_list[i]))) # Set the current pipe. if pipe_list[i] == cdp_name(): self.grid.SetCellValue(i, 3, str_to_gui("cdp")) # Set the tab the pipe belongs to. self.grid.SetCellValue(i, 4, str_to_gui(self.gui.analysis.page_name_from_bundle(get_bundle(pipe_list[i])))) # Set the grid properties once finalised. for i in range(self.grid.GetNumberRows()): # Row properties. self.grid.SetRowSize(i, 27) # Loop over the columns. for j in range(self.grid.GetNumberCols()): # Cell properties. self.grid.SetReadOnly(i, j) # Release the lock. status.pipe_lock.release('pipe editor window') # Unfreeze. self.grid.Thaw()
def update_mf(self): """Update the model-free specific elements.""" # The analysis key. key = self.analysis_key() if not key: return # Loaded a finished state, so fill all gauges and return. elif not key in status.auto_analysis and cdp_name() == 'final': wx.CallAfter(self.mc_gauge_mf.SetValue, 100) wx.CallAfter(self.progress_gauge_mf.SetValue, 100) wx.CallAfter(self.main_gauge.SetValue, 100) return # Nothing to do. if not key in status.auto_analysis: wx.CallAfter(self.mc_gauge_mf.SetValue, 0) wx.CallAfter(self.progress_gauge_mf.SetValue, 0) wx.CallAfter(self.main_gauge.SetValue, 0) return # Set the diffusion model. wx.CallAfter(self.global_model_mf.SetValue, str_to_gui(status.auto_analysis[key].diff_model)) # Update the progress gauge for the local tm model. if status.auto_analysis[key].diff_model == 'local_tm': if status.auto_analysis[key].current_model: # Current model. no = int(status.auto_analysis[key].current_model[2:]) # Total selected models. total_models = len(status.auto_analysis[key].local_tm_models) # Update the progress bar. percent = int(100 * no / float(total_models)) wx.CallAfter(self.progress_gauge_mf.SetValue, percent) # Sphere to ellipsoid Models. elif status.auto_analysis[key].diff_model in ['sphere', 'prolate', 'oblate', 'ellipsoid']: # Check that the round has been set. if status.auto_analysis[key].round == None: wx.CallAfter(self.progress_gauge_mf.SetValue, 0) else: # The round as a percentage. percent = int(100 * (status.auto_analysis[key].round + 1) / (status.auto_analysis[key].max_iter + 1)) # Update the progress bar. wx.CallAfter(self.progress_gauge_mf.SetValue, percent) # Monte Carlo simulations. if status.auto_analysis[key].mc_number: # The simulation number as a percentage. percent = int(100 * (status.auto_analysis[key].mc_number + 1) / cdp.sim_number) # Update the progress bar. wx.CallAfter(self.mc_gauge_mf.SetValue, percent)
def write(file="results", dir=None, force=False, compress_type=1, verbosity=1): """Create the results file.""" # Test if the current data pipe exists. check_pipe() # The special data pipe name directory. if dir == 'pipe_name': dir = pipes.cdp_name() # Open the file for writing. results_file = open_write_file(file_name=file, dir=dir, force=force, compress_type=compress_type, verbosity=verbosity) # Write the results. ds.to_xml(results_file, pipes=pipes.cdp_name()) # Close the results file. results_file.close()
def create(algor='LM', dir=None, force=False): """Create the Dasha script file 'dasha_script' for controlling the program. @keyword algor: The optimisation algorithm to use. This can be the Levenberg-Marquardt algorithm 'LM' or the Newton-Raphson algorithm 'NR'. @type algor: str @keyword dir: The optional directory to place the script into. @type dir: str or None @keyword force: A flag which if True will cause any pre-existing file to be overwritten. @type force: bool """ # Test if the current pipe exists. check_pipe() # Test if sequence data is loaded. if not exists_mol_res_spin_data(): raise RelaxNoSequenceError # Determine the parameter set. model_type = determine_model_type() # Test if diffusion tensor data for the data_pipe exists. if model_type != 'local_tm' and not hasattr(cdp, 'diff_tensor'): raise RelaxNoTensorError('diffusion') # Test if the PDB file has been loaded (for the spheroid and ellipsoid). if model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere' and not hasattr( cdp, 'structure'): raise RelaxNoPdbError # Test the optimisation algorithm. if algor not in ['LM', 'NR']: raise RelaxError( "The Dasha optimisation algorithm '%s' is unknown, it should either be 'LM' or 'NR'." % algor) # Deselect certain spins. __deselect_spins() # Directory creation. if dir == None: dir = pipes.cdp_name() mkdir_nofail(dir, verbosity=0) # Calculate the angle alpha of the XH vector in the spheroid diffusion frame. if cdp.diff_tensor.type == 'spheroid': angles.spheroid_frame() # Calculate the angles theta and phi of the XH vector in the ellipsoid diffusion frame. elif cdp.diff_tensor.type == 'ellipsoid': angles.ellipsoid_frame() # The 'dasha_script' file. script = open_write_file(file_name='dasha_script', dir=dir, force=force) create_script(script, model_type, algor) script.close()
def check_pipe_setup(pipe=None, pcs_id=None, sequence=False, N=False, tensors=False, pcs=False, paramag_centre=False): """Check that the current data pipe has been setup sufficiently. @keyword pipe: The data pipe to check, defaulting to the current pipe. @type pipe: None or str @keyword pcs_id: The PCS ID string to check for in cdp.pcs_ids. @type pcs_id: None or str @keyword sequence: A flag which when True will invoke the sequence data check. @type sequence: bool @keyword N: A flag which if True will check that cdp.N is set. @type N: bool @keyword tensors: A flag which if True will check that alignment tensors exist. @type tensors: bool @keyword pcs: A flag which if True will check that PCSs exist. @type pcs: bool @keyword paramag_centre: A flag which if True will check that the paramagnetic centre has been set. @type paramag_centre: bool """ # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Test if the current data pipe exists. check_pipe(pipe) # Test if sequence data exists. if sequence and not exists_mol_res_spin_data(pipe): raise RelaxNoSequenceError(pipe) # Check for dp.N. if N and not hasattr(dp, 'N'): raise RelaxError("The number of states N has not been set.") # Check that alignment tensors are present. if tensors and (not hasattr(dp, 'align_tensors') or len(dp.align_tensors) == 0): raise RelaxNoTensorError('alignment') # Test for the alignment ID. if pcs_id and (not hasattr(dp, 'align_ids') or pcs_id not in dp.align_ids): raise RelaxNoAlignError(pcs_id, pipe) # Test if PCS data exists. if pcs and not hasattr(dp, 'align_ids'): raise RelaxNoAlignError() if pcs and not hasattr(dp, 'pcs_ids'): raise RelaxNoPCSError() elif pcs and pcs_id and pcs_id not in dp.pcs_ids: raise RelaxNoPCSError(pcs_id) # Test if the paramagnetic centre is set. if paramag_centre and not hasattr(cdp, 'paramagnetic_centre'): raise RelaxError("The paramagnetic centre has not been defined.")
def copy(pipe_from=None, pipe_to=None): """Copy the J coupling data from one data pipe to another. @keyword pipe_from: The data pipe to copy the J coupling data from. This defaults to the current data pipe. @type pipe_from: str @keyword pipe_to: The data pipe to copy the J coupling data to. This defaults to the current data pipe. @type pipe_to: str """ # Defaults. if pipe_from == None and pipe_to == None: raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.") elif pipe_from == None: pipe_from = pipes.cdp_name() elif pipe_to == None: pipe_to = pipes.cdp_name() # Check the pipe setup. check_pipe_setup(pipe=pipe_from, sequence=True, j=True) check_pipe_setup(pipe=pipe_to, sequence=True) # Get the data pipes. dp_from = pipes.get_pipe(pipe_from) dp_to = pipes.get_pipe(pipe_to) # Test that the interatomic data is consistent between the two data pipe. consistent_interatomic_data(pipe1=pipe_to, pipe2=pipe_from) # Loop over the interatomic data. for i in range(len(dp_from.interatomic)): # Alias the containers. interatom_from = dp_from.interatomic[i] interatom_to = dp_to.interatomic[i] # No data or errors. if not hasattr(interatom_from, 'j_coupling') or not hasattr(interatom_from, 'j_coupling_err'): continue # Copy the value and error from pipe_from. if hasattr(interatom_from, 'j_coupling'): interatom_to.j_coupling = interatom_from.j_coupling if hasattr(interatom_from, 'j_coupling_err'): interatom_to.j_coupling_err = interatom_from.j_coupling_err
def create_interatom(spin_id1=None, spin_id2=None, spin1=None, spin2=None, pipe=None, verbose=False): """Create and return the interatomic data container for the two spins. @keyword spin_id1: The spin ID string of the first atom. @type spin_id1: str @keyword spin_id2: The spin ID string of the second atom. @type spin_id2: str @keyword spin1: The optional spin container for the first atom. This is for speeding up the interatomic data container creation, if the spin containers are already available in the calling function. @type spin1: str @keyword spin2: The optional spin container for the second atom. This is for speeding up the interatomic data container creation, if the spin containers are already available in the calling function. @type spin2: str @keyword pipe: The data pipe to create the interatomic data container for. This defaults to the current data pipe if not supplied. @type pipe: str or None @keyword verbose: A flag which if True will result printouts. @type verbose: bool @return: The newly created interatomic data container. @rtype: data.interatomic.InteratomContainer instance """ # Printout. if verbose: print("Creating an interatomic data container between the spins '%s' and '%s'." % (spin_id1, spin_id2)) # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Check that the spin IDs exist. if spin1 == None: spin1 = return_spin(spin_id=spin_id1, pipe=pipe) if spin1 == None: raise RelaxNoSpinError(spin_id1) if spin2 == None: spin2 = return_spin(spin_id=spin_id2, pipe=pipe) if spin2 == None: raise RelaxNoSpinError(spin_id2) # Check if the two spin IDs have already been added. for i in range(len(dp.interatomic)): if spin1._hash != spin2._hash and spin1._hash in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2] and spin2._hash in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2]: raise RelaxError("The spin pair %s and %s have already been added." % (spin_id1, spin_id2)) # Add the data. interatom = dp.interatomic.add_item(spin_id1=spin_id1, spin_id2=spin_id2, spin_hash1=spin1._hash, spin_hash2=spin2._hash) # Store the interatom hash in the spin containers. spin1._interatomic_hashes.append(interatom._hash) spin2._interatomic_hashes.append(interatom._hash) # Return the interatomic data container. return interatom
def update_pipes(self): """Update the data pipe list.""" # Clear the previous data pipe. self.pipe_name.Clear() # The list of data pipes. for pipe in pipe_names(): self.pipe_name.Append(str_to_gui(pipe)) # Set the name to the current data pipe. self.pipe_name.SetValue(str_to_gui(cdp_name()))
def create(algor='LM', dir=None, force=False): """Create the Dasha script file 'dasha_script' for controlling the program. @keyword algor: The optimisation algorithm to use. This can be the Levenberg-Marquardt algorithm 'LM' or the Newton-Raphson algorithm 'NR'. @type algor: str @keyword dir: The optional directory to place the script into. @type dir: str or None @keyword force: A flag which if True will cause any pre-existing file to be overwritten. @type force: bool """ # Test if the current pipe exists. check_pipe() # Test if sequence data is loaded. if not exists_mol_res_spin_data(): raise RelaxNoSequenceError # Determine the parameter set. model_type = determine_model_type() # Test if diffusion tensor data for the data_pipe exists. if model_type != 'local_tm' and not hasattr(cdp, 'diff_tensor'): raise RelaxNoTensorError('diffusion') # Test if the PDB file has been loaded (for the spheroid and ellipsoid). if model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere' and not hasattr(cdp, 'structure'): raise RelaxNoPdbError # Test the optimisation algorithm. if algor not in ['LM', 'NR']: raise RelaxError("The Dasha optimisation algorithm '%s' is unknown, it should either be 'LM' or 'NR'." % algor) # Deselect certain spins. __deselect_spins() # Directory creation. if dir == None: dir = pipes.cdp_name() mkdir_nofail(dir, verbosity=0) # Calculate the angle alpha of the XH vector in the spheroid diffusion frame. if cdp.diff_tensor.type == 'spheroid': angles.spheroid_frame() # Calculate the angles theta and phi of the XH vector in the ellipsoid diffusion frame. elif cdp.diff_tensor.type == 'ellipsoid': angles.ellipsoid_frame() # The 'dasha_script' file. script = open_write_file(file_name='dasha_script', dir=dir, force=force) create_script(script, model_type, algor) script.close()
def test_load_and_reset(self): """The resetting of an unpickled and restored relax data storage singleton. This tests the normal operation of the pipe_control.state.load() function. """ # Test the contents of the empty singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y')) # Load the state. self.state.load_state(state='basic_single_pipe', dir=status.install_path+sep+'test_suite'+sep+'shared_data'+sep+'saved_states') # Reset relax. reset() # Test that there are no contents in the reset singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y'))
def test_load(self): """The unpickling and restoration of the relax data storage singleton. This tests the normal operation of the pipe_control.state.load() function. """ # Test the contents of the empty singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y')) # Load the state. self.state.load_state(state='basic_single_pipe', dir=status.install_path+sep+'test_suite'+sep+'shared_data'+sep+'saved_states') # Get the data pipe. dp = pipes.get_pipe('orig') # Test the contents of the restored singleton. self.assertEqual(list(ds.keys()), ['orig']) self.assertEqual(pipes.cdp_name(), 'orig') self.assertEqual(dp.x, 1) self.assertEqual(ds.y, 'Hello')
def check_pipe_setup(pipe=None, rdc_id=None, sequence=False, N=False, tensors=False, rdc=False): """Check that the current data pipe has been setup sufficiently. @keyword pipe: The data pipe to check, defaulting to the current pipe. @type pipe: None or str @keyword rdc_id: The RDC ID string to check for in cdp.rdc_ids. @type rdc_id: None or str @keyword sequence: A flag which when True will invoke the sequence data check. @type sequence: bool @keyword N: A flag which if True will check that cdp.N is set. @type N: bool @keyword tensors: A flag which if True will check that alignment tensors exist. @type tensors: bool @keyword rdc: A flag which if True will check that RDCs exist. @type rdc: bool """ # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Test if the current data pipe exists. pipes.test(pipe) # Test if sequence data exists. if sequence and not exists_mol_res_spin_data(pipe): raise RelaxNoSequenceError(pipe) # Check for dp.N. if N and not hasattr(dp, 'N'): raise RelaxError("The number of states N has not been set.") # Check that alignment tensors are present. if tensors and (not hasattr(dp, 'align_tensors') or len(dp.align_tensors) == 0): raise RelaxNoTensorError('alignment') # Test for the alignment ID. if rdc_id and (not hasattr(dp, 'align_ids') or rdc_id not in dp.align_ids): raise RelaxNoAlignError(rdc_id, pipe) # Test if RDC data exists. if rdc and not hasattr(dp, 'align_ids'): raise RelaxNoAlignError() if rdc and not hasattr(dp, 'rdc_ids'): raise RelaxNoRDCError() elif rdc and rdc_id and rdc_id not in dp.rdc_ids: raise RelaxNoRDCError(rdc_id)
def test_load_and_reset(self): """The resetting of an unpickled and restored relax data storage singleton. This tests the normal operation of the pipe_control.state.load() function. """ # Test the contents of the empty singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y')) # Load the state. self.state.load_state(state='basic_single_pipe', dir=status.install_path + sep + 'test_suite' + sep + 'shared_data' + sep + 'saved_states') # Reset relax. reset() # Test that there are no contents in the reset singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y'))
def action_export_bmrb(self, event=None): """Export the contents of the current data pipe for BMRB deposition. @keyword event: The wx event. @type event: wx event """ # No current data pipe. if not cdp_name(): gui_raise(RelaxNoPipeError()) return # Open the export window. Export_bmrb_window(self)
def update_status_bar(self): """Update the status bar info.""" # Set the current data pipe info. pipe = cdp_name() # No data pipe. if pipe == None: pipe = '' # Set the status. wx.CallAfter(self.status_bar.SetStatusText, "(C) 2001-2013 the relax development team", 0) wx.CallAfter(self.status_bar.SetStatusText, "Current data pipe:", 1) wx.CallAfter(self.status_bar.SetStatusText, pipe, 2)
def test_creation(self): """Test the creation of a data pipe. The function used is pipe_control.pipes.create(). """ # Create a new model-free data pipe. name = 'new' pipes.create(name, 'mf') # Test that the data pipe exists. self.assert_(name in ds) # Test that the current pipe is the new pipe. self.assertEqual(pipes.cdp_name(), name)
def test_load(self): """The unpickling and restoration of the relax data storage singleton. This tests the normal operation of the pipe_control.state.load() function. """ # Test the contents of the empty singleton. self.assertEqual(list(ds.keys()), []) self.assertEqual(pipes.cdp_name(), None) self.assert_(not hasattr(ds, 'y')) # Load the state. self.state.load_state(state='basic_single_pipe', dir=status.install_path + sep + 'test_suite' + sep + 'shared_data' + sep + 'saved_states') # Get the data pipe. dp = pipes.get_pipe('orig') # Test the contents of the restored singleton. self.assertEqual(list(ds.keys()), ['orig']) self.assertEqual(pipes.cdp_name(), 'orig') self.assertEqual(dp.x, 1) self.assertEqual(ds.y, 'Hello')
def test_pipe_bundle(self): """Test the pipe bundle concepts.""" # Execute the script. self.script_exec(status.install_path + sep+'test_suite'+sep+'system_tests'+sep+'scripts'+sep+'pipe_bundle.py') # Checks. self.assertEqual(pipes.cdp_name(), None) self.assertEqual(pipes.has_bundle('test bundle 1'), True) self.assertEqual(pipes.has_bundle('test bundle 2'), True) self.assertEqual(pipes.has_bundle('test bundle 3'), False) bundles = sorted(pipes.bundle_names()) self.assertEqual(bundles, ['test bundle 1', 'test bundle 2']) for pipe, name in pipes.pipe_loop(name=True): self.assert_(name in ['test pipe 1', 'test pipe 2', 'test pipe 3', 'test pipe 4', 'test pipe 5', 'test pipe 6']) self.assert_(pipes.get_bundle(name) in ['test bundle 1', 'test bundle 2'])
def test_bug_20480(self): """Catch U{bug #20480<https://web.archive.org/web/https://gna.org/bugs/?20480>}, the failure to load a relax state in the GUI. This was reported by U{Stanislava Panova<https://web.archive.org/web/https://gna.org/users/stacy>}. """ # Simulate the 'Open relax state' menu entry. file = status.install_path + sep + 'test_suite' + sep + 'shared_data' + sep + 'saved_states' + sep + 'bug_20480.bz2' self.app.gui.state_load(file_name=file) # Check that the data has been loaded. self.assertEqual(cdp_name(), "aic - mf (Mon Feb 4 13:30:01 2013)") self.assertEqual(cdp.spectrometer_frq['NOE_800'], 800000031.0) self.assertEqual(cdp.spectrometer_frq['R1_800'], 800000031.0) self.assertEqual(cdp.spectrometer_frq['R2_800'], 800000031.0) self.assertEqual(cdp.spectrometer_frq['R2_600'], 599999000.0)
def test_bug_20480(self): """Catch U{bug #20480<https://gna.org/bugs/?20480>}, the failure to load a relax state in the GUI. This was reported by U{Stanislava Panova<https://gna.org/users/stacy>}. """ # Simulate the 'Open relax state' menu entry. file = status.install_path + sep + 'test_suite' + sep + 'shared_data' + sep + 'saved_states' + sep + 'bug_20480.bz2' self.app.gui.state_load(file_name=file) # Check that the data has been loaded. self.assertEqual(cdp_name(), "aic - mf (Mon Feb 4 13:30:01 2013)") self.assertEqual(cdp.spectrometer_frq['NOE_800'], 800000031.0) self.assertEqual(cdp.spectrometer_frq['R1_800'], 800000031.0) self.assertEqual(cdp.spectrometer_frq['R2_800'], 800000031.0) self.assertEqual(cdp.spectrometer_frq['R2_600'], 599999000.0)
def test_bug_21720_pipe_switching_with_tab_closure(self): """Catch U{bug #20479<https://web.archive.org/web/https://gna.org/bugs/?20479>}, the failure to switch pipes when closing non-last tabs.""" # NOE tab: Simulate the new analysis wizard. analysis = self.new_analysis_wizard(analysis_type='noe', analysis_name='NOE test', pipe_name='noe', pipe_bundle='noe bundle') # Mf tab: Simulate the new analysis wizard. analysis = self.new_analysis_wizard(analysis_type='mf', analysis_name='Mf test', pipe_name='mf', pipe_bundle='mf bundle') # NOE tab: Switch back. self.app.gui.analysis.switch_page(index=0) # NOE tab: Closure. self.app.gui.analysis.delete_analysis(0) # Check that the Mf data pipe is now the current pipe. self.assertEqual(cdp_name(), 'mf')
def test_bug_21720_pipe_switching_with_tab_closure(self): """Catch U{bug #20479<https://gna.org/bugs/?20479>}, the failure to switch pipes when closing non-last tabs.""" # NOE tab: Simulate the new analysis wizard. analysis = self.new_analysis_wizard(analysis_type='noe', analysis_name='NOE test', pipe_name='noe', pipe_bundle='noe bundle') # Mf tab: Simulate the new analysis wizard. analysis = self.new_analysis_wizard(analysis_type='mf', analysis_name='Mf test', pipe_name='mf', pipe_bundle='mf bundle') # NOE tab: Switch back. self.app.gui.analysis.switch_page(index=0) # NOE tab: Closure. self.app.gui.analysis.delete_analysis(0) # Check that the Mf data pipe is now the current pipe. self.assertEqual(cdp_name(), 'mf')
def read(file='results', dir=None): """Function for reading the data out of a file.""" # Test if the current data pipe exists. check_pipe() # Make sure that the data pipe is empty. if not cdp.is_empty(): raise RelaxError("The current data pipe is not empty.") # Get the full file path, for later use. file_path = get_file_path(file_name=file, dir=dir) # Open the file. file = open_read_file(file_name=file_path) # Determine the format of the file. format = determine_format(file) # XML results. if format == 'xml': ds.from_xml(file, dir=dirname(file_path), pipe_to=pipes.cdp_name()) # Columnar results (for backwards compatibility with ancient relax results model-free files). elif format == 'columnar': # Extract the data from the file. file_data = extract_data(file=file) # Strip data. file_data = strip(file_data) # Do nothing if the file does not exist. if not file_data: raise RelaxFileEmptyError # Read the results. read_columnar_results(file_data) # Unknown results file. else: raise RelaxError("The format of the results file " + repr(file_path) + " cannot be determined.") # Update all of the required metadata structures. mol_res_spin.metadata_update() interatomic.metadata_update()
def test_deletion(self): """Test the deletion of a data pipe. The function tested is pipe_control.pipes.delete() """ # Set the current pipe to the 'orig' data pipe. name = 'orig' pipes.switch(name) # Delete the 'orig' data pipe. pipes.delete(name) # Test that the data pipe no longer exists. self.assert_(name not in ds) # Test that the current pipe is None (as the current pipe was deleted). self.assertEqual(pipes.cdp_name(), None)
def switch_page(self, index): """Switch to the given page. @param index: The index of the page to switch to. @type index: int """ # Set the current page number. self._current = index # Switch to the major data pipe of the page if not the current one. if pipes.cdp_name() != ds.relax_gui.analyses[self._current].pipe_name: self.gui.interpreter.apply('pipe.switch', ds.relax_gui.analyses[self._current].pipe_name) # Switch to the page. wx.CallAfter(self.notebook.SetSelection, self._current) # Notify the observers of the change. wx.CallAfter(status.observers.gui_analysis.notify)
def generate(mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None, pipe=None, select=True, verbose=True): """Generate the sequence item-by-item by adding a single molecule/residue/spin container as necessary. @keyword mol_name: The molecule name. @type mol_name: str or None @keyword res_num: The residue number. @type res_num: int or None @keyword res_name: The residue name. @type res_name: str or None @keyword spin_num: The spin number. @type spin_num: int or None @keyword spin_name: The spin name. @type spin_name: str or None @keyword pipe: The data pipe in which to generate the sequence. This defaults to the current data pipe. @type pipe: str @keyword select: The spin selection flag. @type select: bool @keyword verbose: A flag which if True will cause info about each spin to be printed out as the sequence is generated. @type verbose: bool """ # The current data pipe. if pipe == None: pipe = pipes.cdp_name() # A new molecule. if not return_molecule(generate_spin_id(mol_name=mol_name), pipe=pipe): create_molecule(mol_name=mol_name, pipe=pipe) # A new residue. curr_res = return_residue(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name), pipe=pipe) if not curr_res or ((res_num != None and curr_res.num != res_num) or (res_name != None and curr_res.name != res_name)): create_residue(mol_name=mol_name, res_num=res_num, res_name=res_name, pipe=pipe) # A new spin. curr_spin = return_spin(spin_id=generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name), pipe=pipe) if not curr_spin or ((spin_num != None and curr_spin.num != spin_num) or (spin_name != None and curr_spin.name != spin_name)): # Add the spin. curr_spin = create_spin(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name, pipe=pipe)[0] # Set the selection flag. curr_spin.select = select
def update_controller(self): """Update the relax controller.""" # Set the current data pipe info. pipe = cdp_name() if pipe == None: pipe = '' wx.CallAfter(self.cdp.SetValue, str_to_gui(pipe)) # Set the current GUI analysis info. name = self.gui.analysis.current_analysis_name() if name == None: name = '' wx.CallAfter(self.name.SetValue, str_to_gui(name)) # The analysis type. type = self.gui.analysis.current_analysis_type() # Rx fitting auto-analysis. if type in ['R1', 'R2']: if status.show_gui: wx.CallAfter(self.panel_rx.Show) wx.CallAfter(self.update_rx) else: if status.show_gui: wx.CallAfter(self.panel_rx.Hide) # Model-free auto-analysis. if type == 'model-free': if status.show_gui: wx.CallAfter(self.panel_mf.Show) wx.CallAfter(self.update_mf) else: if status.show_gui: wx.CallAfter(self.panel_mf.Hide) # Update the main gauge. wx.CallAfter(self.update_gauge) # Re-layout the window. wx.CallAfter(self.main_panel.Layout)
def spin_count(self): """Count the number of loaded spins, returning a string formatted as 'xxx spins loaded'. @return: The number of loaded spins in the format 'xxx spins loaded'. @rtype: str """ # The data pipe. if hasattr(self.data, 'pipe_name'): pipe = self.data.pipe_name else: pipe = cdp_name() # The count. if not has_pipe(pipe): num = 0 else: num = count_spins(pipe=pipe) # Return the formatted string. return "%s spins loaded and selected" % num
def check_pivot_func(pipe_name=None): """Check that the pivot point has been set. @keyword pipe_name: The data pipe to check the pivot for. This defaults to the current data pipe if not set. @type pipe_name: str @return: The initialised RelaxError object if the pivot point has not been set, or nothing. @rtype: None or RelaxError instance """ # The data pipe. if pipe_name == None: pipe_name = cdp_name() # Get the data pipe. dp = get_pipe(pipe_name) # Check for the pivot_x parameter. if not hasattr(dp, 'pivot_x'): return RelaxError( "The pivot point has not been set, please use the frame_order.pivot user function to define the point." )
def check_model_func(pipe_name=None): """Check if the frame order model has been set up. @keyword pipe_name: The data pipe to check for, if not the current pipe. @type pipe_name: None or str @return: The initialised RelaxError object if the model is not set up, or nothing. @rtype: None or RelaxError instance """ # The data pipe. if pipe_name == None: pipe_name = cdp_name() # Get the data pipe. dp = get_pipe(pipe_name) # Check that the model is set up. if not hasattr(dp, 'model'): return RelaxError( "The frame order model has not been set up, please use the frame_order.select_model user function." )