Ignore:
Timestamp:
Mar 21, 2016 5:17:48 AM (9 years ago)
Author:
krzywon
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:
80b1df3
Parents:
240a2d2
Message:

Restoring the proper qsmearing.py file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/data_util/qsmearing.py

    r240a2d2 rf8aa738  
    1313import logging 
    1414import sys 
    15 import sas.models.sas_extension.smearer as smearer 
    16 from sas.sascalc.data_util.smearing_2d import Smearer2D 
    1715 
    18 def smear_selection(data1D, model = None): 
     16from sasmodels.resolution import Slit1D, Pinhole1D 
     17from sasmodels.resolution2d import Pinhole2D 
     18 
     19def smear_selection(data, model = None): 
    1920    """ 
    20     Creates the right type of smearer according  
     21    Creates the right type of smearer according 
    2122    to the data. 
    22  
    2323    The canSAS format has a rule that either 
    2424    slit smearing data OR resolution smearing data 
    25     is available.  
    26      
     25    is available. 
     26 
    2727    For the present purpose, we choose the one that 
    2828    has none-zero data. If both slit and resolution 
    29     smearing arrays are filled with good data  
     29    smearing arrays are filled with good data 
    3030    (which should not happen), then we choose the 
    31     resolution smearing data.  
    32      
    33     :param data1D: Data1D object 
     31    resolution smearing data. 
     32 
     33    :param data: Data1D object 
    3434    :param model: sas.model instance 
    3535    """ 
    3636    # Sanity check. If we are not dealing with a SAS Data1D 
    3737    # object, just return None 
    38     if  data1D.__class__.__name__ not in ['Data1D', 'Theory1D']: 
    39         if data1D == None: 
     38    if  data.__class__.__name__ not in ['Data1D', 'Theory1D']: 
     39        if data == None: 
    4040            return None 
    41         elif data1D.dqx_data == None or data1D.dqy_data == None: 
     41        elif data.dqx_data == None or data.dqy_data == None: 
    4242            return None 
    43         return Smearer2D(data1D) 
    44      
    45     if  not hasattr(data1D, "dx") and not hasattr(data1D, "dxl")\ 
    46          and not hasattr(data1D, "dxw"): 
     43        return Pinhole2D(data) 
     44 
     45    if  not hasattr(data, "dx") and not hasattr(data, "dxl")\ 
     46         and not hasattr(data, "dxw"): 
    4747        return None 
    48      
     48 
    4949    # Look for resolution smearing data 
    5050    _found_resolution = False 
    51     if data1D.dx is not None and len(data1D.dx) == len(data1D.x): 
    52          
     51    if data.dx is not None and len(data.dx) == len(data.x): 
     52 
    5353        # Check that we have non-zero data 
    54         if data1D.dx[0] > 0.0: 
     54        if data.dx[0] > 0.0: 
    5555            _found_resolution = True 
    5656            #print "_found_resolution",_found_resolution 
     
    5858    # If we found resolution smearing data, return a QSmearer 
    5959    if _found_resolution == True: 
    60         return QSmearer(data1D, model) 
    61         #return pinhole_smear(data1D, model) 
     60         return pinhole_smear(data, model) 
    6261 
    6362    # Look for slit smearing data 
    6463    _found_slit = False 
    65     if data1D.dxl is not None and len(data1D.dxl) == len(data1D.x) \ 
    66         and data1D.dxw is not None and len(data1D.dxw) == len(data1D.x): 
    67          
     64    if data.dxl is not None and len(data.dxl) == len(data.x) \ 
     65        and data.dxw is not None and len(data.dxw) == len(data.x): 
     66 
    6867        # Check that we have non-zero data 
    69         if data1D.dxl[0] > 0.0 or data1D.dxw[0] > 0.0: 
     68        if data.dxl[0] > 0.0 or data.dxw[0] > 0.0: 
    7069            _found_slit = True 
    71          
     70 
    7271        # Sanity check: all data should be the same as a function of Q 
    73         for item in data1D.dxl: 
    74             if data1D.dxl[0] != item: 
     72        for item in data.dxl: 
     73            if data.dxl[0] != item: 
    7574                _found_resolution = False 
    7675                break 
    77              
    78         for item in data1D.dxw: 
    79             if data1D.dxw[0] != item: 
     76 
     77        for item in data.dxw: 
     78            if data.dxw[0] != item: 
    8079                _found_resolution = False 
    8180                break 
    8281    # If we found slit smearing data, return a slit smearer 
    8382    if _found_slit == True: 
    84         #return SlitSmearer(data1D, model) 
    85         return slit_smear(data1D, model) 
     83        return slit_smear(data, model) 
    8684    return None 
    87              
    88  
    89 class _BaseSmearer(object): 
    90     """ 
    91         Base class for smearers 
    92     """ 
    93     def __init__(self): 
    94         self.nbins = 0 
    95         self.nbins_low = 0 
    96         self.nbins_high = 0 
    97         self._weights = None 
    98         ## Internal flag to keep track of C++ smearer initialization 
    99         self._init_complete = False 
    100         self._smearer = None 
    101         self.model = None 
    102         self.min = None 
    103         self.max = None 
    104         self.qvalues = [] 
    105          
    106     def __deepcopy__(self, memo=None): 
    107         """ 
    108         Return a valid copy of self. 
    109         Avoid copying the _smearer C object and force a matrix recompute 
    110         when the copy is used.   
    111         """ 
    112         result = _BaseSmearer() 
    113         result.nbins = self.nbins 
    114         return result 
    115  
    116     def _compute_matrix(self): 
    117         """ 
    118             Place holder for matrix computation  
    119         """ 
    120         return NotImplemented 
    121  
    122     def get_unsmeared_range(self, q_min=None, q_max=None): 
    123         """ 
    124             Place holder for method returning unsmeared range 
    125         """ 
    126         return NotImplemented 
    127      
    128     def get_bin_range(self, q_min=None, q_max=None): 
    129         """ 
    130          
    131         :param q_min: minimum q-value to smear 
    132         :param q_max: maximum q-value to smear 
    133           
    134         """ 
    135         # If this is the first time we call for smearing, 
    136         # initialize the C++ smearer object first 
    137         if not self._init_complete: 
    138             self._initialize_smearer() 
    139         if q_min == None: 
    140             q_min = self.min 
    141         if q_max == None: 
    142             q_max = self.max 
    143  
    144         _qmin_unsmeared, _qmax_unsmeared = self.get_unsmeared_range(q_min, 
    145                                                                      q_max) 
    146         _first_bin = None 
    147         _last_bin  = None 
    148  
    149         #step = (self.max - self.min) / (self.nbins - 1.0) 
    150         # Find the first and last bin number in all extrapolated and real data 
    151         try: 
    152             for i in range(self.nbins): 
    153                 q_i = smearer.get_q(self._smearer, i) 
    154                 if (q_i >= _qmin_unsmeared) and (q_i <= _qmax_unsmeared): 
    155                     # Identify first and last bin 
    156                     if _first_bin is None: 
    157                         _first_bin = i 
    158                     else: 
    159                         _last_bin  = i 
    160         except: 
    161             msg = "_BaseSmearer.get_bin_range: " 
    162             msg += " error getting range\n  %s" % sys.exc_value 
    163             raise RuntimeError, msg 
    164     
    165         #  Find the first and last bin number only in the real data 
    166         _first_bin, _last_bin = self._get_unextrapolated_bin( \ 
    167                                         _first_bin, _last_bin) 
    168  
    169         return _first_bin, _last_bin 
    170  
    171     def __call__(self, iq_in, first_bin = 0, last_bin = None): 
    172         """ 
    173         Perform smearing 
    174         """ 
    175         # If this is the first time we call for smearing, 
    176         # initialize the C++ smearer object first 
    177         if not self._init_complete: 
    178             self._initialize_smearer() 
    179  
    180         if last_bin is None or last_bin >= len(iq_in): 
    181             last_bin = len(iq_in) - 1 
    182         # Check that the first bin is positive 
    183         if first_bin < 0: 
    184             first_bin = 0 
    185  
    186         # With a model given, compute I for the extrapolated points and append 
    187         # to the iq_in 
    188         iq_in_temp = iq_in 
    189         if self.model != None: 
    190             temp_first, temp_last = self._get_extrapolated_bin( \ 
    191                                                         first_bin, last_bin) 
    192             if self.nbins_low > 0: 
    193                 iq_in_low = self.model.evalDistribution( \ 
    194                                     numpy.fabs(self.qvalues[0:self.nbins_low])) 
    195             iq_in_high = self.model.evalDistribution( \ 
    196                                             self.qvalues[(len(self.qvalues) - \ 
    197                                             self.nbins_high - 1):]) 
    198             # Todo: find out who is sending iq[last_poin] = 0. 
    199             if iq_in[len(iq_in) - 1] == 0: 
    200                 iq_in[len(iq_in) - 1] = iq_in_high[0] 
    201             # Append the extrapolated points to the data points 
    202             if self.nbins_low > 0: 
    203                 iq_in_temp = numpy.append(iq_in_low, iq_in) 
    204             if self.nbins_high > 0: 
    205                 iq_in_temp = numpy.append(iq_in_temp, iq_in_high[1:]) 
    206         else: 
    207             temp_first = first_bin 
    208             temp_last = last_bin 
    209             #iq_in_temp = iq_in 
    210  
    211         # Sanity check 
    212         if len(iq_in_temp) != self.nbins: 
    213             msg = "Invalid I(q) vector: inconsistent array " 
    214             msg += " length %d != %s" % (len(iq_in_temp), str(self.nbins)) 
    215             raise RuntimeError, msg 
    216  
    217         # Storage for smeared I(q)    
    218         iq_out = numpy.zeros(self.nbins) 
    219  
    220         smear_output = smearer.smear(self._smearer, iq_in_temp, iq_out, 
    221                                       #0, self.nbins - 1) 
    222                                       temp_first, temp_last) 
    223                                       #first_bin, last_bin) 
    224         if smear_output < 0: 
    225             msg = "_BaseSmearer: could not smear, code = %g" % smear_output 
    226             raise RuntimeError, msg 
    227  
    228         temp_first = first_bin + self.nbins_low 
    229         temp_last = self.nbins - self.nbins_high 
    230         out = iq_out[temp_first: temp_last] 
    231  
    232         return out 
    233      
    234     def _initialize_smearer(self): 
    235         """ 
    236             Place holder for initializing data smearer 
    237         """ 
    238         return NotImplemented 
    239              
    240      
    241     def _get_unextrapolated_bin(self, first_bin = 0, last_bin = 0): 
    242         """ 
    243         Get unextrapolated first bin and the last bin 
    244          
    245         : param first_bin: extrapolated first_bin 
    246         : param last_bin: extrapolated last_bin 
    247          
    248         : return fist_bin, last_bin: unextrapolated first and last bin 
    249         """ 
    250         #  For first bin 
    251         if first_bin <= self.nbins_low: 
    252             first_bin = 0 
    253         else: 
    254             first_bin = first_bin - self.nbins_low 
    255         # For last bin 
    256         if last_bin >= (self.nbins - self.nbins_high): 
    257             last_bin  = self.nbins - (self.nbins_high + self.nbins_low + 1) 
    258         elif last_bin >= self.nbins_low: 
    259             last_bin = last_bin - self.nbins_low 
    260         else: 
    261             last_bin = 0 
    262         return first_bin, last_bin 
    263      
    264     def _get_extrapolated_bin(self, first_bin = 0, last_bin = 0): 
    265         """ 
    266         Get extrapolated first bin and the last bin 
    267          
    268         : param first_bin: unextrapolated first_bin 
    269         : param last_bin: unextrapolated last_bin 
    270          
    271         : return first_bin, last_bin: extrapolated first and last bin 
    272         """ 
    273         #  For the first bin 
    274         # In the case that needs low extrapolation data 
    275         first_bin = 0 
    276         # For last bin 
    277         if last_bin >= self.nbins - (self.nbins_high + self.nbins_low + 1): 
    278             # In the case that needs higher q extrapolation data  
    279             last_bin = self.nbins - 1 
    280         else: 
    281             # In the case that doesn't need higher q extrapolation data  
    282             last_bin += self.nbins_low 
    283  
    284         return first_bin, last_bin 
    285          
    286 class _SlitSmearer(_BaseSmearer): 
    287     """ 
    288     Slit smearing for I(q) array 
    289     """ 
    290      
    291     def __init__(self, nbins=None, width=None, height=None, min=None, max=None): 
    292         """ 
    293         Initialization 
    294              
    295         :param iq: I(q) array [cm-1] 
    296         :param width: slit width [A-1] 
    297         :param height: slit height [A-1] 
    298         :param min: Q_min [A-1] 
    299         :param max: Q_max [A-1] 
    300          
    301         """ 
    302         _BaseSmearer.__init__(self) 
    303         ## Slit width in Q units 
    304         self.width  = width 
    305         ## Slit height in Q units 
    306         self.height = height 
    307         ## Q_min (Min Q-value for I(q)) 
    308         self.min    = min 
    309         ## Q_max (Max Q_value for I(q)) 
    310         self.max    = max 
    311         ## Number of Q bins  
    312         self.nbins  = nbins 
    313         ## Number of points used in the smearing computation 
    314         self.npts   = 3000 
    315         ## Smearing matrix 
    316         self._weights = None 
    317         self.qvalues  = None 
    318          
    319     def _initialize_smearer(self): 
    320         """ 
    321         Initialize the C++ smearer object. 
    322         This method HAS to be called before smearing 
    323         """ 
    324         #self._smearer = smearer.new_slit_smearer(self.width, 
    325         # self.height, self.min, self.max, self.nbins) 
    326         self._smearer = smearer.new_slit_smearer_with_q(self.width,  
    327                                                     self.height, self.qvalues) 
    328         self._init_complete = True 
    329  
    330     def get_unsmeared_range(self, q_min, q_max): 
    331         """ 
    332         Determine the range needed in unsmeared-Q to cover 
    333         the smeared Q range 
    334         """ 
    335         # Range used for input to smearing 
    336         _qmin_unsmeared = q_min 
    337         _qmax_unsmeared = q_max  
    338         try: 
    339             _qmin_unsmeared = self.min 
    340             _qmax_unsmeared = self.max 
    341         except: 
    342             logging.error("_SlitSmearer.get_bin_range: %s" % sys.exc_value) 
    343         return _qmin_unsmeared, _qmax_unsmeared 
    344  
    345 class SlitSmearer(_SlitSmearer): 
    346     """ 
    347     Adaptor for slit smearing class and SAS data 
    348     """ 
    349     def __init__(self, data1D, model = None): 
    350         """ 
    351         Assumption: equally spaced bins of increasing q-values. 
    352          
    353         :param data1D: data used to set the smearing parameters 
    354         """ 
    355         # Initialization from parent class 
    356         super(SlitSmearer, self).__init__() 
    357          
    358         ## Slit width 
    359         self.width = 0 
    360         self.nbins_low = 0 
    361         self.nbins_high = 0 
    362         self.model = model 
    363         if data1D.dxw is not None and len(data1D.dxw) == len(data1D.x): 
    364             self.width = data1D.dxw[0] 
    365             # Sanity check 
    366             for value in data1D.dxw: 
    367                 if value != self.width: 
    368                     msg = "Slit smearing parameters must " 
    369                     msg += " be the same for all data" 
    370                     raise RuntimeError, msg 
    371         ## Slit height 
    372         self.height = 0 
    373         if data1D.dxl is not None and len(data1D.dxl) == len(data1D.x): 
    374             self.height = data1D.dxl[0] 
    375             # Sanity check 
    376             for value in data1D.dxl: 
    377                 if value != self.height: 
    378                     msg = "Slit smearing parameters must be" 
    379                     msg += " the same for all data" 
    380                     raise RuntimeError, msg 
    381         # If a model is given, get the q extrapolation 
    382         if self.model == None: 
    383             data1d_x = data1D.x 
    384         else: 
    385             # Take larger sigma 
    386             if self.height > self.width: 
    387                 # The denominator (2.0) covers all the possible w^2 + h^2 range 
    388                 sigma_in = data1D.dxl / 2.0 
    389             elif self.width > 0: 
    390                 sigma_in = data1D.dxw / 2.0 
    391             else: 
    392                 sigma_in = [] 
    393  
    394             self.nbins_low, self.nbins_high, _, data1d_x = \ 
    395                                 get_qextrapolate(sigma_in, data1D.x) 
    396  
    397         ## Number of Q bins 
    398         self.nbins = len(data1d_x) 
    399         ## Minimum Q  
    400         self.min = min(data1d_x) 
    401         ## Maximum 
    402         self.max = max(data1d_x) 
    403         ## Q-values 
    404         self.qvalues = data1d_x 
    405          
    406  
    407 class _QSmearer(_BaseSmearer): 
    408     """ 
    409     Perform Gaussian Q smearing 
    410     """ 
    411          
    412     def __init__(self, nbins=None, width=None, min=None, max=None): 
    413         """ 
    414         Initialization 
    415          
    416         :param nbins: number of Q bins 
    417         :param width: array standard deviation in Q [A-1] 
    418         :param min: Q_min [A-1] 
    419         :param max: Q_max [A-1] 
    420         """ 
    421         _BaseSmearer.__init__(self) 
    422         ## Standard deviation in Q [A-1] 
    423         self.width = width 
    424         ## Q_min (Min Q-value for I(q)) 
    425         self.min = min 
    426         ## Q_max (Max Q_value for I(q)) 
    427         self.max = max 
    428         ## Number of Q bins  
    429         self.nbins = nbins 
    430         ## Smearing matrix 
    431         self._weights = None 
    432         self.qvalues  = None 
    433          
    434     def _initialize_smearer(self): 
    435         """ 
    436         Initialize the C++ smearer object. 
    437         This method HAS to be called before smearing 
    438         """ 
    439         #self._smearer = smearer.new_q_smearer(numpy.asarray(self.width), 
    440         # self.min, self.max, self.nbins) 
    441         self._smearer = smearer.new_q_smearer_with_q(numpy.asarray(self.width), 
    442                                                       self.qvalues) 
    443         self._init_complete = True 
    444          
    445     def get_unsmeared_range(self, q_min, q_max): 
    446         """ 
    447         Determine the range needed in unsmeared-Q to cover 
    448         the smeared Q range 
    449         Take 3 sigmas as the offset between smeared and unsmeared space 
    450         """ 
    451         # Range used for input to smearing 
    452         _qmin_unsmeared = q_min 
    453         _qmax_unsmeared = q_max  
    454         try: 
    455             offset = 3.0 * max(self.width) 
    456             _qmin_unsmeared = self.min#max([self.min, q_min - offset]) 
    457             _qmax_unsmeared = self.max#min([self.max, q_max + offset]) 
    458         except: 
    459             logging.error("_QSmearer.get_bin_range: %s" % sys.exc_value) 
    460         return _qmin_unsmeared, _qmax_unsmeared 
    461          
    462      
    463 class QSmearer(_QSmearer): 
    464     """ 
    465     Adaptor for Gaussian Q smearing class and SAS data 
    466     """ 
    467     def __init__(self, data1D, model = None): 
    468         """ 
    469         Assumption: equally spaced bins of increasing q-values. 
    470          
    471         :param data1D: data used to set the smearing parameters 
    472         """ 
    473         # Initialization from parent class 
    474         super(QSmearer, self).__init__() 
    475         data1d_x = [] 
    476         self.nbins_low = 0 
    477         self.nbins_high = 0 
    478         self.model = model 
    479         ## Resolution 
    480         #self.width = numpy.zeros(len(data1D.x)) 
    481         if data1D.dx is not None and len(data1D.dx) == len(data1D.x): 
    482             self.width = data1D.dx 
    483          
    484         if self.model == None: 
    485             data1d_x = data1D.x 
    486         else: 
    487             self.nbins_low, self.nbins_high, self.width, data1d_x = \ 
    488                                 get_qextrapolate(self.width, data1D.x) 
    489  
    490         ## Number of Q bins 
    491         self.nbins = len(data1d_x) 
    492         ## Minimum Q  
    493         self.min = min(data1d_x) 
    494         ## Maximum 
    495         self.max = max(data1d_x) 
    496         ## Q-values 
    497         self.qvalues = data1d_x 
    498  
    499          
    500 def get_qextrapolate(width, data_x): 
    501     """ 
    502     Make fake data_x points extrapolated outside of the data_x points 
    503      
    504     :param width: array of std of q resolution 
    505     :param Data1D.x: Data1D.x array 
    506      
    507     :return new_width, data_x_ext: extrapolated width array and x array 
    508      
    509     :assumption1: data_x is ordered from lower q to higher q 
    510     :assumption2: len(data) = len(width) 
    511     :assumption3: the distance between the data points is more compact than the size of width  
    512     :Todo1: Make sure that the assumptions are correct for Data1D 
    513     :Todo2: This fixes the edge problem in Qsmearer but still needs to make smearer interface  
    514     """ 
    515     # Length of the width 
    516     length = len(width) 
    517     width_low = math.fabs(width[0])    
    518     width_high = math.fabs(width[length -1]) 
    519     nbins_low = 0.0  
    520     nbins_high = 0.0 
    521     # Compare width(dQ) to the data bin size and take smaller one as the bin  
    522     # size of the extrapolation; this will correct some weird behavior  
    523     # at the edge: This method was out (commented)  
    524     # because it becomes very expansive when 
    525     # bin size is very small comparing to the width. 
    526     # Now on, we will just give the bin size of the extrapolated points  
    527     # based on the width. 
    528     # Find bin sizes 
    529     #bin_size_low = math.fabs(data_x[1] - data_x[0]) 
    530     #bin_size_high = math.fabs(data_x[length - 1] - data_x[length - 2]) 
    531     # Let's set the bin size 1/3 of the width(sigma), it is good as long as 
    532     # the scattering is monotonous. 
    533     #if width_low < (bin_size_low): 
    534     bin_size_low = width_low / 10.0 
    535     #if width_high < (bin_size_high): 
    536     bin_size_high = width_high / 10.0 
    537          
    538     # Number of q points required below the 1st data point in order to extend 
    539     # them 3 times of the width (std) 
    540     if width_low > 0.0: 
    541         nbins_low = math.ceil(3.0 * width_low / bin_size_low) 
    542     # Number of q points required above the last data point 
    543     if width_high > 0.0: 
    544         nbins_high = math.ceil(3.0 * width_high / bin_size_high) 
    545     # Make null q points         
    546     extra_low = numpy.zeros(nbins_low) 
    547     extra_high = numpy.zeros(nbins_high) 
    548     # Give extrapolated values 
    549     ind = 0 
    550     qvalue = data_x[0] - bin_size_low 
    551     #if qvalue > 0: 
    552     while(ind < nbins_low): 
    553         extra_low[nbins_low - (ind + 1)] = qvalue 
    554         qvalue -= bin_size_low 
    555         ind += 1 
    556         #if qvalue <= 0: 
    557         #    break 
    558     # Redefine nbins_low 
    559     nbins_low = ind 
    560     # Reset ind for another extrapolation 
    561     ind = 0 
    562     qvalue = data_x[length -1] + bin_size_high 
    563     while(ind < nbins_high): 
    564         extra_high[ind] = qvalue 
    565         qvalue += bin_size_high 
    566         ind += 1 
    567     # Make a new qx array 
    568     if nbins_low > 0:   
    569         data_x_ext = numpy.append(extra_low, data_x) 
    570     else: 
    571         data_x_ext = data_x 
    572     data_x_ext = numpy.append(data_x_ext, extra_high) 
    573      
    574     # Redefine extra_low and high based on corrected nbins   
    575     # And note that it is not necessary for extra_width to be a non-zero  
    576     if nbins_low > 0:      
    577         extra_low = numpy.zeros(nbins_low) 
    578     extra_high = numpy.zeros(nbins_high)  
    579     # Make new width array 
    580     new_width = numpy.append(extra_low, width) 
    581     new_width = numpy.append(new_width, extra_high) 
    582      
    583     # nbins corrections due to the negative q value 
    584     nbins_low = nbins_low - len(data_x_ext[data_x_ext <= 0]) 
    585     return nbins_low, nbins_high, \ 
    586              new_width[data_x_ext > 0], data_x_ext[data_x_ext > 0] 
    58785 
    58886 
    589  
    590 from .resolution import Slit1D, Pinhole1D 
    59187class PySmear(object): 
    59288    """ 
     
    60197        """ 
    60298        Apply the resolution function to the data. 
    603  
    60499        Note that this is called with iq_in matching data.x, but with 
    605100        iq_in[first_bin:last_bin] set to theory values for these bins, 
    606101        and the remainder left undefined.  The first_bin, last_bin values 
    607102        should be those returned from get_bin_range. 
    608  
    609103        The returned value is of the same length as iq_in, with the range 
    610104        first_bin:last_bin set to the resolution smeared values. 
     
    626120        """ 
    627121        For a given q_min, q_max, find the corresponding indices in the data. 
    628  
    629122        Returns first, last. 
    630  
    631123        Note that these are indexes into q from the data, not the q_calc 
    632124        needed by the resolution function.  Note also that these are the 
Note: See TracChangeset for help on using the changeset viewer.