コード例 #1
0
ファイル: uf.py プロジェクト: pombredanne/relax
def delete():
    """Delete all the model-free data."""

    # Test if the current pipe exists.
    check_pipe()

    # Test if the pipe type is set to 'mf'.
    function_type = pipes.get_type()
    if function_type != "mf":
        raise RelaxFuncSetupError(specific_analyses.setup.get_string(function_type))

    # Test if the sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Get all data structure names.
    names = api_model_free.data_names(scope="spin")

    # Loop over the spins.
    for spin in spin_loop():
        # Loop through the data structure names.
        for name in names:
            # Skip the data structure if it does not exist.
            if not hasattr(spin, name):
                continue

            # Delete the data.
            delattr(spin, name)
コード例 #2
0
ファイル: uf.py プロジェクト: tlinnet/relax
def select_model(model=None, spin_id=None):
    """Function for the selection of a preset model-free model.

    @param model:   The name of the model.
    @type model:    str
    @param spin_id: The spin identification string.
    @type spin_id:  str
    """

    # Test if the current data pipe exists.
    check_pipe()

    # Test if the pipe type is 'mf'.
    function_type = pipes.get_type()
    if function_type != 'mf':
        raise RelaxFuncSetupError(specific_analyses.get_string(function_type))

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Obtain the model info.
    equation, params = model_map(model)

    # Set up the model.
    model_setup(model, equation, params, spin_id)
コード例 #3
0
ファイル: uf.py プロジェクト: tlinnet/relax
def delete():
    """Delete all the model-free data."""

    # Test if the current pipe exists.
    check_pipe()

    # Test if the pipe type is set to 'mf'.
    function_type = pipes.get_type()
    if function_type != 'mf':
        raise RelaxFuncSetupError(
            specific_analyses.setup.get_string(function_type))

    # Test if the sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Get all data structure names.
    names = api_model_free.data_names(scope='spin')

    # Loop over the spins.
    for spin in spin_loop():
        # Loop through the data structure names.
        for name in names:
            # Skip the data structure if it does not exist.
            if not hasattr(spin, name):
                continue

            # Delete the data.
            delattr(spin, name)
コード例 #4
0
ファイル: hybrid.py プロジェクト: pombredanne/relax
    def model_statistics(self, model_info=None, spin_id=None, global_stats=None):
        """Return the k, n, and chi2 model statistics of the hybrid.

        k - number of parameters.
        n - number of data points.
        chi2 - the chi-squared value.


        @keyword model_index:   The model index.  This is zero for the global models or equal to the
                                global spin index (which covers the molecule, residue, and spin
                                indices).  This originates from the model_loop().
        @type model_index:      int
        @keyword spin_id:       The spin identification string.  Either this or the instance keyword
                                argument must be supplied.
        @type spin_id:          None or str
        @keyword global_stats:  A parameter which determines if global or local statistics are
                                returned.  If None, then the appropriateness of global or local
                                statistics is automatically determined.
        @type global_stats:     None or bool
        @return:                The optimisation statistics, in tuple format, of the number of
                                parameters (k), the number of data points (n), and the chi-squared
                                value (chi2).
        @rtype:                 tuple of int, int, float
        """

        # Bad argument combination.
        if model_info == None and spin_id == None:
            raise RelaxError("Either the model_info or spin_id argument must be supplied.")
        elif model_info != None and spin_id != None:
            raise RelaxError("The model_info arg " + repr(model_info) + " and spin_id arg " + repr(spin_id) + " clash.  Only one should be supplied.")

        # Initialise.
        k_total = 0
        n_total = 0
        chi2_total = 0.0

        # Specific setup.
        for pipe in cdp.hybrid_pipes:
            # Switch to the data pipe.
            pipes.switch(pipe)

            # Specific model statistics and number of instances functions.
            model_statistics = setup.get_specific_fn('model_stats', pipes.get_type(pipe))

            # Loop over the instances.
            #for i in range(num):
            # Get the statistics.
            k, n, chi2 = model_statistics(model_info=model_info, spin_id=spin_id, global_stats=global_stats)

            # Bad stats.
            if k == None or n == None or chi2 == None:
                continue

            # Sum the stats.
            k_total = k_total + k
            n_total = n_total + n
            chi2_total = chi2_total + chi2

        # Return the totals.
        return k_total, n_total, chi2_total
コード例 #5
0
    def associate_auto(self, event):
        """Associate the selected data pipe with a new auto-analysis.

        @param event:   The wx event.
        @type event:    wx event
        """

        # Initialise the GUI data store object if needed.
        if not hasattr(ds, 'relax_gui'):
            self.gui.init_data()

        # The type and data pipe bundle.
        type = get_type(self.selected_pipe)
        bundle = get_bundle(self.selected_pipe)

        # Error checking.
        if self.selected_pipe == None:
            raise RelaxError("No data pipe has been selected - this is not possible.")
        if bundle == None:
            raise RelaxError("The selected data pipe is not associated with a data pipe bundle.")

        # The name.
        names = {
            'noe': 'Steady-state NOE',
            'r1': 'R1 relaxation',
            'r2': 'R2 relaxation',
            'mf': 'Model-free',
            'relax_disp': 'Relaxation dispersion'
        }

        # Create a new analysis with the selected data pipe.
        self.gui.analysis.new_analysis(analysis_type=type, analysis_name=names[type], pipe_name=self.selected_pipe, pipe_bundle=bundle)
コード例 #6
0
ファイル: pipe_editor.py プロジェクト: tlinnet/relax
    def associate_auto(self, event):
        """Associate the selected data pipe with a new auto-analysis.

        @param event:   The wx event.
        @type event:    wx event
        """

        # Initialise the GUI data store object if needed.
        if not hasattr(ds, 'relax_gui'):
            self.gui.init_data()

        # The type and data pipe bundle.
        type = get_type(self.selected_pipe)
        bundle = get_bundle(self.selected_pipe)

        # Error checking.
        if self.selected_pipe == None:
            raise RelaxError("No data pipe has been selected - this is not possible.")
        if bundle == None:
            raise RelaxError("The selected data pipe is not associated with a data pipe bundle.")

        # The name.
        names = {
            'noe': 'Steady-state NOE',
            'r1': 'R1 relaxation',
            'r2': 'R2 relaxation',
            'mf': 'Model-free',
            'relax_disp': 'Relaxation dispersion'
        }

        # Create a new analysis with the selected data pipe.
        self.gui.analysis.new_analysis(analysis_type=type, analysis_name=names[type], pipe_name=self.selected_pipe, pipe_bundle=bundle)
コード例 #7
0
ファイル: opendx.py プロジェクト: belisario21/relax_trunk
    def get_param_names(self):
        """Function for retrieving the parameter names."""

        # Initialise.
        self.param_names = []

        # Loop over the parameters.
        for i in range(self.n):
            # Get the parameter name.
            name = self.return_data_name(self.params[i])

            # Diffusion tensor parameter.
            if pipes.get_type() == 'mf':
                # The diffusion tensor parameter name.
                diff_name = diffusion_tensor.return_data_name(self.params[i])

                # Replace the model-free parameter with the diffusion tensor parameter if it exists.
                if diff_name:
                    name = diff_name

                    # Set the flag indicating if there are diffusion tensor parameters.
                    self.diff_params[i] = 1

            # Bad parameter name.
            if not name:
                raise RelaxUnknownParamError(self.params[i])

            # Append the parameter name.
            self.param_names.append(name)
コード例 #8
0
ファイル: uf.py プロジェクト: pombredanne/relax
def select_model(model=None, spin_id=None):
    """Function for the selection of a preset model-free model.

    @param model:   The name of the model.
    @type model:    str
    @param spin_id: The spin identification string.
    @type spin_id:  str
    """

    # Test if the current data pipe exists.
    check_pipe()

    # Test if the pipe type is 'mf'.
    function_type = pipes.get_type()
    if function_type != "mf":
        raise RelaxFuncSetupError(specific_analyses.get_string(function_type))

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Obtain the model info.
    equation, params = model_map(model)

    # Set up the model.
    model_setup(model, equation, params, spin_id)
