Changeset 43c0a8e in sasview for pr_inversion


Ignore:
Timestamp:
May 23, 2008 8:55:39 AM (17 years ago)
Author:
Mathieu Doucet <doucetm@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
dfb58f8
Parents:
eb06cbe
Message:

Add a couple of figures of merit

Location:
pr_inversion
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pr_inversion/c_extensions/Cinvertor.c

    rf71287f4 r43c0a8e  
    492492        PyObject *err_obj; 
    493493        Py_ssize_t npars2; 
    494            
     494        int i;  
     495         
    495496        if (!PyArg_ParseTuple(args, "OOd", &data_obj, &err_obj, &r)) return NULL; 
    496         OUTVECTOR(data_obj,pars,npars); 
     497        OUTVECTOR(data_obj,pars,npars);  
    497498        OUTVECTOR(err_obj,pars_err,npars2); 
    498                  
     499 
    499500        pr_err(pars, pars_err, self->params.d_max, npars, r, &pr_value, &pr_err_value); 
    500501        return Py_BuildValue("ff", pr_value, pr_err_value);      
     
    537538 
    538539        return Py_BuildValue("i", count );       
     540         
     541} 
     542 
     543static PyObject * get_positive(Cinvertor *self, PyObject *args) { 
     544        double *pars; 
     545        PyObject *data_obj; 
     546        Py_ssize_t npars; 
     547        double fraction; 
     548          
     549        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
     550        OUTVECTOR(data_obj,pars,npars); 
     551         
     552        fraction = positive_integral(pars, self->params.d_max, npars, 100); 
     553 
     554        return Py_BuildValue("f", fraction );    
     555         
     556} 
     557 
     558static PyObject * get_pos_err(Cinvertor *self, PyObject *args) { 
     559        double *pars; 
     560        double *pars_err; 
     561        PyObject *data_obj; 
     562        PyObject *err_obj; 
     563        Py_ssize_t npars; 
     564        Py_ssize_t npars2; 
     565        double fraction; 
     566         
     567        if (!PyArg_ParseTuple(args, "OO", &data_obj, &err_obj)) return NULL; 
     568        OUTVECTOR(data_obj,pars,npars);  
     569        OUTVECTOR(err_obj,pars_err,npars2); 
     570         
     571        fraction = positive_errors(pars, pars_err, self->params.d_max, npars, 51); 
     572 
     573        return Py_BuildValue("f", fraction );    
    539574         
    540575} 
     
    567602                   {"oscillations", (PyCFunction)oscillations, METH_VARARGS, ""}, 
    568603                   {"get_peaks", (PyCFunction)get_peaks, METH_VARARGS, ""}, 
     604                   {"get_positive", (PyCFunction)get_positive, METH_VARARGS, ""}, 
     605                   {"get_pos_err", (PyCFunction)get_pos_err, METH_VARARGS, ""}, 
    569606    
    570607   {NULL} 
  • pr_inversion/c_extensions/invertor.c

    rf71287f4 r43c0a8e  
    100100        func_value = ortho(d_max, i+1, r); 
    101101        sum += pars[i] * func_value; 
    102         sum_err += err[i]*err[i]*func_value*func_value; 
     102        //sum_err += err[i]*err[i]*func_value*func_value; 
     103        sum_err += err[i*n_c+i]*func_value*func_value; 
    103104    } 
    104105    *pr_value = sum; 
     
    115116double dprdr(double *pars, double d_max, int n_c, double r) { 
    116117    double sum = 0.0;  
    117         int i; 
     118        int i;  
    118119    for (i=0; i<n_c; i++) { 
    119120        sum += pars[i] * 2.0*(sin(pi*(i+1)*r/d_max) + pi*(i+1)*r/d_max * cos(pi*(i+1)*r/d_max)); 
     
    180181} 
    181182 
     183/** 
     184 * Get the fraction of the integral of P(r) over the whole range 
     185 * of r that is above zero. 
     186 * A valid P(r) is define as being positive for all r. 
     187 */ 
     188double positive_integral(double *pars, double d_max, int n_c, int nslice) { 
     189    double r;  
     190    double value; 
     191        int i; 
     192        double sum_pos = 0.0; 
     193        double sum = 0.0; 
     194         
     195    for (i=0; i<nslice; i++) { 
     196        r = d_max/(1.0*nslice)*i; 
     197        value = pr(pars, d_max, n_c, r); 
     198        if (value>0.0) sum_pos += value; 
     199        sum += value; 
     200    } 
     201    return sum_pos/sum; 
     202} 
     203 
     204/** 
     205 * Get the fraction of the integral of P(r) over the whole range 
     206 * of r that is at least one sigma above zero. 
     207 */ 
     208double positive_errors(double *pars, double *err, double d_max, int n_c, int nslice) { 
     209    double r;  
     210    double value; 
     211        int i;  
     212        double sum_pos = 0.0; 
     213        double sum = 0.0; 
     214        double pr_val; 
     215        double pr_val_err; 
     216         
     217    for (i=0; i<nslice; i++) { 
     218        r = d_max/(1.0*nslice)*i; 
     219        pr_err(pars, err, d_max, n_c, r, &pr_val, &pr_val_err); 
     220        if (pr_val>pr_val_err) sum_pos += pr_val; 
     221        sum += pr_val; 
     222         
     223 
     224    } 
     225    return sum_pos/sum; 
     226} 
  • pr_inversion/c_extensions/invertor.h

    rf71287f4 r43c0a8e  
    3333                double r, double *pr_value, double *pr_value_err); 
    3434int npeaks(double *pars, double d_max, int n_c, int nslice); 
     35double positive_integral(double *pars, double d_max, int n_c, int nslice); 
     36double positive_errors(double *pars, double *err, double d_max, int n_c, int nslice); 
    3537 
    3638#endif 
  • pr_inversion/invertor.py

    r9a11937 r43c0a8e  
    66    """ 
    77        Provide general online help text 
     8        Future work: extend this function to allow topic selection 
    89    """ 
    910    info_txt  = "The inversion approach is based on Moore, J. Appl. Cryst. (1980) 13, 168-175.\n\n" 
     
    3132         
    3233        TODO: explain the maths 
     34         
     35         
     36        Methods inherited from Cinvertor: 
     37        - get_peaks: returns the number of P(r) peaks 
    3338    """ 
    3439    ## Chisqr of the last computation 
     
    189194     
    190195    def pr_err(self, c, c_cov, r): 
    191         import math 
    192         c_err = numpy.zeros(len(c)) 
    193         for i in range(len(c)): 
    194             try: 
    195                 c_err[i] = math.sqrt(math.fabs(c_cov[i][i])) 
    196             except: 
    197                 import sys 
    198                 print sys.exc_value 
    199                 print "oups", c_cov[i][i] 
    200                 c_err[i] = c[i] 
     196        #import math 
     197        #c_err = numpy.zeros(len(c)) 
     198        #for i in range(len(c)): 
     199        #    try: 
     200        #        c_err[i] = math.sqrt(math.fabs(c_cov[i][i])) 
     201        #    except: 
     202        #        import sys 
     203        #        print sys.exc_value 
     204        #        print "oups", c_cov[i][i] 
     205        #        c_err[i] = c[i] 
    201206 
    202         return self.get_pr_err(c, c_err, r) 
     207        return self.get_pr_err(c, c_cov, r) 
    203208        
    204209    def _accept_q(self, q): 
  • pr_inversion/test/utest_invertor.py

    rf71287f4 r43c0a8e  
    1111from sans.pr.invertor import Invertor 
    1212         
     13class TestFiguresOfMerit(unittest.TestCase): 
     14             
     15    def setUp(self): 
     16        self.invertor = Invertor() 
     17        self.invertor.d_max = 100.0 
     18         
     19        # Test array 
     20        self.ntest = 5 
     21        self.x_in = numpy.ones(self.ntest) 
     22        for i in range(self.ntest): 
     23            self.x_in[i] = 1.0*(i+1) 
     24        
     25        x, y, err = load("sphere_80.txt") 
     26 
     27        # Choose the right d_max... 
     28        self.invertor.d_max = 160.0 
     29        # Set a small alpha 
     30        self.invertor.alpha = .0007 
     31        # Set data 
     32        self.invertor.x   = x 
     33        self.invertor.y   = y 
     34        self.invertor.err = err 
     35        # Perform inversion 
     36        #out, cov = self.invertor.invert(10) 
     37         
     38        self.out, self.cov = self.invertor.lstsq(10) 
     39 
     40    def test_positive(self): 
     41        """ 
     42            Test whether P(r) is positive 
     43        """ 
     44        self.assertEqual(self.invertor.get_positive(self.out), 1) 
     45         
     46    def test_positive_err(self): 
     47        """ 
     48            Test whether P(r) is at least 1 sigma greater than zero 
     49            for all r-values 
     50        """ 
     51        self.assertTrue(self.invertor.get_pos_err(self.out, self.cov)>0.9) 
     52        
    1353class TestBasicComponent(unittest.TestCase): 
    1454     
     
    236276            print "chi2(P(r)) =", chi2/51.0 
    237277            raise 
     278         
     279        # Test the number of peaks 
     280        self.assertEqual(self.invertor.get_peaks(out), 1) 
    238281             
    239282    def test_q_zero(self): 
Note: See TracChangeset for help on using the changeset viewer.