1 |
# $Id$ |
# $Id$ |
2 |
|
|
3 |
import numarray |
import numarray |
4 |
|
from types import SliceType |
5 |
|
DEFAULT_BUFFER_SIZE=9 |
6 |
|
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.""" |
|
It takes care of the updating depending TimeSeriesBase objects and the debuging mechnism""" |
|
10 |
|
|
11 |
def __init__(self): |
def __init__(self,debug=False,description="timeseries.Base"): |
12 |
self.__debug=False |
self.__debug=debug |
13 |
|
self.__description=description |
14 |
|
|
15 |
def __str__(self): |
def __str__(self): |
16 |
return "TimeSeriesBase" |
return self.__description |
17 |
|
|
18 |
def setDebugOn(self): |
def setDebugOn(self): |
19 |
"""switch on degugging mode""" |
"""switch on degugging mode""" |
33 |
def debug(self): |
def debug(self): |
34 |
"""returns true if debug mode is on""" |
"""returns true if debug mode is on""" |
35 |
return self.__debug |
return self.__debug |
|
|
|
|
class TimeSeriesFilter(TimeSeriesBase): |
|
|
"""TimeSeriesFilter objects are applied to TimeSeries objects to filer out information or to convert it. |
|
|
A TimeSeriesFilter objects is called by the TimeSeries object it is depending on to consider the values currently in the buffer for |
|
|
updating. Some TimeSeriesFilter may require values outside the buffer. The TimeSeries object maintains the last buffer_overlap values |
|
|
in the buffer so they can be used to process (not neccesarily all) value in the buffer.""" |
|
36 |
|
|
37 |
def __init__(self,buffer_overlap=0): |
#============================================================================================================ |
38 |
self.__left_required_extension=buffer_overlap |
class TimeSeriesDataset(TimeSeriesBase): |
39 |
|
"""provides an interface for accessing a set of linearly ordered data.""" |
40 |
|
def __init__(self,buffer,offset=0,debug=False,description="timeseries.Dataset"): |
41 |
|
TimeSeriesBase.__init__(self,debug,description) |
42 |
|
self.__buffer=buffer |
43 |
|
self.__offset=offset |
44 |
|
if self.debug(): print "Debug: %s: offset %d to buffer"%(self,self.getOffset()) |
45 |
|
|
46 |
|
def __len__(self): |
47 |
|
"""needed to handle negative indexing in slicing""" |
48 |
|
return 0 |
49 |
|
|
50 |
def __str__(self): |
def getNumComponents(self): |
51 |
return "TimeSeriesFilter" |
"""returns the number of components of the data (may be overwritten by subclass)""" |
52 |
|
return self.getBuffer().getNumComponents() |
53 |
|
|
54 |
def getBufferOverlapNeededForUpdate(self): |
def getIdOfLastDatum(self): |
55 |
return self.__left_required_extension |
"""returns the identification number of the last datum in the data set (may be overwritten by subclass)""" |
56 |
|
return self.getBuffer().getIdOfLastDatum()-self.getOffset() |
57 |
|
|
58 |
|
def getIdOfFirstDatum(self): |
59 |
|
"""returns the identification number of the first datum (may be overwritten by subclass)""" |
60 |
|
return self.getBuffer().getIdOfFirstDatum()-self.getOffset() |
61 |
|
|
62 |
|
def getOffsetInBuffer(self): |
63 |
|
"""returns the offset to access elements in getBuffer() (may be overwritten by subclass)""" |
64 |
|
return self.getOffset() |
65 |
|
|
66 |
|
def getIdOfLastUnusedDatum(self): |
67 |
|
"""returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesDataset (may be overwritten by subclass)""" |
68 |
|
return self.getBuffer().getIdOfLastUnusedDatum()-self.getOffset() |
69 |
|
|
70 |
|
def updateIdOfLastUnusedDatum(self,last_unused_datum): |
71 |
|
"""updates the identification number of the last unused datum (to be overwritten by subclass)""" |
72 |
|
self.getBuffer().updateIdOfLastUnusedDatum(last_unused_datum+self.getOffset()) |
73 |
|
|
74 |
|
def append(self,values): |
75 |
|
"""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)""" |
76 |
|
self.getBuffer().append(values) |
77 |
|
|
78 |
def update(self,times,values): |
def getBufferSize(self): |
79 |
pass |
"""returns the size of the buffer (to be overwritten by subclass)""" |
80 |
|
return self.getBuffer().getBufferSize() |
81 |
|
|
82 |
|
def needsRearrangement(self,num_new_data=0): |
83 |
|
"""returns True if the buffer will be full after num_new_data have been appended (to be overwritten by subclass)""" |
84 |
|
return self.getBuffer().needsRearrangement(num_new_data) |
85 |
|
|
86 |
|
def isEmpty(self): |
87 |
|
"""returns true if no data are appeneded to buffer""" |
88 |
|
return self.getNumData()<=0 |
89 |
|
|
90 |
|
def getNumData(self): |
91 |
|
"""returns the number of data (not all of them are accessible)""" |
92 |
|
return self.getIdOfLastDatum()-self.getIdOfFirstDatum()+1 |
93 |
|
|
94 |
|
def getBuffer(self): |
95 |
|
"""return the buffer referenced by the TimeSeriesDataset""" |
96 |
|
return self.__buffer |
97 |
|
|
98 |
|
def getOffset(self): |
99 |
|
"""return the offset when referring to dataset elements""" |
100 |
|
return self.__offset |
101 |
|
|
102 |
|
def __getitem__(self,index): |
103 |
|
"""returns the datum index""" |
104 |
|
if type(index)==SliceType: |
105 |
|
start=index.start |
106 |
|
end=index.stop |
107 |
|
if start==end: |
108 |
|
return self[start] |
109 |
|
else: |
110 |
|
if start<self.getIdOfFirstDatum() or start>self.getIdOfLastDatum() or \ |
111 |
|
end-1<self.getIdOfFirstDatum() or end-1>self.getIdOfLastDatum(): raise IndexError,"%s: Index [%d:%d] out of range"%(self,start,end) |
112 |
|
return self.getBuffer()[start+self.getOffsetInBuffer():end+self.getOffsetInBuffer()] |
113 |
|
else: |
114 |
|
if index<self.getIdOfFirstDatum() or index>self.getIdOfLastDatum(): raise IndexError,"%s: Index %d out of range"%(self,index) |
115 |
|
return self.getBuffer()[index+self.getOffsetInBuffer()] |
116 |
|
|
117 |
_DEFAULT_CACHE_SIZE=9 |
class TimeSeriesBuffer(TimeSeriesDataset): |
118 |
_DEFAULT_BUFFER_SIZE=5 |
"""An inplementation of TimeSeriesDataset which actually is storing data into a numarray buffer""" |
119 |
_FLOATING_TYPE=numarray.Float64 |
def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,numComponents=1,type=DEFAULT_FLOAT_TYPE,id_of_first_datum=0,debug=False,description="timeseries.Buffer"): |
|
|
|
|
class TimeSeries(TimeSeriesBase): |
|
|
def __init__(self,buffer_overlap=0,buffer_size=_DEFAULT_BUFFER_SIZE,cache_size=_DEFAULT_CACHE_SIZE,numComponents=1): |
|
|
if buffer_size>cache_size: raise ValueError,"buffer size has to be less or equal cache size" |
|
|
TimeSeriesBase.__init__(self) |
|
|
self.__updates=list() |
|
|
self.__max_buffer_overlap=0 |
|
|
self.__buffer_overlap=0 |
|
|
self.__numNodes=0 |
|
|
self.__numNodesInBuffer=0 |
|
|
self.__numNodesInCache=0 |
|
|
self.__firstNodeInBuffer=0 |
|
|
self.__firstNodeInCache=0 |
|
|
self.__buffer_size=buffer_size |
|
|
self.__node_cache=numarray.zeros((cache_size,),_FLOATING_TYPE) |
|
|
self.__attachment_cache=[] |
|
120 |
if numComponents<2: |
if numComponents<2: |
121 |
self.__value_cache=numarray.zeros((cache_size,),_FLOATING_TYPE) |
buffer=numarray.zeros((buffer_size,),type) |
122 |
else: |
else: |
123 |
self.__value_cache=numarray.zeros((cache_size,numComponents),_FLOATING_TYPE) |
buffer=numarray.zeros((buffer_size,numComponents),type) |
124 |
self.resizeMaxBufferOverlap(buffer_overlap) |
TimeSeriesDataset.__init__(self,buffer,id_of_first_datum-1,debug,description) |
125 |
|
self.__num_data_in_buffer=0 |
126 |
|
self.__id_last_unused_datum=id_of_first_datum-1 |
127 |
|
self.__id_last_datum=id_of_first_datum-1 |
128 |
|
self.__id_first_datum=id_of_first_datum |
129 |
|
if self.debug(): print "Debug: %s : buffer of size %d with %d components allocated (first datum is %d)."% \ |
130 |
|
(self,self.getBufferSize(),self.getNumComponents(),id_of_first_datum) |
131 |
|
|
|
def __del__(self): |
|
|
self.flush() |
|
|
|
|
|
def __str__(self): |
|
|
return "TimeSeries" |
|
132 |
|
|
133 |
|
def getBufferSize(self): |
134 |
|
"""returns the size of the buffer""" |
135 |
|
return self.getBuffer().shape[0] |
136 |
|
|
137 |
def getNumComponents(self): |
def getNumComponents(self): |
138 |
if self.__value_cache.rank==1: |
"""returns the number of components of the data (overwrites TimeSeriesDataset method)""" |
139 |
|
if self.getBuffer().rank==1: |
140 |
return 1 |
return 1 |
141 |
else: |
else: |
142 |
self.__value_cache.shape[1] |
self.getBuffer().shape[1] |
143 |
|
|
144 |
def getNumNodes(self): |
def getNumDataInBuffer(self): |
145 |
"""returns the number of time nodes in the time series""" |
"""returns the number of data currently in the buffer""" |
146 |
return self.__numNodes |
return self.__num_data_in_buffer |
147 |
|
|
148 |
def getCacheSize(self): |
def getIdOfLastDatum(self): |
149 |
"""returns the cache size""" |
"""returns the identification number of the last datum in the data set (overwrites method from TimeSeriesDataset)""" |
150 |
return self.__node_cache.shape[0] |
return self.__id_last_datum |
151 |
|
|
152 |
|
def getIdOfFirstDatum(self): |
153 |
|
"""returns the identification number of the first datum (overwrites method from TimeSeriesDataset)""" |
154 |
|
return self.__id_first_datum |
155 |
|
|
156 |
|
def getOffsetInBuffer(self): |
157 |
|
"""returns the offset to access elements in the buffer (overwrites method from TimeSeriesDataset)""" |
158 |
|
return -self.getIdOfLastDatum()+self.getNumDataInBuffer()-1 |
159 |
|
|
160 |
|
def getIdOfLastUnusedDatum(self): |
161 |
|
"""returns the identification number of the last datum which has been unused by all TimeSeries refering to the TimeSeriesDataset (overwrites method from TimeSeriesDataset)""" |
162 |
|
return self.__id_last_unused_datum |
163 |
|
|
164 |
|
def updateIdOfLastUnusedDatum(self,last_unused_datum): |
165 |
|
"""updates the identification number of the last unused datum (to be overwritten by subclass)""" |
166 |
|
self.getBuffer().updateIdOfLastUnusedDatum(last_unused_datum-self.getOffset()) |
167 |
|
|
168 |
|
def updateIdOfLastUnusedDatum(self,last_unused_datum): |
169 |
|
"""updates the identification number of the last unused datum (overwrites TimeSeriesDataset method)""" |
170 |
|
if self.__id_last_unused_datum>last_unused_datum: |
171 |
|
self.__id_last_unused_datum=last_unused_datum |
172 |
|
if self.debug(): print "Debug: %s: last unused datum is now %s"%(self,last_unused_datum) |
173 |
|
|
174 |
|
def needsRearrangement(self,num_new_data=0): |
175 |
|
"""returns True if the buffer will be full after num_new_data have been appended""" |
176 |
|
return self.getNumDataInBuffer()+num_new_data>self.getBufferSize() |
177 |
|
|
178 |
|
def append(self,data): |
179 |
|
"""appends data to the buffer. If the buffer would be full the buffer is rearranged before the data are appended (overwrites TimeSeriesDataset method)""" |
180 |
|
data=numarray.array(data) |
181 |
|
nc=self.getNumComponents() |
182 |
|
if data.rank==0: |
183 |
|
if nc==1: |
184 |
|
num_new_data=1 |
185 |
|
else: |
186 |
|
raise ValueError,"%s: illegal data shape"%self |
187 |
|
elif data.rank==1: |
188 |
|
if nc==1: |
189 |
|
num_new_data=data.shape[0] |
190 |
|
else: |
191 |
|
num_new_data=1 |
192 |
|
elif data.rank==2: |
193 |
|
if not nc==data.shape[1]: raise ValueError,"%s: illegal data shape"%self |
194 |
|
num_new_data=data.shape[0] |
195 |
|
else: |
196 |
|
raise ValueError,"%s: illegal rank"%self |
197 |
|
|
198 |
def getBufferSize(self): |
# check is buffer will be overflown when data are appended: |
199 |
"""returns the cache size""" |
if self.needsRearrangement(num_new_data): |
200 |
return self.__buffer_size |
nn=self.getNumDataInBuffer() |
201 |
|
num_protected_data=self.getIdOfLastDatum()-self.getIdOfLastUnusedDatum() |
202 |
|
if num_protected_data+num_new_data>self.getBufferSize(): |
203 |
|
raise ValueError,"%s: buffer overflow: buffer size has to be bigger than %d"%(self,num_protected_data+num_new_data) |
204 |
|
if num_protected_data>0: self.getBuffer()[0:num_protected_data]=self.getBuffer()[nn-num_protected_data:nn] |
205 |
|
self.__num_data_in_buffer=num_protected_data |
206 |
|
self.__id_last_unused_datum=self.__id_last_datum |
207 |
|
if self.debug(): |
208 |
|
print "Debug: %s: rearrangement: first data in buffer is %d."%(self,self.getIdOfLastDatum()-self.getNumDataInBuffer()+1) |
209 |
|
# copy data over: |
210 |
|
nn=self.getNumDataInBuffer() |
211 |
|
self.getBuffer()[nn:nn+num_new_data]=data |
212 |
|
self.__num_data_in_buffer+=num_new_data |
213 |
|
self.__id_last_datum+=num_new_data |
214 |
|
self.__id_last_unused_datum+=num_new_data |
215 |
|
if self.debug(): print "Debug: %s: %d data appended. Last unused datum is now %d."%(self,num_new_data,self.__id_last_unused_datum) |
216 |
|
|
217 |
|
# ====================================== |
218 |
|
class TimeSeries(TimeSeriesDataset): |
219 |
|
"""a TimeSeries glues a Controler controler and a TimeSeriesDataset dataset together. It also provides a TimeSeriesDataset view to the datset""" |
220 |
|
def __init__(self,dataset,debug=False,description="timeseries."): |
221 |
|
TimeSeriesDataset.__init__(self,dataset,0,debug,description) |
222 |
|
self.__id_last_processed_datum=dataset.getIdOfFirstDatum()-1 |
223 |
|
|
224 |
|
def getDataset(self): |
225 |
|
"""returns the TimeSeriesDataset of the time series""" |
226 |
|
return self.getBuffer() |
227 |
|
|
228 |
|
def getControler(self): |
229 |
|
"""returns the Controler of the time series (to be overwritten by subclass)""" |
230 |
|
pass |
231 |
|
|
232 |
|
def getIdOfLastProcessedDatum(self): |
233 |
|
return self.__id_last_processed_datum |
234 |
|
|
235 |
|
def updateIdOfLastProcessedDatum(self,id_last_processed_datum): |
236 |
|
self.__id_last_processed_datum=id_last_processed_datum |
237 |
|
|
238 |
|
def __add__(self,arg): |
239 |
|
if isinstance(arg,TimeSeriesDataset): |
240 |
|
return TimeSeriesSum(self,arg) |
241 |
|
else: |
242 |
|
return TimeSeriesAddScalar(self,arg) |
243 |
|
|
244 |
|
def __sub__(self,arg): |
245 |
|
return self+(-1.)*arg |
246 |
|
|
247 |
|
def __mul__(self,arg): |
248 |
|
if isinstance(arg,TimeSeriesDataset): |
249 |
|
return TimeSeriesMult(self,arg) |
250 |
|
else: |
251 |
|
return TimeSeriesMultScalar(self,arg) |
252 |
|
|
253 |
|
def __div__(self,arg): |
254 |
|
if isinstance(arg,TimeSeriesDataset): |
255 |
|
return TimeSeriesDiv(self,arg) |
256 |
|
else: |
257 |
|
return TimeSeriesMultScalar(self,1./arg) |
258 |
|
|
259 |
|
def __pow__(self,arg): |
260 |
|
if isinstance(arg,TimeSeriesDataset): |
261 |
|
return TimeSeriesPower(self,arg) |
262 |
|
else: |
263 |
|
return TimeSeriesPowerScalar(self,arg) |
264 |
|
|
265 |
|
def __radd__(self,arg): |
266 |
|
return self.__add__(arg) |
267 |
|
|
268 |
def getNumNodesInCache(self): |
def __rsub__(self,arg): |
269 |
"""returns the number of nodes in cache""" |
return arg+(-1.)*self |
|
return self.__numNodesInCache |
|
|
|
|
|
def getNumNodesInBuffer(self): |
|
|
"""returns the number of nodes in cache""" |
|
|
return self.__numNodesInBuffer |
|
|
|
|
|
def getFirstNodeInCache(self): |
|
|
"""returns the id number of the first node in the cache""" |
|
|
return self.__firstNodeInCache |
|
|
|
|
|
def getFirstNodeInBuffer(self): |
|
|
"""returns the id number of the first node in the buffer""" |
|
|
return self.__firstNodeInBuffer |
|
|
|
|
|
def getFirstNodeOfBufferInCache(self): |
|
|
"""returns the first location of the first node in the buffer relative to the cache""" |
|
|
return self.getFirstNodeInBuffer()-self.getFirstNodeInCache() |
|
|
|
|
|
def getBufferOverlap(self): |
|
|
"""returns the current size of the left extension""" |
|
|
return self.__buffer_overlap |
|
|
|
|
|
def getMaxBufferOverlap(self): |
|
|
"""returns the maximum size of the left extension""" |
|
|
return self.__max_buffer_overlap |
|
|
|
|
|
def resizeMaxBufferOverlap(self,new_buffer_overlap=0): |
|
|
if new_buffer_overlap>self.__max_buffer_overlap: |
|
|
if self.getNumNodes()>0: raise ValueError,"left extension can only be resized for empty time series" |
|
|
if self.getCacheSize()<self.getBufferSize()+new_buffer_overlap: |
|
|
raise ValueError,"Cache size is too small! required cache size is %s"%self.getBufferSize()+new_buffer_overlap |
|
|
self.__max_buffer_overlap=new_buffer_overlap |
|
|
if self.debug(): print "Debug: %s: left extension is increased to %d"%(self,new_buffer_overlap) |
|
|
|
|
|
def getLastNode(self): |
|
|
if self.getNumNodesInCache()>0: |
|
|
return self.__node_cache[self.getNumNodesInCache()-1] |
|
|
else: |
|
|
return -1.e300 |
|
270 |
|
|
271 |
def getLastValue(self): |
def __rmul__(self,arg): |
272 |
if self.getNumNodesInCache()>0: |
return self.__mul__(arg) |
273 |
return self.__node_cache[self.getNumNodesInCache()-1] |
|
274 |
else: |
def __rdiv__(self,arg): |
275 |
raise ValueError,"No value available" |
if isinstance(arg,TimeSeriesDataset): |
276 |
|
return TimeSeriesDiv(arg,self) |
277 |
|
else: |
278 |
|
return TimeSeriesDivScalar(self,arg) |
279 |
|
|
280 |
|
def __rpow__(self,arg): |
281 |
|
if isinstance(arg,TimeSeriesDataset): |
282 |
|
return TimeSeriesPower(arg,self) |
283 |
|
else: |
284 |
|
return Exp(numarray.log(arg)*self) |
285 |
|
|
286 |
|
def __lshift__(self,arg): |
287 |
|
return TimeSeriesShift(self,-arg) |
288 |
|
|
289 |
|
def __rshift__(self,arg): |
290 |
|
return TimeSeriesShift(self,arg) |
291 |
|
|
292 |
|
def __neg__(self): |
293 |
|
return (-1.0)*self |
294 |
|
|
295 |
|
def __pos__(self): |
296 |
|
return (1.0)*self |
297 |
|
|
298 |
|
class TimeSeriesFilter(TimeSeries): |
299 |
|
"""a TimeSeriesFilter is a TimeSeriesDataset attached to a Controler where the TimeSeriesDataset provides data |
300 |
|
at the time nodes defined by the Controler. Additional to a TimeSeries a TimeSeriesFilter allows to update |
301 |
|
the underlying TimeSeriesDataset through the update method which is overwritten by a particular implementation of the |
302 |
|
class. The update method is called to append the data [start:end] to the attached dataset by the the attached TimeSerieControler""" |
303 |
|
def __init__(self,controler,dataset,args=[],left_wing_size=0,right_wing_size=0,debug=False,description="timeseries.Filter"): |
304 |
|
TimeSeries.__init__(self,dataset,debug,description) |
305 |
|
self.__left_wing_size=left_wing_size |
306 |
|
self.__right_wing_size=right_wing_size |
307 |
|
self.__args=args |
308 |
|
self.__controler=controler |
309 |
|
controler.appendFilterToUpdateList(self) |
310 |
|
|
311 |
|
def getControler(self): |
312 |
|
"""returns the Controler of the time series (overwrites method of by TimeSeries)""" |
313 |
|
return self.__controler |
314 |
|
|
315 |
|
def update(self,start,end): |
316 |
|
"""appends zeros to the dataset. This method should be overwritten by a particular TimeSeriesFilter""" |
317 |
|
nc=self.getNumComponents() |
318 |
|
if nc>1: |
319 |
|
self.getDataset().append(numarray.zeros([nc,end-start])) |
320 |
|
else: |
321 |
|
self.getDataset().append(numarray.zeros(end-start)) |
322 |
|
def getLeftWingSize(self): |
323 |
|
"""returns the left wing size""" |
324 |
|
return self.__left_wing_size |
325 |
|
|
326 |
|
def getRightWingSize(self): |
327 |
|
"""returns the right wing size""" |
328 |
|
return self.__right_wing_size |
329 |
|
|
330 |
|
def getArguments(self,index=None): |
331 |
|
"""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""" |
332 |
|
if index==None: |
333 |
|
return self.__args |
334 |
|
else: |
335 |
|
if len(self.__args)>0: |
336 |
|
return self.__args[index] |
337 |
|
else: |
338 |
|
return None |
339 |
|
|
340 |
def checkInUpdate(self,time_series_filter): |
def getArgumentDataset(self,index): |
341 |
"""checks in a time_series_filter object to be updated when buffer is full""" |
"""returns the dataset of in the argument with index index""" |
342 |
if self.getNumNodes()>0: |
arg=self.getArguments(index) |
343 |
raise TypeError,"Check in of TimeSeries requires empty buffer." |
if arg==None: |
344 |
self.__updates.append(time_series_filter) |
return None |
345 |
self.resizeMaxBufferOverlap(time_series_filter.getBufferOverlapNeededForUpdate()) |
else: |
346 |
if self.debug(): print "Debug: %s: %s checked in successfully."%(self,time_series_filter) |
return self.getArguments(index).getDataset() |
347 |
|
|
348 |
def append(self,time_nodes,values,attachments=None): |
def flush(self): |
349 |
"""appends the time_nodes and values into the buffer""" |
"""calls the update method with all the maximum processable range. It also updates the id of unused datum for all arguments""" |
350 |
num_additional_nodes=time_nodes.shape[0] |
start=self.getIdOfLastProcessedDatum()+1 |
351 |
if num_additional_nodes<1: return |
end=None |
352 |
if self.debug(): |
for i in self.getArguments(): |
353 |
if num_additional_nodes>1: |
if end==None: |
354 |
print "Debug: %s: values %d to %d are added to time series."%(self,self.getNumNodes(),self.getNumNodes()+num_additional_nodes-1) |
end=i.getIdOfLastDatum() |
355 |
else: |
else: |
356 |
print "Debug: %s: value %d is added to time series."%(self,self.getNumNodes()) |
end=min(end,i.getIdOfLastDatum()) |
357 |
if not num_additional_nodes==values.shape[0]: |
if not end==None: |
358 |
raise ValueError,"Number time nodes and number of values don't match." |
if self.debug(): print "Debug: %s: range [%d:%d] is updated."%(self,start,end-self.getRightWingSize()) |
359 |
if self.getLastNode()>=time_nodes[0]: |
self.update(start,end-self.getRightWingSize()+1) |
360 |
raise ValueError,"first time node to be checked in is less than last previously checked in node" |
for i in self.getArguments(): i.updateIdOfLastUnusedDatum(end-self.getLeftWingSize()) |
361 |
|
self.updateIdOfLastProcessedDatum(end) |
362 |
if num_additional_nodes>1: |
|
363 |
if min(time_nodes[1:num_additional_nodes]-time_nodes[0:num_additional_nodes-1])<=0: |
class Controler(TimeSeries): |
364 |
raise ValueError,"time nodes have to be strictly increasing" |
"""controls a set of TimeSeries""" |
365 |
|
def __init__(self,buffer_size=DEFAULT_BUFFER_SIZE,debug=False,description="timeseries.Controler"): |
366 |
|
TimeSeries.__init__(self,TimeSeriesBuffer(buffer_size,1,DEFAULT_FLOAT_TYPE,0,debug,"Time nodes buffer of "+description),\ |
367 |
|
debug,"Time nodes of "+description) |
368 |
|
self.setFlushRate() |
369 |
|
self.__update_time_series=list() |
370 |
|
|
371 |
# full cache requires a shift: |
def __del__(self): |
372 |
if self.getNumNodesInCache()+num_additional_nodes>self.getCacheSize(): |
self.flush() |
373 |
new_num_nodes_in_cache=self.getNumNodesInBuffer()+self.getBufferOverlap() |
|
374 |
if new_num_nodes_in_cache+num_additional_nodes>self.getCacheSize(): |
def getControler(self): |
375 |
raise ValueError,"Cache overflow: Expected size is bigger than %d"%(new_num_nodes_in_cache+num_additional_nodes) |
"""returns the Controler of the time series (overwrites method of by TimeSeries)""" |
376 |
start=self.getNumNodesInCache()-new_num_nodes_in_cache |
return self |
377 |
end=start+new_num_nodes_in_cache |
|
378 |
self.__node_cache[0:new_num_nodes_in_cache]=self.__node_cache[start:end] |
def setFlushRate(self,rate=50): |
379 |
self.__value_cache[0:new_num_nodes_in_cache]=self.__value_cache[start:end] |
"""set the flush rate, i.e. after rate new time nodes have been checked in the flush method is called.""" |
380 |
self.__attachment_cache[0:new_num_nodes_in_cache]=self.__attachment_cache[start:end] |
self.__flush_rate=rate |
381 |
|
if self.debug(): print "Debug: %s: flush rate is set to %d"%(self,rate) |
382 |
|
|
383 |
self.__firstNodeInCache+=start |
def needsFlushing(self): |
384 |
self.__numNodesInCache=new_num_nodes_in_cache |
"""returns true if the depending TimeSeriesFilters needs to be flushed becuase the time nodes buffer is full or because of the set flush rate""" |
385 |
if self.debug(): print "Debug: %s: %d values from %d onwards are moved to the beginning of the cache (first node in cache is now %d)."% \ |
return self.needsRearrangement(1) or (self.getNumData()+1)%self.__flush_rate==0 |
|
(self,new_num_nodes_in_cache,start,self.__firstNodeInCache) |
|
|
|
|
|
# copy values into cache: |
|
|
if self.getNumNodesInCache()+num_additional_nodes>self.getCacheSize(): |
|
|
raise ValueError,"Cache overflow: Expected size is bigger than %d"%(self.getNumNodesInCache()+num_additional_nodes) |
|
|
if self.debug(): |
|
|
if num_additional_nodes>1: |
|
|
print "Debug: %s: values %d to %d of cache are updated"%(self,self.getNumNodesInCache(),self.getNumNodesInCache()+num_additional_nodes-1) |
|
|
else: |
|
|
print "Debug: %s: value %d of cache is updated."%(self,self.getNumNodesInCache()) |
|
|
self.__node_cache[self.getNumNodesInCache():self.getNumNodesInCache()+num_additional_nodes]=time_nodes |
|
|
self.__value_cache[self.getNumNodesInCache():self.getNumNodesInCache()+num_additional_nodes]=values |
|
|
self.__numNodes+=num_additional_nodes |
|
|
self.__numNodesInBuffer+=num_additional_nodes |
|
|
self.__numNodesInCache+=num_additional_nodes |
|
|
print self.__node_cache |
|
|
print self.__value_cache |
|
|
# copy values into cache: |
|
|
if self.getNumNodesInBuffer()>=self.getBufferSize(): |
|
|
if self.debug() and len(self.__updates)>0: print "Debug: %s: buffer is full. Updating process is started"%self |
|
|
self.processBuffer() |
|
386 |
|
|
387 |
def flush(self): |
def flush(self): |
388 |
self.processBuffer() |
"""flushes all dependend TimeSeriesFilters by processing their flush method""" |
389 |
|
if self.debug(): print "Debug: %s: start flushing"%self |
390 |
|
for time_serie in self.__update_time_series: time_serie.flush() |
391 |
|
|
392 |
|
def appendFilterToUpdateList(self,time_serie): |
393 |
|
if not time_serie.getControler()==self: raise ValueError,"%s: time series time_serie %s is not linked defined on %s."%(self,time_serie,self) |
394 |
|
if not self.isEmpty(): raise ValueError,"%s: you can only check in a time series time_serie is controler is empty."%self |
395 |
|
self.__update_time_series.append(time_serie) |
396 |
|
if self.debug(): print "Debug: %s: %s has been added to update list."%(self,time_serie) |
397 |
|
|
398 |
|
def newTimeNode(self,value): |
399 |
|
if self.needsFlushing(): self.flush() |
400 |
|
self.getDataset().append(value) |
401 |
|
if self.debug(): print "Debug: %s: new time node %e has been added."%(self,value) |
402 |
|
|
403 |
|
# ============================================ |
404 |
|
class TimeSeriesShift(TimeSeries): |
405 |
|
"""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""" |
406 |
|
def __init__(self,time_serie,shift=1): |
407 |
|
if shift<0: |
408 |
|
dsc="(%s)<<%d"%(time_serie,-shift) |
409 |
|
else: |
410 |
|
dsc="(%s)>>%d"%(time_serie,shift) |
411 |
|
self.__controler=time_serie.getControler() |
412 |
|
TimeSeries.__init__(self,TimeSeriesDataset(time_serie.getDataset(),-shift,time_serie.debug(),"buffer view to "+dsc),\ |
413 |
|
time_serie.debug(),dsc) |
414 |
|
def getControler(self): |
415 |
|
return self.__controler |
416 |
|
|
417 |
|
class TimeSeriesSum(TimeSeriesFilter): |
418 |
|
"""adds two TimeSeries""" |
419 |
|
def __init__(self,time_serie_1,time_serie_2): |
420 |
|
dsc="(%s)+(%s)"%(time_serie_1,time_serie_2) |
421 |
|
dbg=time_serie_1.debug() or time_serie_2.debug() |
422 |
|
cntrl=time_serie_1.getControler() |
423 |
|
if not cntrl==time_serie_2.getControler(): |
424 |
|
raise ValueError("TimeSeriesSum: %s and %s have different controler."%(time_serie_1,time_serie_2)) |
425 |
|
id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum()) |
426 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
427 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
428 |
|
[time_serie_1,time_serie_2],0,0,dbg,dsc) |
429 |
|
|
430 |
|
def update(self,start,end): |
431 |
|
self.append(self.getArgumentDataset(0)[start:end]+self.getArgumentDataset(1)[start:end]) |
432 |
|
|
433 |
|
class TimeSeriesAddScalar(TimeSeriesFilter): |
434 |
|
"""adds a single value to a TimeSeries""" |
435 |
|
def __init__(self,time_serie,scalar): |
436 |
|
dsc="(%s)+(%s)"%(time_serie,scalar) |
437 |
|
dbg=time_serie.debug() |
438 |
|
cntrl=time_serie.getControler() |
439 |
|
id_first_datum=time_serie.getIdOfFirstDatum() |
440 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
441 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
442 |
|
[time_serie],0,0,dbg,dsc) |
443 |
|
self.__scalar=scalar |
444 |
|
|
445 |
|
def update(self,start,end): |
446 |
|
self.append(self.getArgumentDataset(0)[start:end]+self.__scalar) |
447 |
|
|
448 |
|
class TimeSeriesMult(TimeSeriesFilter): |
449 |
|
"""multiplies two TimeSeries""" |
450 |
|
def __init__(self,time_serie_1,time_serie_2): |
451 |
|
dsc="(%s)*(%s)"%(time_serie_1,time_serie_2) |
452 |
|
dbg=time_serie_1.debug() or time_serie_2.debug() |
453 |
|
cntrl=time_serie_1.getControler() |
454 |
|
if not cntrl==time_serie_2.getControler(): |
455 |
|
raise ValueError("TimeSeriesMult: %s and %s have different controler."%(time_serie_1,time_serie_2)) |
456 |
|
id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum()) |
457 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
458 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
459 |
|
[time_serie_1,time_serie_2],0,0,dbg,dsc) |
460 |
|
|
461 |
|
def update(self,start,end): |
462 |
|
self.append(self.getArgumentDataset(0)[start:end]*self.getArgumentDataset(1)[start:end]) |
463 |
|
|
464 |
|
class TimeSeriesMultScalar(TimeSeriesFilter): |
465 |
|
"""multiplies a TimeSeries with a single value""" |
466 |
|
def __init__(self,time_serie,scalar): |
467 |
|
dsc="(%s)*%s"%(time_serie,scalar) |
468 |
|
dbg=time_serie.debug() |
469 |
|
cntrl=time_serie.getControler() |
470 |
|
id_first_datum=time_serie.getIdOfFirstDatum() |
471 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
472 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
473 |
|
[time_serie],0,0,dbg,dsc) |
474 |
|
self.__scalar=scalar |
475 |
|
|
476 |
|
def update(self,start,end): |
477 |
|
self.append(self.getArgumentDataset(0)[start:end]*self.__scalar) |
478 |
|
|
479 |
|
class TimeSeriesDiv(TimeSeriesFilter): |
480 |
|
"""divides two TimeSeries""" |
481 |
|
def __init__(self,time_serie_1,time_serie_2): |
482 |
|
dsc="(%s)/(%s)"%(time_serie_1,time_serie_2) |
483 |
|
dbg=time_serie_1.debug() or time_serie_2.debug() |
484 |
|
cntrl=time_serie_1.getControler() |
485 |
|
if not cntrl==time_serie_2.getControler(): |
486 |
|
raise ValueError("TimeSeriesDiv: %s and %s have different controler."%(time_serie_1,time_serie_2)) |
487 |
|
id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum()) |
488 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
489 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
490 |
|
[time_serie_1,time_serie_2],0,0,dbg,dsc) |
491 |
|
|
492 |
|
def update(self,start,end): |
493 |
|
self.append(self.getArgumentDataset(0)[start:end]/self.getArgumentDataset(1)[start:end]) |
494 |
|
|
495 |
|
class TimeSeriesDivScalar(TimeSeriesFilter): |
496 |
|
"""divides a scalar be a TimeSerie""" |
497 |
|
def __init__(self,time_serie,scalar): |
498 |
|
dsc="(%s)/(%s)"%(scalar,time_serie) |
499 |
|
dbg=time_serie.debug() |
500 |
|
cntrl=time_serie.getControler() |
501 |
|
id_first_datum=time_serie.getIdOfFirstDatum() |
502 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
503 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
504 |
|
[time_serie],0,0,dbg,dsc) |
505 |
|
self.__scalar=scalar |
506 |
|
|
507 |
|
def update(self,start,end): |
508 |
|
self.append(self.__scalar/self.getArgumentDataset(0)[start:end]) |
509 |
|
|
510 |
|
class TimeSeriesPower(TimeSeriesFilter): |
511 |
|
"""raise one TimeSeries to the power of an other TimeSeries""" |
512 |
|
def __init__(self,time_serie_1,time_serie_2): |
513 |
|
dsc="(%s)**(%s)"%(time_serie_1,time_serie_2) |
514 |
|
dbg=time_serie_1.debug() or time_serie_2.debug() |
515 |
|
cntrl=time_serie_1.getControler() |
516 |
|
if not cntrl==time_serie_2.getControler(): |
517 |
|
raise ValueError("TimeSeriesPower: %s and %s have different controler."%(time_serie_1,time_serie_2)) |
518 |
|
id_first_datum=max(time_serie_1.getIdOfFirstDatum(),time_serie_2.getIdOfFirstDatum()) |
519 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
520 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie_1.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
521 |
|
[time_serie_1,time_serie_2],0,0,dbg,dsc) |
522 |
|
|
523 |
|
def update(self,start,end): |
524 |
|
self.append(self.getArgumentDataset(0)[start:end]**self.getArgumentDataset(1)[start:end]) |
525 |
|
|
526 |
|
class TimeSeriesPowerScalar(TimeSeriesFilter): |
527 |
|
"""raises a TimeSerie to the power of a scalar""" |
528 |
|
def __init__(self,time_serie,scalar): |
529 |
|
dsc="(%s)**(%s)"%(time_serie,scalar) |
530 |
|
dbg=time_serie.debug() |
531 |
|
cntrl=time_serie.getControler() |
532 |
|
id_first_datum=time_serie.getIdOfFirstDatum() |
533 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
534 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
535 |
|
[time_serie],0,0,dbg,dsc) |
536 |
|
self.__scalar=scalar |
537 |
|
|
538 |
|
def update(self,start,end): |
539 |
|
self.append(self.getArgumentDataset(0)[start:end]**self.__scalar) |
540 |
|
|
541 |
|
class Exp(TimeSeriesFilter): |
542 |
|
"""""" |
543 |
|
def __init__(self,time_serie): |
544 |
|
dsc="exp(%s)"%(time_serie) |
545 |
|
dbg=time_serie.debug() |
546 |
|
cntrl=time_serie.getControler() |
547 |
|
id_first_datum=time_serie.getIdOfFirstDatum() |
548 |
|
TimeSeriesFilter.__init__(self,cntrl, \ |
549 |
|
TimeSeriesBuffer(cntrl.getBufferSize(),time_serie.getNumComponents(),DEFAULT_FLOAT_TYPE,id_first_datum,dbg,"buffer for "+dsc), \ |
550 |
|
[time_serie],0,0,dbg,dsc) |
551 |
|
|
552 |
def processBuffer(self): |
def update(self,start,end): |
553 |
if self.getNumNodesInBuffer()>0: |
self.append(numarray.exp(self.getArgumentDataset(0)[start:end])) |
|
for i in self.__updates: |
|
|
if self.debug(): print "Debug: %s: update for %s started"%(self,i) |
|
|
if i.getBufferOverlapNeededForUpdate()>self.getBufferOverlap(): |
|
|
s=self.getFirstNodeOfBufferInCache() |
|
|
l=self.getNumNodesInBuffer() |
|
|
else: |
|
|
s=self.getFirstNodeOfBufferInCache()-i.getBufferOverlapNeededForUpdate() |
|
|
l=self.getNumNodesInBuffer()+i.getBufferOverlapNeededForUpdate() |
|
|
i.update(self.__node_cache[s:s+l],self.__value_cache[s:s+l]) |
|
|
self.__firstNodeInBuffer+=self.__numNodesInBuffer |
|
|
self.__numNodesInBuffer=0 |
|
|
self.__buffer_overlap=self.getMaxBufferOverlap() |
|
|
if self.debug(): print "Debug: %s: first node in buffer is now %d"%(self,self.__firstNodeInBuffer) |
|
554 |
|
|
555 |
|
class TimeSeriesCumulativeSum(TimeSeriesFilter): |
556 |
|
"""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""" |
557 |
|
def __init__(self,time_series): |
558 |
|
TimeSeriesFilter.__init__(self,1) |
559 |
|
TimeSeries.__init__(self,frame_size=time_series.getDatasetSize(),buffer_size=time_series.getBufferSize(), \ |
560 |
|
numComponents=time_series.getNumComponents()) |
561 |
|
self.setDebug(time_series.debug()) |
562 |
|
time_series.checkInUpdate(self) |
563 |
|
self.__integral=0 |
564 |
|
|
565 |
|
def __str__(self): |
566 |
|
return "timeseries.Integrator" |
567 |
|
|
568 |
|
def update(self,times,data): |
569 |
|
l=times.shape[0] |
570 |
|
self.append(times[1:l],(data[0:l-1]+data[1:l])/2.*(times[1:l]-times[0:l-1])) |
571 |
|
|
572 |
|
|
573 |
class TimeSeriesCollector(TimeSeries): |
class TimeSeriesCollector(TimeSeries): |
574 |
"""TimeSeriesCollector collects values at time nodes""" |
"""timeseries.Collector collects data at time nodes""" |
575 |
def __init__(self): |
def __init__(self): |
576 |
TimeSeries.__init__(self) |
TimeSeries.__init__(self) |
577 |
|
|
578 |
def __str__(self): |
def __str__(self): |
579 |
return "TimeSeriesCollector" |
return "timeseries.Collector" |
580 |
|
|
581 |
def add(self,time_mark,value): |
def add(self,time_mark,value): |
582 |
"""adds the value at time time_mark to the time series""" |
"""adds the value at time time_mark to the time series""" |
588 |
d=l.strip().split(seperator) |
d=l.strip().split(seperator) |
589 |
self.add(float(d[0]),float(d[1])) |
self.add(float(d[0]),float(d[1])) |
590 |
|
|
591 |
class TimeSeriesIntegrator(TimeSeries,TimeSeriesFilter): |
def Differential(time_series): |
592 |
def __init__(self,time_series): |
"""calculates the derivative Dv of the time series v: |
593 |
TimeSeriesFilter.__init__(self,1) |
|
594 |
TimeSeries.__init__(self,buffer_size=time_series.getBufferSize(),cache_size=time_series.getCacheSize(), \ |
Dv[n]=(v[n]-v[n-1])/(t[n]-t[n-1]) |
|
numComponents=time_series.getNumComponents()) |
|
|
self.setDebug(time_series.debug()) |
|
|
time_series.checkInUpdate(self) |
|
|
self.__integral=0 |
|
595 |
|
|
596 |
def __str__(self): |
""" |
597 |
return "TimeSeriesIntegrator" |
return (time_series<<1-time_series)/(time_series.getControler()<<1-time_series.getControler()) |
598 |
|
|
599 |
def update(self,times,values): |
def Integral(time_series): |
600 |
l=times.shape[0] |
"""calculates the intagral Iv of the time series v using the trapozidal rule: |
|
self.append(times[1:l],(values[0:l-1]+values[1:l])/2.*(times[1:l]-times[0:l-1])) |
|
601 |
|
|
602 |
|
Iv[n]=sum_i<n (v[n]+v[n-1])/2*(t[n]-t[n-1]) |
603 |
|
|
604 |
class TimeSeriesDifferential(TimeSeries,TimeSeriesFilter): |
""" |
605 |
def __init__(self,time_series): |
return TimeSeriesCumulativeSum((time_series<<1+time_series)/2.*(time_series.getControler()-(time_series.getControler<<1)),0.) |
|
TimeSeriesFilter.__init__(self,1) |
|
|
TimeSeries.__init__(self,buffer_size=time_series.getBufferSize(),cache_size=time_series.getCacheSize(), \ |
|
|
numComponents=time_series.getNumComponents()) |
|
|
self.setDebug(time_series.debug()) |
|
|
time_series.checkInUpdate(self) |
|
|
|
|
|
def __str__(self): |
|
|
return "TimeSeriesDifferential" |
|
606 |
|
|
|
def update(self,times,values): |
|
|
l=times.shape[0] |
|
|
self.append((times[0:l-1]+times[1:l])/2,(values[0:l-1]-values[1:l])/(times[0:l-1]-times[1:l])) |
|
607 |
|
|
608 |
class TimeSeriesViewer(TimeSeriesFilter): |
class TimeSeriesViewer(TimeSeriesFilter): |
609 |
def __init__(self,time_series): |
def __init__(self,time_series): |
611 |
time_series.checkInUpdate(self) |
time_series.checkInUpdate(self) |
612 |
|
|
613 |
def __str__(self): |
def __str__(self): |
614 |
return "TimeSeriesViewer" |
return "timeseries.Viewer" |
615 |
|
|
616 |
def update(self,times,values): |
def update(self,times,data): |
617 |
for i in range(times.shape[0]): print "[%s: %s]"%(times[i],values[i]) |
for i in range(times.shape[0]): print "[%s: %s]"%(times[i],data[i]) |
618 |
|
|
619 |
class TimeSeriesWriter(TimeSeriesFilter): |
class TimeSeriesWriter(TimeSeriesFilter): |
620 |
def __init__(self,time_series,ostream,seperator=","): |
def __init__(self,time_series,ostream,seperator=","): |
625 |
self.__seperator=seperator |
self.__seperator=seperator |
626 |
|
|
627 |
def __str__(self): |
def __str__(self): |
628 |
return "TimeSeriesWriter" |
return "timeseries.Writer" |
629 |
|
|
630 |
def update(self,times,values): |
def update(self,times,data): |
631 |
for i in range(times.shape[0]): self.__ostream.writelines("%s,%s\n"%(times[i],values[i])) |
for i in range(times.shape[0]): self.__ostream.writelines("%s,%s\n"%(times[i],data[i])) |
632 |
|
|
633 |
# test |
# test |
634 |
|
|
635 |
if __name__=="__main__": |
if __name__=="__main__": |
636 |
|
# tests the interfaces to data sets: |
637 |
|
print "Test of Datasets:" |
638 |
|
print "=================" |
639 |
|
bf=TimeSeriesBuffer(buffer_size=5,numComponents=1,debug=True,description="TestBuffer") |
640 |
|
bfv_l=TimeSeriesDataset(bf,offset=1,debug=True,description="offset 1") |
641 |
|
bfv_r=TimeSeriesDataset(bf,offset=-1,debug=True,description="offset -1") |
642 |
|
bf.append([1.,2.,3.,4.]) |
643 |
|
print "should be all 2. :",bfv_l[0] |
644 |
|
print bf[1] |
645 |
|
print bfv_r[2] |
646 |
|
bf.append([5.,6.,7.]) |
647 |
|
print "should be all 5. :",bfv_l[3],bf[4],bfv_r[5] |
648 |
|
print "should be all 6. :",bfv_l[4],bf[5],bfv_r[6] |
649 |
|
print "should be all 7. :",bfv_l[5],bf[6],bfv_r[7] |
650 |
|
print "should be all [6., 7.] :",bfv_l[4:6],bf[5:7],bfv_r[6:8] |
651 |
|
|
652 |
|
print "Test of Controler" |
653 |
|
print "=================" |
654 |
|
b=Controler(buffer_size=15,debug=True) |
655 |
|
s3=b>>3 |
656 |
|
s1=b>>1 |
657 |
|
s_3=b<<3 |
658 |
|
sum=(s_3+b)+(b+s3) |
659 |
|
|
660 |
|
for i in range(30): |
661 |
|
b.newTimeNode(i*1.) |
662 |
|
b.flush() |
663 |
|
print "should be all 28. :",s_3.getDataset()[25],b.getDataset()[28],s3.getDataset()[31] |
664 |
|
print "should be all 29. :",s_3.getDataset()[26],b.getDataset()[29],s3.getDataset()[32] |
665 |
|
print "should be all 96. :",sum.getDataset()[24] |
666 |
|
|
667 |
|
print "Test of operators" |
668 |
|
print "=================" |
669 |
|
b=Controler(buffer_size=15,debug=True) |
670 |
|
b1=b<<1 |
671 |
|
a=b+b1 |
672 |
|
a_s=b1+1. |
673 |
|
s_a=1.+b1 |
674 |
|
d=b-b1 |
675 |
|
d_s=b1-1. |
676 |
|
s_d=1.-b1 |
677 |
|
m=b*b1 |
678 |
|
m_s=b1*2. |
679 |
|
s_m=2.*b1 |
680 |
|
dv=b/b1 |
681 |
|
dv_s=b1/2. |
682 |
|
s_dv=2./b1 |
683 |
|
p=b**b1 |
684 |
|
p_s=b1**2. |
685 |
|
s_p=2.**b1 |
686 |
|
pb=+b |
687 |
|
mb=-b |
688 |
|
for i in range(30): |
689 |
|
b.newTimeNode(i*1.) |
690 |
|
b.flush() |
691 |
|
print "a[28] should be %e: %e"%(28.+29.,a[28]) |
692 |
|
print "a_s[28] should be %e: %e"%(29.+1.,a_s[28]) |
693 |
|
print "s_a[28] should be %e: %e"%(29.+1.,s_a[28]) |
694 |
|
print "d[28] should be %e: %e"%(28.-29.,d[28]) |
695 |
|
print "d_s[28] should %e: %e"%(29.-1.,d_s[28]) |
696 |
|
print "s_d[28] should %e: %e"%(1.-29.,s_d[28]) |
697 |
|
print "m[28] should be %e: %e"%(28.*29.,m[28]) |
698 |
|
print "m_s[28] should be %e: %e"%(29.*2.,m_s[28]) |
699 |
|
print "s_m[28] should be %e: %e"%(29.*2.,s_m[28]) |
700 |
|
print "dv[28] should be %e: %e"%(28./29.,dv[28]) |
701 |
|
print "dv_s[28] should be %e: %e"%(29./2.,dv_s[28]) |
702 |
|
print "s_dv[28] should be %e: %e"%(2./29.,s_dv[28]) |
703 |
|
print "p[28] should be %e: %e"%(28.**29.,p[28]) |
704 |
|
print "p_s[28] should be %e: %e"%(29.**2,p_s[28]) |
705 |
|
print "s_p[28] should be %e: %e"%(2.**29.,s_p[28]) |
706 |
|
print "pb[28] should be %e: %e"%(28.,pb[28]) |
707 |
|
print "mb[28] should be %e: %e"%(-28.,mb[28]) |
708 |
|
|
709 |
c=TimeSeriesCollector() |
1/0 |
710 |
|
c=TimeSeriesCollector(b) |
711 |
c.setDebugOn() |
c.setDebugOn() |
712 |
ii=TimeSeriesIntegrator(c) |
ii=TimeSeriesIntegrator(c) |
713 |
d=TimeSeriesDifferential(c) |
d=TimeSeriesDifferential(c) |
715 |
w=TimeSeriesWriter(d,file("test.csv","w")) |
w=TimeSeriesWriter(d,file("test.csv","w")) |
716 |
|
|
717 |
for i in range(15): |
for i in range(15): |
718 |
c.add(i*1.,i+1.) |
b.newTime(i*1.) |
719 |
|
c.add(i+1.) |
720 |
|
|