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

Source Code for Module PyFoam.RunDictionary.TimelineDirectory

  1  #  ICE Revision: $Id:$ 
  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   
 11  from PyFoam.Basics.SpreadsheetData import SpreadsheetData 
 12   
13 -class TimelineDirectory(object):
14 """A directory of sampled times""" 15
16 - def __init__(self,case,dirName="probes",writeTime=None):
17 """@param case: The case directory 18 @param dirName: Name of the directory with the timelines 19 @param writeTime: The write time-directory where the data in question is to be plotted""" 20 21 self.dir=path.join(case,dirName) 22 self.writeTimes=[] 23 24 nearest=None 25 26 for d in listdir(self.dir): 27 if path.isdir(path.join(self.dir,d)): 28 try: 29 v=float(d) 30 self.writeTimes.append(d) 31 if writeTime: 32 if nearest==None: 33 nearest=d 34 else: 35 if abs(float(writeTime)-v)<abs(float(writeTime)-float(nearest)): 36 nearest=d 37 except ValueError,e: 38 pass 39 40 self.writeTimes.sort(self.sorttimes) 41 if nearest==None: 42 self.usedTime=self.writeTimes[0] 43 else: 44 self.usedTime=nearest 45 46 self.dir=path.join(self.dir,self.usedTime) 47 48 self.values=[] 49 self.vectors=[] 50 for v in listdir(self.dir): 51 self.values.append(v) 52 if TimelineValue(self.dir,v,self.usedTime).isVector: 53 self.vectors.append(v) 54 55 self.allPositions=None
56
57 - def __iter__(self):
58 for t in self.values: 59 yield TimelineValue(self.dir,t,self.usedTime)
60
61 - def __getitem__(self,value):
62 if value in self: 63 return TimelineValue(self.dir,value,self.usedTime) 64 else: 65 raise KeyError,value
66
67 - def __contains__(self,value):
68 return value in self.values
69
70 - def __len__(self):
71 return len(self.values)
72
73 - def sorttimes(self,x,y):
74 """Sort function for the solution files""" 75 if(float(x)==float(y)): 76 return 0 77 elif float(x)<float(y): 78 return -1 79 else: 80 return 1
81
82 - def positions(self):
83 """Returns all the found positions""" 84 85 if self.allPositions==None: 86 positions=[] 87 first=True 88 89 for t in self: 90 for v in t.positions: 91 if v not in positions: 92 if first: 93 positions.append(v) 94 else: 95 error("Found positions",t.positions,"are inconsistent with previous",positions) 96 if first: 97 self.positionIndex=t.positionIndex 98 first=False 99 self.allPositions=positions 100 101 return self.allPositions
102
103 - def timeRange(self):
104 """Return the range of possible times""" 105 minTime=1e80 106 maxTime=-1e80 107 108 for v in self: 109 mi,ma=v.timeRange() 110 minTime=min(mi,minTime) 111 maxTime=max(ma,maxTime) 112 113 return minTime,maxTime
114
115 - def getDataLocation(self,value=None,position=None,vectorMode=None):
116 """Get Timeline sets 117 @param value: name of the value. All 118 if unspecified 119 @param position: name of the position of the value. All 120 if unspecified""" 121 122 if value==None: 123 value=self.values 124 if position==None: 125 position=self.positions() 126 127 sets=[] 128 129 for v in value: 130 for p in position: 131 fName=path.join(self.dir,v) 132 if not "positionIndex" in self: 133 self.positions() 134 pos=self.positionIndex[self.positions().index(p)] 135 if v in self.vectors: 136 fName="< tr <%s -d '()'" %fName 137 pos=pos*3 138 if vectorMode=="x": 139 pass 140 elif vectorMode=="y": 141 pos+=1 142 elif vectorMode=="z": 143 pos+=2 144 elif vectorMode=="mag": 145 pos+=2 146 pos="(sqrt($%d*$%d+$%d*$%d+$%d*$%d))" % (pos,pos, 147 pos+1,pos+1, 148 pos+2,pos+2) 149 else: 150 error("Unsupported vector mode",vectorMode) 151 152 sets.append((fName,v,p,pos,TimelineValue(self.dir,v,self.usedTime))) 153 154 return sets
155
156 - def getData(self,times,value=None,position=None):
157 """Get data that mstches the given times most closely 158 @param times: a list with times 159 @param value: name of the value. All 160 if unspecified 161 @param position: name of the position of the value. All 162 if unspecified""" 163 164 if value==None: 165 value=self.values 166 if position==None: 167 position=self.positions() 168 169 sets=[] 170 posIndex=[] 171 for p in position: 172 posIndex.append(self.positions().index(p)) 173 174 for v in value: 175 val=TimelineValue(self.dir,v,self.usedTime) 176 data=val.getData(times) 177 for i,t in enumerate(times): 178 used=[] 179 for p in posIndex: 180 used.append(data[i][p]) 181 182 sets.append((v,t,used)) 183 184 return sets
185
186 -class TimelineValue(object):
187 """A file with one timelined value""" 188
189 - def __init__(self,sDir,val,time):
190 """@param sDir: The timeline-dir 191 @param val: the value 192 @param time: the timename""" 193 194 self.val=val 195 self.time=time 196 self.file=path.join(sDir,val) 197 poses=[] 198 199 self.isVector=False 200 201 data=open(self.file) 202 l1=data.readline() 203 if len(l1)<1 or l1[0]!='#': 204 error("Data file",self.file,"has no description of the fields") 205 l2=data.readline() 206 207 self._isProbe=True 208 if l2[0]!='#': 209 # Not a probe-file. The whole description is in the first line 210 poses=l1[1:].split()[1:] 211 firstData=l2 212 self._isProbe=False 213 else: 214 # probe-file so we need one more line 215 l3=data.readline() 216 x=l1[1:].split()[1:] 217 y=l2[1:].split()[1:] 218 z=l3[1:].split()[1:] 219 for i in range(len(x)): 220 poses.append("(%s %s %s)" % (x[i],y[i],z[i])) 221 data.readline() 222 firstData=data.readline() 223 224 self.positions=[] 225 self.positionIndex=[] 226 if len(poses)+1==len(firstData.split()): 227 #scalar 228 for i,v in enumerate(firstData.split()[1:]): 229 if abs(float(v))<1e40: 230 self.positions.append(poses[i]) 231 self.positionIndex.append(i) 232 else: 233 self.isVector=True 234 for i,v in enumerate(firstData.split()[2::3]): 235 if abs(float(v))<1e40: 236 self.positions.append(poses[i]) 237 self.positionIndex.append(i) 238 239 self.cache={}
240
241 - def __repr__(self):
242 if self.isVector: 243 vect=" (vector)" 244 else: 245 vect="" 246 247 return "TimelineData of %s%s on %s at t=%s " % (self.val,vect,str(self.positions),self.time)
248
249 - def isProbe(self):
250 """Is this a probe-file""" 251 return self._isProbe
252
253 - def timeRange(self):
254 """Range of times""" 255 lines=open(self.file).readlines() 256 for l in lines: 257 v=l.split() 258 if v[0][0]!='#': 259 minRange=float(v[0]) 260 break 261 lines.reverse() 262 for l in lines: 263 v=l.split() 264 if len(v)>=len(self.positions)+1: 265 maxRange=float(v[0]) 266 break 267 268 return minRange,maxRange
269
270 - def getData(self,times):
271 """Get the data values that are nearest to the actual times""" 272 dist=len(times)*[1e80] 273 data=len(times)*[len(self.positions)*[1e80]] 274 275 lines=open(self.file).readlines() 276 277 for l in lines: 278 v=l.split() 279 if v[0][0]!='#': 280 try: 281 time=float(v[0]) 282 vals=v[1:] 283 for i,t in enumerate(times): 284 if abs(t-time)<dist[i]: 285 dist[i]=abs(t-time) 286 data[i]=vals 287 except ValueError: 288 pass 289 result=[] 290 for d in data: 291 tmp=[] 292 for v in d: 293 if abs(float(v))<1e40: 294 tmp.append(float(v)) 295 result.append(tmp) 296 297 return result
298
299 - def __call__(self):
300 """Return the data as a SpreadsheetData-object""" 301 302 lines=open(self.file).readlines() 303 data=[] 304 for l in lines: 305 v=l.split() 306 if v[0][0]!='#': 307 data.append(map(lambda x:float(x.replace('(','').replace(')','')),v)) 308 names=["time"] 309 if self.isVector: 310 for p in self.positions: 311 names+=[p+" x",p+" y",p+" z"] 312 else: 313 names+=self.positions 314 315 return SpreadsheetData(data=data, 316 names=names, 317 title="%s_t=%s" % (self.val,self.time))
318