コード例 #9
0
ファイル: pipe_editor.py プロジェクト: tlinnet/relax
    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()
コード例 #10
0
    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()
コード例 #11
0
ファイル: uf.py プロジェクト: pombredanne/relax
def remove_tm(spin_id=None):
    """Remove local tm from the set of model-free parameters for the given spins.

    @param spin_id: The spin identification string.
    @type spin_id:  str or None
    """

    # Test if the current data pipe exists.
    check_pipe()

    # Test if the pipe type is 'mf'.
    function_type = pipes.get_type()
    if function_type != "mf":
        raise RelaxFuncSetupError(specific_analyses.get_string(function_type))

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Loop over the spins.
    for spin in spin_loop(spin_id):
        # Skip deselected spins.
        if not spin.select:
            continue

        # Test if a local tm parameter exists.
        if not hasattr(spin, "params") or not "local_tm" in spin.params:
            continue

        # Remove tm.
        spin.params.remove("local_tm")

        # Model name.
        if match("^tm", spin.model):
            spin.model = spin.model[1:]

        # Delete the local tm variable.
        del spin.local_tm

        # Set all the minimisation stats to None.
        spin.chi2 = None
        spin.iter = None
        spin.f_count = None
        spin.g_count = None
        spin.h_count = None
        spin.warning = None

    # Set the global minimisation stats to None.
    cdp.chi2 = None
    cdp.iter = None
    cdp.f_count = None
    cdp.g_count = None
    cdp.h_count = None
    cdp.warning = None
コード例 #12
0
ファイル: uf.py プロジェクト: tlinnet/relax
def remove_tm(spin_id=None):
    """Remove local tm from the set of model-free parameters for the given spins.

    @param spin_id: The spin identification string.
    @type spin_id:  str or None
    """

    # Test if the current data pipe exists.
    check_pipe()

    # Test if the pipe type is 'mf'.
    function_type = pipes.get_type()
    if function_type != 'mf':
        raise RelaxFuncSetupError(specific_analyses.get_string(function_type))

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Loop over the spins.
    for spin in spin_loop(spin_id):
        # Skip deselected spins.
        if not spin.select:
            continue

        # Test if a local tm parameter exists.
        if not hasattr(spin, 'params') or not 'local_tm' in spin.params:
            continue

        # Remove tm.
        spin.params.remove('local_tm')

        # Model name.
        if match('^tm', spin.model):
            spin.model = spin.model[1:]

        # Delete the local tm variable.
        del spin.local_tm

        # Set all the minimisation stats to None.
        spin.chi2 = None
        spin.iter = None
        spin.f_count = None
        spin.g_count = None
        spin.h_count = None
        spin.warning = None

    # Set the global minimisation stats to None.
    cdp.chi2 = None
    cdp.iter = None
    cdp.f_count = None
    cdp.g_count = None
    cdp.h_count = None
    cdp.warning = None
コード例 #13
0
ファイル: hybrid.py プロジェクト: pombredanne/relax
    def _hybridise(self, hybrid=None, pipe_list=None):
        """Create the hybrid data pipe.

        @keyword hybrid:    The name of the new hybrid data pipe.
        @type hybrid:       str
        @keyword pipe_list: The list of data pipes that the hybrid is composed of.
        @type pipe_list:    list of str
        """

        # Test if the hybrid data pipe already exists.
        if hybrid in pipes.pipe_names():
            raise RelaxPipeError(hybrid)

        # Loop over the pipes to be hybridised and check them.
        pipe_type = pipes.get_type(pipe_list[0])
        for pipe in pipe_list:
            # Switch to the data pipe.
            pipes.switch(pipe)

            # Test if the pipe exists.
            check_pipe()

            # Check that the pipe types match.
            if pipes.get_type() != pipe_type:
                raise RelaxError("The data pipe types do not match.")

            # Test if sequence data is loaded.
            if not exists_mol_res_spin_data():
                raise RelaxNoSequenceError

        # Check that the sequence data matches in all pipes.
        for i in range(1, len(pipe_list)):
            compare_sequence(pipe_list[0], pipe_list[1])

        # Create the data pipe.
        pipes.create(pipe_name=hybrid, pipe_type='hybrid')

        # Store the pipe list forming the hybrid.
        cdp.hybrid_pipes = pipe_list
コード例 #14
0
ファイル: hybrid.py プロジェクト: tlinnet/relax
    def _hybridise(self, hybrid=None, pipe_list=None):
        """Create the hybrid data pipe.

        @keyword hybrid:    The name of the new hybrid data pipe.
        @type hybrid:       str
        @keyword pipe_list: The list of data pipes that the hybrid is composed of.
        @type pipe_list:    list of str
        """

        # Test if the hybrid data pipe already exists.
        if hybrid in pipes.pipe_names():
            raise RelaxPipeError(hybrid)

        # Loop over the pipes to be hybridised and check them.
        pipe_type = pipes.get_type(pipe_list[0])
        for pipe in pipe_list:
            # Switch to the data pipe.
            pipes.switch(pipe)

            # Test if the pipe exists.
            check_pipe()

            # Check that the pipe types match.
            if pipes.get_type() != pipe_type:
                raise RelaxError("The data pipe types do not match.")

            # Test if sequence data is loaded.
            if not exists_mol_res_spin_data():
                raise RelaxNoSequenceError

        # Check that the sequence data matches in all pipes.
        for i in range(1, len(pipe_list)):
            compare_sequence(pipe_list[0], pipe_list[1])

        # Create the data pipe.
        pipes.create(pipe_name=hybrid, pipe_type='hybrid')

        # Store the pipe list forming the hybrid.
        cdp.hybrid_pipes = pipe_list
コード例 #15
0
    def menu(self, event):
        """The pop up menu.

        @param event:   The wx event.
        @type event:    wx event
        """

        # Get the row.
        row = event.GetRow()

        # Get the name of the data pipe.
        self.selected_pipe = gui_to_str(self.grid.GetCellValue(row, 0))

        # No data pipe.
        if not self.selected_pipe:
            return

        # The pipe type and bundle.
        pipe_type = get_type(self.selected_pipe)
        pipe_bundle = get_bundle(self.selected_pipe)

        # Initialise the menu.
        menu = wx.Menu()
        items = []

        # Menu entry:  add the data pipe to a bundle.
        if not pipe_bundle:
            items.append(build_menu_item(menu, parent=self, text="&Add the pipe to a bundle", icon=fetch_icon("relax.pipe_bundle"), fn=self.pipe_bundle))

        # Menu entry:  delete the data pipe.
        items.append(build_menu_item(menu, parent=self, text="&Delete the pipe", icon=fetch_icon('oxygen.actions.list-remove', "16x16"), fn=self.pipe_delete))
 
        # Menu entry:  switch to this data pipe.
        items.append(build_menu_item(menu, parent=self, text="&Switch to this pipe", icon=fetch_icon('oxygen.actions.system-switch-user', "16x16"), fn=self.pipe_switch))
 
        # Menu entry:  new auto-analysis tab.
        if pipe_bundle and self.gui.analysis.page_index_from_bundle(pipe_bundle) == None and pipe_type in ['noe', 'r1', 'r2', 'mf', 'relax_disp']:
            items.append(build_menu_item(menu, parent=self, text="&Associate with a new auto-analysis", icon=fetch_icon('oxygen.actions.document-new', "16x16"), fn=self.associate_auto))
 
        # Set up the entries.
        for item in items:
            menu.AppendItem(item)
            if status.exec_lock.locked():
                item.Enable(False)

        # Show the menu.
        if status.show_gui:
            self.PopupMenu(menu)

        # Kill the menu once done.
        menu.Destroy()
