mailr19382 - /branches/relax_disp/specific_analyses/relax_disp.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by edward on April 05, 2013 - 12:18:
Author: bugman
Date: Fri Apr  5 12:18:09 2013
New Revision: 19382

URL: http://svn.gna.org/viewcvs/relax?rev=19382&view=rev
Log:
Activated Monte Carlo simulations for the relaxation dispersion analysis.

This required a bit of work.  The key parts weres renaming _block_loop() to 
the API method
model_loop() as that is exactly what the model_loop() method is supposed to 
do, converting a bunch
of API common spin-based methods to handle dispersion clustering, and to 
modify existing methods
from Seb's original branch to handle the base_data_loop() method.  The 
following methods have been
added or modified:

_back_calc():  This method has been modified to handle clustering and the 
returning of peak intensities
from only one exponential curve.

_exp_curve_index_from_key():  This new method is used to convert exponential 
curve key into the
corresponding index.

_intensity_key():  This new method is for converting an exponential curve key 
and relaxation time
into the corresponding intensity key.

create_mc_data():  This method is now functional and handles the data from 
the base_data_loop() method.

return_error():  This method now handles the data from the base_data_loop() 
method.

set_selected_sim():  This new method has been modified from the common 
_set_selected_sim_spin()
method but modified for the model_loop() method.

sim_pack_data():  This method now handles the data from the base_data_loop() 
method.

sim_return_param():  This new method has been modified from the common 
_sim_return_param_spin()
method to suit the model_loop().

sim_return_selected():  This new method has been modified from the common
_sim_return_selected_spin() method again to suit the model_loop().


Modified:
    branches/relax_disp/specific_analyses/relax_disp.py

Modified: branches/relax_disp/specific_analyses/relax_disp.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/relax_disp/specific_analyses/relax_disp.py?rev=19382&r1=19381&r2=19382&view=diff
==============================================================================
--- branches/relax_disp/specific_analyses/relax_disp.py (original)
+++ branches/relax_disp/specific_analyses/relax_disp.py Fri Apr  5 12:18:09 
2013
@@ -24,6 +24,7 @@
 """The relaxation dispersion curve fitting specific code."""
 
 # Python module imports.
+from copy import deepcopy
 from minfx.generic import generic_minimise
 from minfx.grid import grid
 from numpy import array, average, dot, float64, identity, log, zeros
@@ -54,15 +55,11 @@
 
         # Place methods into the API.
         self.data_init = self._data_init_spin
-        self.model_loop = self._model_loop_spin
         self.return_conversion_factor = self._return_no_conversion_factor
         self.return_value = self._return_value_general
         self.set_error = self._set_error_spin
         self.set_param_values = self._set_param_values_spin
-        self.set_selected_sim = self._set_selected_sim_spin
         self.sim_init_values = self._sim_init_values_spin
-        self.sim_return_param = self._sim_return_param_spin
-        self.sim_return_selected = self._sim_return_selected_spin
 
         # Set up the spin parameters.
         self.PARAMS.add('intensities', scope='spin', py_type=dict, 
grace_string='\\qPeak intensities\\Q')
@@ -253,32 +250,29 @@
         return scaling_matrix
 
 
