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