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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1388 - (hide annotations)
Fri Jan 11 07:45:58 2008 UTC (11 years, 11 months ago) by trankine
File MIME type: text/x-python
File size: 43080 byte(s)
And get the *(&(*&(* name right
1 ksteube 1312 #
2 jgs 110 # $Id$
3 ksteube 1312 #
4     #######################################################
5     #
6     # Copyright 2003-2007 by ACceSS MNRF
7     # Copyright 2007 by University of Queensland
8     #
9     # http://esscc.uq.edu.au
10     # Primary Business: Queensland, Australia
11     # Licensed under the Open Software License version 3.0
12     # http://www.opensource.org/licenses/osl-3.0.php
13     #
14     #######################################################
15     #
16 jgs 110
17 gross 637 """
18     Time serieas analysis
19    
20     @var __author__: name of author
21     @var __copyright__: copyrights
22     @var __license__: licence agreement
23     @var __url__: url entry point on documentation
24     @var __version__: version
25     @var __date__: date of the version
26     """
27    
28    
29     __author__="Lutz Gross, l.gross@uq.edu.au"
30 elspeth 609 __copyright__=""" Copyright (c) 2006 by ACcESS MNRF
31     http://www.access.edu.au
32     Primary Business: Queensland, Australia"""
33 elspeth 614 __license__="""Licensed under the Open Software License version 3.0
34     http://www.opensource.org/licenses/osl-3.0.php"""
35 gross 637 __url__="http://www.iservo.edu.au/esys/escript"
36     __version__="$Revision$"
37     __date__="$Date$"
38 elspeth 609
39 gross 637
40 jgs 110 import numarray
41 jgs 117 from types import SliceType
42 jgs 119 DEFAULT_BUFFER_SIZE=1000
43 jgs 117 DEFAULT_FLOAT_TYPE=numarray.Float64
44 jgs 110
45     class TimeSeriesBase:
46 jgs 117 """The TimeSeriesBase class is the base class for all class of the TimeSeries module."""
47 jgs 110
48 jgs 119 def __init__(self,debug=False,description="TimeSeriesBase"):
49 jgs 117 self.__debug=debug
50 jgs 119 self.setDescription(description)
51 jgs 110
52     def __str__(self):
53 jgs 117 return self.__description
54 jgs 119
55     def setDescription(self,text):
56     self.__description=text
57 jgs 110
58     def setDebugOn(self):
59     """switch on degugging mode"""
60     self.__debug=True
61    
62     def setDebugOff(self):
63     """switch off degugging mode"""
64     self.__debug=False
65    
66     def setDebug(self,flag=False):
67     """sets debug mode to flag"""
68     if flag:
69     self.setDebugOn()
70     else:
71     self.setDebugOff()
72    
73     def debug(self):
74     """returns true if debug mode is on"""
75     return self.__debug
76    
77 jgs 117 #============================================================================================================
78 jgs 119 class TimeSeriesBaseDataset(TimeSeriesBase):
79 jgs 117 """provides an interface for accessing a set of linearly ordered data."""
80 jgs 119 def __init__(self,buffer,offset=0,debug=False,description="TimeSeriesDataset"):
81 jgs 117 TimeSeriesBase.__init__(self,debug,description)
82     self.__buffer=buffer
83     self.__offset=offset
84     if self.debug(): print "Debug: %s: offset %d to buffer"%(self,self.getOffset())
85 jgs 110
86 jgs 117 def __len__(self):
87     """needed to handle negative indexing in slicing"""
88     return 0
89 jgs 110
90 jgs 117 def getNumComponents(self):
91     """returns the number of components of the data (may be overwritten by subclass)"""
92 jgs 119 return self.getBaseBuffer().getNumComponents()
93 jgs 110
94 jgs 117 def getIdOfLastDatum(self):
95     """returns the identification number of the last datum in the data set (may be overwritten by subclass)"""
96 jgs 119 return self.getBaseBuffer().getIdOfLastDatum()-self.getOffset()
97 jgs 110
98 jgs 117 def getIdOfFirstDatum(self):
99     """returns the identification number of the first datum (may be overwritten by subclass)"""
100 jgs 119 return self.getBaseBuffer().getIdOfFirstDatum()-self.getOffset()
101 jgs 110
102 jgs 119 def getIdOfFirstAvailableDatum(self):
103     """returns the identification number of the first avaiable datum (may be overwritten by subclass)"""
104     return self.getBaseBuffer().getIdOfFirstAvailableDatum()-self.getOffset()
105    
106     def getOffsetInBaseBuffer(self):
107     """returns the offset to access elements in getBaseBuffer() (may be overwritten by subclass)"""
108 jgs 117 return self.getOffset()
109    
110 jgs 119 def getIdOfLastUnreferencedDatum(self):
111     """returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesBaseDataset (may be overwritten by subclass)"""
112     return self.getBaseBuffer().getIdOfLastUnreferencedDatum()-self.getOffset()
113 jgs 117
114 jgs 119 def updateIdOfLastUnreferencedDatum(self,last_unreferenced_datum):
115 jgs 117 """updates the identification number of the last unused datum (to be overwritten by subclass)"""
116 jgs 119 self.getBaseBuffer().updateIdOfLastUnreferencedDatum(last_unreferenced_datum+self.getOffset())
117 jgs 117
118     def append(self,values):
119     """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)"""
120 jgs 119 self.getBaseBuffer().append(values)
121 jgs 117
122 jgs 119 def getBaseBufferSize(self):
123 jgs 117 """returns the size of the buffer (to be overwritten by subclass)"""
124 jgs 119 return self.getBaseBuffer().getBaseBufferSize()
125 jgs 117
126     def needsRearrangement(self,num_new_data=0):
127     """returns True if the buffer will be full after num_new_data have been appended (to be overwritten by subclass)"""
128 jgs 119 return self.getBaseBuffer().needsRearrangement(num_new_data)
129 jgs 117
130     def isEmpty(self):
131     """returns true if no data are appeneded to buffer"""
132     return self.getNumData()<=0
133    
134     def getNumData(self):
135     """returns the number of data (not all of them are accessible)"""
136     return self.getIdOfLastDatum()-self.getIdOfFirstDatum()+1
137    
138 jgs 119 def getBaseBuffer(self):
139     """return the buffer referenced by the TimeSeriesBaseDataset"""
140 jgs 117 return self.__buffer
141    
142     def getOffset(self):
143     """return the offset when referring to dataset elements"""
144     return self.__offset
145    
146     def __getitem__(self,index):
147     """returns the datum index"""
148     if type(index)==SliceType:
149     start=index.start
150     end=index.stop
151     if start==end:
152     return self[start]
153     else:
154     if start<self.getIdOfFirstDatum() or start>self.getIdOfLastDatum() or \
155     end-1<self.getIdOfFirstDatum() or end-1>self.getIdOfLastDatum(): raise IndexError,"%s: Index [%d:%d] out of range"%(self,start,end)
156 jgs 119 return self.getBaseBuffer()[start+self.getOffsetInBaseBuffer():end+self.getOffsetInBaseBuffer()]
157 jgs 117 else:
158     if index<self.getIdOfFirstDatum() or index>self.getIdOfLastDatum(): raise IndexError,"%s: Index %d out of range"%(self,index)
159 jgs 119 return self.getBaseBuffer()[index+self.getOffsetInBaseBuffer()]
160 jgs 117
161 jgs 119 class TimeSeriesBaseBuffer(TimeSeriesBaseDataset):
162     """An inplementation of TimeSeriesBaseDataset which actually is storing data into a numarray buffer"""
163     def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,numComponents=1,type=DEFAULT_FLOAT_TYPE,id_of_first_datum=0,debug=False,description="TimeSeriesBaseBuffer"):
164 jgs 110 if numComponents<2:
165 jgs 117 buffer=numarray.zeros((buffer_size,),type)
166 jgs 110 else:
167 jgs 117 buffer=numarray.zeros((buffer_size,numComponents),type)
168 jgs 119 TimeSeriesBaseDataset.__init__(self,buffer,id_of_first_datum-1,debug,description)
169 jgs 117 self.__num_data_in_buffer=0
170 jgs 119 self.__id_last_unreferenced_datum=id_of_first_datum-1
171 jgs 117 self.__id_last_datum=id_of_first_datum-1
172     self.__id_first_datum=id_of_first_datum
173     if self.debug(): print "Debug: %s : buffer of size %d with %d components allocated (first datum is %d)."% \
174 jgs 119 (self,self.getBaseBufferSize(),self.getNumComponents(),id_of_first_datum)
175 jgs 110
176    
177 jgs 119 def getBaseBufferSize(self):
178 jgs 117 """returns the size of the buffer"""
179 jgs 119 return self.getBaseBuffer().shape[0]
180 jgs 117
181 jgs 110 def getNumComponents(self):
182 jgs 119 """returns the number of components of the data (overwrites TimeSeriesBaseDataset method)"""
183     if self.getBaseBuffer().rank==1:
184 jgs 110 return 1
185     else:
186 jgs 119 self.getBaseBuffer().shape[1]
187 jgs 110
188 jgs 119 def getNumDataInBaseBuffer(self):
189 jgs 117 """returns the number of data currently in the buffer"""
190     return self.__num_data_in_buffer
191 jgs 110
192 jgs 117 def getIdOfLastDatum(self):
193 jgs 119 """returns the identification number of the last datum in the data set (overwrites method from TimeSeriesBaseDataset)"""
194 jgs 117 return self.__id_last_datum
195 jgs 110
196 jgs 117 def getIdOfFirstDatum(self):
197 jgs 119 """returns the identification number of the first datum (overwrites method from TimeSeriesBaseDataset)"""
198 jgs 117 return self.__id_first_datum
199 jgs 110
200 jgs 119 def getOffsetInBaseBuffer(self):
201     """returns the offset to access elements in the buffer (overwrites method from TimeSeriesBaseDataset)"""
202     return -self.getIdOfLastDatum()+self.getNumDataInBaseBuffer()-1
203 jgs 110
204 jgs 119 def getIdOfLastUnreferencedDatum(self):
205     """returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesBaseDataset (overwrites method from TimeSeriesBaseDataset)"""
206     return self.__id_last_unreferenced_datum
207 jgs 110
208 jgs 119 def updateIdOfLastUnreferencedDatum(self,last_unreferenced_datum):
209 jgs 117 """updates the identification number of the last unused datum (to be overwritten by subclass)"""
210 jgs 119 self.getBaseBuffer().updateIdOfLastUnreferencedDatum(last_unreferenced_datum-self.getOffset())
211 jgs 110
212 jgs 119 def updateIdOfLastUnreferencedDatum(self,last_unreferenced_datum):
213     """updates the identification number of the last unused datum (overwrites TimeSeriesBaseDataset method)"""
214     if self.__id_last_unreferenced_datum>last_unreferenced_datum:
215     self.__id_last_unreferenced_datum=last_unreferenced_datum
216     if self.debug(): print "Debug: %s: last unused datum is now %s"%(self,last_unreferenced_datum)
217 jgs 110
218 jgs 117 def needsRearrangement(self,num_new_data=0):
219     """returns True if the buffer will be full after num_new_data have been appended"""
220 jgs 119 return self.getNumDataInBaseBuffer()+num_new_data>self.getBaseBufferSize()
221 jgs 117
222 jgs 119 def getIdOfFirstAvailableDatum(self):
223     """returns the identification number of the first avaiable datum (overwrites TimeSeriesBaseDataset method)"""
224     return self.getIdOfLastDatum()-self.__num_data_in_buffer+1
225    
226 jgs 117 def append(self,data):
227 jgs 119 """appends data to the buffer. If the buffer would be full the buffer is rearranged before the data are appended (overwrites TimeSeriesBaseDataset method)"""
228 jgs 117 data=numarray.array(data)
229     nc=self.getNumComponents()
230     if data.rank==0:
231     if nc==1:
232     num_new_data=1
233     else:
234     raise ValueError,"%s: illegal data shape"%self
235     elif data.rank==1:
236     if nc==1:
237     num_new_data=data.shape[0]
238     else:
239     num_new_data=1
240     elif data.rank==2:
241     if not nc==data.shape[1]: raise ValueError,"%s: illegal data shape"%self
242     num_new_data=data.shape[0]
243     else:
244     raise ValueError,"%s: illegal rank"%self
245 jgs 110
246 jgs 117 # check is buffer will be overflown when data are appended:
247     if self.needsRearrangement(num_new_data):
248 jgs 119 nn=self.getNumDataInBaseBuffer()
249     num_protected_data=self.getIdOfLastDatum()-self.getIdOfLastUnreferencedDatum()
250     if num_protected_data+num_new_data>self.getBaseBufferSize():
251 jgs 117 raise ValueError,"%s: buffer overflow: buffer size has to be bigger than %d"%(self,num_protected_data+num_new_data)
252 jgs 119 if num_protected_data>0: self.getBaseBuffer()[0:num_protected_data]=self.getBaseBuffer()[nn-num_protected_data:nn]
253 jgs 117 self.__num_data_in_buffer=num_protected_data
254 jgs 119 self.__id_last_unreferenced_datum=self.__id_last_datum
255 jgs 117 if self.debug():
256 jgs 119 print "Debug: %s: rearrangement: first data in buffer is %d."%(self,self.getIdOfLastDatum()-self.getNumDataInBaseBuffer()+1)
257 jgs 117 # copy data over:
258 jgs 119 nn=self.getNumDataInBaseBuffer()
259     self.getBaseBuffer()[nn:nn+num_new_data]=data
260 jgs 117 self.__num_data_in_buffer+=num_new_data
261     self.__id_last_datum+=num_new_data
262 jgs 119 self.__id_last_unreferenced_datum+=num_new_data
263     if self.debug(): print "Debug: %s: %d data appended. Last unreferenced datum is now %d."%(self,num_new_data,self.__id_last_unreferenced_datum)
264 jgs 110
265 jgs 117 # ======================================
266 jgs 119 class TimeSeriesControlerView(TimeSeriesBase):
267     """A TimeSeriesControlerView is attached to a Controler and moves forward in time by increasing the id of the last processed datum.
268     Any implementation of a TimeSeriesControlerView must provide the getControler method which returns the controler"""
269     def __init__(self,id_first_datum=0,debug=False,description="TimeSeries"):
270     TimeSeriesBase.__init__(self,debug,description)
271     self.__id_last_processed_datum=id_first_datum-1
272     if self.debug(): print "Debug: %s created with first datum %d"%(str(self),id_first_datum)
273 jgs 110
274 jgs 117 def getIdOfLastProcessedDatum(self):
275     return self.__id_last_processed_datum
276 jgs 110
277 jgs 117 def updateIdOfLastProcessedDatum(self,id_last_processed_datum):
278     self.__id_last_processed_datum=id_last_processed_datum
279 jgs 110
280 jgs 119 # def getControler(self):
281     # """returns the Controler of the time series (to be overwritten by subclass)"""
282     # pass
283    
284     class TimeSeries(TimeSeriesBaseDataset,TimeSeriesControlerView):
285     """makes TimeSeriesBaseDataset look like a TimeSeries and introduces operations
286     Any implementation of a TimeSeriesControlerView must provide the getControler method which returns the controler"""
287     def __init__(self,dataset,debug=False,description="TimeSeries"):
288     TimeSeriesControlerView.__init__(self,dataset.getIdOfFirstDatum(),debug,description)
289     TimeSeriesBaseDataset.__init__(self,dataset,0,debug,description)
290    
291     def getDataset(self):
292     """returns the TimeSeriesBaseDataset of the time series"""
293     return self.getBaseBuffer()
294    
295     # def getControler(self):
296     # """returns the Controler of the time series (to be overwritten by subclass)"""
297     # pass
298    
299 jgs 117 def __add__(self,arg):
300 jgs 119 if isinstance(arg,TimeSeriesBaseDataset):
301     return TimeSeriesAdd(self,arg)
302 jgs 117 else:
303     return TimeSeriesAddScalar(self,arg)
304 jgs 110
305 jgs 117 def __sub__(self,arg):
306     return self+(-1.)*arg
307    
308     def __mul__(self,arg):
309 jgs 119 if isinstance(arg,TimeSeriesBaseDataset):
310 jgs 117 return TimeSeriesMult(self,arg)
311     else:
312     return TimeSeriesMultScalar(self,arg)
313    
314     def __div__(self,arg):
315 jgs 119 if isinstance(arg,TimeSeriesBaseDataset):
316 jgs 117 return TimeSeriesDiv(self,arg)
317     else:
318     return TimeSeriesMultScalar(self,1./arg)
319    
320     def __pow__(self,arg):
321 jgs 119 if isinstance(arg,TimeSeriesBaseDataset):
322 jgs 117 return TimeSeriesPower(self,arg)
323     else:
324     return TimeSeriesPowerScalar(self,arg)
325 jgs 110
326 jgs 117 def __radd__(self,arg):
327     return self.__add__(arg)
328    
329     def __rsub__(self,arg):
330     return arg+(-1.)*self
331    
332     def __rmul__(self,arg):
333     return self.__mul__(arg)
334    
335     def __rdiv__(self,arg):
336 jgs 119 if isinstance(arg,TimeSeriesBaseDataset):
337 jgs 117 return TimeSeriesDiv(arg,self)
338     else:
339     return TimeSeriesDivScalar(self,arg)
340    
341     def __rpow__(self,arg):
342 jgs 119 if isinstance(arg,TimeSeriesBaseDataset):
343 jgs 117 return TimeSeriesPower(arg,self)
344     else:
345     return Exp(numarray.log(arg)*self)
346    
347     def __lshift__(self,arg):
348     return TimeSeriesShift(self,-arg)
349    
350     def __rshift__(self,arg):
351     return TimeSeriesShift(self,arg)
352    
353     def __neg__(self):
354     return (-1.0)*self
355    
356     def __pos__(self):
357     return (1.0)*self
358    
359 jgs 119 class TimeSeriesOperator(TimeSeriesControlerView):
360     """a TimeSeriesOperator decribes an operation acting on list of TimeSeries time_series_args. It allows to update its output (if there is any)
361     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
362     [start-left_wing_size:end+right_wing_size] of its arguments"""
363     def __init__(self,controler,time_series_args=[],left_wing_size=0,right_wing_size=0,debug=False,description="TimeSeriesOperator"):
364     id_first_datum=controler.getIdOfFirstDatum()
365     for i in time_series_args: id_first_datum=max(id_first_datum,i.getIdOfFirstDatum())
366     TimeSeriesControlerView.__init__(self,id_first_datum+left_wing_size,debug,description)
367 jgs 117 self.__left_wing_size=left_wing_size
368     self.__right_wing_size=right_wing_size
369 jgs 119 self.__time_series_args=time_series_args
370 jgs 117 self.__controler=controler
371 jgs 119 controler.appendOperatorToUpdateList(self)
372     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))
373 jgs 117
374 jgs 119 def __del__(self):
375     self.getControler().removeOperatorFromUpdateList(self)
376    
377 jgs 117 def getControler(self):
378 jgs 119 """returns the Controler updating the TimeSeriesOperator"""
379 jgs 117 return self.__controler
380    
381     def getLeftWingSize(self):
382     """returns the left wing size"""
383     return self.__left_wing_size
384    
385     def getRightWingSize(self):
386     """returns the right wing size"""
387     return self.__right_wing_size
388    
389     def getArguments(self,index=None):
390     """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"""
391     if index==None:
392 jgs 119 return self.__time_series_args
393 jgs 117 else:
394 jgs 119 if len(self.__time_series_args)>0:
395     return self.__time_series_args[index]
396 jgs 117 else:
397     return None
398    
399     def getArgumentDataset(self,index):
400     """returns the dataset of in the argument with index index"""
401     arg=self.getArguments(index)
402     if arg==None:
403     return None
404     else:
405     return self.getArguments(index).getDataset()
406    
407     def flush(self):
408     """calls the update method with all the maximum processable range. It also updates the id of unused datum for all arguments"""
409     start=self.getIdOfLastProcessedDatum()+1
410 jgs 119 end=self.getControler().getIdOfLastDatum()
411     for i in self.getArguments(): end=min(end,i.getIdOfLastDatum())
412     if start<=end-self.getRightWingSize():
413     if self.debug(): print "Debug: %s: range [%d:%d] is updated."%(self,start,end-self.getRightWingSize())
414     self.update(start,end-self.getRightWingSize()+1)
415     for i in self.getArguments(): i.updateIdOfLastUnreferencedDatum(end-self.getLeftWingSize())
416     self.updateIdOfLastProcessedDatum(end)
417 jgs 117
418 jgs 119 def update(self,start,end):
419     """updates the the data [start:end] using [start-left_wing_size:end+right_wing_size] of its arguments (is overwritten by a particular TimeSeriesOperator)"""
420     pass
421    
422    
423     class TimeSeriesFilter(TimeSeries,TimeSeriesOperator):
424     """a TimeSeriesFilter is a TimeSeries taht is created trough a TimeSeriesOperator"""
425     def __init__(self,controler,dataset,time_series_args=[],left_wing_size=0,right_wing_size=0,debug=False,description="TimeSeriesFilter"):
426     TimeSeriesOperator.__init__(self,controler,time_series_args,left_wing_size,right_wing_size,debug,description)
427     TimeSeries.__init__(self,dataset,debug,description)
428    
429     def update(self,start,end):
430     """appends zeros to the dataset. This method should be overwritten by a particular TimeSeriesFilter"""
431     nc=self.getNumComponents()
432     if nc>1:
433     self.getDataset().append(numarray.zeros([nc,end-start]))
434     else:
435     self.getDataset().append(numarray.zeros(end-start))
436    
437 jgs 117 class Controler(TimeSeries):
438     """controls a set of TimeSeries"""
439 jgs 119 def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,debug=False,description="TimeSeriesControler"):
440     TimeSeries.__init__(self,TimeSeriesBaseBuffer(buffer_size,1,DEFAULT_FLOAT_TYPE,0,debug,"node buffer of "+description),debug,"nodes of "+description)
441 jgs 117 self.setFlushRate()
442     self.__update_time_series=list()
443    
444     def getControler(self):
445     """returns the Controler of the time series (overwrites method of by TimeSeries)"""
446     return self
447    
448     def setFlushRate(self,rate=50):
449     """set the flush rate, i.e. after rate new time nodes have been checked in the flush method is called."""
450     self.__flush_rate=rate
451     if self.debug(): print "Debug: %s: flush rate is set to %d"%(self,rate)
452 jgs 110
453 jgs 117 def needsFlushing(self):
454     """returns true if the depending TimeSeriesFilters needs to be flushed becuase the time nodes buffer is full or because of the set flush rate"""
455     return self.needsRearrangement(1) or (self.getNumData()+1)%self.__flush_rate==0
456 jgs 110
457     def flush(self):
458 jgs 117 """flushes all dependend TimeSeriesFilters by processing their flush method"""
459     if self.debug(): print "Debug: %s: start flushing"%self
460     for time_serie in self.__update_time_series: time_serie.flush()
461 jgs 110
462 jgs 119 def appendOperatorToUpdateList(self,time_serie):
463     if not time_serie.getControler()==self: raise ValueError,"%s: TimeSeries %s is not defined on this controler."%(self,time_serie)
464 jgs 117 if not self.isEmpty(): raise ValueError,"%s: you can only check in a time series time_serie is controler is empty."%self
465     self.__update_time_series.append(time_serie)
466     if self.debug(): print "Debug: %s: %s has been added to update list."%(self,time_serie)
467 jgs 110
468 jgs 119 def removeOperatorFromUpdateList(self,time_serie):
469     self.__update_time_series.remove(time_serie)
470     if self.debug(): print "Debug: %s: %s has been removed from update list."%(self,time_serie)
471    
472     def nextTime(self,value):
473 jgs 117 if self.needsFlushing(): self.flush()
474     self.getDataset().append(value)
475     if self.debug(): print "Debug: %s: new time node %e has been added."%(self,value)
476 jgs 110
477 jgs 117 class TimeSeriesShift(TimeSeries):
478     """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"""
479     def __init__(self,time_serie,shift=1):
480     if shift<0:
481     dsc="(%s)<<%d"%(time_serie,-shift)
482     else:
483     dsc="(%s)>>%d"%(time_serie,shift)
484     self.__controler=time_serie.getControler()
485 jgs 119 TimeSeries.__init__(self,TimeSeriesBaseDataset(time_serie.getDataset(),-shift,time_serie.debug(),"buffer view to "+dsc),time_serie.debug(),dsc)
486    
487 jgs 117 def getControler(self):
488     return self.__controler
489 jgs 110
490 jgs 119 class TimeSeriesAdd(TimeSeriesFilter):
491 jgs 117 """adds two TimeSeries"""
492     def __init__(self,time_serie_1,time_serie_2):
493     dsc="(%s)+(%s)"%(time_serie_1,time_serie_2)
494     dbg=time_serie_1.debug() or time_serie_2.debug()
495     cntrl=time_serie_1.getControler()
496     if not cntrl==time_serie_2.getControler():
497 jgs 119 raise ValueError("TimeSeriesAdd: %s and %s have different controler."%(time_serie_1,time_serie_2))
498 jgs 117 id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
499     TimeSeriesFilter.__init__(self,cntrl, \
500 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
501 jgs 117 [time_serie_1,time_serie_2],0,0,dbg,dsc)
502    
503     def update(self,start,end):
504     self.append(self.getArgumentDataset(0)[start:end]+self.getArgumentDataset(1)[start:end])
505    
506     class TimeSeriesAddScalar(TimeSeriesFilter):
507     """adds a single value to a TimeSeries"""
508     def __init__(self,time_serie,scalar):
509     dsc="(%s)+(%s)"%(time_serie,scalar)
510     dbg=time_serie.debug()
511     cntrl=time_serie.getControler()
512     id_first_datum=time_serie.getIdOfFirstDatum()
513     TimeSeriesFilter.__init__(self,cntrl, \
514 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
515 jgs 117 [time_serie],0,0,dbg,dsc)
516     self.__scalar=scalar
517    
518     def update(self,start,end):
519     self.append(self.getArgumentDataset(0)[start:end]+self.__scalar)
520    
521     class TimeSeriesMult(TimeSeriesFilter):
522     """multiplies two TimeSeries"""
523     def __init__(self,time_serie_1,time_serie_2):
524     dsc="(%s)*(%s)"%(time_serie_1,time_serie_2)
525     dbg=time_serie_1.debug() or time_serie_2.debug()
526     cntrl=time_serie_1.getControler()
527     if not cntrl==time_serie_2.getControler():
528     raise ValueError("TimeSeriesMult: %s and %s have different controler."%(time_serie_1,time_serie_2))
529     id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
530     TimeSeriesFilter.__init__(self,cntrl, \
531 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
532 jgs 117 [time_serie_1,time_serie_2],0,0,dbg,dsc)
533    
534     def update(self,start,end):
535     self.append(self.getArgumentDataset(0)[start:end]*self.getArgumentDataset(1)[start:end])
536    
537     class TimeSeriesMultScalar(TimeSeriesFilter):
538     """multiplies a TimeSeries with a single value"""
539     def __init__(self,time_serie,scalar):
540     dsc="(%s)*%s"%(time_serie,scalar)
541     dbg=time_serie.debug()
542     cntrl=time_serie.getControler()
543     id_first_datum=time_serie.getIdOfFirstDatum()
544     TimeSeriesFilter.__init__(self,cntrl, \
545 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
546 jgs 117 [time_serie],0,0,dbg,dsc)
547     self.__scalar=scalar
548    
549     def update(self,start,end):
550     self.append(self.getArgumentDataset(0)[start:end]*self.__scalar)
551    
552     class TimeSeriesDiv(TimeSeriesFilter):
553     """divides two TimeSeries"""
554     def __init__(self,time_serie_1,time_serie_2):
555     dsc="(%s)/(%s)"%(time_serie_1,time_serie_2)
556     dbg=time_serie_1.debug() or time_serie_2.debug()
557     cntrl=time_serie_1.getControler()
558     if not cntrl==time_serie_2.getControler():
559     raise ValueError("TimeSeriesDiv: %s and %s have different controler."%(time_serie_1,time_serie_2))
560     id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
561     TimeSeriesFilter.__init__(self,cntrl, \
562 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
563 jgs 117 [time_serie_1,time_serie_2],0,0,dbg,dsc)
564    
565     def update(self,start,end):
566     self.append(self.getArgumentDataset(0)[start:end]/self.getArgumentDataset(1)[start:end])
567    
568     class TimeSeriesDivScalar(TimeSeriesFilter):
569     """divides a scalar be a TimeSerie"""
570     def __init__(self,time_serie,scalar):
571     dsc="(%s)/(%s)"%(scalar,time_serie)
572     dbg=time_serie.debug()
573     cntrl=time_serie.getControler()
574     id_first_datum=time_serie.getIdOfFirstDatum()
575     TimeSeriesFilter.__init__(self,cntrl, \
576 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
577 jgs 117 [time_serie],0,0,dbg,dsc)
578     self.__scalar=scalar
579    
580     def update(self,start,end):
581     self.append(self.__scalar/self.getArgumentDataset(0)[start:end])
582    
583     class TimeSeriesPower(TimeSeriesFilter):
584     """raise one TimeSeries to the power of an other TimeSeries"""
585     def __init__(self,time_serie_1,time_serie_2):
586     dsc="(%s)**(%s)"%(time_serie_1,time_serie_2)
587     dbg=time_serie_1.debug() or time_serie_2.debug()
588     cntrl=time_serie_1.getControler()
589     if not cntrl==time_serie_2.getControler():
590     raise ValueError("TimeSeriesPower: %s and %s have different controler."%(time_serie_1,time_serie_2))
591     id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum())
592     TimeSeriesFilter.__init__(self,cntrl, \
593 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
594 jgs 117 [time_serie_1,time_serie_2],0,0,dbg,dsc)
595    
596     def update(self,start,end):
597     self.append(self.getArgumentDataset(0)[start:end]**self.getArgumentDataset(1)[start:end])
598    
599     class TimeSeriesPowerScalar(TimeSeriesFilter):
600     """raises a TimeSerie to the power of a scalar"""
601     def __init__(self,time_serie,scalar):
602     dsc="(%s)**(%s)"%(time_serie,scalar)
603     dbg=time_serie.debug()
604     cntrl=time_serie.getControler()
605     id_first_datum=time_serie.getIdOfFirstDatum()
606     TimeSeriesFilter.__init__(self,cntrl, \
607 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
608 jgs 117 [time_serie],0,0,dbg,dsc)
609     self.__scalar=scalar
610    
611     def update(self,start,end):
612     self.append(self.getArgumentDataset(0)[start:end]**self.__scalar)
613    
614     class Exp(TimeSeriesFilter):
615     """"""
616     def __init__(self,time_serie):
617     dsc="exp(%s)"%(time_serie)
618     dbg=time_serie.debug()
619     cntrl=time_serie.getControler()
620     id_first_datum=time_serie.getIdOfFirstDatum()
621     TimeSeriesFilter.__init__(self,cntrl, \
622 jgs 119 TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
623 jgs 117 [time_serie],0,0,dbg,dsc)
624    
625     def update(self,start,end):
626     self.append(numarray.exp(self.getArgumentDataset(0)[start:end]))
627    
628 jgs 119 class Writer(TimeSeriesOperator):
629     """writes the time series into an output strim ostream which mast have the writeline method. The values are seperated by the string seperator."""
630     def __init__(self,time_serie,ostream,seperator=",",commend_tag="#"):
631     dsc="write %s to %s"%(time_serie,ostream)
632     dbg=time_serie.debug()
633     cntrl=time_serie.getControler()
634     self.__ostream=ostream
635     self.__seperator=seperator
636     TimeSeriesOperator.__init__(self,cntrl,[time_serie],0,0,dbg,dsc)
637     ostream.writelines("%s time series %s\n"%(commend_tag,str(self)))
638    
639     def update(self,start,end):
640     cntrl=self.getControler()
641     arg=self.getArguments(0)
642     n=arg.getNumComponents()
643     if n<2:
644     for i in range(start,end): self.__ostream.writelines("%s%s%s\n"%(cntrl[i],self.__seperator,arg[i]))
645     else:
646     for i in range(start,end):
647     l="%s"%cntrl[i]
648     for j in range(n): l=l+"%s%s"(self.__seperator,arg[i][j])
649     self.__ostream.writelines("%s\n"%l)
650    
651     class DataCatcher(TimeSeries):
652     """collects data into a time series."""
653     def __init__(self,controler,numComponents=1,description="DataCatcher"):
654     self.__controler=controler
655     dbg=controler.debug()
656     TimeSeries.__init__(self,TimeSeriesBaseBuffer(controler.getBaseBufferSize(),numComponents,DEFAULT_FLOAT_TYPE,controler.getIdOfFirstDatum(),dbg,"buffer for "+description),dbg,description)
657    
658     def getControler(self):
659     return self.__controler
660    
661     def nextValue(self,value):
662     """append a value to the time series"""
663     id_last=self.getIdOfLastDatum()
664     id_current=self.getControler().getIdOfLastDatum()
665     if id_last+1==id_current:
666     self.getDataset().append(value)
667     elif id_last+1<id_current:
668     if self.isEmpty():
669     self.getDataset().append(value)
670     id_last+=1
671     t_last=self.getControler()[id_last]
672     t_current=self.getControler()[id_current]
673     value_last=self[id_last]
674     out=(value_last-value)/(t_last-t_current)*(self.getControler()[id_last+1:id_current+1]-t_current)+value
675     self.getDataset().append(out)
676     else :
677     raise ValueError,"%s: a new time node must be introduced before a new value can be added."
678     self.updateIdOfLastUnreferencedDatum(id_last)
679    
680    
681 jgs 117 class TimeSeriesCumulativeSum(TimeSeriesFilter):
682 jgs 119 """cummulative sum of the time series values"""
683     def __init__(self,time_serie):
684     dsc="cumsum(%s)"%(time_serie)
685     dbg=time_serie.debug()
686     cntrl=time_serie.getControler()
687     id_first_datum=time_serie.getIdOfFirstDatum()
688     TimeSeriesFilter.__init__(self,cntrl, \
689     TimeSeriesBaseBuffer(cntrl.getBaseBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \
690     [time_serie],0,0,dbg,dsc)
691     self.__last_value=0
692 jgs 117
693 jgs 119 def update(self,start,end):
694     out=numarray.cumsum(self.getArgumentDataset(0)[start:end])+self.__last_value
695     self.__last_value=out[end-start-1]
696     self.append(out)
697 jgs 117
698    
699 jgs 119 class Reader(TimeSeriesBase):
700     """reads a list of input streams and creates a time series for each input stream but on the same Controler where the first column
701     is used to create the time nodes"""
702     def __init__(self,list_of_istreams,buffer_size=DEFAULT_BUFFER_SIZE,seperator=",",commend_tag="#",debug=False):
703     TimeSeriesBase.__init__(self,debug=debug,description="reader")
704     if not isinstance(list_of_istreams,list):
705     self.__list_of_istreams=[list_of_istreams]
706     else:
707     self.__list_of_istreams=list_of_istreams
708     self.__cntrl=Controler(buffer_size,debug,"reader controler")
709     self.__seperator=seperator
710     self.__commend_tag=commend_tag
711     self.__time_series={}
712     self.__t={}
713     self.__v={}
714     # set up the time series:
715     for i in self.__list_of_istreams:
716     line=self.__commend_tag
717     while not line=="" and line[0]==self.__commend_tag:
718     line=i.readline().strip()
719     if line=="":
720     list_of_istreams.remove(i)
721     else:
722     d=line.split(self.__seperator)
723     self.__t[i]=float(d[0])
724     tmp=[]
725     for j in d[1:]: tmp.append(float(j))
726     self.__v[i]=numarray.array(tmp)
727     self.__time_series[i]=DataCatcher(self.__cntrl,len(d)-1,str(i))
728 jgs 110
729 jgs 119 #
730     def run(self):
731     while len(self.__list_of_istreams)>0:
732     if len(self.__time_series)>0:
733     # find list all times with minumum time node:
734     tminargs=[]
735     for i in self.__time_series:
736     if len(tminargs)==0:
737     tminargs.append(i)
738     elif abs(t[tminargs[0]]-self.__t[i])<1.e-8*abs(self.__t[i]):
739     tminargs.append(i)
740     elif self.__t[i]<t[tminargs[0]]:
741     tminargs=[i]
742     # find list all times with minumum time node:
743     self.__cntrl.nextTime(self.__t[tminargs[0]])
744     for i in tminargs:
745     self.__time_series[i].nextValue(self.__v[i])
746     # find next line without leading "#"
747     line="#"
748     while not line=="" and line[0]==self.__commend_tag:
749     line=i.readline().strip()
750     # if eof reached iostream is removed for searching
751     if line=="":
752     self.__list_of_istreams.remove(i)
753     else:
754     d=line.split(self.__seperator)
755     self.__t[i]=float(d[0])
756     tmp=[]
757     for j in d[1:]: tmp.append(float(j))
758     self.__v[i]=numarray.array(tmp)
759 jgs 110
760 jgs 119 def getControler(self):
761     """returns the controler shared by all time series created through the input streams"""
762     return self.__cntrl
763 jgs 110
764 jgs 119 def getTimeSeries(self,istream=None):
765     """returns the time series as a tuple. If istream is present its time series is returned"""
766     if istream==None:
767     out=self.__time_series.values()
768     if len(out)>1:
769     return tuple(out)
770     elif len(out)>0:
771     return out[0]
772     else:
773     return None
774     else:
775     return self.__time_series[istream]
776 jgs 110
777 jgs 119
778     class Plotter(TimeSeriesOperator):
779     def __init__(self,time_series,window_size=DEFAULT_BUFFER_SIZE/4,file_name=None,format=None):
780     if isinstance(time_series,list):
781     dbg=time_series[0].getControler().debug()
782     text=""
783     for i in time_series:
784     if len(text)==0:
785     text=str(i)
786     else:
787     text=text+","+str(i)
788     TimeSeriesOperator.__init__(self,time_series[0].getControler(),time_series,window_size,0,dbg,"plot(%s)"%text)
789     else:
790     dbg=time_series.getControler().debug()
791     text=str(time_series)
792     TimeSeriesOperator.__init__(self,time_series.getControler(),[time_series],window_size,0,dbg,"plot(%s)"%text)
793     from pyvisi.renderers.gnuplot import LinePlot,Scene,PsImage
794     self.__renderer=Scene()
795     self.__line_plot=LinePlot(self.__renderer)
796     self.__line_plot.setTitle(text)
797     self.__line_plot.setLineStyle("lines")
798     self.__line_plot.setXLabel("time")
799     self.__line_plot.setYLabel("values")
800     self.__file_name=file_name
801     if format==None:
802     self.__format=PsImage()
803     else:
804     self.__format=format
805     self.__window_size=window_size
806    
807     def update(self,start,end):
808     s=max(end-self.__window_size,self.getControler().getIdOfFirstAvailableDatum())
809     args=[self.getControler()[s:end]]
810     for arg in self.getArguments(): args.append(arg[s:end])
811     self.__line_plot.setData(*args)
812     self.__line_plot.render()
813     if self.__file_name==None:
814     raise SystemError,"Online viewing is not avilabel yet!"
815     else:
816     self.__renderer.save(fname=self.__file_name, format=self.__format)
817    
818    
819     def viewer(time_serie,seperator=","):
820     """creates a viewer for a time series"""
821     import sys
822     return Writer(time_serie,sys.stdout,seperator)
823    
824     def differential(time_serie):
825 jgs 117 """calculates the derivative Dv of the time series v:
826    
827     Dv[n]=(v[n]-v[n-1])/(t[n]-t[n-1])
828 jgs 110
829 jgs 117 """
830 jgs 119 out=(((time_serie<<1)-time_serie)/((time_serie.getControler()<<1)-time_serie.getControler())+ \
831     ((time_serie>>1)-time_serie)/((time_serie.getControler()>>1)-time_serie.getControler()))/2.
832     out.setDescription("d(%s)/dt"%str(time_serie))
833     out.setDebug(time_serie.debug())
834     return out
835 jgs 110
836 jgs 119 def integral(time_serie):
837 jgs 117 """calculates the intagral Iv of the time series v using the trapozidal rule:
838 jgs 110
839 jgs 119 Iv[n]=int_{t_0}^{t_n} v ~ sum_{0<i<=n} n (v[i]+v[i-1])/2*(t[i]-t[i-1])
840 jgs 110
841 jgs 117 """
842 jgs 119 out=TimeSeriesCumulativeSum(((time_serie>>1)+time_serie)/2.*(time_serie.getControler()-(time_serie.getControler()>>1)))
843     out.setDescription("I (%s) dt"%str(time_serie))
844     out.setDebug(time_serie.debug())
845     return out
846 jgs 110
847 jgs 119 def smooth(time_serie,range=5):
848     """smoothes a time series using the at each time the previous and next range values"""
849     i=integral(time_serie)
850     out=((i>>range)-(i<<range))/((time_serie.getControler()>>range)-(time_serie.getControler()<<range))
851     out.setDescription("smooth(%s,-%d:%d) dt"%(str(time_serie),range,range))
852     out.setDebug(time_serie.debug())
853     return out
854 jgs 110
855 jgs 119 def leakySmooth(time_serie,l=0.99):
856     """leaky smoother: s(t)=int_{t_0}^{t} v(r) l^{t-r} dr/ int_{t_0}^{t} l^{t-r} dr """
857     w=l**(-time_serie.getControler())
858     out=integrate(time_serie*w)/integrate(w)
859     out.setDescription("leaky smoother(%s)"%str(time_serie))
860     return out
861 jgs 110
862     # test
863    
864     if __name__=="__main__":
865 jgs 117 # tests the interfaces to data sets:
866     print "Test of Datasets:"
867     print "================="
868 jgs 119 bf=TimeSeriesBaseBuffer(buffer_size=5,numComponents=1,debug=True,description="TestBaseBuffer")
869     bfv_l=TimeSeriesBaseDataset(bf,offset=1,debug=True,description="offset 1")
870     bfv_r=TimeSeriesBaseDataset(bf,offset=-1,debug=True,description="offset -1")
871 jgs 117 bf.append([1.,2.,3.,4.])
872     print "should be all 2. :",bfv_l[0]
873     print bf[1]
874     print bfv_r[2]
875     bf.append([5.,6.,7.])
876     print "should be all 5. :",bfv_l[3],bf[4],bfv_r[5]
877     print "should be all 6. :",bfv_l[4],bf[5],bfv_r[6]
878     print "should be all 7. :",bfv_l[5],bf[6],bfv_r[7]
879     print "should be all [6., 7.] :",bfv_l[4:6],bf[5:7],bfv_r[6:8]
880 jgs 110
881 jgs 117 print "Test of Controler"
882     print "================="
883     b=Controler(buffer_size=15,debug=True)
884     s3=b>>3
885     s1=b>>1
886     s_3=b<<3
887 jgs 119 print s_3
888     print b
889     print b+s3
890 jgs 117 sum=(s_3+b)+(b+s3)
891    
892     for i in range(30):
893 jgs 119 b.nextTime(i*1.)
894 jgs 117 b.flush()
895     print "should be all 28. :",s_3.getDataset()[25],b.getDataset()[28],s3.getDataset()[31]
896     print "should be all 29. :",s_3.getDataset()[26],b.getDataset()[29],s3.getDataset()[32]
897     print "should be all 96. :",sum.getDataset()[24]
898    
899     print "Test of operators"
900     print "================="
901     b=Controler(buffer_size=15,debug=True)
902 jgs 119 b.setFlushRate(2)
903     q=DataCatcher(b)
904 jgs 117 b1=b<<1
905     a=b+b1
906     a_s=b1+1.
907     s_a=1.+b1
908     d=b-b1
909     d_s=b1-1.
910     s_d=1.-b1
911     m=b*b1
912     m_s=b1*2.
913     s_m=2.*b1
914     dv=b/b1
915     dv_s=b1/2.
916     s_dv=2./b1
917     p=b**b1
918     p_s=b1**2.
919     s_p=2.**b1
920     pb=+b
921     mb=-b
922 jgs 119 sum=TimeSeriesCumulativeSum(b)
923     diff=differential(b)
924     smt=smooth(b,2)
925     int=integral(b*2)
926     fl=file("/tmp/test.csv","w")
927     w=Writer(q,fl)
928     v=viewer(q)
929     plo=Plotter([a,a_s],window_size=4,file_name="s.ps")
930 jgs 117 for i in range(30):
931 jgs 119 b.nextTime(i*1.)
932     if i%2==1: q.nextValue(i*28.)
933 jgs 117 b.flush()
934     print "a[28] should be %e: %e"%(28.+29.,a[28])
935     print "a_s[28] should be %e: %e"%(29.+1.,a_s[28])
936     print "s_a[28] should be %e: %e"%(29.+1.,s_a[28])
937     print "d[28] should be %e: %e"%(28.-29.,d[28])
938     print "d_s[28] should %e: %e"%(29.-1.,d_s[28])
939     print "s_d[28] should %e: %e"%(1.-29.,s_d[28])
940     print "m[28] should be %e: %e"%(28.*29.,m[28])
941     print "m_s[28] should be %e: %e"%(29.*2.,m_s[28])
942     print "s_m[28] should be %e: %e"%(29.*2.,s_m[28])
943     print "dv[28] should be %e: %e"%(28./29.,dv[28])
944     print "dv_s[28] should be %e: %e"%(29./2.,dv_s[28])
945     print "s_dv[28] should be %e: %e"%(2./29.,s_dv[28])
946     print "p[28] should be %e: %e"%(28.**29.,p[28])
947     print "p_s[28] should be %e: %e"%(29.**2,p_s[28])
948     print "s_p[28] should be %e: %e"%(2.**29.,s_p[28])
949     print "pb[28] should be %e: %e"%(28.,pb[28])
950     print "mb[28] should be %e: %e"%(-28.,mb[28])
951 jgs 119 print "sum[28] should be %e: %e"%(28*29./2,sum[28])
952     print "diff[28] should be %e: %e"%(1.,diff[28])
953     print "smt[27] should be %e: %e"%(27.,smt[27])
954     print "int[28] should be %e: %e"%(28.**2,int[28])
955     print "q[27] should be %e: %e"%(27*28.,q[27])
956     print "q[28] should be %e: %e"%(28*28.,q[28])
957     print "q[29] should be %e: %e"%(29*28.,q[29])
958     fl.flush()
959    
960     rin=Reader(file("/tmp/test.csv","r+"),buffer_size=15,debug=True)
961     rin.run()
962     inp=rin.getTimeSeries()
963     print "inp[27] should be %e: %e"%(27*28.,inp[27])
964     print "inp[28] should be %e: %e"%(28*28.,inp[28])
965     print "inp[29] should be %e: %e"%(29*28.,inp[29])
966 jgs 117

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26