Package PyFoam :: Package RunDictionary :: Module SampleDirectory
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.RunDictionary.SampleDirectory

  1  #  ICE Revision: $Id:$ 
  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   
10 -class SampleDirectory(object):
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
30 - def __len__(self):
31 return len(self.times)
32
33 - def __iter__(self):
34 for t in self.times: 35 yield SampleTime(self.dir,t)
36
37 - def __getitem__(self,time):
38 if time in self: 39 return SampleTime(self.dir,time) 40 else: 41 raise KeyError,time
42
43 - def __contains__(self,time):
44 return time in self.times
45
46 - def sorttimes(self,x,y):
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
55 - def lines(self):
56 """Returns all the found sample lines""" 57 58 lines=[] 59 60 for t in self: 61 for l in t.lines: 62 if l not in lines: 63 lines.append(l) 64 lines.sort() 65 66 return lines
67
68 - def values(self):
69 """Returns all the found sampled values""" 70 71 values=[] 72 73 for t in self: 74 for v in t.values: 75 if v not in values: 76 values.append(v) 77 values.sort() 78 79 return values
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
112 -class SampleTime(object):
113 """A directory with one sampled time""" 114
115 - def __init__(self,sDir,time):
116 """@param sDir: The sample-dir 117 @param time: the timename""" 118 119 self.dir=path.join(sDir,time) 120 self.lines=[] 121 self.values=[] 122 123 for f in listdir(self.dir): 124 nm=self.extractLine(f) 125 vals=self.extractValues(f) 126 if nm not in self.lines: 127 self.lines.append(nm) 128 for v in vals: 129 if v not in self.values: 130 self.values.append(v) 131 132 self.lines.sort() 133 self.values.sort() 134 135 self.cache={}
136
137 - def extractLine(self,fName):
138 """Extract the name of the line from a filename""" 139 return fName.split("_")[0]
140
141 - def extractValues(self,fName):
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
148 - def __getitem__(self,key):
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
197 - def determineIndex(self,fName,vName,data):
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
222 -class SampleData(object):
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
239 - def __repr__(self):
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
247 - def line(self):
248 """Get the line of the sample""" 249 return path.basename(self.file).split("_")[0]
250
251 - def time(self):
252 """Get the time of the sample (as a string)""" 253 return path.basename(path.dirname(self.file))
254
255 - def isVector(self):
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
268 - def domain(self):
269 """Range of the data domain""" 270 return (min(self.col0),max(self.col0))
271
272 - def component(self,component=None):
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
291 - def __call__(self):
292 """Return the data as SpreadsheetData-object""" 293 294 data=[] 295 if self.isVector(): 296 for i,c in enumerate(self.col0): 297 data.append([c]+list(self.data[i])) 298 else: 299 for i,c in enumerate(self.col0): 300 data.append([c,self.data[i]]) 301 302 names=["col0"] 303 if self.isVector(): 304 names+=[self.name+"_x",self.name+"_y",self.name+"_z"] 305 else: 306 names.append(self.name) 307 308 return SpreadsheetData(data=data, 309 names=names, 310 title="%s_t=%s" % (self.line(),self.time()))
311