コード例 #16
0
ファイル: value.py プロジェクト: belisario21/relax_trunk
def copy(pipe_from=None, pipe_to=None, param=None):
    """Copy spin specific data values from pipe_from to pipe_to.

    @param pipe_from:   The data pipe to copy the value from.  This defaults to the current data
                        pipe.
    @type pipe_from:    str
    @param pipe_to:     The data pipe to copy the value to.  This defaults to the current data pipe.
    @type pipe_to:      str
    @param param:       The name of the parameter to copy the values of.
    @type param:        str
    """

    # The current data pipe.
    if pipe_from == None:
        pipe_from = pipes.cdp_name()
    if pipe_to == None:
        pipe_to = pipes.cdp_name()
    pipe_orig = pipes.cdp_name()

    # The second pipe does not exist.
    pipes.test(pipe_to)

    # Test if the sequence data for pipe_from is loaded.
    if not exists_mol_res_spin_data(pipe_from):
        raise RelaxNoSequenceError(pipe_from)

    # Test if the sequence data for pipe_to is loaded.
    if not exists_mol_res_spin_data(pipe_to):
        raise RelaxNoSequenceError(pipe_to)

    # Specific value and error returning function.
    return_value = specific_analyses.setup.get_specific_fn('return_value', pipes.get_type(pipe_from))

    # Test if the data exists for pipe_to.
    for spin in spin_loop(pipe=pipe_to):
        # Get the value and error for pipe_to.
        value, error = return_value(spin, param)

        # Data exists.
        if value != None or error != None:
            raise RelaxValueError(param, pipe_to)

    # Switch to the data pipe to copy values to.
    pipes.switch(pipe_to)

    # Copy the values.
    for spin, spin_id in spin_loop(pipe=pipe_from, return_id=True):
        # Get the value and error from pipe_from.
        value, error = return_value(spin, param)

        # Set the values of pipe_to.
        if value != None:
            set(spin_id=spin_id, val=value, param=param, pipe=pipe_to)
        if error != None:
            set(spin_id=spin_id, val=error, param=param, pipe=pipe_to, error=True)

    # Reset all minimisation statistics.
    minimise.reset_min_stats(pipe_to)

    # Switch back to the original current data pipe.
    pipes.switch(pipe_orig)
コード例 #17
0
def select(method=None, modsel_pipe=None, bundle=None, pipes=None):
    """Model selection function.

    @keyword method:        The model selection method.  This can currently be one of:
                                - 'AIC', Akaike's Information Criteria.
                                - 'AICc', Small sample size corrected AIC.
                                - 'BIC', Bayesian or Schwarz Information Criteria.
                                - 'CV', Single-item-out cross-validation.
                            None of the other model selection techniques are currently supported.
    @type method:           str
    @keyword modsel_pipe:   The name of the new data pipe to be created by copying of the selected data pipe.
    @type modsel_pipe:      str
    @keyword bundle:        The optional data pipe bundle to associate the newly created pipe with.
    @type bundle:           str or None
    @keyword pipes:         A list of the data pipes to use in the model selection.
    @type pipes:            list of str
    """

    # Test if the pipe already exists.
    if has_pipe(modsel_pipe):
        raise RelaxPipeError(modsel_pipe)

    # Use all pipes.
    if pipes == None:
        # Get all data pipe names from the relax data store.
        pipes = pipe_names()

    # Select the model selection technique.
    if method == 'AIC':
        print("AIC model selection.")
        formula = aic
    elif method == 'AICc':
        print("AICc model selection.")
        formula = aicc
    elif method == 'BIC':
        print("BIC model selection.")
        formula = bic
    elif method == 'CV':
        print("CV model selection.")
        raise RelaxError("The model selection technique " + repr(method) + " is not currently supported.")
    else:
        raise RelaxError("The model selection technique " + repr(method) + " is not currently supported.")

    # No pipes.
    if len(pipes) == 0:
        raise RelaxError("No data pipes are available for use in model selection.")

    # Initialise.
    function_type = {}
    model_loop = {}
    model_type = {}
    duplicate_data = {}
    model_statistics = {}
    skip_function = {}
    modsel_pipe_exists = False

    # Cross validation setup.
    if isinstance(pipes[0], list):
        # No pipes.
        if len(pipes[0]) == 0:
            raise RelaxError("No pipes are available for use in model selection in the array " + repr(pipes[0]) + ".")

        # Loop over the data pipes.
        for i in range(len(pipes)):
            for j in range(len(pipes[i])):
                # Specific functions.
                model_loop[pipes[i][j]] = get_specific_fn('model_loop', get_type(pipes[i][j]))
                model_type[pipes[i][j]] = get_specific_fn('model_type', get_type(pipes[i][j]))
                duplicate_data[pipes[i][j]] = get_specific_fn('duplicate_data', get_type(pipes[i][j]))
                model_statistics[pipes[i][j]] = get_specific_fn('model_stats', get_type(pipes[i][j]))
                skip_function[pipes[i][j]] = get_specific_fn('skip_function', get_type(pipes[i][j]))

        # The model loop should be the same for all data pipes!
        for i in range(len(pipes)):
            for j in range(len(pipes[i])):
                if model_loop[pipes[0][j]] != model_loop[pipes[i][j]]:
                    raise RelaxError("The models for each data pipes should be the same.")
        model_loop = model_loop[pipes[0][0]]

        # The model description.
        model_desc = get_specific_fn('model_desc', get_type(pipes[0]))

        # Global vs. local models.
        global_flag = False
        for i in range(len(pipes)):
            for j in range(len(pipes[i])):
                if model_type[pipes[i][j]]() == 'global':
                    global_flag = True

    # All other model selection setup.
    else:
        # Loop over the data pipes.
        for i in range(len(pipes)):
            # Specific functions.
            model_loop[pipes[i]] = get_specific_fn('model_loop', get_type(pipes[i]))
            model_type[pipes[i]] = get_specific_fn('model_type', get_type(pipes[i]))
            duplicate_data[pipes[i]] = get_specific_fn('duplicate_data', get_type(pipes[i]))
            model_statistics[pipes[i]] = get_specific_fn('model_stats', get_type(pipes[i]))
            skip_function[pipes[i]] = get_specific_fn('skip_function', get_type(pipes[i]))

        model_loop = model_loop[pipes[0]]

        # The model description.
        model_desc = get_specific_fn('model_desc', get_type(pipes[0]))

        # Global vs. local models.
        global_flag = False
        for j in range(len(pipes)):
            if model_type[pipes[j]]() == 'global':
                global_flag = True


    # Loop over the base models.
    for model_info in model_loop():
        # Print out.
        print("\n")
        desc = model_desc(model_info)
        if desc:
            print(desc)

        # Initial model.
        best_model = None
        best_crit = 1e300
        data = []

        # Loop over the pipes.
        for j in range(len(pipes)):
            # Single-item-out cross validation.
            if method == 'CV':
                # Sum of chi-squared values.
                sum_crit = 0.0

                # Loop over the validation samples and sum the chi-squared values.
                for k in range(len(pipes[j])):
                    # Alias the data pipe name.
                    pipe = pipes[j][k]

                    # Switch to this pipe.
                    switch(pipe)

                    # Skip function.
                    if skip_function[pipe](model_info):
                        continue

                    # Get the model statistics.
                    k, n, chi2 = model_statistics[pipe](model_info)

                    # Missing data sets.
                    if k == None or n == None or chi2 == None:
                        continue

                    # Chi2 sum.
                    sum_crit = sum_crit + chi2

                # Cross-validation criterion (average chi-squared value).
                crit = sum_crit / float(len(pipes[j]))

            # Other model selection methods.
            else:
                # Reassign the pipe.
                pipe = pipes[j]

                # Switch to this pipe.
                switch(pipe)

                # Skip function.
                if skip_function[pipe](model_info):
                    continue

                # Get the model statistics.
                k, n, chi2 = model_statistics[pipe](model_info, global_stats=global_flag)

                # Missing data sets.
                if k == None or n == None or chi2 == None:
                    continue

                # Calculate the criterion value.
                crit = formula(chi2, float(k), float(n))

                # Store the values for a later printout.
                data.append([pipe, repr(k), repr(n), "%.5f" % chi2, "%.5f" % crit])

            # Select model.
            if crit < best_crit:
                best_model = pipe
                best_crit = crit

        # Write out the table.
        write_data(out=sys.stdout, headings=["Data pipe", "Num_params_(k)", "Num_data_sets_(n)", "Chi2", "Criterion"], data=data)

        # Duplicate the data from the 'best_model' to the model selection data pipe.
        if best_model != None:
            # Print out of selected model.
            print("The model from the data pipe " + repr(best_model) + " has been selected.")

            # Switch to the selected data pipe.
            switch(best_model)

            # Duplicate.
            duplicate_data[best_model](best_model, modsel_pipe, model_info, global_stats=global_flag, verbose=False)

            # Model selection pipe now exists.
            modsel_pipe_exists = True

        # No model selected.
        else:
            # Print out of selected model.
            print("No model has been selected.")

    # Switch to the model selection pipe.
    if modsel_pipe_exists:
        switch(modsel_pipe)

    # Bundle the data pipe.
    if bundle:
        pipe_control.pipes.bundle(bundle=bundle, pipe=modsel_pipe)