-    def _back_calc(self, spins=None, result_index=None):
-        """Back-calculation of peak intensity for the given CPMG pulse train 
frequency.
-
-        @keyword spins:         The list of spin data containers for the 
block.
-        @type spins:            list of SpinContainer instances
-        @keyword result_index:  The index for the back-calculated data 
associated to every CPMG or R1rho frequency, as well as every magnetic field 
frequency.
-        @type result_index:     int
-        @return:                The R2eff value associated to every CPMG or 
R1rho frequency, as well as every magnetic field frequency.
-        @rtype:                 float
+    def _back_calc(self, spin=None, index=None):
+        """Back-calculation of peak intensity for the given spin and 
exponential curve index.
+
+        @keyword spin:  The specific spin data container.
+        @type spin:     SpinContainer instance
+        @keyword index: The index for the specific exponential curve.
+        @type index:    int
+        @return:        The back-calculated peak intensities for the given 
exponential curve
+        @rtype:         numpy rank-1 float array
         """
 
         # Create the initial parameter vector.
-        param_vector = self._assemble_param_vector(spins=spins)
+        param_vector = self._assemble_param_vector(spins=[spin])
 
         # Create a scaling matrix.
-        scaling_matrix = self._assemble_scaling_matrix(spins=spins, 
scaling=False)
-
-        # The spin count.
-        spin_num = len(spins)
+        scaling_matrix = self._assemble_scaling_matrix(spins=[spin], 
scaling=False)
 
         # Initialise the data structures for the target function.
-        values = zeros((spin_num, cdp.curve_count, cdp.num_time_pts), 
float64)
-        errors = zeros((spin_num, cdp.curve_count, cdp.num_time_pts), 
float64)
+        values = zeros((1, cdp.curve_count, cdp.num_time_pts), float64)
+        errors = zeros((1, cdp.curve_count, cdp.num_time_pts), float64)
 
         # Initialise the relaxation dispersion fit functions.
-        model = Dispersion(model=cdp.model, 
num_params=self._param_num(spins=spins), num_spins=spin_num, 
num_exp_curves=cdp.curve_count, num_times=cdp.num_time_pts, values=values, 
errors=errors, cpmg_frqs=cdp.cpmg_frqs_list, 
spin_lock_nu1=cdp.spin_lock_nu1_list, relax_times=cdp.relax_time_list, 
scaling_matrix=scaling_matrix)
+        model = Dispersion(model=cdp.model, 
num_params=self._param_num(spins=[spin]), num_spins=1, 
num_exp_curves=cdp.curve_count, num_times=cdp.num_time_pts, values=values, 
errors=errors, cpmg_frqs=cdp.cpmg_frqs_list, 
spin_lock_nu1=cdp.spin_lock_nu1_list, relax_times=cdp.relax_time_list, 
scaling_matrix=scaling_matrix)
 
         # Make a single function call.  This will cause back calculation and 
the data will be stored in the class instance.
         model.func(param_vector)
@@ -286,25 +280,8 @@
         # Get the data back.
         results = model.back_calc
 
-        # Return the correct peak height.
-        return results
-
-
-    def _block_loop(self):
-        """Loop over the spin groupings for one model applied to multiple 
spins.
-
-        @return:    The list of spins per block will be yielded, as well as 
the list of spin IDs.
-        @rtype:     list of SpinContainer instances
-        """
-
-        # Loop over the sequence.
-        for spin, spin_id in spin_loop(return_id=True):
-            # Skip deselected spins.
-            if not spin.select:
-                continue
-
-            # Return the spin container as a stop-gap measure.
-            yield [spin], [spin_id]
+        # Return the correct peak intensity series.
+        return results[0, index]
 
 
     def _cpmg_delayT(self, id=None, delayT=None):
@@ -441,14 +418,14 @@
                     # Effective transversal relaxation rate.
                     if spin.params[i] == 'R2eff':
                         if sim_index != None:
-                            spin.r2eff_sim[key][sim_index] = 
param_vector[index]
+                            spin.r2eff_sim[sim_index][key] = 
param_vector[index]
                         else:
                             spin.r2eff[key] = param_vector[index]
 
                     # Initial intensity.
                     elif spin.params[i] == 'I0':
                         if sim_index != None:
-                            spin.i0_sim[key][sim_index] = 
param_vector[index+1]
+                            spin.i0_sim[sim_index][key] = 
param_vector[index+1]
                         else:
                             spin.i0[key] = param_vector[index+1]
 
@@ -499,6 +476,24 @@
 
             # Increment the parameter index.
             param_index = param_index + 1
+
+
+    def _exp_curve_index_from_key(self, key):
+        """Convert the exponential curve key into the corresponding index.
+
+        @param key: The exponential curve key - either the CPMG frequency or 
R1rho spin-lock field strength.
+        @type key:  float
+        @return:    The corresponding index.
+        @rtype:     int
+        """
+
+        # CPMG data.
+        if cdp.exp_type == 'cpmg':
+            return cdp.cpmg_frqs_list.index(key)
+
+        # R1rho data.
+        else:
+            return cdp.spin_lock_nu1_list.index(key)
 
 
     def _exp_curve_loop(self):
@@ -702,6 +697,47 @@
         return grid_size, inc, lower_new, upper_new, sparseness
 
 
+    def _intensity_key(self, exp_key=None, relax_time=None):
+        """Return the intensity key corresponding to the given exponential 
curve key and relaxation time.
+
+        @keyword exp_key:       The CPMG frequency or R1rho spin-lock field 
strength used as a key to identify each exponential curve.
+        @type exp_key:          float
+        @keyword relax_time:    The time, in seconds, of the relaxation 
period.
+        @type relax_time:       float
+        """
+
+        # Find all keys corresponding to the given relaxation time.
+        time_keys = []
+        for key in cdp.relax_times:
+            if cdp.relax_times[key] == relax_time:
+                time_keys.append(key)
+
+        # Find all keys corresponding to the given exponential key.
+        exp_keys = []
+        if cdp.exp_type == 'cpmg':
+            data = cdp.cpmg_frqs
+        else:
+            data = cdp.spin_lock_nu1
+        for key in data:
+            if data[key] == exp_key:
+                exp_keys.append(key)
+
+        # The common key.
+        common_key = []
+        for key in time_keys:
+            if key in exp_keys:
+                common_key.append(key)
+
+        # Sanity checks.
+        if len(common_key) == 0:
+            raise RelaxError("No intensity key could be found for the CPMG 
frequency or R1rho spin-lock field strength of %s and relaxation time period 
of %s seconds." % (exp_key, relax_time))
+        if len(common_key) != 1:
+            raise RelaxError("More than one intensity key %s found for the 
CPMG frequency or R1rho spin-lock field strength of %s and relaxation time 
period of %s seconds." % (common_key, exp_key, relax_time))
+
+        # Return the unique key.
+        return common_key[0]
+
+
     def _linear_constraints(self, spins=None, scaling_matrix=None):
         """Set up the relaxation dispersion curve fitting linear constraint 
