Changeset 70975f3 in sasview for DataLoader


Ignore:
Timestamp:
Sep 18, 2008 2:15:39 PM (16 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:
916a15f
Parents:
1f8accb
Message:

Added slab averaging (X and Y)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • DataLoader/manipulations.py

    rf8d0ee7 r70975f3  
    1515""" 
    1616#TODO: copy the meta data from the 2D object to the resulting 1D object 
     17#TODO: Don't assume square pixels 
    1718 
    1819from data_info import plottable_2D, Data1D 
     
    3233    return (4.0*math.pi/wavelength)*math.sin(theta) 
    3334     
    34  
    35  
    36 class Slabs: 
    37     def __init__(self): 
    38         pass 
    39      
     35class _Slab(object): 
     36    """ 
     37        Compute average I(Q) for a region of interest 
     38    """ 
     39    def __init__(self, x_min=0.0, x_max=0.0, y_min=0.0, y_max=0.0, bin_width=0.001): 
     40        # Minimum Qx value [A-1] 
     41        self.x_min = x_min 
     42        # Maximum Qx value [A-1] 
     43        self.x_max = x_max 
     44        # Minimum Qy value [A-1] 
     45        self.y_min = y_min 
     46        # Maximum Qy value [A-1] 
     47        self.y_max = y_max 
     48        # Bin width (step size) [A-1] 
     49        self.bin_width = bin_width 
     50        # If True, I(|Q|) will be return, otherwise, negative q-values are allowed 
     51        self.fold = False 
     52         
     53    def __call__(self, data2D): return NotImplemented 
     54         
     55    def _avg(self, data2D, maj): 
     56        """ 
     57             Compute average I(Q_maj) for a region of interest. 
     58             The major axis is defined as the axis of Q_maj. 
     59             The minor axis is the axis that we average over. 
     60              
     61             @param data2D: Data2D object 
     62             @param maj_min: min value on the major axis 
     63             @return: Data1D object 
     64        """ 
     65        if len(data2D.detector) != 1: 
     66            raise RuntimeError, "_Slab._avg: invalid number of detectors: %g" % len(data2D.detector) 
     67         
     68        pixel_width_x = data2D.detector[0].pixel_size.x 
     69        pixel_width_y = data2D.detector[0].pixel_size.y 
     70        det_dist    = data2D.detector[0].distance 
     71        wavelength  = data2D.source.wavelength 
     72        center_x    = data2D.detector[0].beam_center.x/pixel_width_x 
     73        center_y    = data2D.detector[0].beam_center.y/pixel_width_y 
     74                 
     75        # Build array of Q intervals 
     76        if maj=='x': 
     77            nbins = int(math.ceil((self.x_max-self.x_min)/self.bin_width)) 
     78            qbins = self.bin_width*numpy.arange(nbins)+self.x_min 
     79        elif maj=='y': 
     80            nbins = int(math.ceil((self.y_max-self.y_min)/self.bin_width)) 
     81            qbins = self.bin_width*numpy.arange(nbins)+self.y_min             
     82        else: 
     83            raise RuntimeError, "_Slab._avg: unrecognized axis %s" % str(maj) 
     84                                 
     85        x  = numpy.zeros(nbins) 
     86        y  = numpy.zeros(nbins) 
     87        err_y = numpy.zeros(nbins) 
     88        y_counts = numpy.zeros(nbins) 
     89                                                 
     90        for i in range(numpy.size(data2D.data,1)): 
     91            # Min and max x-value for the pixel 
     92            minx = pixel_width_x*(i - center_x) 
     93            maxx = pixel_width_x*(i+1.0 - center_x) 
     94             
     95            qxmin = get_q(minx, 0.0, det_dist, wavelength) 
     96            qxmax = get_q(maxx, 0.0, det_dist, wavelength) 
     97             
     98            # Get the count fraction in x for that pixel 
     99            frac_min = get_pixel_fraction_square(self.x_min, qxmin, qxmax) 
     100            frac_max = get_pixel_fraction_square(self.x_max, qxmin, qxmax) 
     101            frac_x = frac_max - frac_min 
     102             
     103            if frac_x == 0:  
     104                continue 
     105             
     106            if maj=='x': 
     107                dx = pixel_width_x*(i+0.5 - center_x) 
     108                q_value = get_q(dx, 0.0, det_dist, wavelength) 
     109                if self.fold==False and dx<0: 
     110                    q_value = -q_value 
     111                i_q = int(math.ceil((q_value-self.x_min)/self.bin_width)) - 1 
     112                 
     113                if i_q<0 or i_q>=nbins: 
     114                    continue 
     115                         
     116            for j in range(numpy.size(data2D.data,0)): 
     117                # Min and max y-value for the pixel 
     118                miny = pixel_width_y*(j - center_y) 
     119                maxy = pixel_width_y*(j+1.0 - center_y) 
     120 
     121                qymin = get_q(0.0, miny, det_dist, wavelength) 
     122                qymax = get_q(0.0, maxy, det_dist, wavelength) 
     123                 
     124                # Get the count fraction in x for that pixel 
     125                frac_min = get_pixel_fraction_square(self.y_min, qymin, qymax) 
     126                frac_max = get_pixel_fraction_square(self.y_max, qymin, qymax) 
     127                frac_y = frac_max - frac_min 
     128                 
     129                frac = frac_x * frac_y 
     130                 
     131                if frac == 0: 
     132                    continue 
     133 
     134                if maj=='y': 
     135                    dy = pixel_width_y*(j+0.5 - center_y) 
     136                    q_value = get_q(0.0, dy, det_dist, wavelength) 
     137                    if self.fold==False and dy<0: 
     138                        q_value = -q_value 
     139                    i_q = int(math.ceil((q_value-self.y_min)/self.bin_width)) - 1 
     140                     
     141                    if i_q<0 or i_q>=nbins: 
     142                        continue 
     143             
     144                x[i_q]          = q_value 
     145                y[i_q]         += frac * data2D.data[j][i] 
     146                if data2D.err_data == None or data2D.err_data[j][i]==0.0: 
     147                    err_y[i_q] += frac * frac * math.fabs(data2D.data[j][i]) 
     148                else: 
     149                    err_y[i_q] += frac * frac * data2D.err_data[j][i] * data2D.err_data[j][i] 
     150                y_counts[i_q]  += frac 
     151 
     152        # Average the sums 
     153        for i in range(nbins): 
     154            if y_counts[i]>0: 
     155                err_y[i] = math.sqrt(err_y[i])/y_counts[i] 
     156                y[i]     = y[i]/y_counts[i] 
     157         
     158        return Data1D(x=x, y=y, dy=err_y) 
     159         
     160class SlabY(_Slab): 
     161    """ 
     162        Compute average I(Qy) for a region of interest 
     163    """ 
     164    def __call__(self, data2D): 
     165        """ 
     166             Compute average I(Qy) for a region of interest 
     167              
     168             @param data2D: Data2D object 
     169             @return: Data1D object 
     170        """ 
     171        return self._avg(data2D, 'y') 
     172         
     173class SlabX(_Slab): 
     174    """ 
     175        Compute average I(Qx) for a region of interest 
     176    """ 
     177    def __call__(self, data2D): 
     178        """ 
     179             Compute average I(Qx) for a region of interest 
     180              
     181             @param data2D: Data2D object 
     182             @return: Data1D object 
     183        """ 
     184        return self._avg(data2D, 'x')  
    40185         
    41186class Boxsum(object): 
     
    123268         
    124269        return y, err_y, y_counts 
    125         # Average the sums 
    126         counts = 0 if y_counts==0 else y/y_counts 
    127         error  = 0 if y_counts==0 else math.sqrt(err_y)/y_counts 
    128          
    129         return counts, error 
    130270       
    131271class Boxavg(Boxsum): 
     
    507647     
    508648    #r = Boxsum(x_min=.2, x_max=.4, y_min=0.2, y_max=0.4) 
    509     r = Boxsum(x_min=.01, x_max=.015, y_min=0.01, y_max=0.015) 
     649    r = SlabX(x_min=-.01, x_max=.01, y_min=-0.0002, y_max=0.0002, bin_width=0.0004) 
     650    r.fold = False 
    510651    o = r(d) 
    511     print o 
    512      
    513     r = Boxavg(x_min=.01, x_max=.015, y_min=0.01, y_max=0.015) 
    514     o = r(d) 
    515     print o 
     652     
     653    #s = SlabY(x_min=-.01, x_max=.01, y_min=-0.0002, y_max=0.0002, bin_width=0.0004) 
     654    #s.fold = False 
     655    #p = s(d) 
     656     
     657    for i in range(len(o.x)): 
     658        print o.x[i], o.y[i], o.dy[i] 
    516659     
    517660  
Note: See TracChangeset for help on using the changeset viewer.