1
2 """Collection of array of timelines"""
3
4 from PyFoam.Error import error
5
7 """Mean value of a and b"""
8 return 0.5*(a+b)
9
11 """Absolute Maximum of a and b with the sign preserved"""
12 if a<0. or b<0.:
13 return min(a,b)
14 else:
15 return max(a,b)
16
18
19 possibleAccumulations=["first", "last", "min", "max", "average"]
20
21 - def __init__(self,deflt=0.,extendCopy=False,splitThres=None,splitFun=None,accumulation="first"):
22 """@param deflt: default value for timelines if none has been defined before
23 @param extendCopy: Extends the timeline by cpying the last element
24 @param splitThres: Threshold after which the number of points is halved
25 @param splitFun: Function that is used for halving. If none is specified the mean function is used
26 @param accumulation: if more than one value is given at any time-step, how to accumulate them (possible values: "first", "last", "min", "max", "average")
27 """
28
29 self.cTime=None
30 self.times=[]
31 self.values={}
32 self.setDefault(deflt)
33 self.setExtend(extendCopy)
34 self.thres=None
35 self.fun=None
36
37 if not (accumulation in TimeLineCollection.possibleAccumulations):
38 error("Value",accumulation,"not in list of possible values:",TimeLineCollection.possibleAccumulations)
39 self.accumulation=accumulation
40 self.occured={}
41
42 self.setSplitting(splitThres=splitThres,splitFun=splitFun)
43
45 """Sets the parameters for splitting"""
46 if splitThres:
47 self.thres=splitThres
48 if (self.thres % 2)==1:
49 self.thres+=1
50
51 if splitFun:
52 self.fun=splitFun
53 elif not self.fun:
54 self.fun=mean
55
57 """@param deflt: default value to be used"""
58 self.defaultValue=float(deflt)
59
60 - def setExtend(self,mode):
61 """@param mode: whether or not to extend the timeline by copying or setting the default value"""
62 self.extendCopy=mode
63
65 """Number of elements in timelines"""
66 return len(self.times)
67
69 """Sets the time. If time is new all the timelines are extended
70 @param time: the new current time"""
71
72 dTime=float(time)
73
74 if dTime!=self.cTime:
75 self.cTime=dTime
76 self.times.append(self.cTime)
77 for v in self.values.values():
78 if len(v)>0 and self.extendCopy:
79 val=v[-1]
80 else:
81 val=self.defaultValue
82 v.append(val)
83 if self.thres:
84 if len(self.times)==self.thres:
85 self.times=self.split(self.times,mean)
86 for k in self.values.keys():
87 self.values[k]=self.split(self.values[k],self.fun)
88 self.occured={}
89
90 - def split(self,array,func):
91 """Makes the array smaller by joining every two points
92 @param array: the field to split
93 @param func: The function to use for joining two points"""
94
95 newLen=len(array)/2
96 newArray=[0.]*newLen
97
98 for i in range(newLen):
99 newArray[i]=func(array[2*i],array[2*i+1])
100
101 return newArray
102
104 """@return: A list of the time values"""
105 return self.times
106
108 """@return: A list with the names of the safed values"""
109 return self.values.keys()
110
112 """Gets a timeline
113 @param name: Name of the timeline
114 @return: List with the values"""
115
116 if not self.values.has_key(name):
117 self.values[name]=self.nr()*[self.defaultValue]
118 return self.values[name]
119
121 """Sets the value of the last element in a timeline
122 @param name: name of the timeline
123 @param value: the last element"""
124 data=self.getValues(name)
125 val=float(value)
126 if len(data)>0:
127 if not self.occured.has_key(name):
128 newValue=val
129 self.occured[name]=1
130 else:
131 oldValue=data[-1]
132 n=self.occured[name]
133 self.occured[name]+=1
134 if self.accumulation=="first":
135 newValue=oldValue
136 elif self.accumulation=="last":
137 newValue=val
138 elif self.accumulation=="max":
139 newValue=max(val,oldValue)
140 elif self.accumulation=="min":
141 newValue=min(val,oldValue)
142 elif self.accumulation=="average":
143 newValue=(n*oldValue+val)/(n+1)
144 else:
145 error("Unimplemented accumulator",self.accumulation)
146
147 data[-1]=newValue
148