Changeset 9198b83 in sasview


Ignore:
Timestamp:
Aug 1, 2008 12:10: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:
cfe97ea
Parents:
30c6721
Message:

Added basic arithmetic for data class, with unit tests.

Location:
DataLoader
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • DataLoader/data_info.py

    r8780e9a r9198b83  
    2020 
    2121from sans.guitools.plottables import Data1D as plottable_1D 
     22from data_util.uncertainty import Uncertainty 
     23import numpy 
     24import math 
    2225 
    2326class Data2D: 
     
    276279    ## Loading errors 
    277280    errors = [] 
    278      
    279     def __add__(self, data): 
    280         """ 
    281             Add two data sets 
    282              
    283             @param data: data set to add to the current one 
    284             @return: new data set 
    285             @raise ValueError: raised when two data sets are incompatible 
    286         """ 
    287         raise RuntimeError, "DataInfo addition is not implemented yet" 
    288      
    289     def __sub__(self, data): 
    290         """ 
    291             Subtract two data sets 
    292              
    293             @param data: data set to subtract from the current one 
    294             @return: new data set 
    295             @raise ValueError: raised when two data sets are incompatible 
    296         """ 
    297         raise RuntimeError, "DataInfo subtraction is not implemented yet" 
    298      
    299     def __mul__(self, constant): 
    300         """ 
    301             Multiply every entry of the current data set by a constant 
    302              
    303             @param constant: constant to multiply the data by 
    304             @return: new data set 
    305             @raise ValueError: raised when the constant is not a float 
    306         """ 
    307         raise RuntimeError, "DataInfo multiplication is not implemented yet" 
    308      
    309     def __div__(self, constant): 
    310         """ 
    311         """ 
    312         raise RuntimeError, "DataInfo division is not implemented yet" 
    313      
    314          
     281             
    315282class Data1D(plottable_1D, DataInfo): 
    316283    """ 
     
    351318        return _str 
    352319 
    353  
    354  
    355  
     320    def clone_without_data(self, length=0): 
     321        from copy import deepcopy 
     322         
     323        x  = numpy.zeros(length)  
     324        dx = numpy.zeros(length)  
     325        y  = numpy.zeros(length)  
     326        dy = numpy.zeros(length)  
     327         
     328        clone = Data1D(x, y, dx=dx, dy=dy) 
     329        clone.title       = self.title 
     330        clone.run         = self.run 
     331        clone.filename    = self.filename 
     332        clone.notes       = deepcopy(self.notes)  
     333        clone.process     = deepcopy(self.process)  
     334        clone.detector    = deepcopy(self.detector)  
     335        clone.sample      = deepcopy(self.sample)  
     336        clone.source      = deepcopy(self.source)  
     337        clone.collimation = deepcopy(self.collimation)  
     338        clone.meta_data   = deepcopy(self.meta_data)  
     339        clone.errors      = deepcopy(self.errors)  
     340         
     341        return clone 
     342 
     343    def _validity_check(self, other): 
     344        """ 
     345            Checks that the data lengths are compatible. 
     346            Checks that the x vectors are compatible. 
     347            Returns errors vectors equal to original 
     348            errors vectors if they were present or vectors 
     349            of zeros when none was found. 
     350             
     351            @param other: other data set for operation 
     352            @return: dy for self, dy for other [numpy arrays] 
     353            @raise ValueError: when lengths are not compatible 
     354        """ 
     355        dy_other = None 
     356        if isinstance(other, Data1D): 
     357            # Check that data lengths are the same 
     358            if len(self.x) != len(other.x) or \ 
     359                len(self.y) != len(other.y): 
     360                raise ValueError, "Unable to perform operation: data length are not equal" 
     361             
     362            # Here we could also extrapolate between data points 
     363            for i in range(len(self.x)): 
     364                if self.x[i] != other.x[i]: 
     365                    raise ValueError, "Incompatible data sets: x-values do not match" 
     366             
     367            # Check that the other data set has errors, otherwise 
     368            # create zero vector 
     369            dy_other = other.dy 
     370            if other.dy==None or (len(other.dy) != len(other.y)): 
     371                dy_other = numpy.zeros(len(other.y)) 
     372             
     373        # Check that we have errors, otherwise create zero vector 
     374        dy = self.dy 
     375        if self.dy==None or (len(self.dy) != len(self.y)): 
     376            dy = numpy.zeros(len(self.y))             
     377             
     378        return dy, dy_other 
     379 
     380    def _perform_operation(self, other, operation): 
     381        """ 
     382        """ 
     383        # First, check the data compatibility 
     384        dy, dy_other = self._validity_check(other) 
     385        result = self.clone_without_data(len(self.x)) 
     386         
     387        for i in range(len(self.x)): 
     388            result.x[i] = self.x[i] 
     389            if self.dx is not None and len(self.x)==len(self.dx): 
     390                result.dx[i] = self.dx[i] 
     391             
     392            a = Uncertainty(self.y[i], dy[i]**2) 
     393            if isinstance(other, Data1D): 
     394                b = Uncertainty(other.y[i], dy_other[i]**2) 
     395            else: 
     396                b = other 
     397             
     398            output = operation(a, b) 
     399            result.y[i] = output.x 
     400            result.dy[i] = math.sqrt(math.fabs(output.variance)) 
     401        return result 
     402         
     403 
     404    def __add__(self, other): 
     405        """ 
     406            Add two data sets 
     407             
     408            @param other: data set to add to the current one 
     409            @return: new data set 
     410            @raise ValueError: raised when two data sets are incompatible 
     411        """ 
     412        def operation(a, b): return a+b 
     413        return self._perform_operation(other, operation) 
     414         
     415    def __radd__(self, other): 
     416        """ 
     417            Add two data sets 
     418             
     419            @param other: data set to add to the current one 
     420            @return: new data set 
     421            @raise ValueError: raised when two data sets are incompatible 
     422        """ 
     423        def operation(a, b): return b+a 
     424        return self._perform_operation(other, operation) 
     425         
     426    def __sub__(self, other): 
     427        """ 
     428            Subtract two data sets 
     429             
     430            @param other: data set to subtract from the current one 
     431            @return: new data set 
     432            @raise ValueError: raised when two data sets are incompatible 
     433        """ 
     434        def operation(a, b): return a-b 
     435        return self._perform_operation(other, operation) 
     436         
     437    def __rsub__(self, other): 
     438        """ 
     439            Subtract two data sets 
     440             
     441            @param other: data set to subtract from the current one 
     442            @return: new data set 
     443            @raise ValueError: raised when two data sets are incompatible 
     444        """ 
     445        def operation(a, b): return b-a 
     446        return self._perform_operation(other, operation) 
     447         
     448    def __mul__(self, other): 
     449        """ 
     450            Multiply two data sets 
     451             
     452            @param other: data set to subtract from the current one 
     453            @return: new data set 
     454            @raise ValueError: raised when two data sets are incompatible 
     455        """ 
     456        def operation(a, b): return a*b 
     457        return self._perform_operation(other, operation) 
     458         
     459    def __rmul__(self, other): 
     460        """ 
     461            Multiply two data sets 
     462             
     463            @param other: data set to subtract from the current one 
     464            @return: new data set 
     465            @raise ValueError: raised when two data sets are incompatible 
     466        """ 
     467        def operation(a, b): return b*a 
     468        return self._perform_operation(other, operation) 
     469         
     470    def __div__(self, other): 
     471        """ 
     472            Divided a data set by another 
     473             
     474            @param other: data set that the current one is divided by 
     475            @return: new data set 
     476            @raise ValueError: raised when two data sets are incompatible 
     477        """ 
     478        def operation(a, b): return a/b 
     479        return self._perform_operation(other, operation) 
     480         
     481    def __rdiv__(self, other): 
     482        """ 
     483            Divided a data set by another 
     484             
     485            @param other: data set that the current one is divided by 
     486            @return: new data set 
     487            @raise ValueError: raised when two data sets are incompatible 
     488        """ 
     489        def operation(a, b): return b/a 
     490        return self._perform_operation(other, operation) 
     491         
     492 
     493 
Note: See TracChangeset for help on using the changeset viewer.