Hi Edward.

Thank you for the detailed description.

I currently don't have time to look into api implementation.

Best
Troels

2014-09-12 11:53 GMT+02:00 Edward d'Auvergne <[email protected]>:
> Hi Troels,
>
> For the backend function, instead of duplicating code and having one
> backend in the relaxation dispersion analysis and one backend in the
> relaxation curve-fitting analysis - now is the time to learn the
> specific analysis API!  I cannot emphasis how simple this is.  The
> steps would be:
>
> 1)  Create the error_analysis.covariance_matrix user function frontend
> in user_functions/.  This would be instead of creating a new relax_fit
> user function, and would be pretty much identical anyway.
>
> 2a)  I have renamed the pipe_control.monte_carlo module to
> pipe_control.error_analysis.  I have prepended the text 'monte_carlo_'
> to all of the current functions.  This module will be used for all
> error analysis techniques:  Monte Carlo simulations, covariance
> matrix, Jackknife simulations, Bootstrapping (which is currently via
> the Monte Carlo functions), etc.
>
> 2b)  Create a new function in pipe_control.error_analysis called
> covariance_matrix().
>
> 3)  Inside covariance_matrix(), call "api = return_api()", and then
> call "api.covariance_matrix()".  For the 'relax-fit' analysis, this
> will be the covariance_matrix() method in the
> specific_analyses.relax_fit.api module.
>
> 4)  Add a stub covariance_matrix() method to
> specific_analyses.api_base.  This defines how the method should be
> named and what arguments it takes.
>
> 5)  Add a new covariance_matrix() method to specific_analyses.relax_fit.api.
>
> That's all there is too it.  It is really time for this!  The entire
> point of the specific analysis API is to avoid what you are currently
> implementing in relax.  If the pattern of what you are doing is
> extended to all analysis types, which might happen in the future, then
> there will be huge amounts of code duplication required.  This is a
> bad design.  You need to dive into the specific API!  The steps above
> are all that are required for this.  Oh, a system test with a call to
> the error_analysis.covariance_matrix user function would be the best
> way to start this.
>
> Regards,
>
> Edward
>
> On 12 September 2014 11:25,  <[email protected]> wrote:
>> Author: tlinnet
>> Date: Fri Sep 12 11:25:50 2014
>> New Revision: 25775
>>
>> URL: http://svn.gna.org/viewcvs/relax?rev=25775&view=rev
>> Log:
>> Implemented back-end function to estimate Rx and I0 errors from Jacobian 
>> matrix.
>>
>> This is to prepare for user funcion in relax_fit, to estimate errors.
>>
>> Added:
>>     trunk/specific_analyses/relax_fit/estimate_rx_err.py
>> Modified:
>>     trunk/specific_analyses/relax_fit/__init__.py
>>
>> Modified: trunk/specific_analyses/relax_fit/__init__.py
>> URL: 
>> http://svn.gna.org/viewcvs/relax/trunk/specific_analyses/relax_fit/__init__.py?rev=25775&r1=25774&r2=25775&view=diff
>> ==============================================================================
>> --- trunk/specific_analyses/relax_fit/__init__.py       (original)
>> +++ trunk/specific_analyses/relax_fit/__init__.py       Fri Sep 12 11:25:50 
>> 2014
>> @@ -25,6 +25,7 @@
>>  # The available modules.
>>  __all__ = [
>>      'api',
>> +    'estimate_rx_err',
>>      'optimisation',
>>      'parameter_object',
>>      'parameters',
>>
>> Added: trunk/specific_analyses/relax_fit/estimate_rx_err.py
>> URL: 
>> http://svn.gna.org/viewcvs/relax/trunk/specific_analyses/relax_fit/estimate_rx_err.py?rev=25775&view=auto
>> ==============================================================================
>> --- trunk/specific_analyses/relax_fit/estimate_rx_err.py        (added)
>> +++ trunk/specific_analyses/relax_fit/estimate_rx_err.py        Fri Sep 12 
>> 11:25:50 2014
>> @@ -0,0 +1,157 @@
>> +###############################################################################
>> +#                                                                           
>>   #
>> +# Copyright (C) 2014 Troels E. Linnet                                       
>>   #
>> +#                                                                           
>>   #
>> +# This file is part of the program relax (http://www.nmr-relax.com).        
>>   #
>> +#                                                                           
>>   #
>> +# This program is free software: you can redistribute it and/or modify      
>>   #
>> +# it under the terms of the GNU General Public License as published by      
>>   #
>> +# the Free Software Foundation, either version 3 of the License, or         
>>   #
>> +# (at your option) any later version.                                       
>>   #
>> +#                                                                           
>>   #
>> +# This program is distributed in the hope that it will be useful,           
>>   #
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of            
>>   #
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             
>>   #
>> +# GNU General Public License for more details.                              
>>   #
>> +#                                                                           
>>   #
>> +# You should have received a copy of the GNU General Public License         
>>   #
>> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.     
>>   #
>> +#                                                                           
>>   #
>> +###############################################################################
>> +
>> +# Module docstring.
>> +"""Estimation of rx error, from Co-variance matrix."""
>> +
>> +# Python module imports.
>> +from copy import deepcopy
>> +from numpy import asarray, diag, sqrt, transpose
>> +import sys
>> +from warnings import warn
>> +
>> +# relax module imports.
>> +from dep_check import C_module_exp_fn
>> +from lib.errors import RelaxError
>> +from lib.statistics import multifit_covar
>> +from lib.text.sectioning import subsection
>> +from lib.warnings import RelaxWarning
>> +from pipe_control.mol_res_spin import generate_spin_string, spin_loop
>> +
>> +# C modules.
>> +if C_module_exp_fn:
>> +    from target_functions.relax_fit import jacobian, jacobian_chi2, setup
>> +
>> +
>> +def estimate_rx_err(spin_id=None, epsrel=0.0, verbosity=2):
>> +    """This will estimate the rx and i0 errors from the covariance matrix 
>> Qxx.  Qxx is calculated from the Jacobian matrix and the optimised 
>> parameters.
>> +
>> +    @keyword spin_id:       The spin identification string.
>> +    @type spin_id:          str
>> +    @param epsrel:          Any columns of R which satisfy |R_{kk}| <= 
>> epsrel |R_{11}| are considered linearly-dependent and are excluded from the 
>> covariance matrix, where the corresponding rows and columns of the 
>> covariance matrix are set to zero.
>> +    @type epsrel:           float
>> +    @keyword verbosity:     The amount of information to print.  The higher 
>> the value, the greater the verbosity.
>> +    @type verbosity:        int
>> +    """
>> +
>> +    # Check that the C modules have been compiled.
>> +    if not C_module_exp_fn:
>> +        raise RelaxError("Relaxation curve fitting is not available.  Try 
>> compiling the C modules on your platform.")
>> +
>> +    # Perform checks.
>> +    if not cdp.curve_type == 'exp':
>> +        raise RelaxError("Only curve type of 'exp' is allowed for error 
>> estimation.  Set by: relax_fit.select_model('exp').")
>> +
>> +    # Loop over the spins.
>> +    for cur_spin, mol_name, resi, resn, cur_spin_id in 
>> spin_loop(selection=spin_id, full_info=True, return_id=True, 
>> skip_desel=True):
>> +        # Generate spin string.
>> +        spin_string = generate_spin_string(spin=cur_spin, 
>> mol_name=mol_name, res_num=resi, res_name=resn)
>> +
>> +        # Raise Error, if not optimised.
>> +        if not (hasattr(cur_spin, 'rx') and hasattr(cur_spin, 'i0')):
>> +            raise RelaxError("Spin '%s' does not contain optimised 'rx' and 
>> 'i0' values.  Try execute: minimise.execute(min_algor='Newton', 
>> constraints=False)"%(spin_string))
>> +
>> +        # Raise warning, if gradient count is 0.  This could point to a 
>> lack of minimisation first.
>> +        if hasattr(cur_spin, 'g_count'):
>> +            if getattr(cur_spin, 'g_count') == 0.0:
>> +                text = "Spin %s contains a gradient count of 0.0.  Is the 
>> rx parameter optimised?  Try execute: minimise.execute(min_algor='Newton', 
>> constraints=False)" %(spin_string)
>> +                warn(RelaxWarning("%s." % text))
>> +
>> +        # Print information.
>> +        if verbosity >= 1:
>> +            # Individual spin block section.
>> +            top = 2
>> +            if verbosity >= 2:
>> +                top += 2
>> +            subsection(file=sys.stdout, text="Estimating rx error for spin: 
>> %s"%spin_string, prespace=top)
>> +
>> +        # The keys.
>> +        keys = list(cur_spin.peak_intensity.keys())
>> +
>> +        # The peak intensities and times.
>> +        values = []
>> +        errors = []
>> +        times = []
>> +        for key in keys:
>> +            values.append(cur_spin.peak_intensity[key])
>> +            errors.append(cur_spin.peak_intensity_err[key])
>> +            times.append(cdp.relax_times[key])
>> +
>> +        # Convert to numpy array.
>> +        values = asarray(values)
>> +        errors = asarray(errors)
>> +        times = asarray(times)
>> +
>> +        # Extract values.
>> +        rx = getattr(cur_spin, 'rx')
>> +        i0 = getattr(cur_spin, 'i0')
>> +
>> +        # Pack data
>> +        param_vector = [rx, i0]
>> +
>> +        # Initialise data in C code.
>> +        scaling_list = [1.0, 1.0]
>> +        setup(num_params=len(param_vector), num_times=len(times), 
>> values=values, sd=errors, relax_times=times, scaling_matrix=scaling_list)
>> +
>> +        # Use the direct Jacobian from function.
>> +        jacobian_matrix_exp = transpose(asarray( jacobian(param_vector) ) )
>> +        weights = 1. / errors**2
>> +
>> +        # Get the co-variance
>> +        pcov = multifit_covar(J=jacobian_matrix_exp, weights=weights)
>> +
>> +        # To compute one standard deviation errors on the parameters, take 
>> the square root of the diagonal covariance.
>> +        param_vector_error = sqrt(diag(pcov))
>> +
>> +        # Extract values.
>> +        rx_err, i0_err = param_vector_error
>> +
>> +        # Copy rx, to rx_err, if not exists.
>> +        if not hasattr(cur_spin, 'rx_err'):
>> +            setattr(cur_spin, 'rx_err', deepcopy(getattr(cur_spin, 'rx')))
>> +        if not hasattr(cur_spin, 'i0_err'):
>> +            setattr(cur_spin, 'i0_err', deepcopy(getattr(cur_spin, 'i0')))
>> +
>> +        # Set error.
>> +        cur_spin.rx_err = rx_err
>> +        cur_spin.i0_err = i0_err
>> +
>> +        # Get other relevant information.
>> +        chi2 = getattr(cur_spin, 'chi2')
>> +
>> +        # Print information.
>> +        print_strings = []
>> +        if verbosity >= 1:
>> +            # Add print strings.
>> +            point_info = "Spin: '%s', with %i time points." % (spin_string, 
>> len(times))
>> +            print_strings.append(point_info)
>> +
>> +            par_info = "rx=%3.3f rx_err=%3.4f, i0=%6.1f, i0_err=%3.4f, 
>> chi2=%3.3f.\n" % ( rx, rx_err, i0, i0_err, chi2)
>> +            print_strings.append(par_info)
>> +
>> +            if verbosity >= 2:
>> +                time_info = ', '.join(map(str, times))
>> +                print_strings.append('For time array: '+time_info+'.\n\n')
>> +
>> +        # Print info
>> +        if len(print_strings) > 0:
>> +            for print_string in print_strings:
>> +                print(print_string),
>>
>>
>> _______________________________________________
>> relax (http://www.nmr-relax.com)
>>
>> This is the relax-commits mailing list
>> [email protected]
>>
>> To unsubscribe from this list, get a password
>> reminder, or change your subscription options,
>> visit the list information page at
>> https://mail.gna.org/listinfo/relax-commits
>
> _______________________________________________
> relax (http://www.nmr-relax.com)
>
> This is the relax-devel mailing list
> [email protected]
>
> To unsubscribe from this list, get a password
> reminder, or change your subscription options,
> visit the list information page at
> https://mail.gna.org/listinfo/relax-devel

_______________________________________________
relax (http://www.nmr-relax.com)

This is the relax-devel mailing list
[email protected]

To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-devel

Reply via email to