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", "sum"]
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", "sum")
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.accumulations={}
41 self.occured={}
42
43 self.setSplitting(splitThres=splitThres,splitFun=splitFun)
44
52
54 """Sets the parameters for splitting"""
55 if splitThres:
56 self.thres=splitThres
57 if (self.thres % 2)==1:
58 self.thres+=1
59
60 if splitFun:
61 self.fun=splitFun
62 elif not self.fun:
63 self.fun=mean
64
66 """@param deflt: default value to be used"""
67 self.defaultValue=float(deflt)
68
69 - def setExtend(self,mode):
70 """@param mode: whether or not to extend the timeline by copying or setting the default value"""
71 self.extendCopy=mode
72
74 """Number of elements in timelines"""
75 return len(self.times)
76
78 """Sets the time. If time is new all the timelines are extended
79 @param time: the new current time"""
80
81 dTime=float(time)
82
83 if dTime!=self.cTime:
84 self.cTime=dTime
85 self.times.append(self.cTime)
86 for v in self.values.values():
87 if len(v)>0 and self.extendCopy:
88 val=v[-1]
89 else:
90 val=self.defaultValue
91 v.append(val)
92 if self.thres:
93 if len(self.times)==self.thres:
94 self.times=self.split(self.times,min)
95 for k in self.values.keys():
96 self.values[k]=self.split(self.values[k],self.fun)
97 self.occured={}
98
99 - def split(self,array,func):
100 """Makes the array smaller by joining every two points
101 @param array: the field to split
102 @param func: The function to use for joining two points"""
103
104 newLen=len(array)/2
105 newArray=[0.]*newLen
106
107 for i in range(newLen):
108 newArray[i]=func(array[2*i],array[2*i+1])
109
110 return newArray
111
113 """@return: A list of the time values"""
114 return self.times
115
117 """@return: A list with the names of the safed values"""
118 return self.values.keys()
119
121 """Gets a timeline
122 @param name: Name of the timeline
123 @return: List with the values"""
124
125 if not self.values.has_key(name):
126 self.values[name]=self.nr()*[self.defaultValue]
127 return self.values[name]
128
130 """Sets the value of the last element in a timeline
131 @param name: name of the timeline
132 @param value: the last element"""
133 data=self.getValues(name)
134 val=float(value)
135 if len(data)>0:
136 if not self.occured.has_key(name):
137 newValue=val
138 self.occured[name]=1
139 else:
140 oldValue=data[-1]
141 n=self.occured[name]
142 self.occured[name]+=1
143 accu=self.accumulation
144 if name in self.accumulations:
145 accu=self.accumulations[name]
146 if accu=="first":
147 newValue=oldValue
148 elif accu=="last":
149 newValue=val
150 elif accu=="max":
151 newValue=max(val,oldValue)
152 elif accu=="min":
153 newValue=min(val,oldValue)
154 elif accu=="sum":
155 newValue=val+oldValue
156 elif accu=="average":
157 newValue=(n*oldValue+val)/(n+1)
158 else:
159 error("Unimplemented accumulator",accu,"for",name)
160
161 data[-1]=newValue
162