/[escript]/trunk/escript/py_src/timeseries.py
ViewVC logotype

Diff of /trunk/escript/py_src/timeseries.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 117 by jgs, Fri Apr 1 05:48:57 2005 UTC revision 119 by jgs, Tue Apr 12 04:45:05 2005 UTC
# Line 2  Line 2 
2    
3  import numarray  import numarray
4  from types import SliceType  from types import SliceType
5  DEFAULT_BUFFER_SIZE=9  DEFAULT_BUFFER_SIZE=1000
6  DEFAULT_FLOAT_TYPE=numarray.Float64  DEFAULT_FLOAT_TYPE=numarray.Float64
7    
8  class TimeSeriesBase:  class TimeSeriesBase:
9     """The TimeSeriesBase class is the base class for all class of the TimeSeries module."""     """The TimeSeriesBase class is the base class for all class of the TimeSeries module."""
10    
11     def __init__(self,debug=False,description="timeseries.Base"):     def __init__(self,debug=False,description="TimeSeriesBase"):
12         self.__debug=debug         self.__debug=debug
13         self.__description=description         self.setDescription(description)
14    
15     def __str__(self):     def __str__(self):
16         return self.__description         return self.__description
17      
18       def setDescription(self,text):
19           self.__description=text
20    
21     def setDebugOn(self):     def setDebugOn(self):
22        """switch on degugging mode"""        """switch on degugging mode"""
# Line 35  class TimeSeriesBase: Line 38  class TimeSeriesBase:
38        return self.__debug        return self.__debug
39    
40  #============================================================================================================  #============================================================================================================
41  class TimeSeriesDataset(TimeSeriesBase):  class TimeSeriesBaseDataset(TimeSeriesBase):
42     """provides an interface for accessing a set of linearly ordered data."""     """provides an interface for accessing a set of linearly ordered data."""
43     def __init__(self,buffer,offset=0,debug=False,description="timeseries.Dataset"):     def __init__(self,buffer,offset=0,debug=False,description="TimeSeriesDataset"):
44         TimeSeriesBase.__init__(self,debug,description)         TimeSeriesBase.__init__(self,debug,description)
45         self.__buffer=buffer         self.__buffer=buffer
46         self.__offset=offset         self.__offset=offset
# Line 49  class TimeSeriesDataset(TimeSeriesBase): Line 52  class TimeSeriesDataset(TimeSeriesBase):
52    
53     def getNumComponents(self):     def getNumComponents(self):
54         """returns the number of components of the data (may be overwritten by subclass)"""         """returns the number of components of the data (may be overwritten by subclass)"""
55         return self.getBuffer().getNumComponents()         return self.getBaseBuffer().getNumComponents()
56    
57     def getIdOfLastDatum(self):     def getIdOfLastDatum(self):
58        """returns the identification number of the last datum in the data set (may be overwritten by subclass)"""        """returns the identification number of the last datum in the data set (may be overwritten by subclass)"""
59        return self.getBuffer().getIdOfLastDatum()-self.getOffset()        return self.getBaseBuffer().getIdOfLastDatum()-self.getOffset()
60    
61     def getIdOfFirstDatum(self):     def getIdOfFirstDatum(self):
62        """returns the identification number of the first datum (may be overwritten by subclass)"""        """returns the identification number of the first datum (may be overwritten by subclass)"""
63        return self.getBuffer().getIdOfFirstDatum()-self.getOffset()        return self.getBaseBuffer().getIdOfFirstDatum()-self.getOffset()
64    
65       def getIdOfFirstAvailableDatum(self):
66          """returns the identification number of the first avaiable datum (may be overwritten by subclass)"""
67          return self.getBaseBuffer().getIdOfFirstAvailableDatum()-self.getOffset()
68    
69     def getOffsetInBuffer(self):     def getOffsetInBaseBuffer(self):
70        """returns the offset to access elements in getBuffer() (may be overwritten by subclass)"""        """returns the offset to access elements in getBaseBuffer() (may be overwritten by subclass)"""
71        return  self.getOffset()        return  self.getOffset()
72    
73     def getIdOfLastUnusedDatum(self):     def getIdOfLastUnreferencedDatum(self):
74         """returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesDataset (may be overwritten by subclass)"""         """returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesBaseDataset (may be overwritten by subclass)"""
75         return self.getBuffer().getIdOfLastUnusedDatum()-self.getOffset()         return self.getBaseBuffer().getIdOfLastUnreferencedDatum()-self.getOffset()
76    
77     def updateIdOfLastUnusedDatum(self,last_unused_datum):     def updateIdOfLastUnreferencedDatum(self,last_unreferenced_datum):
78         """updates the identification number of the last unused datum (to be overwritten by subclass)"""         """updates the identification number of the last unused datum (to be overwritten by subclass)"""
79         self.getBuffer().updateIdOfLastUnusedDatum(last_unused_datum+self.getOffset())         self.getBaseBuffer().updateIdOfLastUnreferencedDatum(last_unreferenced_datum+self.getOffset())
80    
81     def append(self,values):     def append(self,values):
82         """appends data to the buffer. If the buffer would be full the buffer is rearranged before the data are appended  (to be overwritten by subclass)"""         """appends data to the buffer. If the buffer would be full the buffer is rearranged before the data are appended  (to be overwritten by subclass)"""
83         self.getBuffer().append(values)         self.getBaseBuffer().append(values)
84    
85     def getBufferSize(self):     def getBaseBufferSize(self):
86         """returns the size of the buffer (to be overwritten by subclass)"""         """returns the size of the buffer (to be overwritten by subclass)"""
87         return self.getBuffer().getBufferSize()         return self.getBaseBuffer().getBaseBufferSize()
88        
89     def needsRearrangement(self,num_new_data=0):     def needsRearrangement(self,num_new_data=0):
90         """returns True if the buffer will be full after num_new_data have been appended (to be overwritten by subclass)"""         """returns True if the buffer will be full after num_new_data have been appended (to be overwritten by subclass)"""
91         return self.getBuffer().needsRearrangement(num_new_data)         return self.getBaseBuffer().needsRearrangement(num_new_data)
92    
93     def isEmpty(self):     def isEmpty(self):
94        """returns true if no data are appeneded to buffer"""        """returns true if no data are appeneded to buffer"""
# Line 91  class TimeSeriesDataset(TimeSeriesBase): Line 98  class TimeSeriesDataset(TimeSeriesBase):
98        """returns the number of data (not all of them are accessible)"""        """returns the number of data (not all of them are accessible)"""
99        return self.getIdOfLastDatum()-self.getIdOfFirstDatum()+1        return self.getIdOfLastDatum()-self.getIdOfFirstDatum()+1
100    
101     def getBuffer(self):     def getBaseBuffer(self):
102        """return the buffer referenced by the TimeSeriesDataset"""        """return the buffer referenced by the TimeSeriesBaseDataset"""
103        return self.__buffer        return self.__buffer
104    
105     def getOffset(self):     def getOffset(self):
# Line 109  class TimeSeriesDataset(TimeSeriesBase): Line 116  class TimeSeriesDataset(TimeSeriesBase):
116           else:           else:
117               if start<self.getIdOfFirstDatum() or start>self.getIdOfLastDatum() or \               if start<self.getIdOfFirstDatum() or start>self.getIdOfLastDatum() or \
118                   end-1<self.getIdOfFirstDatum() or end-1>self.getIdOfLastDatum(): raise IndexError,"%s: Index [%d:%d] out of range"%(self,start,end)                   end-1<self.getIdOfFirstDatum() or end-1>self.getIdOfLastDatum(): raise IndexError,"%s: Index [%d:%d] out of range"%(self,start,end)
119               return self.getBuffer()[start+self.getOffsetInBuffer():end+self.getOffsetInBuffer()]               return self.getBaseBuffer()[start+self.getOffsetInBaseBuffer():end+self.getOffsetInBaseBuffer()]
120        else:        else:
121           if index<self.getIdOfFirstDatum() or index>self.getIdOfLastDatum(): raise IndexError,"%s: Index %d out of range"%(self,index)           if index<self.getIdOfFirstDatum() or index>self.getIdOfLastDatum(): raise IndexError,"%s: Index %d out of range"%(self,index)
122           return self.getBuffer()[index+self.getOffsetInBuffer()]           return self.getBaseBuffer()[index+self.getOffsetInBaseBuffer()]
123    
124  class TimeSeriesBuffer(TimeSeriesDataset):  class TimeSeriesBaseBuffer(TimeSeriesBaseDataset):
125     """An inplementation of TimeSeriesDataset which actually is storing data into a numarray buffer"""     """An inplementation of TimeSeriesBaseDataset which actually is storing data into a numarray buffer"""
126     def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,numComponents=1,type=DEFAULT_FLOAT_TYPE,id_of_first_datum=0,debug=False,description="timeseries.Buffer"):     def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,numComponents=1,type=DEFAULT_FLOAT_TYPE,id_of_first_datum=0,debug=False,description="TimeSeriesBaseBuffer"):
127         if numComponents<2:         if numComponents<2:
128            buffer=numarray.zeros((buffer_size,),type)            buffer=numarray.zeros((buffer_size,),type)
129         else:         else:
130            buffer=numarray.zeros((buffer_size,numComponents),type)            buffer=numarray.zeros((buffer_size,numComponents),type)
131         TimeSeriesDataset.__init__(self,buffer,id_of_first_datum-1,debug,description)         TimeSeriesBaseDataset.__init__(self,buffer,id_of_first_datum-1,debug,description)
132         self.__num_data_in_buffer=0         self.__num_data_in_buffer=0
133         self.__id_last_unused_datum=id_of_first_datum-1         self.__id_last_unreferenced_datum=id_of_first_datum-1
134         self.__id_last_datum=id_of_first_datum-1         self.__id_last_datum=id_of_first_datum-1
135         self.__id_first_datum=id_of_first_datum         self.__id_first_datum=id_of_first_datum
136         if self.debug(): print "Debug: %s : buffer of size %d with %d components allocated (first datum is %d)."% \         if self.debug(): print "Debug: %s : buffer of size %d with %d components allocated (first datum is %d)."% \
137                         (self,self.getBufferSize(),self.getNumComponents(),id_of_first_datum)                         (self,self.getBaseBufferSize(),self.getNumComponents(),id_of_first_datum)
138    
139    
140     def getBufferSize(self):     def getBaseBufferSize(self):
141         """returns the size of the buffer"""         """returns the size of the buffer"""
142         return self.getBuffer().shape[0]         return self.getBaseBuffer().shape[0]
143        
144     def getNumComponents(self):     def getNumComponents(self):
145         """returns the number of components of the data (overwrites TimeSeriesDataset method)"""         """returns the number of components of the data (overwrites TimeSeriesBaseDataset method)"""
146         if self.getBuffer().rank==1:         if self.getBaseBuffer().rank==1:
147            return 1            return 1
148         else:         else:
149            self.getBuffer().shape[1]            self.getBaseBuffer().shape[1]
150    
151     def getNumDataInBuffer(self):     def getNumDataInBaseBuffer(self):
152         """returns the number of data currently in the buffer"""         """returns the number of data currently in the buffer"""
153         return self.__num_data_in_buffer         return self.__num_data_in_buffer
154    
155     def getIdOfLastDatum(self):     def getIdOfLastDatum(self):
156        """returns the identification number of the last datum in the data set (overwrites method from TimeSeriesDataset)"""        """returns the identification number of the last datum in the data set (overwrites method from TimeSeriesBaseDataset)"""
157        return self.__id_last_datum        return self.__id_last_datum
158    
159     def getIdOfFirstDatum(self):     def getIdOfFirstDatum(self):
160        """returns the identification number of the first datum (overwrites method from TimeSeriesDataset)"""        """returns the identification number of the first datum (overwrites method from TimeSeriesBaseDataset)"""
161        return self.__id_first_datum        return self.__id_first_datum
162    
163     def getOffsetInBuffer(self):     def getOffsetInBaseBuffer(self):
164        """returns the offset to access elements in the buffer (overwrites method from TimeSeriesDataset)"""          """returns the offset to access elements in the buffer (overwrites method from TimeSeriesBaseDataset)"""  
165        return -self.getIdOfLastDatum()+self.getNumDataInBuffer()-1          return -self.getIdOfLastDatum()+self.getNumDataInBaseBuffer()-1  
166    
167     def getIdOfLastUnusedDatum(self):     def getIdOfLastUnreferencedDatum(self):
168         """returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesDataset (overwrites method from TimeSeriesDataset)"""         """returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesBaseDataset (overwrites method from TimeSeriesBaseDataset)"""
169         return self.__id_last_unused_datum         return self.__id_last_unreferenced_datum
170    
171     def updateIdOfLastUnusedDatum(self,last_unused_datum):     def updateIdOfLastUnreferencedDatum(self,last_unreferenced_datum):
172         """updates the identification number of the last unused datum (to be overwritten by subclass)"""         """updates the identification number of the last unused datum (to be overwritten by subclass)"""
173         self.getBuffer().updateIdOfLastUnusedDatum(last_unused_datum-self.getOffset())         self.getBaseBuffer().updateIdOfLastUnreferencedDatum(last_unreferenced_datum-self.getOffset())
174    
175     def updateIdOfLastUnusedDatum(self,last_unused_datum):     def updateIdOfLastUnreferencedDatum(self,last_unreferenced_datum):
176         """updates the identification number of the last unused datum (overwrites TimeSeriesDataset method)"""         """updates the identification number of the last unused datum (overwrites TimeSeriesBaseDataset method)"""
177         if self.__id_last_unused_datum>last_unused_datum:         if self.__id_last_unreferenced_datum>last_unreferenced_datum:
178             self.__id_last_unused_datum=last_unused_datum             self.__id_last_unreferenced_datum=last_unreferenced_datum
179             if self.debug(): print "Debug: %s: last unused datum is now %s"%(self,last_unused_datum)             if self.debug(): print "Debug: %s: last unused datum is now %s"%(self,last_unreferenced_datum)
180    
181     def needsRearrangement(self,num_new_data=0):     def needsRearrangement(self,num_new_data=0):
182         """returns True if the buffer will be full after num_new_data have been appended"""         """returns True if the buffer will be full after num_new_data have been appended"""
183         return self.getNumDataInBuffer()+num_new_data>self.getBufferSize()         return self.getNumDataInBaseBuffer()+num_new_data>self.getBaseBufferSize()
184                    
185       def getIdOfFirstAvailableDatum(self):
186          """returns the identification number of the first avaiable datum (overwrites TimeSeriesBaseDataset method)"""
187          return self.getIdOfLastDatum()-self.__num_data_in_buffer+1
188    
189     def append(self,data):     def append(self,data):
190        """appends data to the buffer. If the buffer would be full the buffer is rearranged before the data are appended (overwrites TimeSeriesDataset method)"""        """appends data to the buffer. If the buffer would be full the buffer is rearranged before the data are appended (overwrites TimeSeriesBaseDataset method)"""
191        data=numarray.array(data)        data=numarray.array(data)
192        nc=self.getNumComponents()        nc=self.getNumComponents()
193        if data.rank==0:        if data.rank==0:
# Line 197  class TimeSeriesBuffer(TimeSeriesDataset Line 208  class TimeSeriesBuffer(TimeSeriesDataset
208    
209        # check is buffer will be overflown when data are appended:        # check is buffer will be overflown when data are appended:
210        if self.needsRearrangement(num_new_data):        if self.needsRearrangement(num_new_data):
211          nn=self.getNumDataInBuffer()          nn=self.getNumDataInBaseBuffer()
212          num_protected_data=self.getIdOfLastDatum()-self.getIdOfLastUnusedDatum()          num_protected_data=self.getIdOfLastDatum()-self.getIdOfLastUnreferencedDatum()
213          if num_protected_data+num_new_data>self.getBufferSize():          if num_protected_data+num_new_data>self.getBaseBufferSize():
214                raise ValueError,"%s: buffer overflow: buffer size has to be bigger than %d"%(self,num_protected_data+num_new_data)                raise ValueError,"%s: buffer overflow: buffer size has to be bigger than %d"%(self,num_protected_data+num_new_data)
215          if num_protected_data>0: self.getBuffer()[0:num_protected_data]=self.getBuffer()[nn-num_protected_data:nn]          if num_protected_data>0: self.getBaseBuffer()[0:num_protected_data]=self.getBaseBuffer()[nn-num_protected_data:nn]
216          self.__num_data_in_buffer=num_protected_data          self.__num_data_in_buffer=num_protected_data
217          self.__id_last_unused_datum=self.__id_last_datum          self.__id_last_unreferenced_datum=self.__id_last_datum
218          if self.debug():          if self.debug():
219               print "Debug: %s: rearrangement: first data in buffer is %d."%(self,self.getIdOfLastDatum()-self.getNumDataInBuffer()+1)               print "Debug: %s: rearrangement: first data in buffer is %d."%(self,self.getIdOfLastDatum()-self.getNumDataInBaseBuffer()+1)
220        # copy data over:        # copy data over:
221        nn=self.getNumDataInBuffer()        nn=self.getNumDataInBaseBuffer()
222        self.getBuffer()[nn:nn+num_new_data]=data        self.getBaseBuffer()[nn:nn+num_new_data]=data
223        self.__num_data_in_buffer+=num_new_data        self.__num_data_in_buffer+=num_new_data
224        self.__id_last_datum+=num_new_data        self.__id_last_datum+=num_new_data
225        self.__id_last_unused_datum+=num_new_data        self.__id_last_unreferenced_datum+=num_new_data
226        if self.debug(): print "Debug: %s: %d data appended. Last unused datum is now %d."%(self,num_new_data,self.__id_last_unused_datum)        if self.debug(): print "Debug: %s: %d data appended. Last unreferenced datum is now %d."%(self,num_new_data,self.__id_last_unreferenced_datum)
227    
228  # ======================================  # ======================================
229  class TimeSeries(TimeSeriesDataset):  class TimeSeriesControlerView(TimeSeriesBase):
230        """a TimeSeries glues a Controler controler and a TimeSeriesDataset dataset together. It also provides a TimeSeriesDataset view to the datset"""        """A TimeSeriesControlerView is attached to a Controler and moves forward in time by increasing the id of the last processed datum.
231        def __init__(self,dataset,debug=False,description="timeseries."):           Any implementation of a TimeSeriesControlerView must provide the getControler method which returns the controler"""
232             TimeSeriesDataset.__init__(self,dataset,0,debug,description)        def __init__(self,id_first_datum=0,debug=False,description="TimeSeries"):
233             self.__id_last_processed_datum=dataset.getIdOfFirstDatum()-1                  TimeSeriesBase.__init__(self,debug,description)
234                  self.__id_last_processed_datum=id_first_datum-1
235        def getDataset(self):          if self.debug(): print "Debug: %s  created with first datum %d"%(str(self),id_first_datum)
           """returns the TimeSeriesDataset of the time series"""  
           return self.getBuffer()  
   
       def getControler(self):  
           """returns the Controler of the time series (to be overwritten by subclass)"""  
           pass  