matrices A and b.
 
@@ -999,40 +1035,23 @@
     def create_mc_data(self, data_id):
         """Create the Monte Carlo peak intensity data.
 
-        @param data_id: The spin identification string, as yielded by the 
base_data_loop() generator method.
-        @type data_id:  str
+        @param data_id: The tuple of the spin container and the exponential 
curve identifying key, as yielded by the base_data_loop() generator method.
+        @type data_id:  SpinContainer instance and float
         @return:        The Monte Carlo simulation data.
         @rtype:         list of floats
         """
 
-        # Initialise the MC data data structure.
-        mc_data = []
-
-        # Get the spin container.
-        spin = return_spin(data_id)
-
-        # Skip deselected spins.
-        if not spin.select:
-            return
-
-        # Skip spins which have no data.
-        if not hasattr(spin, 'intensities'):
-            return
-
-        # Test if the model is set.
-        if not hasattr(spin, 'model') or not spin.model:
-            raise RelaxNoModelError
-
-        # Loop over the spectral time points.
-        for j in xrange(len(cdp.cpmg_frqs)):
-            # Back calculate the value.
-            value = self._back_calc(spin=spin, result_index=j)
-
-            # Append the value.
-            mc_data.append(value)
+        # Unpack the data.
+        spin, key = data_id
+
+        # The exponential curve index.
+        index = self._exp_curve_index_from_key(key)
+
+        # Back calculate the peak intensities.
+        values = self._back_calc(spin=spin, index=index)
 
         # Return the MC data.
-        return mc_data
+        return values
 
 
     def grid_search(self, lower=None, upper=None, inc=None, 
constraints=True, verbosity=1, sim_index=None):
@@ -1111,7 +1130,7 @@
             cdp.spin_lock_nu1_list = []
 
         # Loop over the spin blocks.
-        for spins, spin_ids in self._block_loop():
+        for spins, spin_ids in self.model_loop():
             # The spin count.
             spin_num = len(spins)
 
@@ -1140,7 +1159,7 @@
                     if sim_index == None:
                         values[spin_index, curve_index, time_index] = 
spin.intensities[key]
                     else:
-                        values[spin_index, curve_index, time_index] = 
spin.sim_intensities[sim_index][key]
+                        values[spin_index, curve_index, time_index] = 
spin.intensity_sim[key][sim_index]
 
                     # The errors.
                     errors[spin_index, curve_index, time_index] = 
spin.intensity_err[key]
@@ -1246,6 +1265,23 @@
 
                     # Warning.
                     spin.warning = warning
+
+
+    def model_loop(self):
+        """Loop over the spin groupings for one model applied to multiple 
spins.
+
+        @return:    The list of spins per block will be yielded, as well as 
the list of spin IDs.
+        @rtype:     tuple of list of SpinContainer instances and list of 
spin IDs
+        """
+
+        # Loop over the sequence.
+        for spin, spin_id in spin_loop(return_id=True):
+            # Skip deselected spins.
+            if not spin.select:
+                continue
+
+            # Return the spin container as a stop-gap measure.
+            yield [spin], [spin_id]
 
 
     def overfit_deselect(self, data_check=True, verbose=True):
@@ -1307,38 +1343,104 @@
     def return_error(self, data_id=None):
         """Return the standard deviation data structure.
 
-        @param data_id: The spin ID string, as yielded by the 
base_data_loop() generator method.
-        @type data_id:  str
+        @param data_id: The tuple of the spin container and the exponential 
curve identifying key, as yielded by the base_data_loop() generator method.
+        @type data_id:  SpinContainer instance and float
         @return:        The standard deviation data structure.
         @rtype:         list of float
         """
 
