1
2 """Working with a directory of samples"""
3
4 from os import path,listdir
5 from PyFoam.Error import error
6 import math
7
8 from PyFoam.Basics.SpreadsheetData import SpreadsheetData
9
11 """A directory of sampled times"""
12
13 - def __init__(self,case,dirName="samples"):
14 """@param case: The case directory
15 @param dirName: Name of the directory with the samples"""
16
17 self.dir=path.join(case,dirName)
18 self.times=[]
19
20 for d in listdir(self.dir):
21 if path.isdir(path.join(self.dir,d)):
22 try:
23 v=float(d)
24 self.times.append(d)
25 except ValueError,e:
26 pass
27
28 self.times.sort(self.sorttimes)
29
31 return len(self.times)
32
34 for t in self.times:
35 yield SampleTime(self.dir,t)
36
42
44 return time in self.times
45
47 """Sort function for the solution files"""
48 if(float(x)==float(y)):
49 return 0
50 elif float(x)<float(y):
51 return -1
52 else:
53 return 1
54
67
80
81 - def getData(self,line=None,value=None,time=None,note=""):
82 """Get Sample sets
83 @param line: name of the line. All
84 if unspecified
85 @param value: name of the sampled value. All
86 if unspecified
87 @param time: times for which the samples are to be got. All
88 if unspecified
89 @param note: A short annotation (for plots)"""
90
91 if line==None:
92 line=self.lines()
93 if value==None:
94 value=self.values()
95 if time==None:
96 time=self.times
97
98 sets=[]
99
100 for t in time:
101 for l in line:
102 for v in value:
103 try:
104 d=self[t][(l,v)]
105 d.note=note
106 sets.append(d)
107 except KeyError:
108 pass
109
110 return sets
111
113 """A directory with one sampled time"""
114
136
138 """Extract the name of the line from a filename"""
139 return fName.split("_")[0]
140
142 """Extracts the names of the contained Values from a filename"""
143 tmp=fName.split("_")[1:]
144 tmp[-1]=tmp[-1].split(".")[0]
145
146 return tmp
147
149 """Get the data for a value on a specific line
150 @param key: A tuple with the line-name and the value-name
151 @returns: A SampleData-object"""
152
153 if key in self.cache:
154 return self.cache[key]
155
156 line,val=key
157 if line not in self.lines or val not in self.values:
158 raise KeyError,key
159
160 fName=None
161
162 for f in listdir(self.dir):
163 if line==self.extractLine(f) and val in self.extractValues(f):
164 fName=f
165 break
166
167 if fName==None:
168 error("Can't find a file for the line",line,"and the value",val,"in the directory",self.dir)
169
170 first=True
171 col0=[]
172 data=[]
173
174 for l in open(path.join(self.dir,fName)).readlines():
175 tmp=l.split()
176 if first:
177 first=False
178 vector,index=self.determineIndex(fName,val,tmp)
179
180 col0.append(float(tmp[0]))
181 try:
182 if vector:
183 data.append(tuple(map(float,tmp[index:index+3])))
184 else:
185 data.append(float(tmp[index]))
186 except IndexError:
187 raise KeyError(key)
188
189 self.cache[key]=SampleData(fName=path.join(self.dir,fName),
190 name=val,
191 index=index,
192 col0=col0,
193 data=data)
194
195 return self.cache[key]
196
198 """Determines the index of the data from the filename and a dataset
199 @param fName: name of the file
200 @param vName: Name of the quantity
201 @param data: A list with the data
202 @returns: A tuple of a boolean (whether the data is supposed to be
203 a vector or a scalar) and an integer (the index of the data set -
204 or the first component of the vector"""
205
206 vals=self.extractValues(fName)
207 if len(vals)+1==len(data):
208 vector=False
209 elif len(vals)*3+1==len(data):
210 vector=True
211 else:
212 error("The data in file",fName,"is neither vector nor scalar:",data)
213
214 index=vals.index(vName)
215 if vector:
216 index=index*3+1
217 else:
218 index=index+1
219
220 return vector,index
221
223 """Data from a sample-set"""
224
225 - def __init__(self,fName,name,index,col0,data,note=""):
226 """@param fName: Name of the file
227 @param name: Name of the value
228 @param index: Index of the data in the file
229 @param col0: Values that identify the data (the location)
230 @param data: The actual data"""
231
232 self.file=fName
233 self.col0=col0
234 self.data=data
235 self.name=name
236 self.index=index
237 self.note=note
238
240 if self.isVector():
241 vect=" (vector)"
242 else:
243 vect=""
244
245 return "SampleData of %s%s on %s at t=%s " % (self.name,vect,self.line(),self.time())
246
248 """Get the line of the sample"""
249 return path.basename(self.file).split("_")[0]
250
252 """Get the time of the sample (as a string)"""
253 return path.basename(path.dirname(self.file))
254
256 """Is this vector or scalar data?"""
257 if type(self.data[0])==tuple:
258 return True
259 else:
260 return False
261
262 - def range(self,component=None):
263 """Range of the data"""
264 data=self.component(component)
265
266 return (min(data),max(data))
267
269 """Range of the data domain"""
270 return (min(self.col0),max(self.col0))
271
273 """Return the data as a number of single scalars.
274 @param component: If None for vectors the absolute value is taken.
275 else the number of the component"""
276
277 if self.isVector():
278 data=[]
279 if component==None:
280 for d in self.data:
281 data.append(math.sqrt(d[0]*d[0]+d[1]*d[1]+d[2]*d[2]))
282 else:
283 if component<0 or component>=len(self.data[0]):
284 error("Requested component",component,"does not fit the size of the data",len(self.data[0]))
285 for d in self.data:
286 data.append(d[component])
287 return data
288 else:
289 return self.data
290
311