1
2 """Working with a directory of timelines
3
4 Currently not optimal as it reads the files more often than necessary"""
5
6 from os import path,listdir
7 from glob import glob
8 from PyFoam.Error import error
9 import math
10
12 """A directory of sampled times"""
13
14 - def __init__(self,case,dirName="probes",writeTime=None):
15 """@param case: The case directory
16 @param dirName: Name of the directory with the timelines
17 @param writeTime: The write time-directory where the data in question is to be plotted"""
18
19 self.dir=path.join(case,dirName)
20 self.writeTimes=[]
21
22 nearest=None
23
24 for d in listdir(self.dir):
25 if path.isdir(path.join(self.dir,d)):
26 try:
27 v=float(d)
28 self.writeTimes.append(d)
29 if writeTime:
30 if nearest==None:
31 nearest=d
32 else:
33 if abs(float(writeTime)-v)<abs(float(writeTime)-float(nearest)):
34 nearest=d
35 except ValueError,e:
36 pass
37
38 self.writeTimes.sort(self.sorttimes)
39 if nearest==None:
40 self.usedTime=self.writeTimes[0]
41 else:
42 self.usedTime=nearest
43
44 self.dir=path.join(self.dir,self.usedTime)
45
46 self.values=[]
47 for v in listdir(self.dir):
48 if not TimelineValue(self.dir,v).isVector:
49 self.values.append(v)
50 self.allPositions=None
51
55
61
64
66 """Sort function for the solution files"""
67 if(float(x)==float(y)):
68 return 0
69 elif float(x)<float(y):
70 return -1
71 else:
72 return 1
73
75 """Returns all the found positions"""
76
77 if self.allPositions==None:
78 positions=[]
79 first=True
80
81 for t in self:
82 for v in t.positions:
83 if v not in positions:
84 if first:
85 positions.append(v)
86 else:
87 error("Found positions",t.positions,"are inconsistent with previous",positions)
88 if first:
89 self.positionIndex=t.positionIndex
90 first=False
91 self.allPositions=positions
92
93 return self.allPositions
94
96 """Return the range of possible times"""
97 minTime=1e80
98 maxTime=-1e80
99
100 for v in self:
101 mi,ma=v.timeRange()
102 minTime=min(mi,minTime)
103 maxTime=max(ma,maxTime)
104
105 return minTime,maxTime
106
108 """Get Timeline sets
109 @param value: name of the value. All
110 if unspecified
111 @param position: name of the position of the value. All
112 if unspecified"""
113
114 if value==None:
115 value=se<lf.values
116 if position==None:
117 position=self.positions()
118
119 sets=[]
120
121 for v in value:
122 for p in position:
123 sets.append((path.join(self.dir,v),v,p,self.positionIndex[self.positions().index(p)]))
124
125 return sets
126
127 - def getData(self,times,value=None,position=None):
128 """Get data that mstches the given times most closely
129 @param times: a list with times
130 @param value: name of the value. All
131 if unspecified
132 @param position: name of the position of the value. All
133 if unspecified"""
134
135 if value==None:
136 value=se<lf.values
137 if position==None:
138 position=self.positions()
139
140 sets=[]
141 posIndex=[]
142 for p in position:
143 posIndex.append(self.positions().index(p))
144
145 for v in value:
146 val=TimelineValue(self.dir,v)
147 data=val.getData(times)
148 for i,t in enumerate(times):
149 used=[]
150 for p in posIndex:
151 used.append(data[i][p])
152
153 sets.append((v,t,used))
154
155 return sets
156
158 """A file with one timelined value"""
159
161 """@param sDir: The timeline-dir
162 @param time: the timename"""
163
164 self.file=path.join(sDir,val)
165 poses=[]
166
167 self.isVector=False
168
169 data=open(self.file)
170 l1=data.readline()
171 if len(l1)<1 or l1[0]!='#':
172 error("Data file",self.file,"has no description of the fields")
173 l2=data.readline()
174 if l2[0]!='#':
175
176 poses=l1[1:].split()[1:]
177 firstData=l2
178 else:
179
180 l3=data.readline()
181 x=l1[1:].split()[1:]
182 y=l2[1:].split()[1:]
183 z=l3[1:].split()[1:]
184 for i in range(len(x)):
185 poses.append("(%s %s %s)" % (x[i],y[i],z[i]))
186 data.readline()
187 firstData=data.readline()
188
189 self.positions=[]
190 self.positionIndex=[]
191 if len(poses)+1==len(firstData.split()):
192
193 for i,v in enumerate(firstData.split()[1:]):
194 if abs(float(v))<1e40:
195 self.positions.append(poses[i])
196 self.positionIndex.append(i)
197 else:
198 self.isVector=True
199 for i,v in enumerate(firstData.split()[2::3]):
200 if abs(float(v))<1e40:
201 self.positions.append(poses[i])
202 self.positionIndex.append(i)
203
204 self.cache={}
205
207 """Range of times"""
208 lines=open(self.file).readlines()
209 for l in lines:
210 v=l.split()
211 if v[0][0]!='#':
212 minRange=float(v[0])
213 break
214 lines.reverse()
215 for l in lines:
216 v=l.split()
217 if len(v)>=len(self.positions)+1:
218 maxRange=float(v[0])
219 break
220
221 return minRange,maxRange
222
224 """Get the data values that are nearest to the actual times"""
225 dist=len(times)*[1e80]
226 data=len(times)*[len(self.positions)*[1e80]]
227
228 lines=open(self.file).readlines()
229
230 for l in lines:
231 v=l.split()
232 if v[0][0]!='#':
233 try:
234 time=float(v[0])
235 vals=v[1:]
236 for i,t in enumerate(times):
237 if abs(t-time)<dist[i]:
238 dist[i]=abs(t-time)
239 data[i]=vals
240 except ValueError:
241 pass
242 result=[]
243 for d in data:
244 tmp=[]
245 for v in d:
246 if abs(float(v))<1e40:
247 tmp.append(float(v))
248 result.append(tmp)
249
250 return result
251