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 -class SampleDirectory(object):
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
28 - def __iter__(self):
29 for t in self.times: 30 yield SampleTime(self.dir,t)
31
32 - def __getitem__(self,time):
33 if time in self: 34 return SampleTime(self.dir,time) 35 else: 36 raise KeyError,time
37
38 - def __contains__(self,time):
39 return time in self.times
40
41 - def sorttimes(self,x,y):
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
50 - def lines(self):
51 """Returns all the found sample lines""" 52 53 lines=[] 54 55 for t in self: 56 for l in t.lines: 57 if l not in lines: 58 lines.append(l) 59 lines.sort() 60 61 return lines
62
63 - def values(self):
64 """Returns all the found sampled values""" 65 66 values=[] 67 68 for t in self: 69 for v in t.values: 70 if v not in values: 71 values.append(v) 72 values.sort() 73 74 return values
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
105 -class SampleTime(object):
106 """A directory with one sampled time""" 107
108 - def __init__(self,sDir,time):
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
130 - def extractLine(self,fName):
131 """Extract the name of the line from a filename""" 132 return fName.split("_")[0]
133
134 - def extractValues(self,fName):
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
141 - def __getitem__(self,key):
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
187 - def determineIndex(self,fName,vName,data):
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
212 -class SampleData(object):
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
228 - def __repr__(self):
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
236 - def line(self):
237 """Get the line of the sample""" 238 return path.basename(self.file).split("_")[0]
239
240 - def time(self):
241 """Get the time of the sample (as a string)""" 242 return path.basename(path.dirname(self.file))
243
244 - def isVector(self):
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
257 - def domain(self):
258 """Range of the data domain""" 259 return (min(self.col0),max(self.col0))
260
261 - def component(self,component=None):
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