Changeset 5859862 in sasview for DataLoader/extensions


Ignore:
Timestamp:
Sep 20, 2009 5:41:40 PM (15 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:
a65ffcb
Parents:
a1100c07
Message:

dataloader: fixed problem with uneven binning. Added utility method to get first and last bins in unsmeared q.

Location:
DataLoader/extensions
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • DataLoader/extensions/smearer.cpp

    ra3f8d58 r5859862  
    3333        // whether we need to compute one 
    3434        has_matrix = false; 
     35        even_binning = true; 
     36}; 
     37 
     38/** 
     39 * Constructor for BaseSmearer 
     40 * 
     41 * Used for uneven binning 
     42 * @param q: array of Q values 
     43 * @param nbins: number of Q bins 
     44 */ 
     45BaseSmearer :: BaseSmearer(double* q, int nbins) { 
     46        // Number of bins 
     47        this->nbins = nbins; 
     48        this->q_values = q; 
     49        // Flag to keep track of whether we have a smearing matrix or 
     50        // whether we need to compute one 
     51        has_matrix = false; 
     52        even_binning = false; 
    3553}; 
    3654 
     
    5068}; 
    5169 
    52         /** 
    53          * Constructor for SlitSmearer 
    54          * 
    55          * @param width: array slit widths for each Q point, in Q units 
    56          * @param qmin: minimum Q value 
    57          * @param qmax: maximum Q value 
    58          * @param nbins: number of Q bins 
    59          */ 
     70/** 
     71 * Constructor for SlitSmearer 
     72 * 
     73 * @param width: slit width in Q units 
     74 * @param height: slit height in Q units 
     75 * @param q: array of Q values 
     76 * @param nbins: number of Q bins 
     77 */ 
     78SlitSmearer :: SlitSmearer(double width, double height, double* q, int nbins) : 
     79        BaseSmearer(q, nbins){ 
     80        this->height = height; 
     81        this->width = width; 
     82}; 
     83 
     84/** 
     85 * Constructor for QSmearer 
     86 * 
     87 * @param width: array slit widths for each Q point, in Q units 
     88 * @param qmin: minimum Q value 
     89 * @param qmax: maximum Q value 
     90 * @param nbins: number of Q bins 
     91 */ 
    6092QSmearer :: QSmearer(double* width, double qmin, double qmax, int nbins) : 
    6193        BaseSmearer(qmin, qmax, nbins){ 
     
    6496 
    6597/** 
     98 * Constructor for QSmearer 
     99 * 
     100 * @param width: array slit widths for each Q point, in Q units 
     101 * @param q: array of Q values 
     102 * @param nbins: number of Q bins 
     103 */ 
     104QSmearer :: QSmearer(double* width, double* q, int nbins) : 
     105        BaseSmearer(q, nbins){ 
     106        this->width = width; 
     107}; 
     108 
     109/** 
    66110 * Compute the slit smearing matrix 
     111 * 
     112 * For even binning (q_min to q_max with nbins): 
     113 * 
     114 *   step = (q_max-q_min)/(nbins-1) 
     115 *   first bin goes from q_min to q_min+step 
     116 *   last bin goes from q_max to q_max+step 
     117 * 
     118 * For binning according to q array: 
     119 * 
     120 * Each q point represents a bin going from half the distance between it 
     121 * and the previous point to half the distance between it and the next point. 
     122 * 
     123 *    Example: bin i goes from (q_values[i-1]+q_values[i])/2 to (q_values[i]+q_values[i+1])/2 
     124 * 
     125 * The exceptions are the first and last bins, which are centered at the first and 
     126 * last q-values, respectively. The width of the first and last bins is the distance between 
     127 * their respective neighboring q-value. 
    67128 */ 
    68129void SlitSmearer :: compute_matrix(){ 
    69130 
    70131        weights = new vector<double>(nbins*nbins,0); 
     132 
     133        // Check the length of the data 
     134        if (nbins<2) return; 
    71135 
    72136        // Loop over all q-values 
    73137        for(int i=0; i<nbins; i++) { 
    74                 double q = qmin + (double)i*(qmax-qmin)/((double)nbins-1.0); 
     138                double q, q_min, q_max; 
     139                get_bin_range(i, &q, &q_min, &q_max); 
    75140 
    76141                // For each q-value, compute the weight of each other q-bin 
     
    102167                                } 
    103168                                double q_shifted = sqrt( ((q-shift_w)*(q-shift_w) + shift_h*shift_h) ); 
    104                                 int q_i = (int)(floor( (q_shifted-qmin) /((qmax-qmin)/((double)nbins -1.0)) )); 
     169 
     170                                // Find in which bin this shifted value belongs 
     171                                int q_i=nbins; 
     172                                if (even_binning) { 
     173                                        // This is kept for backward compatibility since the binning 
     174                                        // was originally defined differently for even bins. 
     175                                        q_i = (int)(floor( (q_shifted-qmin) /((qmax-qmin)/((double)nbins -1.0)) )); 
     176                                } else { 
     177                                        for(int t=0; t<nbins; t++) { 
     178                                                double q_t, q_high, q_low; 
     179                                                get_bin_range(t, &q_t, &q_low, &q_high); 
     180                                                if(q_shifted>=q_low && q_shifted<q_high) { 
     181                                                        q_i = t; 
     182                                                        break; 
     183                                                } 
     184                                        } 
     185                                } 
    105186 
    106187                                // Skip the entries outside our I(q) range 
     
    121202        // Loop over all q-values 
    122203        double step = (qmax-qmin)/((double)nbins-1.0); 
     204        double q, q_min, q_max; 
     205        double q_j, q_jmax, q_jmin; 
    123206        for(int i=0; i<nbins; i++) { 
    124                 double q = qmin + (double)i*step; 
    125                 double q_min = q - 0.5*step; 
    126                 double q_max = q + 0.5*step; 
     207                get_bin_range(i, &q, &q_min, &q_max); 
    127208 
    128209                for(int j=0; j<nbins; j++) { 
    129                         double q_j = qmin + (double)j*step; 
     210                        get_bin_range(j, &q_j, &q_jmin, &q_jmax); 
    130211 
    131212                        // Compute the fraction of the Gaussian contributing 
     
    139220 
    140221/** 
     222 * Computes the Q range of a given bin of the Q distribution. 
     223 * The range is computed according the the data distribution that 
     224 * was given to the object at initialization. 
     225 * 
     226 * @param i: number of the bin in the distribution 
     227 * @param q: q-value of bin i 
     228 * @param q_min: lower bound of the bin 
     229 * @param q_max: higher bound of the bin 
     230 * 
     231 */ 
     232void BaseSmearer :: get_bin_range(int i, double* q, double* q_min, double* q_max) { 
     233        if (even_binning) { 
     234                double step = (qmax-qmin)/((double)nbins-1.0); 
     235                *q = qmin + (double)i*step; 
     236                *q_min = *q - 0.5*step; 
     237                *q_max = *q + 0.5*step; 
     238        } else { 
     239                *q = q_values[i]; 
     240                if (i==0) { 
     241                        double step = (q_values[1]-q_values[0])/2.0; 
     242                        *q_min = *q - step; 
     243                        *q_max = *q + step; 
     244                } else if (i==nbins-1) { 
     245                        double step = (q_values[i]-q_values[i-1])/2.0; 
     246                        *q_min = *q - step; 
     247                        *q_max = *q + step; 
     248                } else { 
     249                        *q_min = *q - (q_values[i]-q_values[i-1])/2.0; 
     250                        *q_max = *q + (q_values[i+1]-q_values[i])/2.0; 
     251                } 
     252        } 
     253} 
     254 
     255/** 
    141256 * Perform smearing by applying the smearing matrix to the input Q array 
    142257 */ 
  • DataLoader/extensions/smearer.hh

    ra3f8d58 r5859862  
    2424class BaseSmearer { 
    2525protected: 
     26        // Internal flag: true when the weights vector is filled 
    2627        bool has_matrix; 
    27     // Smearing matrix 
    28     vector<double>* weights; 
     28        // True when only qmin, qmax and nbins are given. Bins are equidistant 
     29        bool even_binning; 
     30        // Smearing matrix 
     31        vector<double>* weights; 
     32        // Q vector 
     33        double* q_values; 
    2934    // Q_min (Min Q-value for I(q)) 
    3035    double qmin; 
     
    3742    // Constructor 
    3843    BaseSmearer(double qmin, double qmax, int nbins); 
     44    BaseSmearer(double* q, int nbins); 
    3945        // Smear function 
    4046        virtual void smear(double *, double *, int, int); 
     
    4349        // Utility function to check the number of bins 
    4450        int get_nbins() { return nbins; } 
     51        // Get the q range of a particular bin 
     52        virtual void get_bin_range(int, double*, double*, double*); 
    4553}; 
    4654 
     
    6371    // Constructor 
    6472        SlitSmearer(double width, double height, double qmin, double qmax, int nbins); 
     73        SlitSmearer(double width, double height, double* q, int nbins); 
    6574        // Compute the smearing matrix 
    6675        virtual void compute_matrix(); 
     
    8089 
    8190    // Constructor 
    82     QSmearer(double* width,double qmin, double qmax, int nbins); 
     91    QSmearer(double* width, double qmin, double qmax, int nbins); 
     92    QSmearer(double* width, double* q, int nbins); 
    8393        // Compute the smearing matrix 
    8494        virtual void compute_matrix(); 
  • DataLoader/extensions/smearer_module.cpp

    ra3f8d58 r5859862  
    5454 
    5555/** 
     56 * Create a SlitSmearer as a python object by supplying a q array 
     57 */ 
     58PyObject * new_slit_smearer_with_q(PyObject *, PyObject *args) { 
     59        PyObject *qvalues_obj; 
     60        Py_ssize_t n_q; 
     61        double* qvalues; 
     62        double width; 
     63        double height; 
     64 
     65        if (!PyArg_ParseTuple(args, "ddO", &width, &height, &qvalues_obj)) return NULL; 
     66        OUTVECTOR(qvalues_obj, qvalues, n_q); 
     67        SlitSmearer* smearer = new SlitSmearer(width, height, qvalues, n_q); 
     68        return PyCObject_FromVoidPtr(smearer, del_slit_smearer); 
     69} 
     70 
     71/** 
    5672 * Delete a QSmearer object 
    5773 */ 
     
    7692        OUTVECTOR(width_obj, width, n_w); 
    7793        QSmearer* smearer = new QSmearer(width, qmin, qmax, nbins); 
     94        return PyCObject_FromVoidPtr(smearer, del_q_smearer); 
     95} 
     96 
     97/** 
     98 * Create a QSmearer as a python object by supplying a q array 
     99 */ 
     100PyObject * new_q_smearer_with_q(PyObject *, PyObject *args) { 
     101        PyObject *width_obj; 
     102        Py_ssize_t n_w; 
     103        double* width; 
     104        PyObject *qvalues_obj; 
     105        Py_ssize_t n_q; 
     106        double* qvalues; 
     107 
     108        if (!PyArg_ParseTuple(args, "OO", &width_obj, &qvalues_obj)) return NULL; 
     109        OUTVECTOR(width_obj, width, n_w); 
     110        OUTVECTOR(qvalues_obj, qvalues, n_q); 
     111        QSmearer* smearer = new QSmearer(width, qvalues, n_q); 
    78112        return PyCObject_FromVoidPtr(smearer, del_q_smearer); 
    79113} 
     
    114148} 
    115149 
     150/** 
     151 * Get the q-value of a given bin 
     152 */ 
     153PyObject * get_q(PyObject *, PyObject *args) { 
     154        PyObject *smear_obj; 
     155        int bin; 
     156 
     157        if (!PyArg_ParseTuple(args, "Oi", &smear_obj, &bin)) return NULL; 
     158 
     159        // Set the array pointers 
     160        void *temp = PyCObject_AsVoidPtr(smear_obj); 
     161        BaseSmearer* s = static_cast<BaseSmearer *>(temp); 
     162 
     163        double q, q_min, q_max; 
     164        s->get_bin_range(bin, &q, &q_min, &q_max); 
     165 
     166        return Py_BuildValue("d", q); 
     167} 
     168 
    116169 
    117170/** 
     
    121174        {"new_slit_smearer", (PyCFunction)new_slit_smearer, METH_VARARGS, 
    122175                  "Create a new Slit Smearer object"}, 
     176        {"new_slit_smearer_with_q", (PyCFunction)new_slit_smearer_with_q, METH_VARARGS, 
     177                  "Create a new Slit Smearer object by supplying an array of Q values"}, 
    123178        {"new_q_smearer", (PyCFunction)new_q_smearer, METH_VARARGS, 
    124179                  "Create a new Q Smearer object"}, 
     180        {"new_q_smearer_with_q", (PyCFunction)new_q_smearer_with_q, METH_VARARGS, 
     181                  "Create a new Q Smearer object by supplying an array of Q values"}, 
    125182        {"smear",(PyCFunction)smear_input, METH_VARARGS, 
    126183                  "Smear the given input array"}, 
     184        {"get_q",(PyCFunction)get_q, METH_VARARGS, 
     185                  "Get the q-value of a given bin"}, 
    127186    {NULL} 
    128187}; 
Note: See TracChangeset for help on using the changeset viewer.