236    
237        def getIdOfLastProcessedDatum(self):        def getIdOfLastProcessedDatum(self):
238            return self.__id_last_processed_datum            return self.__id_last_processed_datum
# Line 235  class TimeSeries(TimeSeriesDataset): Line 240  class TimeSeries(TimeSeriesDataset):
240        def updateIdOfLastProcessedDatum(self,id_last_processed_datum):        def updateIdOfLastProcessedDatum(self,id_last_processed_datum):
241            self.__id_last_processed_datum=id_last_processed_datum            self.__id_last_processed_datum=id_last_processed_datum
242    
243          # def getControler(self):
244          #      """returns the Controler of the time series (to be overwritten by subclass)"""
245          #      pass
246    
247    class TimeSeries(TimeSeriesBaseDataset,TimeSeriesControlerView):
248          """makes TimeSeriesBaseDataset look like a TimeSeries and introduces operations
249             Any implementation of a TimeSeriesControlerView must provide the getControler method which returns the controler"""
250          def __init__(self,dataset,debug=False,description="TimeSeries"):
251            TimeSeriesControlerView.__init__(self,dataset.getIdOfFirstDatum(),debug,description)
252            TimeSeriesBaseDataset.__init__(self,dataset,0,debug,description)
253          
254          def getDataset(self):
255              """returns the TimeSeriesBaseDataset of the time series"""
256              return self.getBaseBuffer()
257    
258          # def getControler(self):
259          #      """returns the Controler of the time series (to be overwritten by subclass)"""
260          #      pass
261    
262        def __add__(self,arg):        def __add__(self,arg):
263           if isinstance(arg,TimeSeriesDataset):           if isinstance(arg,TimeSeriesBaseDataset):
264              return TimeSeriesSum(self,arg)              return TimeSeriesAdd(self,arg)
265           else:           else:
266              return TimeSeriesAddScalar(self,arg)              return TimeSeriesAddScalar(self,arg)
267    
# Line 245  class TimeSeries(TimeSeriesDataset): Line 269  class TimeSeries(TimeSeriesDataset):
269           return self+(-1.)*arg           return self+(-1.)*arg
270    
271        def __mul__(self,arg):        def __mul__(self,arg):
272           if isinstance(arg,TimeSeriesDataset):           if isinstance(arg,TimeSeriesBaseDataset):
273              return TimeSeriesMult(self,arg)              return TimeSeriesMult(self,arg)
274           else:           else:
275              return TimeSeriesMultScalar(self,arg)              return TimeSeriesMultScalar(self,arg)
276    
277        def __div__(self,arg):        def __div__(self,arg):
278           if isinstance(arg,TimeSeriesDataset):           if isinstance(arg,TimeSeriesBaseDataset):
279              return TimeSeriesDiv(self,arg)              return TimeSeriesDiv(self,arg)
280           else:           else:
281              return TimeSeriesMultScalar(self,1./arg)              return TimeSeriesMultScalar(self,1./arg)
282    
283        def __pow__(self,arg):        def __pow__(self,arg):
284           if isinstance(arg,TimeSeriesDataset):           if isinstance(arg,TimeSeriesBaseDataset):
285              return TimeSeriesPower(self,arg)              return TimeSeriesPower(self,arg)
286           else:           else:
287              return TimeSeriesPowerScalar(self,arg)              return TimeSeriesPowerScalar(self,arg)
# Line 272  class TimeSeries(TimeSeriesDataset): Line 296  class TimeSeries(TimeSeriesDataset):
296           return self.__mul__(arg)           return self.__mul__(arg)
297    
298        def __rdiv__(self,arg):        def __rdiv__(self,arg):
299           if isinstance(arg,TimeSeriesDataset):           if isinstance(arg,TimeSeriesBaseDataset):
300              return TimeSeriesDiv(arg,self)              return TimeSeriesDiv(arg,self)
301           else:           else:
302              return TimeSeriesDivScalar(self,arg)              return TimeSeriesDivScalar(self,arg)
303    
304        def __rpow__(self,arg):        def __rpow__(self,arg):
305           if isinstance(arg,TimeSeriesDataset):           if isinstance(arg,TimeSeriesBaseDataset):
306              return TimeSeriesPower(arg,self)              return TimeSeriesPower(arg,self)
307           else:           else:
308              return Exp(numarray.log(arg)*self)              return Exp(numarray.log(arg)*self)
# Line 295  class TimeSeries(TimeSeriesDataset): Line 319  class TimeSeries(TimeSeriesDataset):
319        def __pos__(self):        def __pos__(self):
320           return (1.0)*self           return (1.0)*self
321    
322  class TimeSeriesFilter(TimeSeries):  class TimeSeriesOperator(TimeSeriesControlerView):
323        """a TimeSeriesFilter is a TimeSeriesDataset attached to a Controler where the TimeSeriesDataset provides data        """a TimeSeriesOperator decribes an operation acting on list of TimeSeries time_series_args. It allows to update its output (if there is any)
324            at the time nodes defined by the Controler. Additional to a TimeSeries a TimeSeriesFilter allows to update           through the update method which is overwritten by a particular implementation of the class. The update method is called to process the data [start:end] using
325            the underlying TimeSeriesDataset through the update method which is overwritten by a particular implementation of the           [start-left_wing_size:end+right_wing_size] of its arguments"""
326            class. The update method is called to append the data [start:end] to the attached dataset by the the attached TimeSerieControler"""        def __init__(self,controler,time_series_args=[],left_wing_size=0,right_wing_size=0,debug=False,description="TimeSeriesOperator"):
327        def __init__(self,controler,dataset,args=[],left_wing_size=0,right_wing_size=0,debug=False,description="timeseries.Filter"):            id_first_datum=controler.getIdOfFirstDatum()
328            TimeSeries.__init__(self,dataset,debug,description)            for i in time_series_args: id_first_datum=max(id_first_datum,i.getIdOfFirstDatum())
329              TimeSeriesControlerView.__init__(self,id_first_datum+left_wing_size,debug,description)
330            self.__left_wing_size=left_wing_size            self.__left_wing_size=left_wing_size
331            self.__right_wing_size=right_wing_size            self.__right_wing_size=right_wing_size
332            self.__args=args            self.__time_series_args=time_series_args
333            self.__controler=controler            self.__controler=controler
334            controler.appendFilterToUpdateList(self)            controler.appendOperatorToUpdateList(self)
335              if self.debug(): print "Debug: %s: with left/right wing size %d/%d and %d arguments."%(str(self),left_wing_size,right_wing_size,len(time_series_args))
336    
337          def __del__(self):
338              self.getControler().removeOperatorFromUpdateList(self)
339    
340        def getControler(self):        def getControler(self):
341            """returns the Controler of the time series (overwrites method of by TimeSeries)"""            """returns the Controler updating the TimeSeriesOperator"""
342            return self.__controler            return self.__controler
343    
       def update(self,start,end):  
           """appends zeros to the dataset. This method should be overwritten by a particular TimeSeriesFilter"""  
           nc=self.getNumComponents()  
           if nc>1:  
              self.getDataset().append(numarray.zeros([nc,end-start]))  
           else:  
              self.getDataset().append(numarray.zeros(end-start))  
