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
9 """A directory of sampled times"""
10
11 - def __init__(self,case,dirName="samples"):
12 """@param case: The case directory
13 @param dirName: Name of the directory with the samples"""
14
15 self.dir=path.join(case,dirName)
16 self.times=[]
17
18 for d in listdir(self.dir):
19 if path.isdir(path.join(self.dir,d)):
20 try:
21 v=float(d)
22 self.times.append(d)
23 except ValueError,e:
24 pass
25
26 self.times.sort(self.sorttimes)
27
29 for t in self.times:
30 yield SampleTime(self.dir,t)
31
37
39 return time in self.times
40
42 """Sort function for the solution files"""
43 if(float(x)==float(y)):
44 return 0
45 elif float(x)<float(y):
46 return -1
47 else:
48 return 1
49
62
75
76 - def getData(self,line=None,value=None,time=None):
77 """Get Sample sets
78 @param line: name of the line. All
79 if unspecified
80 @param value: name of the sampled value. All
81 if unspecified
82 @param time: times for which the samples are to be got. All
83 if unspecified"""
84
85 if line==None:
86 line=self.lines()
87 if value==None:
88 value=self.values()
89 if time==None:
90 time=self.times
91
92 sets=[]
93
94 for t in time:
95 for l in line:
96 for v in value:
97 try:
98 d=self[t][(l,v)]
99 sets.append(d)
100 except KeyError:
101 pass
102
103 return sets
104
106 """A directory with one sampled time"""
107
109 """@param sDir: The sample-dir
110 @param time: the timename"""
111
112 self.dir=path.join(sDir,time)
113 self.lines=[]
114 self.values=[]
115
116 for f in listdir(self.dir):
117 nm=self.extractLine(f)
118 vals=self.extractValues(f)
119 if nm not in self.lines:
120 self.lines.append(nm)
121 for v in vals:
122 if v not in self.values:
123 self.values.append(v)
124
125 self.lines.sort()
126 self.values.sort()
127
128 self.cache={}
129
131 """Extract the name of the line from a filename"""
132 return fName.split("_")[0]
133
135 """Extracts the names of the contained Values from a filename"""
136 tmp=fName.split("_")[1:]
137 tmp[-1]=tmp[-1].split(".")[0]
138
139 return tmp
140
142 """Get the data for a value on a specific line
143 @param key: A tuple with the line-name and the value-name
144 @returns: A SampleData-object"""
145
146 if key in self.cache:
147 return self.cache[key]
148
149 line,val=key
150 if line not in self.lines or val not in self.values:
151 raise KeyError,key
152
153 fName=None
154
155 for f in listdir(self.dir):
156 if line==self.extractLine(f) and val in self.extractValues(f):
157 fName=f
158 break
159
160 if fName==None:
161 error("Can't find a file for the line",line,"and the value",val,"in the directory",self.dir)
162
163 first=True
164 col0=[]
165 data=[]
166
167 for l in open(path.join(self.dir,fName)).readlines():
168 tmp=l.split()
169 if first:
170 first=False
171 vector,index=self.determineIndex(fName,val,tmp)
172
173 col0.append(float(tmp[0]))
174 if vector:
175 data.append(tuple(map(float,tmp[index:index+3])))
176 else:
177 data.append(float(tmp[index]))
178
179 self.cache[key]=SampleData(fName=path.join(self.dir,fName),
180 name=val,
181 index=index,
182 col0=col0,
183 data=data)
184
185 return self.cache[key]
186
188 """Determines the index of the data from the filename and a dataset
189 @param fName: name of the file
190 @param vName: Name of the quantity
191 @param data: A list with the data
192 @returns: A tuple of a boolean (whether the data is supposed to be
193 a vector or a scalar) and an integer (the index of the data set -
194 or the first component of the vector"""
195
196 vals=self.extractValues(fName)
197 if len(vals)+1==len(data):
198 vector=False
199 elif len(vals)*3+1==len(data):
200 vector=True
201 else:
202 error("The data in file",fName,"is neither vector nor scalar:",data)
203
204 index=vals.index(vName)
205 if vector:
206 index=index*3+1
207 else:
208 index=index+1
209
210 return vector,index
211
213 """Data from a sample-set"""
214
215 - def __init__(self,fName,name,index,col0,data):
216 """@param fName: Name of the file
217 @param name: Name of the value
218 @param index: Index of the data in the file
219 @param col0: Values that identify the data (the location)
220 @param data: The actual data"""
221
222 self.file=fName
223 self.col0=col0
224 self.data=data
225 self.name=name
226 self.index=index
227
229 if self.isVector():
230 vect=" (vector)"
231 else:
232 vect=""
233
234 return "SampleData of %s%s on %s at t=%s " % (self.name,vect,self.line(),self.time())
235
237 """Get the line of the sample"""
238 return path.basename(self.file).split("_")[0]
239
241 """Get the time of the sample (as a string)"""
242 return path.basename(path.dirname(self.file))
243
245 """Is this vector or scalar data?"""
246 if type(self.data[0])==tuple:
247 return True
248 else:
249 return False
250
251 - def range(self,component=None):
252 """Range of the data"""
253 data=self.component(component)
254
255 return (min(data),max(data))
256
258 """Range of the data domain"""
259 return (min(self.col0),max(self.col0))
260
262 """Return the data as a number of single scalars.
263 @param component: If None for vectors the absolute value is taken.
264 else the number of the component"""
265
266 if self.isVector():
267 data=[]
268 if component==None:
269 for d in self.data:
270 data.append(math.sqrt(d[0]*d[0]+d[1]*d[1]+d[2]*d[2]))
271 else:
272 if component<0 or component>=len(self.data[0]):
273 error("Requested component",component,"does not fit the size of the data",len(self.data[0]))
274 for d in self.data:
275 data.append(d[component])
276 return data
277 else:
278 return self.data
279