コード例 #18
0
ファイル: value.py プロジェクト: belisario21/relax_trunk
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
    """

    # Get the value and error returning function parameter description function if required.
    if not return_value:
        return_value = specific_analyses.setup.get_specific_fn('return_value', pipes.get_type())
    if not return_data_desc:
        return_data_desc = specific_analyses.setup.get_specific_fn('return_data_desc', pipes.get_type())

    # 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))

    # 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)
コード例 #19
0
ファイル: value.py プロジェクト: belisario21/relax_trunk
def set(val=None, param=None, pipe=None, spin_id=None, error=False, force=True, reset=True):
    """Set global or spin specific data values.

    @keyword val:       The parameter values.
    @type val:          None or list
    @keyword param:     The parameter names.
    @type param:        None, str, or list of str
    @keyword pipe:      The data pipe the values should be placed in.
    @type pipe:         None or str
    @keyword spin_id:   The spin identification string.
    @type spin_id:      str
    @keyword error:     A flag which if True will allow the parameter errors to be set instead of the values.
    @type error:        bool
    @keyword force:     A flag forcing the overwriting of current values.
    @type force:        bool
    @keyword reset:     A flag which if True will cause all minimisation statistics to be reset.
    @type reset:        bool
    """

    # Switch to the data pipe, storing the original.
    if pipe:
        orig_pipe = pipes.cdp_name()
        pipes.switch(pipe)

    # Test if the current data pipe exists.
    pipes.test()

    # Specific functions.
    default_value = specific_analyses.setup.get_specific_fn('default_value', pipes.get_type())
    get_param_names = specific_analyses.setup.get_specific_fn('get_param_names', pipes.get_type())
    return_data_name = specific_analyses.setup.get_specific_fn('return_data_name', pipes.get_type())
    set_param_values = specific_analyses.setup.get_specific_fn('set_param_values', pipes.get_type())

    # Convert numpy arrays to lists, if necessary.
    if isinstance(val, ndarray):
        val = val.tolist()

    # Invalid combinations.
    if (isinstance(val, float) or isinstance(val, int)) and param == None:
        raise RelaxError("The combination of a single value '%s' without specifying the parameter name is invalid." % val)
    if isinstance(val, list) and isinstance(param, str):
        raise RelaxError("Invalid combination:  When multiple values '%s' are specified, either no parameters or a list of parameters must by supplied rather than the single parameter '%s'." % (val, param))

    # Value array and parameter array of equal length.
    if isinstance(val, list) and isinstance(param, list) and len(val) != len(param):
        raise RelaxError("Both the value array and parameter array must be of equal length.")

    # Get the parameter list if needed.
    if param == None:
        param = get_param_names()

    # Convert the param to a list if needed.
    if not isinstance(param, list):
        param = [param]

    # Convert the value to a list if needed.
    if val != None and not isinstance(val, list):
        val = [val] * len(param)

    # Default values.
    if val == None:
        # Loop over the parameters, getting the default values.
        val = []
        for i in range(len(param)):
            val.append(default_value(return_data_name(param[i])))

            # Check that there is a default.
            if val[-1] == None:
                raise RelaxParamSetError(param[i])

    # Set the parameter values.
    set_param_values(param=param, value=val, spin_id=spin_id, error=error, force=force)

    # Reset all minimisation statistics.
    if reset:
        minimise.reset_min_stats()

    # Switch back.
    if pipe:
        pipes.switch(orig_pipe)
コード例 #20
0
ファイル: setup.py プロジェクト: belisario21/relax_trunk
def get_specific_fn(eqi, function_type=None, raise_error=True):
    """The function for returning the requested specific function."""

    # Initialise.
    function = None
    if function_type == None:
        function_type = pipes.get_type()

    # Get the class instance corresponding to function_type.
    inst = get_instance(function_type)

    # Attempt to retrieve the function.
    try:
        # Back calculation of relaxation data.
        if eqi == 'back_calc_ri':
            function = inst.back_calc_ri

        # Base data loop generator function.
        if eqi == 'base_data_loop':
            function = inst.base_data_loop

        # BMRB NMR-STAR v3.1 reading function.
        if eqi == 'bmrb_read':
            function = inst.bmrb_read

        # BMRB NMR-STAR v3.1 writing function.
        if eqi == 'bmrb_write':
            function = inst.bmrb_write

        # Calculate function.
        if eqi == 'calculate':
            function = inst.calculate

        # Optimisation constraint algorithm override.
        if eqi == 'constraint_algorithm':
            function = inst.constraint_algorithm

        # Create Monte Carlo data function.
        if eqi == 'create_mc_data':
            function = inst.create_mc_data

        # Data structure initialisation function.
        if eqi == 'data_init':
            function = inst.data_init

        # List of parameter names returning function.
        if eqi == 'data_names':
            function = inst.data_names

        # The parameter type function.
        if eqi == 'data_type':
            function = inst.data_type

        # Default parameter value returning function.
        if eqi == 'default_value':
            function = inst.default_value

        # Duplicate data function.
        if eqi == 'duplicate_data':
            function = inst.duplicate_data

        # Eliminate models.
        if eqi == 'eliminate':
            function = inst.eliminate

        # Parameter names function.
        if eqi == 'get_param_names':
            function = inst.get_param_names

        # Parameter values function.
        if eqi == 'get_param_values':
            function = inst.get_param_values

        # Grid search function.
        if eqi == 'grid_search':
            function = inst.grid_search

        # Initial Monte Carlo parameter value search function.
        if eqi == 'init_sim_values':
            function = inst.sim_init_values

        # Spin specific parameter determining function.
        if eqi == 'is_spin_param':
            function = inst.is_spin_param

        # Map bounds function.
        if eqi == 'map_bounds':
            function = inst.map_bounds

        # Minimise function.
        if eqi == 'minimise':
            function = inst.minimise

        # Model loop.
        if eqi == 'model_desc':
            function = inst.model_desc

        # Model loop.
        if eqi == 'model_loop':
            function = inst.model_loop

        # Model statistics.
        if eqi == 'model_stats':
            function = inst.model_statistics

        # Model type.
        if eqi == 'model_type':
            function = inst.model_type

        # Molmol macro creation.
        if eqi == 'molmol_macro':
            function = inst.molmol_macro

        # Number of instances.
        if eqi == 'num_instances':
            function = inst.num_instances

        # Overfit deselect.
        if eqi == 'overfit_deselect':
            function = inst.overfit_deselect

        # Pack Monte Carlo simulation data function.
        if eqi == 'pack_sim_data':
            function = inst.sim_pack_data

        # Pymol macro creation.
        if eqi == 'pymol_macro':
            function = inst.pymol_macro

        # Read results file function (Columnar format).
        if eqi == 'read_columnar_results':
            function = inst.read_columnar_results

        # Read results file function (XML format).
        #if eqi == 'read_xml_results':
        #    function = inst.read_xml_results

        # Data returning function.
        if eqi == 'return_data':
            function = inst.return_data

        # Parameter description returning function.
        if eqi == 'return_data_desc':
            function = inst.return_data_desc

        # Data or parameter name returning function.
        if eqi == 'return_data_name':
            function = inst.return_data_name

        # Data error returning function.
        if eqi == 'return_error':
            function = inst.return_error

        # Factor of conversion between different parameter units returning function.
        if eqi == 'return_conversion_factor':
            function = inst.return_conversion_factor

        # Grace string returning function.
        if eqi == 'return_grace_string':
            function = inst.return_grace_string

        # Selected simulation array returning function.
        if eqi == 'return_selected_sim':
            function = inst.sim_return_selected

        # Simulation chi-squared array returning function.
        if eqi == 'return_sim_chi2':
            function = inst.sim_return_chi2

        # Simulation parameter array returning function.
        if eqi == 'return_sim_param':
            function = inst.sim_return_param

        # String of the external parameter units returning function.
        if eqi == 'return_units':
            function = inst.return_units

        # Value and error returning function.
        if eqi == 'return_value':
            function = inst.return_value

        # Set error function.
        if eqi == 'set_error':
            function = inst.set_error

        # Set parameter values function.
        if eqi == 'set_param_values':
            function = inst.set_param_values

        # Set the selected simulations array.
        if eqi == 'set_selected_sim':
            function = inst.set_selected_sim

        # Set update function.
        if eqi == 'set_update':
            function = inst.set_update

        # Skip function.
        if eqi == 'skip_function':
            function = inst.skip_function

        # Deselection function.
        if eqi == 'deselect':
            function = inst.deselect

    # Catch if the function is missing.
    except AttributeError:
        function = None

    # Raise an error if the function doesn't exist.
    if raise_error and function == None:
        # Raise the error.
        raise RelaxFuncSetupError(get_string(function_type))

    # Return the function.
    return function
コード例 #21
0
ファイル: uf.py プロジェクト: tlinnet/relax
def create_model(model=None, equation=None, params=None, spin_id=None):
    """Function for creating a custom model-free model.

    @param model:       The name of the model.
    @type model:        str
    @param equation:    The equation type to use.  The 3 allowed types are:  'mf_orig' for the original model-free equations with parameters {s2, te}; 'mf_ext' for the extended model-free equations with parameters {s2f, tf, s2, ts}; and 'mf_ext2' for the extended model-free equations with parameters {s2f, tf, s2s, ts}.
    @type equation:     str
    @param params:      A list of the parameters to include in the model.  The allowed parameter names includes those for the equation type as well as chemical exchange 'rex', the bond length 'r', and the chemical shift anisotropy 'csa'.
    @type params:       list of str
    @param spin_id:     The spin identification string.
    @type spin_id:      str
    """

    # Test if the current data pipe exists.
    check_pipe()

    # Test if the pipe type is 'mf'.
    function_type = pipes.get_type()
    if function_type != 'mf':
        raise RelaxFuncSetupError(specific_analyses.get_string(function_type))

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Check the validity of the model-free equation type.
    valid_types = ['mf_orig', 'mf_ext', 'mf_ext2']
    if not equation in valid_types:
        raise RelaxError("The model-free equation type argument " +
                         repr(equation) + " is invalid and should be one of " +
                         repr(valid_types) + ".")

    # Check the validity of the parameter array.
    s2, te, s2f, tf, s2s, ts, rex, csa, r = 0, 0, 0, 0, 0, 0, 0, 0, 0
    for i in range(len(params)):
        # Invalid parameter flag.
        invalid_param = 0

        # S2.
        if params[i] == 's2':
            # Does the array contain more than one instance of S2.
            if s2:
                invalid_param = 1
            s2 = 1

            # Does the array contain S2s.
            s2s_flag = 0
            for j in range(len(params)):
                if params[j] == 's2s':
                    s2s_flag = 1
            if s2s_flag:
                invalid_param = 1

        # te.
        elif params[i] == 'te':
            # Does the array contain more than one instance of te and has the extended model-free formula been selected.
            if equation == 'mf_ext' or te:
                invalid_param = 1
            te = 1

            # Does the array contain the parameter S2.
            s2_flag = 0
            for j in range(len(params)):
                if params[j] == 's2':
                    s2_flag = 1
            if not s2_flag:
                invalid_param = 1

        # S2f.
        elif params[i] == 's2f':
            # Does the array contain more than one instance of S2f and has the original model-free formula been selected.
            if equation == 'mf_orig' or s2f:
                invalid_param = 1
            s2f = 1

        # S2s.
        elif params[i] == 's2s':
            # Does the array contain more than one instance of S2s and has the original model-free formula been selected.
            if equation == 'mf_orig' or s2s:
                invalid_param = 1
            s2s = 1

        # tf.
        elif params[i] == 'tf':
            # Does the array contain more than one instance of tf and has the original model-free formula been selected.
            if equation == 'mf_orig' or tf:
                invalid_param = 1
            tf = 1

            # Does the array contain the parameter S2f.
            s2f_flag = 0
            for j in range(len(params)):
                if params[j] == 's2f':
                    s2f_flag = 1
            if not s2f_flag:
                invalid_param = 1

        # ts.
        elif params[i] == 'ts':
            # Does the array contain more than one instance of ts and has the original model-free formula been selected.
            if equation == 'mf_orig' or ts:
                invalid_param = 1
            ts = 1

            # Does the array contain the parameter S2 or S2s.
            flag = 0
            for j in range(len(params)):
                if params[j] == 's2' or params[j] == 's2f':
                    flag = 1
            if not flag:
                invalid_param = 1

        # Rex.
        elif params[i] == 'rex':
            if rex:
                invalid_param = 1
            rex = 1

        # Interatomic distances.
        elif params[i] == 'r':
            if r:
                invalid_param = 1
            r = 1

        # CSA.
        elif params[i] == 'csa':
            if csa:
                invalid_param = 1
            csa = 1

        # Unknown parameter.
        else:
            raise RelaxError("The parameter " + params[i] +
                             " is not supported.")

        # The invalid parameter flag is set.
        if invalid_param:
            raise RelaxError("The parameter array " + repr(params) +
                             " contains an invalid combination of parameters.")

    # Set up the model.
    model_setup(model, equation, params, spin_id)
コード例 #22
0
ファイル: value.py プロジェクト: belisario21/relax_trunk
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.
    pipes.test()

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Minimisation parameter.
    if minimise.return_data_name(param):
        # Minimisation statistic flag.
        min_stat = True

        # Specific value and error returning function.
        return_value = minimise.return_value

        # Specific set function.
        set_fn = minimise.set

    # Normal parameter.
    else:
        # Minimisation statistic flag.
        min_stat = False

        # Specific v
        return_value = specific_analyses.setup.get_specific_fn('return_value', pipes.get_type())

        # 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 not min_stat:
        minimise.reset_min_stats()
コード例 #23
0
ファイル: hybrid.py プロジェクト: tlinnet/relax
    def model_statistics(self,
                         model_info=None,
                         spin_id=None,
                         global_stats=None):
        """Return the k, n, and chi2 model statistics of the hybrid.

        k - number of parameters.
        n - number of data points.
        chi2 - the chi-squared value.


        @keyword model_index:   The model index.  This is zero for the global models or equal to the
                                global spin index (which covers the molecule, residue, and spin
                                indices).  This originates from the model_loop().
        @type model_index:      int
        @keyword spin_id:       The spin identification string.  Either this or the instance keyword
                                argument must be supplied.
        @type spin_id:          None or str
        @keyword global_stats:  A parameter which determines if global or local statistics are
                                returned.  If None, then the appropriateness of global or local
                                statistics is automatically determined.
        @type global_stats:     None or bool
        @return:                The optimisation statistics, in tuple format, of the number of
                                parameters (k), the number of data points (n), and the chi-squared
                                value (chi2).
        @rtype:                 tuple of int, int, float
        """

        # Bad argument combination.
        if model_info == None and spin_id == None:
            raise RelaxError(
                "Either the model_info or spin_id argument must be supplied.")
        elif model_info != None and spin_id != None:
            raise RelaxError("The model_info arg " + repr(model_info) +
                             " and spin_id arg " + repr(spin_id) +
                             " clash.  Only one should be supplied.")

        # Initialise.
        k_total = 0
        n_total = 0
        chi2_total = 0.0

        # Specific setup.
        for pipe in cdp.hybrid_pipes:
            # Switch to the data pipe.
            pipes.switch(pipe)

            # Specific model statistics and number of instances functions.
            model_statistics = setup.get_specific_fn('model_stats',
                                                     pipes.get_type(pipe))

            # Loop over the instances.
            #for i in range(num):
            # Get the statistics.
            k, n, chi2 = model_statistics(model_info=model_info,
                                          spin_id=spin_id,
                                          global_stats=global_stats)

            # Bad stats.
            if k == None or n == None or chi2 == None:
                continue

            # Sum the stats.
            k_total = k_total + k
            n_total = n_total + n
            chi2_total = chi2_total + chi2

        # Return the totals.
        return k_total, n_total, chi2_total
コード例 #24
0
ファイル: uf.py プロジェクト: pombredanne/relax
def create_model(model=None, equation=None, params=None, spin_id=None):
    """Function for creating a custom model-free model.

    @param model:       The name of the model.
    @type model:        str
    @param equation:    The equation type to use.  The 3 allowed types are:  'mf_orig' for the original model-free equations with parameters {s2, te}; 'mf_ext' for the extended model-free equations with parameters {s2f, tf, s2, ts}; and 'mf_ext2' for the extended model-free equations with parameters {s2f, tf, s2s, ts}.
    @type equation:     str
    @param params:      A list of the parameters to include in the model.  The allowed parameter names includes those for the equation type as well as chemical exchange 'rex', the bond length 'r', and the chemical shift anisotropy 'csa'.
    @type params:       list of str
    @param spin_id:     The spin identification string.
    @type spin_id:      str
    """

    # Test if the current data pipe exists.
    check_pipe()

    # Test if the pipe type is 'mf'.
    function_type = pipes.get_type()
    if function_type != "mf":
        raise RelaxFuncSetupError(specific_analyses.get_string(function_type))

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Check the validity of the model-free equation type.
    valid_types = ["mf_orig", "mf_ext", "mf_ext2"]
    if not equation in valid_types:
        raise RelaxError(
            "The model-free equation type argument "
            + repr(equation)
            + " is invalid and should be one of "
            + repr(valid_types)
            + "."
        )

    # Check the validity of the parameter array.
    s2, te, s2f, tf, s2s, ts, rex, csa, r = 0, 0, 0, 0, 0, 0, 0, 0, 0
    for i in range(len(params)):
        # Invalid parameter flag.
        invalid_param = 0

        # S2.
        if params[i] == "s2":
            # Does the array contain more than one instance of S2.
            if s2:
                invalid_param = 1
            s2 = 1

            # Does the array contain S2s.
            s2s_flag = 0
            for j in range(len(params)):
                if params[j] == "s2s":
                    s2s_flag = 1
            if s2s_flag:
                invalid_param = 1

        # te.
        elif params[i] == "te":
            # Does the array contain more than one instance of te and has the extended model-free formula been selected.
            if equation == "mf_ext" or te:
                invalid_param = 1
            te = 1

            # Does the array contain the parameter S2.
            s2_flag = 0
            for j in range(len(params)):
                if params[j] == "s2":
                    s2_flag = 1
            if not s2_flag:
                invalid_param = 1

        # S2f.
        elif params[i] == "s2f":
            # Does the array contain more than one instance of S2f and has the original model-free formula been selected.
            if equation == "mf_orig" or s2f:
                invalid_param = 1
            s2f = 1

        # S2s.
        elif params[i] == "s2s":
            # Does the array contain more than one instance of S2s and has the original model-free formula been selected.
            if equation == "mf_orig" or s2s:
                invalid_param = 1
            s2s = 1

        # tf.
        elif params[i] == "tf":
            # Does the array contain more than one instance of tf and has the original model-free formula been selected.
            if equation == "mf_orig" or tf:
                invalid_param = 1
            tf = 1

            # Does the array contain the parameter S2f.
            s2f_flag = 0
            for j in range(len(params)):
                if params[j] == "s2f":
                    s2f_flag = 1
            if not s2f_flag:
                invalid_param = 1

        # ts.
        elif params[i] == "ts":
            # Does the array contain more than one instance of ts and has the original model-free formula been selected.
            if equation == "mf_orig" or ts:
                invalid_param = 1
            ts = 1

            # Does the array contain the parameter S2 or S2s.
            flag = 0
            for j in range(len(params)):
                if params[j] == "s2" or params[j] == "s2f":
                    flag = 1
            if not flag:
                invalid_param = 1

        # Rex.
        elif params[i] == "rex":
            if rex:
                invalid_param = 1
            rex = 1

        # Interatomic distances.
        elif params[i] == "r":
            if r:
                invalid_param = 1
            r = 1

        # CSA.
        elif params[i] == "csa":
            if csa:
                invalid_param = 1
            csa = 1

        # Unknown parameter.
        else:
            raise RelaxError("The parameter " + params[i] + " is not supported.")

        # The invalid parameter flag is set.
        if invalid_param:
            raise RelaxError("The parameter array " + repr(params) + " contains an invalid combination of parameters.")

    # Set up the model.
    model_setup(model, equation, params, spin_id)
コード例 #25
0
ファイル: pipe_editor.py プロジェクト: tlinnet/relax
    def menu(self, event):
        """The pop up menu.

        @param event:   The wx event.
        @type event:    wx event
        """

        # Get the row.
        row = event.GetRow()

        # Get the name of the data pipe.
        self.selected_pipe = gui_to_str(self.grid.GetCellValue(row, 0))

        # No data pipe.
        if not self.selected_pipe:
            return

        # The pipe type and bundle.
        pipe_type = get_type(self.selected_pipe)
        pipe_bundle = get_bundle(self.selected_pipe)

        # Initialise the menu.
        popup_menus = []

        # Menu entry:  add the data pipe to a bundle.
        if not pipe_bundle:
            popup_menus.append({
                'id': MENU_BUNDLE,
                'text': "&Add the pipe to a bundle",
                'icon': fetch_icon("relax.pipe_bundle"),
                'method': self.pipe_bundle
            })

        # Menu entry:  delete the data pipe.
        popup_menus.append({
            'id': MENU_DELETE,
            'text': "&Delete the pipe",
            'icon': fetch_icon('oxygen.actions.list-remove', "16x16"),
            'method': self.pipe_delete
        })

        # Menu entry:  switch to this data pipe.
        popup_menus.append({
            'id': MENU_SWITCH,
            'text': "&Switch to this pipe",
            'icon': fetch_icon('oxygen.actions.system-switch-user', "16x16"),
            'method': self.pipe_switch
        })

        # Menu entry:  new auto-analysis tab.
        if pipe_bundle and self.gui.analysis.page_index_from_bundle(pipe_bundle) == None and pipe_type in ['noe', 'r1', 'r2', 'mf', 'relax_disp']:
            popup_menus.append({
                'id': MENU_NEW_AUTO_ANALYSIS,
                'text': "&Associate with a new auto-analysis",
                'icon': fetch_icon('oxygen.actions.document-new', "16x16"),
                'method': self.associate_auto
            })

        # Execution lock, so do nothing.
        if status.exec_lock.locked():
            return

        # Initialise the menu.
        menu = wx.Menu()

        # Loop over the menu items.
        for i in range(len(popup_menus)):
            # Alias.
            info = popup_menus[i]

            # Add the menu item.
            menu.AppendItem(build_menu_item(menu, id=info['id'], text=info['text'], icon=info['icon']))

            # Bind clicks.
            self.Bind(wx.EVT_MENU, info['method'], id=info['id'])

        # Pop up the menu.
        if status.show_gui:
            self.PopupMenu(menu)

        # Cleanup.
        menu.Destroy()
コード例 #26
0
ファイル: grace.py プロジェクト: belisario21/relax_trunk
def write_xy_header(file=None, paper_size='A4', title=None, subtitle=None, view=None, graph_num=1, sets=None, set_names=None, set_colours=None, x_axis_type_zero=None, y_axis_type_zero=None, symbols=None, symbol_sizes=None, symbol_fill=None, linestyle=None, linetype=None, linewidth=None, data_type=None, seq_type=None, axis_labels=None, legend=None, legend_pos=None, legend_box_fill_pattern=None, legend_char_size=None, norm=None):
    """Write the grace header for xy-scatter plots.

    Many of these keyword arguments should be supplied in a [X, Y] list format, where the first element corresponds to the X data, and the second the Y data.  Defaults will be used for any non-supplied args (or lists with elements set to None).


    @keyword file:                      The file object to write the data to.
    @type file:                         file object
    @keyword paper_size:                The paper size, i.e. 'A4'.  If set to None, this will default to letter size.
    @type paper_size:                   str
    @keyword title:                     The title of the graph.
    @type title:                        None or str
    @keyword subtitle:                  The sub-title of the graph.
    @type subtitle:                     None or str
    @keyword view:                      List of 4 coordinates defining the graph view port.
    @type view:                         None or list of float
    @keyword graph_num:                 The total number of graphs.
    @type graph_num:                    int
    @keyword sets:                      The number of data sets in each graph.
    @type sets:                         list of int
    @keyword set_names:                 The names associated with each graph data set Gx.Sy.  For example this can be a list of spin identification strings.  The first dimension is the graph, the second is the set.
    @type set_names:                    None or list of list of str
    @keyword set_colours:               The colours for each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type set_colours:                  None or list of list of int
    @keyword x_axis_type_zero:          The flags specifying if the X-axis should be placed at zero.
    @type x_axis_type_zero:             None or list of lists of bool
    @keyword y_axis_type_zero:          The flags specifying if the Y-axis should be placed at zero.
    @type y_axis_type_zero:             None or list of lists of bool
    @keyword symbols:                   The symbol style for each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type symbols:                      None or list of list of int
    @keyword symbol_sizes:              The symbol size for each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type symbol_sizes:                 None or list of list of int
    @keyword symbol_fill:               The symbol file style for each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type symbol_fill:                  None or list of list of int
    @keyword linestyle:                 The line style for each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type linestyle:                    None or list of list of int
    @keyword linetype:                  The line type for each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type linetype:                     None or list of list of int
    @keyword linewidth:                 The line width for all elements of each graph data set Gx.Sy.  The first dimension is the graph, the second is the set.
    @type linewidth:                    None or list of float
    @keyword data_type:                 The axis data category (in the [X, Y] list format).
    @type data_type:                    None or list of list of str
    @keyword seq_type:                  The sequence data type (in the [X, Y] list format).  This is for molecular sequence specific data and can be one of 'res', 'spin', or 'mixed'.
    @type seq_type:                     None or list of list of str
    @keyword axis_labels:               The labels for the axes (in the [X, Y] list format).  The first dimension is the graph.
    @type axis_labels:                  None or list of list of str
    @keyword legend:                    If True, the legend will be visible.  The first dimension is the graph.
    @type legend:                       list of bool
    @keyword legend_pos:                The position of the legend, e.g. [0.3, 0.8].  The first dimension is the graph.
    @type legend_pos:                   None or list of list of float
    @keyword legend_box_fill_pattern:   The legend box fill.  If set to 0, it will become transparent.
    @type legend_box_fill_pattern:      int
    @keyword legend_char_size:          The size of the legend box text.
    @type legend_char_size:             float
    @keyword norm:                      The normalisation flag which if set to True will cause all graphs to be normalised to 1.  The first dimension is the graph.
    @type norm:                         list of bool
    """

    # Defaults.
    if sets == None:
        sets = []
        for gi in range(graph_num):
            sets.append(1)
    if x_axis_type_zero == None:
        x_axis_type_zero = []
        for gi in range(graph_num):
            x_axis_type_zero.append(False)
    if y_axis_type_zero == None:
        y_axis_type_zero = []
        for gi in range(graph_num):
            y_axis_type_zero.append(False)
    if linewidth == None:
        linewidth = []
        for gi in range(graph_num):
            linewidth.append(0.5)
    if norm == None:
        norm = []
        for gi in range(graph_num):
            norm.append(False)
    if not legend_box_fill_pattern:
        legend_box_fill_pattern = []
        for gi in range(graph_num):
            legend_box_fill_pattern.append(1)
    if not legend_char_size:
        legend_char_size = []
        for gi in range(graph_num):
            legend_char_size.append(1.0)

    # Set the None args to lists as needed.
    if not data_type:
        data_type = [None, None]
    if not seq_type:
        seq_type = [None, None]
    if not axis_labels:
        axis_labels = []
        for gi in range(graph_num):
            axis_labels.append([None, None])

    # Set the Grace version number of the header's formatting for compatibility.
    file.write("@version 50121\n")

    # The paper size.
    if paper_size == 'A4':
        file.write("@page size 842, 595\n")

    # Loop over each graph.
    for gi in range(graph_num):
        # Graph Gi.
        file.write("@with g%i\n" % gi)

        # The view port.
        if not view:
            view = [0.15, 0.15, 1.28, 0.85]
        file.write("@    view %s, %s, %s, %s\n" % (view[0], view[1], view[2], view[3]))

        # The title and subtitle.
        if title:
            file.write("@    title \"%s\"\n" % title)
        if subtitle:
            file.write("@    subtitle \"%s\"\n" % subtitle)

        # Axis at zero.
        if x_axis_type_zero[gi]:
            file.write("@    xaxis  type zero true\n")
        if y_axis_type_zero[gi]:
            file.write("@    yaxis  type zero true\n")

        # Axis specific settings.
        axes = ['x', 'y']
        for i in range(2):
            # Analysis specific methods for making labels.
            analysis_spec = False
            if pipes.cdp_name():
                # Flag for making labels.
                analysis_spec = True

                # Specific value and error, conversion factor, and units returning functions.
                return_units = specific_analyses.setup.get_specific_fn('return_units', pipes.get_type())
                return_grace_string = specific_analyses.setup.get_specific_fn('return_grace_string', pipes.get_type())

                # Test if the axis data type is a minimisation statistic.
                if data_type[i] and data_type[i] != 'spin' and pipe_control.minimise.return_data_name(data_type[i]):
                    return_units = pipe_control.minimise.return_units
                    return_grace_string = pipe_control.minimise.return_grace_string

            # Some axis default values for spin data.
            if data_type[i] == 'spin':
                # Residue only data.
                if seq_type[i] == 'res':
                    # X-axis label.
                    if not axis_labels[gi][i]:
                        axis_labels[gi][i] = "Residue number"

                # Spin only data.
                if seq_type[i] == 'spin':
                    # X-axis label.
                    if not axis_labels[gi][i]:
                        axis_labels[gi][i] = "Spin number"

                # Mixed data.
                if seq_type[i] == 'mixed':
                    # X-axis label.
                    if not axis_labels[gi][i]:
                        axis_labels[gi][i] = "Spin identification string"

            # Some axis default values for other data types.
            else:
                # Label.
                if analysis_spec and (not axis_labels or not axis_labels[gi][i]):
                    # Get the units.
                    units = return_units(data_type[i])

                    # Set the label.
                    axis_labels[gi][i] = return_grace_string(data_type[i])

                    # Add units.
                    if units:
                        axis_labels[gi][i] = axis_labels[gi][i] + "\\N (" + units + ")"

                    # Normalised data.
                    if norm and norm[gi] and axes[i] == 'y':
                        axis_labels[gi][i] = axis_labels[gi][i] + " \\N\\q(normalised)\\Q"

            # Write out the data.
            if axis_labels[gi][i]:
                file.write("@    %saxis  label \"%s\"\n" % (axes[i], axis_labels[gi][i]))
            file.write("@    %saxis  label char size 1.00\n" % axes[i])
            file.write("@    %saxis  tick major size 0.50\n" % axes[i])
            file.write("@    %saxis  tick major linewidth %s\n" % (axes[i], linewidth[gi]))
            file.write("@    %saxis  tick minor linewidth %s\n" % (axes[i], linewidth[gi]))
            file.write("@    %saxis  tick minor size 0.25\n" % axes[i])
            file.write("@    %saxis  ticklabel char size 0.70\n" % axes[i])

        # Legend box.
        if legend != None and legend[gi]:
            file.write("@    legend on\n")
        else:
            file.write("@    legend off\n")
        if legend_pos != None:
            file.write("@    legend %s, %s\n" % (legend_pos[gi][0], legend_pos[gi][1]))
        file.write("@    legend box fill pattern %s\n" % legend_box_fill_pattern[gi])
        file.write("@    legend char size %s\n" % legend_char_size[gi])

        # Frame.
        file.write("@    frame linewidth %s\n" % linewidth[gi])

        # Loop over each graph set.
        for i in range(sets[gi]):
            # Symbol style (default to all different symbols).
            if symbols:
                file.write("@    s%i symbol %i\n" % (i, symbols[gi][i]))
            else:
                # The symbol number (cycle between 1 and 10).
                num = i % 10 + 1

                # Write out.
                file.write("@    s%i symbol %i\n" % (i, num))

            # Symbol sizes (default to a small size).
            if symbol_sizes:
                file.write("@    s%i symbol size %s\n" % (i, symbol_sizes[gi][i]))
            else:
                file.write("@    s%i symbol size 0.45\n" % i)

            # The symbol fill.
            if symbol_fill:
                file.write("@    s%i symbol fill pattern %i\n" % (i, symbol_fill[gi][i]))

            # The symbol line width.
            file.write("@    s%i symbol linewidth %s\n" % (i, linewidth[gi]))

            # Symbol colour (default to nothing).
            if set_colours:
                file.write("@    s%i symbol color %s\n" % (i, set_colours[gi][i]))
                file.write("@    s%i symbol fill color %s\n" % (i, set_colours[gi][i]))

            # Error bars.
            file.write("@    s%i errorbar size 0.5\n" % i)
            file.write("@    s%i errorbar linewidth %s\n" % (i, linewidth[gi]))
            file.write("@    s%i errorbar riser linewidth %s\n" % (i, linewidth[gi]))

            # Line linestyle (default to nothing).
            if linestyle:
                file.write("@    s%i line linestyle %s\n" % (i, linestyle[gi][i]))

            # Line linetype (default to nothing).
            if linetype:
                file.write("@    s%i line type %s\n" % (i, linetype[gi][i]))

            # Line and all other colours (default to nothing).
            if set_colours:
                file.write("@    s%i line color %s\n" % (i, set_colours[gi][i]))
                file.write("@    s%i fill color %s\n" % (i, set_colours[gi][i]))
                file.write("@    s%i avalue color %s\n" % (i, set_colours[gi][i]))
                file.write("@    s%i errorbar color %s\n" % (i, set_colours[gi][i]))

            # Legend.
            if set_names and len(set_names) and len(set_names[gi]) and set_names[gi][i]:
                file.write("@    s%i legend \"%s\"\n" % (i, set_names[gi][i]))
コード例 #27
0
ファイル: value.py プロジェクト: belisario21/relax_trunk
def partition_params(val, param):
    """Function for sorting and partitioning the parameters and their values.

    The two major partitions are the tensor parameters and the spin specific parameters.

    @param val:     The parameter values.
    @type val:      None, number, or list of numbers
    @param param:   The parameter names.
    @type param:    None, str, or list of str
    @return:        A tuple, of length 4, of lists.  The first and second elements are the lists of
                    spin specific parameters and values respectively.  The third and forth elements
                    are the lists of all other parameters and their values.
    @rtype:         tuple of 4 lists
    """

    # Specific functions.
    is_spin_param = specific_analyses.setup.get_specific_fn('is_spin_param', pipes.get_type())

    # Initialise.
    spin_params = []
    spin_values = []
    other_params = []
    other_values = []

    # Single parameter.
    if isinstance(param, str):
        # Spin specific parameter.
        if is_spin_param(param):
            params = spin_params
            values = spin_values

        # Other parameters.
        else:
            params = other_params
            values = other_values

        # List of values.
        if isinstance(val, list) or isinstance(val, ndarray):
            # Parameter name.
            for i in range(len(val)):
                params.append(param)

            # Parameter value.
            values = val

        # Single value.
        else:
            # Parameter name.
            params.append(param)

            # Parameter value.
            values.append(val)

    # Multiple parameters.
    elif isinstance(param, list):
        # Loop over all parameters.
        for i in range(len(param)):
            # Spin specific parameter.
            if is_spin_param(param[i]):
                params = spin_params
                values = spin_values

            # Other parameters.
            else:
                params = other_params
                values = other_values

            # Parameter name.
            params.append(param[i])

            # Parameter value.
            if isinstance(val, list) or isinstance(val, ndarray):
                values.append(val[i])
            else:
                values.append(val)


    # Return the partitioned parameters and values.
    return spin_params, spin_values, other_params, other_values
コード例 #28
0
ファイル: relax_data.py プロジェクト: belisario21/relax_trunk
def back_calc(ri_id=None, ri_type=None, frq=None):
    """Back calculate the relaxation data.

    If no relaxation data currently exists, then the ri_id, ri_type, and frq args are required.


    @keyword ri_id:     The relaxation data ID string.  If not given, all relaxation data will be back calculated.
    @type ri_id:        None or str
    @keyword ri_type:   The relaxation data type.  This should be one of 'R1', 'R2', or 'NOE'.
    @type ri_type:      None or str
    @keyword frq:       The spectrometer proton frequency in Hz.
    @type frq:          None or float
    """

    # Test if the current pipe exists.
    pipes.test()

    # Test if sequence data is loaded.
    if not exists_mol_res_spin_data():
        raise RelaxNoSequenceError

    # Check that ri_type and frq are supplied if no relaxation data exists.
    if ri_id and (not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids) and (ri_type == None or frq == None):
        raise RelaxError("The 'ri_type' and 'frq' arguments must be supplied as no relaxation data corresponding to '%s' exists." % ri_id)

    # Check if the type is valid.
    if ri_type and ri_type not in VALID_TYPES:
        raise RelaxError("The relaxation data type '%s' must be one of %s." % (ri_type, VALID_TYPES))

    # Frequency checks.
    frequency_checks(frq)

    # 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 = []

    # Update the global data if needed.
    if ri_id and ri_id not in cdp.ri_ids:
        cdp.ri_ids.append(ri_id)
        cdp.ri_type[ri_id] = ri_type
        set_frequency(id=ri_id, frq=frq)

    # Specific Ri back calculate function setup.
    back_calculate = specific_analyses.setup.get_specific_fn('back_calc_ri', pipes.get_type())

    # The IDs to loop over.
    if ri_id == None:
        ri_ids = cdp.ri_ids
    else:
        ri_ids = [ri_id]

    # The data types.
    if ri_type == None:
        ri_types = cdp.ri_type
    else:
        ri_types = {ri_id: ri_type}

    # The frequencies.
    if frq == None:
        frqs = cdp.spectrometer_frq
    else:
        frqs = {ri_id: frq}

    # Loop over the spins.
    for spin, spin_id in spin_loop(return_id=True):
        # Skip deselected spins.
        if not spin.select:
            continue

        # The global index.
        spin_index = find_index(spin_id)

        # Initialise the spin data if necessary.
        if not hasattr(spin, 'ri_data_bc'):
            spin.ri_data_bc = {}

        # Back-calculate the relaxation value.
        for ri_id in ri_ids:
            spin.ri_data_bc[ri_id] = back_calculate(spin_index=spin_index, ri_id=ri_id, ri_type=ri_types[ri_id], frq=frqs[ri_id])