344        def getLeftWingSize(self):        def getLeftWingSize(self):
345            """returns the left wing size"""              """returns the left wing size"""  
346            return self.__left_wing_size            return self.__left_wing_size
# Line 330  class TimeSeriesFilter(TimeSeries): Line 352  class TimeSeriesFilter(TimeSeries):
352        def getArguments(self,index=None):        def getArguments(self,index=None):
353            """returns the list of arguments or, index is present, the argument with index index. In the latter case None is returned if no arguments are present"""            """returns the list of arguments or, index is present, the argument with index index. In the latter case None is returned if no arguments are present"""
354            if index==None:            if index==None:
355               return self.__args               return self.__time_series_args
356            else:            else:
357               if len(self.__args)>0:               if len(self.__time_series_args)>0:
358                  return self.__args[index]                  return self.__time_series_args[index]
359               else:               else:
360                  return None                  return None
361    
# Line 348  class TimeSeriesFilter(TimeSeries): Line 370  class TimeSeriesFilter(TimeSeries):
370        def flush(self):        def flush(self):
371            """calls the update method with all the maximum processable range. It also updates the id of unused datum for all arguments"""            """calls the update method with all the maximum processable range. It also updates the id of unused datum for all arguments"""
372            start=self.getIdOfLastProcessedDatum()+1            start=self.getIdOfLastProcessedDatum()+1
373            end=None            end=self.getControler().getIdOfLastDatum()
374            for i in self.getArguments():            for i in self.getArguments(): end=min(end,i.getIdOfLastDatum())
375               if end==None:            if start<=end-self.getRightWingSize():
376                  end=i.getIdOfLastDatum()               if self.debug(): print "Debug: %s: range [%d:%d] is updated."%(self,start,end-self.getRightWingSize())
377               else:               self.update(start,end-self.getRightWingSize()+1)      
378                  end=min(end,i.getIdOfLastDatum())               for i in self.getArguments(): i.updateIdOfLastUnreferencedDatum(end-self.getLeftWingSize())
379            if not end==None:               self.updateIdOfLastProcessedDatum(end)
380                if self.debug(): print "Debug: %s: range [%d:%d] is updated."%(self,start,end-self.getRightWingSize())  
381                self.update(start,end-self.getRightWingSize()+1)              def update(self,start,end):
382                for i in self.getArguments(): i.updateIdOfLastUnusedDatum(end-self.getLeftWingSize())            """updates the the data [start:end] using [start-left_wing_size:end+right_wing_size] of its arguments (is overwritten by a particular TimeSeriesOperator)"""
383                self.updateIdOfLastProcessedDatum(end)            pass
384    
385    
386    class TimeSeriesFilter(TimeSeries,TimeSeriesOperator):
387          """a TimeSeriesFilter is a TimeSeries taht is created trough a TimeSeriesOperator"""
388          def __init__(self,controler,dataset,time_series_args=[],left_wing_size=0,right_wing_size=0,debug=False,description="TimeSeriesFilter"):
389             TimeSeriesOperator.__init__(self,controler,time_series_args,left_wing_size,right_wing_size,debug,description)
390             TimeSeries.__init__(self,dataset,debug,description)
391    
392          def update(self,start,end):
393              """appends zeros to the dataset. This method should be overwritten by a particular TimeSeriesFilter"""
394              nc=self.getNumComponents()
395              if nc>1:
396                 self.getDataset().append(numarray.zeros([nc,end-start]))
397              else:
398                 self.getDataset().append(numarray.zeros(end-start))
399    
400  class Controler(TimeSeries):  class Controler(TimeSeries):
401     """controls a set of TimeSeries"""     """controls a set of TimeSeries"""
402     def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,debug=False,description="timeseries.Controler"):     def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,debug=False,description="TimeSeriesControler"):
403          TimeSeries.__init__(self,TimeSeriesBuffer(buffer_size,1,DEFAULT_FLOAT_TYPE,0,debug,"Time nodes buffer of "+description),\          TimeSeries.__init__(self,TimeSeriesBaseBuffer(buffer_size,1,DEFAULT_FLOAT_TYPE,0,debug,"node buffer of "+description),debug,"nodes of "+description)
                                                                                    debug,"Time nodes of "+description)  
