Author: bugman Date: Tue Jul 23 20:00:59 2013 New Revision: 20469 URL: http://svn.gna.org/viewcvs/relax?rev=20469&view=rev Log: Implemented the new relax_disp.parameter_copy user function. This is used to copy relaxation dispersion parameters from one data pipe to another, taking cluster averaging into account. It is used by the dispersion auto-analysis to handle clustering. Modified: branches/relax_disp/specific_analyses/relax_disp/parameters.py branches/relax_disp/user_functions/relax_disp.py Modified: branches/relax_disp/specific_analyses/relax_disp/parameters.py URL: http://svn.gna.org/viewcvs/relax/branches/relax_disp/specific_analyses/relax_disp/parameters.py?rev=20469&r1=20468&r2=20469&view=diff ============================================================================== --- branches/relax_disp/specific_analyses/relax_disp/parameters.py (original) +++ branches/relax_disp/specific_analyses/relax_disp/parameters.py Tue Jul 23 20:00:59 2013 @@ -24,13 +24,18 @@ """Functions relating to the parameters of the relaxation dispersion models.""" # Python module imports. +from copy import deepcopy from numpy import array, float64, identity, zeros from re import search +import sys # relax module imports. -from lib.errors import RelaxError +from lib.errors import RelaxError, RelaxNoSequenceError from lib.mathematics import round_to_next_order -from specific_analyses.relax_disp.disp_data import count_frq, loop_frq, loop_frq_point +from lib.text.sectioning import subsection +from pipe_control import pipes +from pipe_control.mol_res_spin import exists_mol_res_spin_data, return_spin +from specific_analyses.relax_disp.disp_data import count_frq, loop_cluster, loop_frq, loop_frq_point from specific_analyses.relax_disp.variables import MODEL_R2EFF, MODEL_M61B, VAR_TIME_EXP @@ -118,6 +123,162 @@ # Return the scaling matrix. return scaling_matrix + +def copy(pipe_from=None, pipe_to=None): + """Copy dispersion parameters from one data pipe to another, averaging values for clusters. + + @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 + """ + + # The current data pipe. + pipe_orig = pipes.cdp_name() + if pipe_from == None: + pipe_from = pipe_orig + if pipe_to == None: + pipe_to = pipe_orig + + # Test that the pipes exist. + pipes.test(pipe_from) + pipes.test(pipe_to) + + # Test that the pipes are not the same. + if pipe_from == pipe_to: + raise RelaxError("The source and destination pipes cannot be the same.") + + # 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) + + # Switch to the destination data pipe. + pipes.switch(pipe_to) + + # Loop over the clusters. + for spin_ids in loop_cluster(): + # Initialise some variables. + model = None + pA = 0.0 + kex = 0.0 + kB = 0.0 + kC = 0.0 + tex = 0.0 + count = 0 + spins_from = [] + spins_to = [] + selected_cluster = False + + # Loop over the spins, summing the parameters to be averaged. + for id in spin_ids: + # Get the spins, then store them. + spin_from = return_spin(id, pipe=pipe_from) + spin_to = return_spin(id, pipe=pipe_to) + spins_from.append(spin_from) + spins_to.append(spin_to) + + # Skip deselected spins. + if not spin_from.select or not spin_to.select: + continue + + # The first printout. + if not selected_cluster: + subsection(file=sys.stdout, text="Copying parameters for the spin block %s"%spin_ids, prespace=2) + + # Change the cluster selection flag. + selected_cluster = True + + # The model. + if not model: + model = spin_from.model + + # Check that the models match for all spins of the cluster. + if spin_from.model != model: + raise RelaxError("The model '%s' of spin '%s' from the source data pipe does not match the '%s' model of previous spins of the cluster." % (spin_from.model, id, model)) + if spin_to.model != model: + raise RelaxError("The model '%s' of spin '%s' from the destination data pipe does not match the '%s' model of previous spins of the cluster." % (spin_from.model, id, model)) + + # Sum the source parameters. + if 'pA' in spin_from.params: + pA += spin_from.pA + if 'kex' in spin_from.params: + kex += spin_from.kex + if 'kB' in spin_from.params: + kB += spin_from.kB + if 'kC' in spin_from.params: + kC += spin_from.kC + if 'tex' in spin_from.params: + tex += spin_from.tex + + # Increment the spin count. + count += 1 + + # The cluster is not selected, so move to the next. + if not selected_cluster: + continue + + # Average parameters. + if pA != 0.0: + pA = pA / count + print("Averaged pA value: %.15f" % pA) + if kex != 0.0: + kex = kex / count + print("Averaged kex value: %.15f" % kex) + if kB != 0.0: + kB = kB / count + print("Averaged kB value: %.15f" % kB) + if kC != 0.0: + kC = kC / count + print("Averaged kC value: %.15f" % kC) + if tex != 0.0: + tex = tex / count + print("Averaged tex value: %.15f" % tex) + + # Loop over the spins, this time copying the parameters. + for i in range(len(spin_ids)): + # Alias the containers. + spin_from = spins_from[i] + spin_to = spins_to[i] + + # Skip deselected spins. + if not spin_from.select or not spin_to.select: + continue + + # The R20 parameters. + if 'r2' in spin_from.params: + spin_to.r2 = deepcopy(spin_from.r2) + if 'r2a' in spin_from.params: + spin_to.r2a = deepcopy(spin_from.r2a) + if 'r2b' in spin_from.params: + spin_to.r2b = deepcopy(spin_from.r2b) + + # The averaged parameters. + if 'pA' in spin_from.params: + spin_to.pA = pA + spin_to.pB = 1.0 - pA + if 'kex' in spin_from.params: + spin_to.kex = kex + if 'kB' in spin_from.params: + spin_to.kB = kB + if 'kC' in spin_from.params: + spin_to.kC = kC + if 'tex' in spin_from.params: + spin_to.tex = tex + + # All other spin specific parameters. + for param in spin_from.params: + if param in ['r2', 'pA', 'kex', 'kB', 'kC', 'tex']: + continue + + # Copy the value. + setattr(spin_to, param, deepcopy(getattr(spin_from, param))) + + # Switch back to the original data pipe. + pipes.switch(pipe_orig) def disassemble_param_vector(param_vector=None, key=None, spins=None, sim_index=None): """Disassemble the parameter vector. Modified: branches/relax_disp/user_functions/relax_disp.py URL: http://svn.gna.org/viewcvs/relax/branches/relax_disp/user_functions/relax_disp.py?rev=20469&r1=20468&r2=20469&view=diff ============================================================================== --- branches/relax_disp/user_functions/relax_disp.py (original) +++ branches/relax_disp/user_functions/relax_disp.py Tue Jul 23 20:00:59 2013 @@ -32,12 +32,13 @@ FD_SAVE = -1 # relax module imports. -from pipe_control import spectrum +from pipe_control import pipes, spectrum from pipe_control.mol_res_spin import get_spin_ids from graphics import ANALYSIS_IMAGE_PATH, WIZARD_IMAGE_PATH from specific_analyses.relax_disp.cpmgfit import cpmgfit_execute, cpmgfit_input from specific_analyses.relax_disp.disp_data import cpmg_frq, plot_disp_curves, plot_exp_curves, relax_time, spin_lock_field from specific_analyses.relax_disp.nessy import nessy_input +from specific_analyses.relax_disp.parameters import copy from specific_analyses.relax_disp.sherekhan import sherekhan_input from specific_analyses.relax_disp.variables import MODEL_CR72, MODEL_CR72_FULL, MODEL_DPL94, MODEL_IT99, MODEL_LM63, MODEL_LM63_3SITE, MODEL_M61, MODEL_M61B, MODEL_NOREX, MODEL_R2EFF, MODEL_NS_2SITE_3D, MODEL_NS_2SITE_3D_FULL, MODEL_NS_2SITE_EXPANDED, MODEL_NS_2SITE_STAR, MODEL_NS_2SITE_STAR_FULL from specific_analyses.setup import relax_disp_obj @@ -316,6 +317,42 @@ uf.wizard_size = (800, 600) uf.wizard_apply_button = False uf.wizard_image = WIZARD_IMAGE_PATH + 'nessy.png' + + +# The relax_disp.parameter_copy user function. +uf = uf_info.add_uf('relax_disp.parameter_copy') +uf.title = "Copy dispersion specific parameters values from one data pipe to another." +uf.title_short = "Dispersion parameter copying." +uf.add_keyarg( + name = "pipe_from", + py_type = "str", + desc_short = "source data pipe", + desc = "The name of the pipe to copy from.", + wiz_element_type = 'combo', + wiz_combo_iter = pipes.pipe_names, + wiz_read_only = True +) +uf.add_keyarg( + name = "pipe_to", + py_type = "str", + desc_short = "destination data pipe", + desc = "The name of the pipe to copy to.", + wiz_element_type = 'combo', + wiz_combo_iter = pipes.pipe_names, + wiz_read_only = True +) +# Description. +uf.desc.append(Desc_container()) +uf.desc[-1].add_paragraph("This is a special function for copying relaxation dispersion parameters from one data pipe to another. It is much more advanced than the value.copy user function, in that clustering is taken into account. When the destination data pipe has spin clusters defined, then the new parameter values, when required, will be averaged.") +uf.desc[-1].add_paragraph("For the cluster specific parameters, i.e. the populations of the states and the exchange parameters, an average value will be used as the starting point. For all other parameters, the R20 values for each spin and magnetic field, as well as the parameters related to the chemical shift difference dw, the optimised values of the previous run will be directly copied.") +uf.desc.append(Desc_container("Prompt examples")) +uf.desc[-1].add_paragraph("To copy the CSA values from the data pipe 'm1' to 'm2', type:") +uf.desc[-1].add_prompt("relax> value.parameter_copy('m1', 'm2', 'csa')") +uf.backend = copy +uf.menu_text = "¶meter_copy" +uf.gui_icon = "oxygen.actions.list-add" +uf.wizard_size = (800, 500) +uf.wizard_image = ANALYSIS_IMAGE_PATH + 'relax_disp_200x200.png' # The relax_disp.plot_disp_curves user function.