Hi Ed. I would like to collect the grid seach lower and upper bounds into the table of specific_analysis/relax_disp/parameter_object.py This is to make one place, where such details are collected. And the lower and upper bounds can be extracted for unit tests, and for example dx.map more easily. I have worked it out for lower bounds of pA, and tested it. --- a/specific_analyses/api_base.py +++ b/specific_analyses/api_base.py @@ -314,6 +314,22 @@ class API_base(object): raise RelaxImplementError('grid_search') + def grid_lower(self, param): + """Return the default lower bounds of paramater for the grid search. + + This basic method will first search for a global parameter and, if not found, then a spin parameter. + + + @param param: The specific analysis parameter. + @type param: str + @return: The default value. + @rtype: float + """ + + # Return the value. + return self._PARAMS.grid_lower(param) + + def has_errors(self): """Test if errors exist for the current data pipe. diff --git a/specific_analyses/parameter_object.py b/specific_analyses/parameter_object.py index b626a83..8e7abab 100644 --- a/specific_analyses/parameter_object.py +++ b/specific_analyses/parameter_object.py @@ -54,6 +54,7 @@ class Param_list(object): self._scope = {} self._string = {} self._defaults = {} + self._grid_lowers = {} self._units = {} self._desc = {} self._py_types = {} @@ -92,7 +93,7 @@ class Param_list(object): return cls._instance - def _add(self, name, scope=None, string=None, default=None, units=None, desc=None, py_type=None, set='all', conv_factor=None, grace_string=None, err=False, sim=False): + def _add(self, name, scope=None, string=None, default=None, grid_lower=None, units=None, desc=None, py_type=None, set='all', conv_factor=None, grace_string=None, err=False, sim=False): """Add a parameter to the list. @param name: The name of the parameter. This will be used as the variable name. @@ -103,6 +104,8 @@ class Param_list(object): @type string: None or str @keyword default: The default value of the parameter. @type default: anything + @keyword grid_lower: The default lower bounds of the grid search. + @type grid_lower: float @keyword units: A string representing the parameters units. @type units: None or str @keyword desc: The text description of the parameter. @@ -134,6 +137,7 @@ class Param_list(object): self._names.append(name) self._scope[name] = scope self._defaults[name] = default + self._grid_lowers[name] = grid_lower self._units[name] = units self._desc[name] = desc self._py_types[name] = py_type @@ -540,6 +544,22 @@ class Param_list(object): return self._grace_string[name] + def grid_lower(self, name): + """Return the default lower bounds of paramater for the grid search. + + @param name: The name of the parameter. + @type name: str + @return: The default value. + @rtype: None or str + """ + + # Parameter check. + self.check_param(name) + + # Return the default value. + return self._grid_lowers[name] + + def is_spin_param(self, name): """Determine whether the given parameter is spin specific. diff --git a/specific_analyses/relax_disp/optimisation.py b/specific_analyses/relax_disp/optimisation.py index a92922e..82bd364 100644 --- a/specific_analyses/relax_disp/optimisation.py +++ b/specific_analyses/relax_disp/optimisation.py @@ -38,6 +38,7 @@ from lib.errors import RelaxError from lib.text.sectioning import subsection from multi import Memo, Result_command, Slave_command from pipe_control.mol_res_spin import spin_loop +from specific_analyses.api import return_api from specific_analyses.relax_disp.checks import check_disp_points, check_exp_type, check_exp_type_fixed_time from specific_analyses.relax_disp.data import average_intensity, count_spins, find_intensity_keys, has_exponential_exp_type, has_proton_mmq_cpmg, loop_exp, loop_exp_frq_offset_point, loop_exp_frq_offset_point_time, loop_frq, loop_offset, loop_time, pack_back_calc_r2eff, return_cpmg_frqs, return_offset_data, return_param_key_from_data, return_r1_data, return_r2eff_arrays, return_spin_lock_nu1 from specific_analyses.relax_disp.parameters import assemble_param_vector, assemble_scaling_matrix, disassemble_param_vector, linear_constraints, loop_parameters, param_conversion, param_num @@ -296,6 +297,9 @@ def grid_search_setup(spins=None, spin_ids=None, param_vector=None, lower=None, elif isinstance(inc, int): inc = [inc]*n + # The specific analysis API object. + api = return_api() + # Set up the default bounds. if not lower: # Init. @@ -357,7 +361,9 @@ def grid_search_setup(spins=None, spin_ids=None, param_vector=None, lower=None, if spins[si].model == MODEL_M61B: lower.append(0.85) else: - lower.append(0.5) + #lower.append(0.5) + lower.append(api.grid_lower('pA')) + #lower.append(api.default_value('pA')) upper.append(1.0) # The population of state B (for 3-site exchange). diff --git a/specific_analyses/relax_disp/parameter_object.py b/specific_analyses/relax_disp/parameter_object.py index 936d2b1..21dfe99 100644 --- a/specific_analyses/relax_disp/parameter_object.py +++ b/specific_analyses/relax_disp/parameter_object.py @@ -61,7 +61,7 @@ class Relax_disp_params(Param_list): self._add('r2', scope='spin', default=10.0, desc='The transversal relaxation rate', set='params', py_type=dict, grace_string='\\qR\\s2\\N\\Q (rad.s\\S-1\\N)', err=True, sim=True) self._add('r2a', scope='spin', default=10.0, desc='The transversal relaxation rate for state A in the absence of exchange', set='params', py_type=dict, grace_string='\\qR\\s2,A\\N\\Q (rad.s\\S-1\\N)', err=True, sim=True) self._add('r2b', scope='spin', default=10.0, desc='The transversal relaxation rate for state B in the absence of exchange', set='params', py_type=dict, grace_string='\\qR\\s2,B\\N\\Q (rad.s\\S-1\\N)', err=True, sim=True) - self._add('pA', scope='spin', default=0.90, desc='The population for state A', set='params', py_type=float, grace_string='\\qp\\sA\\N\\Q', err=True, sim=True) + self._add('pA', scope='spin', default=0.90, grid_lower=0.6, desc='The population for state A', set='params', py_type=float, grace_string='\\qp\\sA\\N\\Q', err=True, sim=True) self._add('pB', scope='spin', default=0.5, desc='The population for state B', set='params', py_type=float, grace_string='\\qp\\sB\\N\\Q', err=True, sim=True) self._add('pC', scope='spin', default=0.5, desc='The population for state C', set='params', py_type=float, grace_string='\\qp\\sC\\N\\Q', err=True, sim=True) self._add('phi_ex', scope='spin', default=5.0, desc='The phi_ex = pA.pB.dw**2 value (ppm^2)', set='params', py_type=float, grace_string='\\xF\\B\\sex\\N = \\q p\\sA\\N.p\\sB\\N.\\xDw\\B\\S2\\N\\Q (ppm\\S2\\N)', err=True, sim=True) Best Troels