404          self.setFlushRate()            self.setFlushRate()  
405          self.__update_time_series=list()          self.__update_time_series=list()
406                
# Line 389  class Controler(TimeSeries): Line 425  class Controler(TimeSeries):
425         if self.debug(): print "Debug: %s: start flushing"%self         if self.debug(): print "Debug: %s: start flushing"%self
426         for time_serie in self.__update_time_series: time_serie.flush()         for time_serie in self.__update_time_series: time_serie.flush()
427    
428     def appendFilterToUpdateList(self,time_serie):     def appendOperatorToUpdateList(self,time_serie):
429         if not time_serie.getControler()==self: raise ValueError,"%s: time series time_serie %s is not linked defined on %s."%(self,time_serie,self)         if not time_serie.getControler()==self: raise ValueError,"%s: TimeSeries %s is not defined on this controler."%(self,time_serie)
430         if not self.isEmpty(): raise ValueError,"%s: you can only check in a time series time_serie is controler is empty."%self         if not self.isEmpty(): raise ValueError,"%s: you can only check in a time series time_serie is controler is empty."%self
431         self.__update_time_series.append(time_serie)         self.__update_time_series.append(time_serie)
432         if self.debug(): print "Debug: %s: %s has been added to update list."%(self,time_serie)         if self.debug(): print "Debug: %s: %s has been added to update list."%(self,time_serie)
433    
434     def newTimeNode(self,value):     def removeOperatorFromUpdateList(self,time_serie):
435           self.__update_time_series.remove(time_serie)
436           if self.debug(): print "Debug: %s: %s has been removed from update list."%(self,time_serie)
437    
438       def nextTime(self,value):
439         if self.needsFlushing(): self.flush()         if self.needsFlushing(): self.flush()
440         self.getDataset().append(value)         self.getDataset().append(value)
441         if self.debug(): print "Debug: %s: new time node %e has been added."%(self,value)         if self.debug(): print "Debug: %s: new time node %e has been added."%(self,value)
442    
 # ============================================  
