Changeset cd2ced80 in sasview for DataLoader/extensions


Ignore:
Timestamp:
Jan 14, 2011 5:45:58 PM (14 years ago)
Author:
Jae Cho <jhjcho@…>
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:
8fb8b0c
Parents:
67c7e89
Message:

new algorithm for slit smearing and its test

Location:
DataLoader/extensions
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • DataLoader/extensions/smearer.cpp

    ra74d650a rcd2ced80  
    133133        // Check the length of the data 
    134134        if (nbins<2) return; 
     135        int npts_h = height>0.0 ? npts : 1; 
     136        int npts_w = width>0.0 ? npts : 1; 
     137 
     138        // If both height and width are great than zero, 
     139        // modify the number of points in each direction so 
     140        // that the total number of points is still what 
     141        // the user would expect (downgrade resolution) 
     142        //if(npts_h>1 && npts_w>1){ 
     143        //      npts_h = (int)ceil(sqrt((double)npts)); 
     144        //      npts_w = npts_h; 
     145        //} 
     146        double shift_h, shift_w, hbin_size, wbin_size; 
     147        // Make sure height and width are all positive (FWMH/2) 
     148        // Assumption; height and width are all same for all q points 
     149        if(npts_h == 1){ 
     150                shift_h = 0.0; 
     151        } else { 
     152                shift_h = fabs(height); 
     153        } 
     154        if(npts_w == 1){ 
     155                shift_w = 0.0; 
     156        } else { 
     157                shift_w = fabs(width); 
     158        } 
     159        // size of the h bin and w bin 
     160        hbin_size = shift_h / nbins; 
     161        wbin_size = shift_w / nbins; 
    135162 
    136163        // Loop over all q-values 
    137164        for(int i=0; i<nbins; i++) { 
    138                 double q, q_min, q_max; 
     165                // Find Weights 
     166                // Find q where the resolution smearing calculation of I(q) occurs 
     167                double q, q_min, q_max, q_0; 
    139168                get_bin_range(i, &q, &q_min, &q_max); 
    140  
    141                 // For each q-value, compute the weight of each other q-bin 
    142                 // in the I(q) array 
    143                 int npts_h = height>0 ? npts : 1; 
    144                 int npts_w = width>0 ? npts : 1; 
    145  
    146                 // If both height and width are great than zero, 
    147                 // modify the number of points in each direction so 
    148                 // that the total number of points is still what 
    149                 // the user would expect (downgrade resolution) 
    150                 // Never down-grade npts_h. That will give incorrect slit smearing... 
    151                 if(npts_h>1 && npts_w>1){ 
    152                         npts_h = npts;//(int)ceil(sqrt((double)npts)); 
    153                         // In general width is much smaller than height, so smaller npt_w 
    154                         // should work fine. 
    155                         // Todo: It is still very expansive in time. Think about better way. 
    156                         npts_w = (int)ceil(npts_h / 100); 
    157                 } 
    158  
    159                 double shift_h, shift_w; 
    160                 for(int k=0; k<npts_h; k++){ 
    161                         if(npts_h==1){ 
    162                                 shift_h = 0; 
    163                         } else { 
    164                                 shift_h = height/((double)npts_h-1.0) * (double)k; 
    165                         } 
    166                         for(int j=0; j<npts_w; j++){ 
    167                                 if(npts_w==1){ 
    168                                         shift_w = 0; 
    169                                 } else { 
    170                                         shift_w = width/((double)npts_w-1.0) * (double)j; 
     169                bool last_qpoint = true; 
     170                // Find q[0] value to normalize the weight later, 
     171                //  otherwise, we will have a precision problem. 
     172                if (i == 0){ 
     173                        q_0 = q; 
     174                } 
     175                // Loop over all qj-values 
     176                bool first_w = true; 
     177                for(int j=0; j<nbins; j++) { 
     178                        double q_j, q_high, q_low; 
     179                        // Calculate bin size of q_j 
     180                        get_bin_range(j, &q_j, &q_low, &q_high); 
     181                        // Check q_low that can not be negative. 
     182                        if (q_low < 0.0){ 
     183                                q_low = 0.0; 
     184                        } 
     185                        // default parameter values 
     186                        (*weights)[i*nbins+j] = 0.0; 
     187                        double shift_w = 0.0; 
     188                        // Condition: zero slit smear. 
     189                        if (npts_w == 1 && npts_h == 1){ 
     190                                if(q_j == q) { 
     191                                        (*weights)[i*nbins+j] = 1.0; 
    171192                                } 
    172                                 double q_shifted = sqrt( ((q-shift_w)*(q-shift_w) + shift_h*shift_h) ); 
    173  
    174                                 // Find in which bin this shifted value belongs 
    175                                 int q_i=nbins; 
    176                                 if (even_binning) { 
    177                                         // This is kept for backward compatibility since the binning 
    178                                         // was originally defined differently for even bins. 
    179                                         q_i = (int)(floor( (q_shifted-qmin) /((qmax-qmin)/((double)nbins -1.0)) )); 
    180                                 } else { 
    181                                         for(int t=0; t<nbins; t++) { 
    182                                                 double q_t, q_high, q_low; 
    183                                                 get_bin_range(t, &q_t, &q_low, &q_high); 
    184                                                 if(q_shifted>=q_low && q_shifted<q_high) { 
    185                                                         q_i = t; 
    186                                                         break; 
     193                        } 
     194                        //Condition:Smear weight integration for width >0 when the height (=0) does not present. 
     195                        //Or height << width. 
     196                        else if((npts_w!=1 && npts_h == 1)|| (npts_w!=1 && npts_h != 1 && width/height > 100.0)){ 
     197                                shift_w = width; 
     198                                //del_w = width/((double)npts_w-1.0); 
     199                                double q_shifted_low = q - shift_w; 
     200                                // High limit of the resolution range 
     201                                double q_shifted_high = q + shift_w; 
     202                                // Go through all the q_js for weighting those points 
     203                                if(q_j >= q_shifted_low && q_j <= q_shifted_high) { 
     204                                        // The weighting factor comes, 
     205                                        // Give some weight (delq_bin) for the q_j within the resolution range 
     206                                        // Weight should be same for all qs except 
     207                                        // for the q bin size at j. 
     208                                        // Note that the division by q_0 is only due to the precision problem 
     209                                        // where q_high - q_low gets to very small. 
     210                                        // Later, it will be normalized again. 
     211                                        (*weights)[i*nbins+j] += (q_high - q_low)/q_0 ; 
     212                                } 
     213                        } 
     214                        else{ 
     215                                // Loop for width (;Height is analytical.) 
     216                                // Condition: height >>> width, otherwise, below is not accurate enough. 
     217                                // Smear weight numerical iteration for width >0 when the height (>0) presents. 
     218                                // When width = 0, the numerical iteration will be skipped. 
     219                                // The resolution calculation for the height is done by direct integration, 
     220                                // assuming the I(q'=sqrt(q_j^2-(q+shift_w)^2)) is constant within a q' bin, [q_high, q_low]. 
     221                                // In general, this weight numerical iteration for width >0 might be a rough approximation, 
     222                                // but it must be good enough when height >>> width. 
     223                                for(int k=(-npts_w + 1); k<npts_w; k++){ 
     224                                        if(npts_w!=1){ 
     225                                                shift_w = width/((double)npts_w-1.0)*(double)k; 
     226                                        } 
     227                                        // For each q-value, compute the weight of each other q-bin 
     228                                        // in the I(q) array 
     229                                        // Low limit of the resolution range 
     230                                        double q_shift = q + shift_w; 
     231                                        if (q_shift < 0.0){ 
     232                                                q_shift = 0.0; 
     233                                        } 
     234                                        double q_shifted_low = q_shift; 
     235                                        // High limit of the resolution range 
     236                                        double q_shifted_high = sqrt(q_shift * q_shift + shift_h * shift_h); 
     237 
     238 
     239                                        // Go through all the q_js for weighting those points 
     240                                        if(q_j >= q_shifted_low && q_j <= q_shifted_high) { 
     241                                                // The weighting factor comes, 
     242                                                // Give some weight (delq_bin) for the q_j within the resolution range 
     243                                                // Weight should be same for all qs except 
     244                                                // for the q bin size at j. 
     245                                                // Note that the division by q_0 is only due to the precision problem 
     246                                                // where q_high - q_low gets to very small. 
     247                                                // Later, it will be normalized again. 
     248 
     249                                                double q_shift_min = q - width; 
     250 
     251                                                double u = (q_j * q_j - (q_shift) * (q_shift)); 
     252                                                // The fabs below are not necessary but in case: the weight should never be imaginary. 
     253                                                // At the edge of each sub_width. weight += u(at q_high bin) - u(0), where u(0) = 0, 
     254                                                // and weighted by (2.0* npts_w -1.0)once for each q. 
     255                                                if (q == q_j) { 
     256                                                        if (k==0) 
     257                                                                (*weights)[i*nbins+j] += (sqrt(fabs((q_high)*(q_high)-q_shift * q_shift)))/q_0 * (2.0*double(npts_w)-1.0); 
     258                                                } 
     259                                                // For the rest of sub_width. weight += u(at q_high bin) - u(at q_low bin) 
     260                                                else if (u > 0.0){ 
     261                                                        (*weights)[i*nbins+j] += (sqrt(fabs((q_high)*(q_high)- q_shift * q_shift))-sqrt(fabs((q_low)*(q_low)- q_shift * q_shift)))/q_0 ; 
    187262                                                } 
    188263                                        } 
    189264                                } 
    190  
    191                                 // Skip the entries outside our I(q) range 
    192                                 //TODO: be careful with edge effect 
    193                                 if(q_i<nbins) 
    194                                         (*weights)[i*nbins+q_i]++; 
    195265                        } 
    196266                } 
     
    277347 
    278348                for(int i=first_bin; i<=last_bin; i++){ 
    279                         // Skip if weight is less than 1e-04(this value is much smaller than 
     349                        // Skip if weight is less than 1e-03(this value is much smaller than 
    280350                        // the weight at the 3*sigma distance 
    281351                        // Will speed up a little bit... 
    282                         if ((*weights)[q_i*nbins+i] < 1.0e-004){ 
     352                        if ((*weights)[q_i*nbins+i] < 1.0e-003){ 
    283353                                continue; 
    284354                        } 
     
    288358 
    289359                // Normalize counts 
    290                 iq_out[q_i] = (counts>0.0) ? sum/counts : 0; 
     360                iq_out[q_i] = (counts>0.0) ? sum/counts : 0.0; 
    291361        } 
    292362} 
  • DataLoader/extensions/smearer.hh

    r2ca00c4 rcd2ced80  
    6161protected: 
    6262    // Number of points used in the smearing computation 
    63     static const int npts   = 3000; 
     63    static const int npts   = 500; 
    6464 
    6565public: 
Note: See TracChangeset for help on using the changeset viewer.