-        # Get the spin container.
-        spin = return_spin(data_id)
+        # Unpack the data.
+        spin, key = data_id
+
+        # Generate the data structure to return.
+        errors = []
+        for time in cdp.relax_time_list:
+            # Get the intensity key.
+            int_key = self._intensity_key(exp_key=key, relax_time=time)
+
+            # Add the data.
+            errors.append(spin.intensity_err[int_key])
 
         # Return the error list.
-        return spin.intensity_err
+        return errors
 
 
     set_doc = Desc_container("Relaxation dispersion curve fitting set 
details")
     set_doc.add_paragraph("Only three parameters can be set for either the 
slow- or the fast-exchange regime. For the slow-exchange regime, these 
parameters include the transversal relaxation rate for state A (R2A), the 
exchange rate from state A to state (kA) and the chemical shift difference 
between states A and B (dw). For the fast-exchange regime, these include the 
transversal relaxation rate (R2), the chemical exchange contribution to R2 
(Rex) and the exchange rate (kex). Setting parameters for a non selected 
model has no effect.")
 
 
+    def set_selected_sim(self, model_info, select_sim):
+        """Set the simulation selection flag.
+
+        @param model_info:  The list of spins and spin IDs per cluster 
originating from model_loop().
+        @type model_info:   tuple of list of SpinContainer instances and 
list of spin IDs
+        @param select_sim:  The selection flag for the simulations.
+        @type select_sim:   bool
+        """
+
+        # Unpack the data.
+        spins, spin_ids = model_info
+
+        # Loop over the spins, storing the structure for each spin.
+        for spin in spins:
+            spin.select_sim = deepcopy(select_sim)
+
+
     def sim_pack_data(self, data_id, sim_data):
         """Pack the Monte Carlo simulation data.
 
-        @param data_id:     The spin ID string, as yielded by the 
base_data_loop() generator method.
-        @type data_id:      str
+        @param data_id:     The tuple of the spin container and the 
exponential curve identifying key, as yielded by the base_data_loop() 
generator method.
+        @type data_id:      SpinContainer instance and float
         @param sim_data:    The Monte Carlo simulation data.
         @type sim_data:     list of float
         """
 
-        # Get the spin container.
-        spin = return_spin(data_id)
-
-        # Test if the simulation data already exists.
-        if hasattr(spin, 'sim_intensities'):
-            raise RelaxError("Monte Carlo simulation data already exists.")
-
-        # Create the data structure.
-        spin.sim_intensities = sim_data
+        # Unpack the data.
+        spin, key = data_id
+
+        # Initialise the data structure if needed.
+        if not hasattr(spin, 'intensity_sim'):
+            spin.intensity_sim = {}
+
+        # Loop over each time point.
+        for time_index in range(cdp.num_time_pts):
+            # Get the intensity key.
+            int_key = self._intensity_key(exp_key=key, 
relax_time=cdp.relax_time_list[time_index])
+
+            # Test if the simulation data point already exists.
+            if int_key in spin.intensity_sim:
+                raise RelaxError("Monte Carlo simulation data for the key 
'%s' already exists." % int_key)
+
+            # Initialise the list.
+            spin.intensity_sim[int_key] = []
+
+            # Loop over the simulations, appending the corresponding data.
+            for i in range(cdp.sim_number):
+                spin.intensity_sim[int_key].append(sim_data[i][time_index])
+
+
+    def sim_return_param(self, model_info, index):
+        """Return the array of simulation parameter values.
+
+        @param model_info:  The model information originating from 
model_loop().
+        @type model_info:   unknown
+        @param index:       The index of the parameter to return the array 
of values for.
+        @type index:        int
+        @return:            The array of simulation parameter values.
+        @rtype:             list of float
+        """
+
+    def sim_return_selected(self, model_info):
+        """Return the array of selected simulation flags.
+
+        @param model_info:  The list of spins and spin IDs per cluster 
originating from model_loop().
+        @type model_info:   tuple of list of SpinContainer instances and 
list of spin IDs
+        @return:            The array of selected simulation flags.
+        @rtype:             list of int
+        """
+
+        # Unpack the data.
+        spins, spin_ids = model_info
+
+        # Return the array from the first spin, as this array will be 
identical for all spins in the cluster.
+        return spins[0].select_sim




Related Messages


Powered by MHonArc, Updated Fri Apr 05 12:40:01 2013