443  class TimeSeriesShift(TimeSeries):  class TimeSeriesShift(TimeSeries):
444        """creates a shift of the time series, i.e. if d[n] is the datum at time t[n], the value at t[n] becomes v[n+shift] on the output"""        """creates a shift of the time series, i.e. if d[n] is the datum at time t[n], the value at t[n] becomes v[n+shift] on the output"""
445        def __init__(self,time_serie,shift=1):        def __init__(self,time_serie,shift=1):
# Line 409  class TimeSeriesShift(TimeSeries): Line 448  class TimeSeriesShift(TimeSeries):
448            else:            else:
449                dsc="(%s)>>%d"%(time_serie,shift)                dsc="(%s)>>%d"%(time_serie,shift)
450            self.__controler=time_serie.getControler()            self.__controler=time_serie.getControler()
451            TimeSeries.__init__(self,TimeSeriesDataset(time_serie.getDataset(),-shift,time_serie.debug(),"buffer view to "+dsc),\            TimeSeries.__init__(self,TimeSeriesBaseDataset(time_serie.getDataset(),-shift,time_serie.debug(),"buffer view to "+dsc),time_serie.debug(),dsc)
452                                            time_serie.debug(),dsc)  
453        def getControler(self):        def getControler(self):
454            return self.__controler            return self.__controler
455    
456  class TimeSeriesSum(TimeSeriesFilter):  class TimeSeriesAdd(TimeSeriesFilter):
457        """adds two TimeSeries"""        """adds two TimeSeries"""
458        def __init__(self,time_serie_1,time_serie_2):        def __init__(self,time_serie_1,time_serie_2):
459            dsc="(%s)+(%s)"%(time_serie_1,time_serie_2)            dsc="(%s)+(%s)"%(time_serie_1,time_serie_2)
460            dbg=time_serie_1.debug() or time_serie_2.debug()            dbg=time_serie_1.debug() or time_serie_2.debug()
461            cntrl=time_serie_1.getControler()            cntrl=time_serie_1.getControler()
462            if not cntrl==time_serie_2.getControler():            if not cntrl==time_serie_2.getControler():
463                    raise ValueError("TimeSeriesSum: %s and %s have different controler."%(time_serie_1,time_serie_2))                    raise ValueError("TimeSeriesAdd: %s and %s have different controler."%(time_serie_1,time_serie_2))
464            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
465            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
466                                TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                                TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
467                                [time_serie_1,time_serie_2],0,0,dbg,dsc)                                [time_serie_1,time_serie_2],0,0,dbg,dsc)
468    
469        def update(self,start,end):        def update(self,start,end):
# Line 438  class TimeSeriesAddScalar(TimeSeriesFilt Line 477  class TimeSeriesAddScalar(TimeSeriesFilt
477            cntrl=time_serie.getControler()            cntrl=time_serie.getControler()
478            id_first_datum=time_serie.getIdOfFirstDatum()            id_first_datum=time_serie.getIdOfFirstDatum()
479            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
480                         TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                         TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
481                         [time_serie],0,0,dbg,dsc)                         [time_serie],0,0,dbg,dsc)
482            self.__scalar=scalar            self.__scalar=scalar
483    
# Line 455  class TimeSeriesMult(TimeSeriesFilter): Line 494  class TimeSeriesMult(TimeSeriesFilter):
494                    raise ValueError("TimeSeriesMult: %s and %s have different controler."%(time_serie_1,time_serie_2))                    raise ValueError("TimeSeriesMult: %s and %s have different controler."%(time_serie_1,time_serie_2))
495            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
496            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
497                     TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                     TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
498                     [time_serie_1,time_serie_2],0,0,dbg,dsc)                     [time_serie_1,time_serie_2],0,0,dbg,dsc)
499    
500        def update(self,start,end):        def update(self,start,end):
# Line 469  class TimeSeriesMultScalar(TimeSeriesFil Line 508  class TimeSeriesMultScalar(TimeSeriesFil
508            cntrl=time_serie.getControler()            cntrl=time_serie.getControler()
509            id_first_datum=time_serie.getIdOfFirstDatum()            id_first_datum=time_serie.getIdOfFirstDatum()
510            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
511                         TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                         TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
512                         [time_serie],0,0,dbg,dsc)                         [time_serie],0,0,dbg,dsc)
513            self.__scalar=scalar            self.__scalar=scalar
514    
# Line 486  class TimeSeriesDiv(TimeSeriesFilter): Line 525  class TimeSeriesDiv(TimeSeriesFilter):
525                    raise ValueError("TimeSeriesDiv: %s and %s have different controler."%(time_serie_1,time_serie_2))                    raise ValueError("TimeSeriesDiv: %s and %s have different controler."%(time_serie_1,time_serie_2))
526            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
527            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
528                       TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                       TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
529                       [time_serie_1,time_serie_2],0,0,dbg,dsc)                       [time_serie_1,time_serie_2],0,0,dbg,dsc)
530    
531        def update(self,start,end):        def update(self,start,end):
# Line 500  class TimeSeriesDivScalar(TimeSeriesFilt Line 539  class TimeSeriesDivScalar(TimeSeriesFilt
539            cntrl=time_serie.getControler()            cntrl=time_serie.getControler()
540            id_first_datum=time_serie.getIdOfFirstDatum()            id_first_datum=time_serie.getIdOfFirstDatum()
541            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
542                         TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                         TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
543                         [time_serie],0,0,dbg,dsc)                         [time_serie],0,0,dbg,dsc)
544            self.__scalar=scalar            self.__scalar=scalar
545    
# Line 517  class TimeSeriesPower(TimeSeriesFilter): Line 556  class TimeSeriesPower(TimeSeriesFilter):
556                    raise ValueError("TimeSeriesPower: %s and %s have different controler."%(time_serie_1,time_serie_2))                    raise ValueError("TimeSeriesPower: %s and %s have different controler."%(time_serie_1,time_serie_2))
557            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())            id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
558            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
559                  TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                  TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
560                  [time_serie_1,time_serie_2],0,0,dbg,dsc)                  [time_serie_1,time_serie_2],0,0,dbg,dsc)
561    
562        def update(self,start,end):        def update(self,start,end):
# Line 531  class TimeSeriesPowerScalar(TimeSeriesFi Line 570  class TimeSeriesPowerScalar(TimeSeriesFi
570            cntrl=time_serie.getControler()            cntrl=time_serie.getControler()
571            id_first_datum=time_serie.getIdOfFirstDatum()            id_first_datum=time_serie.getIdOfFirstDatum()
572            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
573                         TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                         TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
574                         [time_serie],0,0,dbg,dsc)                         [time_serie],0,0,dbg,dsc)
575            self.__scalar=scalar            self.__scalar=scalar
576    
# Line 546  class Exp(TimeSeriesFilter): Line 585  class Exp(TimeSeriesFilter):
585            cntrl=time_serie.getControler()            cntrl=time_serie.getControler()
586            id_first_datum=time_serie.getIdOfFirstDatum()            id_first_datum=time_serie.getIdOfFirstDatum()
587            TimeSeriesFilter.__init__(self,cntrl, \            TimeSeriesFilter.__init__(self,cntrl, \
588                       TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \                       TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
589                       [time_serie],0,0,dbg,dsc)                       [time_serie],0,0,dbg,dsc)
590    
591        def update(self,start,end):        def update(self,start,end):
592            self.append(numarray.exp(self.getArgumentDataset(0)[start:end]))            self.append(numarray.exp(self.getArgumentDataset(0)[start:end]))
593    
594    class Writer(TimeSeriesOperator):
595          """writes the time series into an output strim ostream which mast have the writeline method. The values are seperated by the string seperator."""
596          def __init__(self,time_serie,ostream,seperator=",",commend_tag="#"):
597             dsc="write %s to %s"%(time_serie,ostream)
598             dbg=time_serie.debug()
599             cntrl=time_serie.getControler()
600             self.__ostream=ostream
601             self.__seperator=seperator
602             TimeSeriesOperator.__init__(self,cntrl,[time_serie],0,0,dbg,dsc)
603             ostream.writelines("%s time series %s\n"%(commend_tag,str(self)))
604    
605          def update(self,start,end):
606             cntrl=self.getControler()
607             arg=self.getArguments(0)
608             n=arg.getNumComponents()
609             if n<2:
610                for i in range(start,end): self.__ostream.writelines("%s%s%s\n"%(cntrl[i],self.__seperator,arg[i]))
611             else:
612                for i in range(start,end):
613                   l="%s"%cntrl[i]
614                   for j in range(n): l=l+"%s%s"(self.__seperator,arg[i][j])
615                   self.__ostream.writelines("%s\n"%l)
616    
617    class DataCatcher(TimeSeries):
618          """collects data into a time series."""
619          def __init__(self,controler,numComponents=1,description="DataCatcher"):
620             self.__controler=controler
621             dbg=controler.debug()
622             TimeSeries.__init__(self,TimeSeriesBaseBuffer(controler.getBaseBufferSize(),numComponents,DEFAULT_FLOAT_TYPE,controler.getIdOfFirstDatum(),dbg,"buffer for "+description),dbg,description)
623    
624          def getControler(self):
625              return self.__controler
626    
627          def nextValue(self,value):
628              """append a value to the time series"""
629              id_last=self.getIdOfLastDatum()
630              id_current=self.getControler().getIdOfLastDatum()
631              if id_last+1==id_current:
632                 self.getDataset().append(value)
633              elif id_last+1<id_current:
634                   if self.isEmpty():
635                       self.getDataset().append(value)
636                       id_last+=1
637                   t_last=self.getControler()[id_last]
638                   t_current=self.getControler()[id_current]
639                   value_last=self[id_last]
640                   out=(value_last-value)/(t_last-t_current)*(self.getControler()[id_last+1:id_current+1]-t_current)+value
641                   self.getDataset().append(out)
642              else :
643                 raise ValueError,"%s: a new time node must be introduced before a new value can be added."
644              self.updateIdOfLastUnreferencedDatum(id_last)
645              
646      
647  class TimeSeriesCumulativeSum(TimeSeriesFilter):  class TimeSeriesCumulativeSum(TimeSeriesFilter):
648        """creates a shift of the time series, i.e. if d[n] is the datum at time t[n], the value at t[n] becomes v[n+shift] on the output"""        """cummulative sum of the time series values"""
649        def __init__(self,time_series):        def __init__(self,time_serie):
650           TimeSeriesFilter.__init__(self,1)           dsc="cumsum(%s)"%(time_serie)
651           TimeSeries.__init__(self,frame_size=time_series.getDatasetSize(),buffer_size=time_series.getBufferSize(), \           dbg=time_serie.debug()
652                                                                           numComponents=time_series.getNumComponents())           cntrl=time_serie.getControler()
653           self.setDebug(time_series.debug())           id_first_datum=time_serie.getIdOfFirstDatum()
654           time_series.checkInUpdate(self)           TimeSeriesFilter.__init__(self,cntrl, \
655           self.__integral=0                       TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
656                         [time_serie],0,0,dbg,dsc)
657        def __str__(self):           self.__last_value=0
658           return "timeseries.Integrator"  
659          def update(self,start,end):
660        def update(self,times,data):            out=numarray.cumsum(self.getArgumentDataset(0)[start:end])+self.__last_value
661            l=times.shape[0]            self.__last_value=out[end-start-1]
662            self.append(times[1:l],(data[0:l-1]+data[1:l])/2.*(times[1:l]-times[0:l-1]))            self.append(out)
663                    
664    
665  class TimeSeriesCollector(TimeSeries):  class Reader(TimeSeriesBase):
666        """timeseries.Collector collects data at time nodes"""        """reads a list of input streams and creates a time series for each input stream but on the same Controler where the first column
667        def __init__(self):           is used to create the time nodes"""
668           TimeSeries.__init__(self)        def __init__(self,list_of_istreams,buffer_size=DEFAULT_BUFFER_SIZE,seperator=",",commend_tag="#",debug=False):
669             TimeSeriesBase.__init__(self,debug=debug,description="reader")
670        def __str__(self):           if not isinstance(list_of_istreams,list):
671           return "timeseries.Collector"                self.__list_of_istreams=[list_of_istreams]
672             else:
673        def add(self,time_mark,value):                self.__list_of_istreams=list_of_istreams
674             """adds the value at time time_mark to the time series"""           self.__cntrl=Controler(buffer_size,debug,"reader controler")
675             self.append(numarray.array([time_mark]),numarray.array([value]))           self.__seperator=seperator
676             self.__commend_tag=commend_tag
677        def read(self,istream,seperator=","):           self.__time_series={}
678          """reads pairs from iostream istream"""           self.__t={}
679          for l in istream:           self.__v={}
680             d=l.strip().split(seperator)           # set up the time series:
681             self.add(float(d[0]),float(d[1]))           for i in self.__list_of_istreams:
682               line=self.__commend_tag
683               while  not line=="" and line[0]==self.__commend_tag:
684                   line=i.readline().strip()
685               if line=="":
686                  list_of_istreams.remove(i)
687               else:
688                  d=line.split(self.__seperator)
689                  self.__t[i]=float(d[0])
690                  tmp=[]
691                  for j in d[1:]: tmp.append(float(j))
692                  self.__v[i]=numarray.array(tmp)
693                  self.__time_series[i]=DataCatcher(self.__cntrl,len(d)-1,str(i))
694    
695             #
696          def run(self):
697             while len(self.__list_of_istreams)>0:
698                if len(self.__time_series)>0:
699                   # find list all times with minumum time node:
700                   tminargs=[]
701                   for i in self.__time_series:
702                       if len(tminargs)==0:
703                           tminargs.append(i)
704                       elif abs(t[tminargs[0]]-self.__t[i])<1.e-8*abs(self.__t[i]):
705                           tminargs.append(i)
706                       elif self.__t[i]<t[tminargs[0]]:
707                           tminargs=[i]
708                   # find list all times with minumum time node:
709                   self.__cntrl.nextTime(self.__t[tminargs[0]])
710                   for i in tminargs:
711                       self.__time_series[i].nextValue(self.__v[i])
712                       # find next line without leading "#"
713                       line="#"
714                       while not line=="" and line[0]==self.__commend_tag:
715                           line=i.readline().strip()
716                       # if eof reached iostream is removed for searching
717                       if line=="":
718                          self.__list_of_istreams.remove(i)
719                       else:
720                          d=line.split(self.__seperator)
721                          self.__t[i]=float(d[0])
722                          tmp=[]
723                          for j in d[1:]: tmp.append(float(j))
724                          self.__v[i]=numarray.array(tmp)
725    
726          def getControler(self):
727             """returns the controler shared by all time series created through the input streams"""
728             return self.__cntrl
729    
730          def getTimeSeries(self,istream=None):
731             """returns the time series as a tuple. If istream is present its time series is returned"""
732             if istream==None:
733                out=self.__time_series.values()
734                if len(out)>1:
735                   return tuple(out)
736                elif len(out)>0:
737                   return out[0]
738                else:
739                   return None
740             else:
741                return self.__time_series[istream]
742    
743  def Differential(time_series):  
744    class Plotter(TimeSeriesOperator):
745        def __init__(self,time_series,window_size=DEFAULT_BUFFER_SIZE/4,file_name=None,format=None):
746             if isinstance(time_series,list):
747                 dbg=time_series[0].getControler().debug()
748                 text=""
749                 for i in time_series:
750                   if len(text)==0:
751                      text=str(i)
752                   else:
753                      text=text+","+str(i)
754                 TimeSeriesOperator.__init__(self,time_series[0].getControler(),time_series,window_size,0,dbg,"plot(%s)"%text)
755             else:
756                 dbg=time_series.getControler().debug()
757                 text=str(time_series)
758                 TimeSeriesOperator.__init__(self,time_series.getControler(),[time_series],window_size,0,dbg,"plot(%s)"%text)
759             from pyvisi.renderers.gnuplot import LinePlot,Scene,PsImage
760             self.__renderer=Scene()
761             self.__line_plot=LinePlot(self.__renderer)
762             self.__line_plot.setTitle(text)
763             self.__line_plot.setLineStyle("lines")
764             self.__line_plot.setXLabel("time")
765             self.__line_plot.setYLabel("values")
766             self.__file_name=file_name
767             if format==None:
768                 self.__format=PsImage()
769             else:
770                 self.__format=format
771             self.__window_size=window_size
772    
773        def update(self,start,end):
774             s=max(end-self.__window_size,self.getControler().getIdOfFirstAvailableDatum())
775             args=[self.getControler()[s:end]]
776             for arg in self.getArguments(): args.append(arg[s:end])
777             self.__line_plot.setData(*args)
778             self.__line_plot.render()
779             if self.__file_name==None:
780                 raise SystemError,"Online viewing is not avilabel yet!"
781             else:
782                 self.__renderer.save(fname=self.__file_name, format=self.__format)
783                
784    
785    def viewer(time_serie,seperator=","):
786          """creates a viewer for a time series"""
787          import sys
788          return Writer(time_serie,sys.stdout,seperator)
789    
790    def differential(time_serie):
791        """calculates the derivative Dv of the time series v:        """calculates the derivative Dv of the time series v:
792                    
793              Dv[n]=(v[n]-v[n-1])/(t[n]-t[n-1])              Dv[n]=(v[n]-v[n-1])/(t[n]-t[n-1])
794    
795        """        """
796        return (time_series<<1-time_series)/(time_series.getControler()<<1-time_series.getControler())        out=(((time_serie<<1)-time_serie)/((time_serie.getControler()<<1)-time_serie.getControler())+ \
797               ((time_serie>>1)-time_serie)/((time_serie.getControler()>>1)-time_serie.getControler()))/2.
798          out.setDescription("d(%s)/dt"%str(time_serie))
799          out.setDebug(time_serie.debug())
800          return out
801    
802  def Integral(time_series):  def integral(time_serie):
803        """calculates the intagral Iv of the time series v using the trapozidal rule:        """calculates the intagral Iv of the time series v using the trapozidal rule:
804                    
805              Iv[n]=sum_i<n (v[n]+v[n-1])/2*(t[n]-t[n-1])              Iv[n]=int_{t_0}^{t_n} v ~ sum_{0<i<=n} n (v[i]+v[i-1])/2*(t[i]-t[i-1])
806    
807        """        """
808        return TimeSeriesCumulativeSum((time_series<<1+time_series)/2.*(time_series.getControler()-(time_series.getControler<<1)),0.)        out=TimeSeriesCumulativeSum(((time_serie>>1)+time_serie)/2.*(time_serie.getControler()-(time_serie.getControler()>>1)))
809          out.setDescription("I (%s) dt"%str(time_serie))
810          out.setDebug(time_serie.debug())
811  class TimeSeriesViewer(TimeSeriesFilter):        return out
812        def __init__(self,time_series):  
813           TimeSeriesFilter.__init__(self,0)  def smooth(time_serie,range=5):
814           time_series.checkInUpdate(self)       """smoothes a time series using the at each time the previous and next range values"""
815         i=integral(time_serie)
816        def __str__(self):       out=((i>>range)-(i<<range))/((time_serie.getControler()>>range)-(time_serie.getControler()<<range))
817           return "timeseries.Viewer"       out.setDescription("smooth(%s,-%d:%d) dt"%(str(time_serie),range,range))
818         out.setDebug(time_serie.debug())
819        def update(self,times,data):       return out
820            for i in range(times.shape[0]): print "[%s: %s]"%(times[i],data[i])  
821    def leakySmooth(time_serie,l=0.99):
822  class TimeSeriesWriter(TimeSeriesFilter):       """leaky smoother: s(t)=int_{t_0}^{t} v(r) l^{t-r} dr/ int_{t_0}^{t} l^{t-r} dr """
823        def __init__(self,time_series,ostream,seperator=","):       w=l**(-time_serie.getControler())
824           TimeSeriesFilter.__init__(self,0)       out=integrate(time_serie*w)/integrate(w)
825           time_series.checkInUpdate(self)       out.setDescription("leaky smoother(%s)"%str(time_serie))
826           self.setDebug(time_series.debug())       return out
          self.__ostream=ostream  
          self.__seperator=seperator  
   
       def __str__(self):  
          return "timeseries.Writer"  
   
       def update(self,times,data):  
         for i in range(times.shape[0]): self.__ostream.writelines("%s,%s\n"%(times[i],data[i]))  
827    
828  # test  # test
829    
# Line 636  if __name__=="__main__": Line 831  if __name__=="__main__":
831     # tests the interfaces to data sets:     # tests the interfaces to data sets:
832     print "Test of Datasets:"     print "Test of Datasets:"
833     print "================="     print "================="
834     bf=TimeSeriesBuffer(buffer_size=5,numComponents=1,debug=True,description="TestBuffer")     bf=TimeSeriesBaseBuffer(buffer_size=5,numComponents=1,debug=True,description="TestBaseBuffer")
835     bfv_l=TimeSeriesDataset(bf,offset=1,debug=True,description="offset 1")     bfv_l=TimeSeriesBaseDataset(bf,offset=1,debug=True,description="offset 1")
836     bfv_r=TimeSeriesDataset(bf,offset=-1,debug=True,description="offset -1")     bfv_r=TimeSeriesBaseDataset(bf,offset=-1,debug=True,description="offset -1")
837     bf.append([1.,2.,3.,4.])     bf.append([1.,2.,3.,4.])
838     print "should be all 2. :",bfv_l[0]     print "should be all 2. :",bfv_l[0]
839     print bf[1]     print bf[1]
# Line 655  if __name__=="__main__": Line 850  if __name__=="__main__":
850     s3=b>>3     s3=b>>3
851     s1=b>>1     s1=b>>1
852     s_3=b<<3     s_3=b<<3
853       print s_3
854       print b
855       print b+s3
856     sum=(s_3+b)+(b+s3)     sum=(s_3+b)+(b+s3)
857        
858     for i in range(30):     for i in range(30):
859         b.newTimeNode(i*1.)         b.nextTime(i*1.)
860     b.flush()     b.flush()
861     print "should be all 28. :",s_3.getDataset()[25],b.getDataset()[28],s3.getDataset()[31]     print "should be all 28. :",s_3.getDataset()[25],b.getDataset()[28],s3.getDataset()[31]
862     print "should be all 29. :",s_3.getDataset()[26],b.getDataset()[29],s3.getDataset()[32]     print "should be all 29. :",s_3.getDataset()[26],b.getDataset()[29],s3.getDataset()[32]
# Line 667  if __name__=="__main__": Line 865  if __name__=="__main__":
865     print "Test of operators"     print "Test of operators"
866     print "================="     print "================="
867     b=Controler(buffer_size=15,debug=True)     b=Controler(buffer_size=15,debug=True)
868       b.setFlushRate(2)
869       q=DataCatcher(b)
870     b1=b<<1     b1=b<<1
871     a=b+b1     a=b+b1
872     a_s=b1+1.     a_s=b1+1.
# Line 685  if __name__=="__main__": Line 885  if __name__=="__main__":
885     s_p=2.**b1     s_p=2.**b1
886     pb=+b     pb=+b
887     mb=-b     mb=-b
888       sum=TimeSeriesCumulativeSum(b)
889       diff=differential(b)
890       smt=smooth(b,2)
891       int=integral(b*2)
892       fl=file("/tmp/test.csv","w")
893       w=Writer(q,fl)
894       v=viewer(q)
895       plo=Plotter([a,a_s],window_size=4,file_name="s.ps")
896     for i in range(30):     for i in range(30):
897         b.newTimeNode(i*1.)         b.nextTime(i*1.)
898           if i%2==1: q.nextValue(i*28.)
899     b.flush()     b.flush()
900     print "a[28] should be %e: %e"%(28.+29.,a[28])     print "a[28] should be %e: %e"%(28.+29.,a[28])
901     print "a_s[28] should be %e: %e"%(29.+1.,a_s[28])     print "a_s[28] should be %e: %e"%(29.+1.,a_s[28])
# Line 705  if __name__=="__main__": Line 914  if __name__=="__main__":
914     print "s_p[28] should be %e: %e"%(2.**29.,s_p[28])     print "s_p[28] should be %e: %e"%(2.**29.,s_p[28])
915     print "pb[28] should be %e: %e"%(28.,pb[28])     print "pb[28] should be %e: %e"%(28.,pb[28])
916     print "mb[28] should be %e: %e"%(-28.,mb[28])     print "mb[28] should be %e: %e"%(-28.,mb[28])
917       print "sum[28] should be %e: %e"%(28*29./2,sum[28])
918     1/0     print "diff[28] should be %e: %e"%(1.,diff[28])
919     c=TimeSeriesCollector(b)     print "smt[27] should be %e: %e"%(27.,smt[27])
920     c.setDebugOn()     print "int[28] should be %e: %e"%(28.**2,int[28])
921     ii=TimeSeriesIntegrator(c)     print "q[27] should be %e: %e"%(27*28.,q[27])
922     d=TimeSeriesDifferential(c)     print "q[28] should be %e: %e"%(28*28.,q[28])
923     v=TimeSeriesViewer(ii)     print "q[29] should be %e: %e"%(29*28.,q[29])
924     w=TimeSeriesWriter(d,file("test.csv","w"))     fl.flush()
   
    for i in range(15):  
       b.newTime(i*1.)  
       c.add(i+1.)  
925        
926       rin=Reader(file("/tmp/test.csv","r+"),buffer_size=15,debug=True)
927       rin.run()
928       inp=rin.getTimeSeries()
929       print "inp[27] should be %e: %e"%(27*28.,inp[27])
930       print "inp[28] should be %e: %e"%(28*28.,inp[28])
931       print "inp[29] should be %e: %e"%(29*28.,inp[29])
932    

Legend:
Removed from v.117  
changed lines
  Added in v.119

  ViewVC Help
Powered by ViewVC 1.1.26