Package PyFoam :: Package Applications :: Module ListCases
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Applications.ListCases

  1  """ 
  2  Application-class that implements pyFoamListCases.py 
  3  """ 
  4  from optparse import OptionGroup 
  5  from os import path,listdir,stat 
  6  import time,datetime 
  7  from stat import ST_MTIME 
  8  import string 
  9  import subprocess 
 10  import re 
 11  import os 
 12   
 13  from .PyFoamApplication import PyFoamApplication 
 14   
 15  from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory 
 16  from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile,PyFoamParserError 
 17   
 18  from PyFoam import configuration 
 19   
 20  from PyFoam.ThirdParty.six import print_,iteritems,PY3 
 21   
 22  from PyFoam.Basics.Utilities import humanReadableSize 
 23   
 24  if PY3: 
 25      long=int 
 26   
27 -class ListCases(PyFoamApplication):
28 - def __init__(self,args=None):
29 description="""\ 30 List the valid OpenFOAM-cases in a number of directories along with 31 some basic information (number of timesteps, last timestep, 32 etc). Currently doesn't honor the parallel data 33 """ 34 PyFoamApplication.__init__(self, 35 args=args, 36 description=description, 37 usage="%prog [<directories>]", 38 interspersed=True, 39 changeVersion=False, 40 nr=0, 41 exactNr=False)
42 43 sortChoices=["name","first","last","mtime","nrSteps","procs","diskusage","pFirst","pLast","nrParallel","nowTime","state","lastOutput","startedAt"] 44
45 - def addOptions(self):
46 what=OptionGroup(self.parser, 47 "What", 48 "Define what should be shown") 49 self.parser.add_option_group(what) 50 51 what.add_option("--dump", 52 action="store_true", 53 dest="dump", 54 default=False, 55 help="Dump the information as Python-dictionaries") 56 57 what.add_option("--disk-usage", 58 action="store_true", 59 dest="diskusage", 60 default=False, 61 help="Show the disk-usage of the case (in MB) - may take a long time") 62 63 what.add_option("--parallel-info", 64 action="store_true", 65 dest="parallel", 66 default=False, 67 help="Print information about parallel runs (if present): number of processors and processor first and last time. The mtime will be that of the processor-directories") 68 69 what.add_option("--no-state", 70 action="store_false", 71 dest="state", 72 default=True, 73 help="Don't read state-files") 74 75 what.add_option("--advanced-state", 76 action="store_true", 77 dest="advancedState", 78 default=False, 79 help="Additional state information (run started, last output seen)") 80 81 what.add_option("--estimate-end-time", 82 action="store_true", 83 dest="estimateEndTime", 84 default=False, 85 help="Print an estimated end time (calculated from the start time of the run, the current time and the current simulation time)") 86 87 what.add_option("--start-end-time", 88 action="store_true", 89 dest="startEndTime", 90 default=False, 91 help="Start and end time from the controlDict") 92 93 how=OptionGroup(self.parser, 94 "How", 95 "How the things should be shown") 96 self.parser.add_option_group(how) 97 98 how.add_option("--sort-by", 99 type="choice", 100 action="store", 101 dest="sort", 102 default=configuration().get("CommandOptionDefaults","sortListCases",default="name"), 103 choices=self.sortChoices, 104 help="Sort the cases by a specific key (Keys: "+string.join(self.sortChoices,", ")+") Default: %default") 105 how.add_option("--reverse-sort", 106 action="store_true", 107 dest="reverse", 108 default=False, 109 help="Sort in reverse order") 110 how.add_option("--relative-times", 111 action="store_true", 112 dest="relativeTime", 113 default=False, 114 help="Show the timestamps relative to the current time") 115 116 behave=OptionGroup(self.parser, 117 "Behaviour", 118 "Additional output etc") 119 self.parser.add_option_group(behave) 120 121 behave.add_option("--progress", 122 action="store_true", 123 dest="progress", 124 default=False, 125 help="Print the directories while they are being processed")
126
127 - def readState(self,sol,sFile,default=""):
128 fName=path.join(sol.name,"PyFoamState."+sFile) 129 if not path.exists(fName): 130 return default 131 else: 132 self.hasState=True 133 return open(fName).read().strip()
134
135 - def run(self):
136 dirs=self.parser.getArgs() 137 138 if len(dirs)==0: 139 dirs=[path.curdir] 140 141 cData=[] 142 totalDiskusage=0 143 144 self.hasState=False 145 146 for d in dirs: 147 for n in listdir(d): 148 cName=path.join(d,n) 149 if path.isdir(cName): 150 try: 151 sol=SolutionDirectory(cName,archive=None,paraviewLink=False) 152 if sol.isValid(): 153 if self.opts.progress: 154 print_("Processing",cName) 155 156 data={} 157 158 data["mtime"]=stat(cName)[ST_MTIME] 159 times=sol.getTimes() 160 try: 161 data["first"]=times[0] 162 except IndexError: 163 data["first"]="None" 164 try: 165 data["last"]=times[-1] 166 except IndexError: 167 data["last"]="None" 168 data["nrSteps"]=len(times) 169 data["procs"]=sol.nrProcs() 170 data["pFirst"]=-1 171 data["pLast"]=-1 172 data["nrParallel"]=-1 173 if self.opts.parallel: 174 pTimes=sol.getParallelTimes() 175 data["nrParallel"]=len(pTimes) 176 if len(pTimes)>0: 177 data["pFirst"]=pTimes[0] 178 data["pLast"]=pTimes[-1] 179 data["name"]=cName 180 data["diskusage"]=-1 181 if self.opts.diskusage: 182 try: 183 data["diskusage"]=int( 184 subprocess.Popen( 185 ["du","-sb",cName], 186 stdout=subprocess.PIPE, 187 stderr=open(os.devnull,"w") 188 ).communicate()[0].split()[0]) 189 except IndexError: 190 # assume that this du does not support -b 191 data["diskusage"]=int( 192 subprocess.Popen( 193 ["du","-sk",cName], 194 stdout=subprocess.PIPE 195 ).communicate()[0].split()[0])*1024 196 197 totalDiskusage+=data["diskusage"] 198 if self.opts.parallel: 199 for f in listdir(cName): 200 if re.compile("processor[0-9]+").match(f): 201 data["mtime"]=max(stat(path.join(cName,f))[ST_MTIME],data["mtime"]) 202 203 if self.opts.state: 204 try: 205 data["nowTime"]=float(self.readState(sol,"CurrentTime")) 206 except ValueError: 207 data["nowTime"]=None 208 209 try: 210 data["lastOutput"]=time.mktime(time.strptime(self.readState(sol,"LastOutputSeen"))) 211 except ValueError: 212 data["lastOutput"]="nix" 213 214 data["state"]=self.readState(sol,"TheState") 215 216 if self.opts.state or self.opts.estimateEndTime: 217 try: 218 data["startedAt"]=time.mktime(time.strptime(self.readState(sol,"StartedAt"))) 219 except ValueError: 220 data["startedAt"]="nix" 221 222 if self.opts.startEndTime or self.opts.estimateEndTime: 223 try: 224 ctrlDict=ParsedParameterFile(sol.controlDict(),doMacroExpansion=True) 225 except PyFoamParserError: 226 # Didn't work with Macro expansion. Let's try without 227 ctrlDict=ParsedParameterFile(sol.controlDict()) 228 229 data["startTime"]=ctrlDict["startTime"] 230 data["endTime"]=ctrlDict["endTime"] 231 232 if self.opts.estimateEndTime: 233 data["endTimeEstimate"]=None 234 if self.readState(sol,"TheState")=="Running": 235 gone=time.time()-data["startedAt"] 236 try: 237 current=float(self.readState(sol,"CurrentTime")) 238 frac=(current-data["startTime"])/(data["endTime"]-data["startTime"]) 239 except ValueError: 240 frac=0 241 if frac>0: 242 data["endTimeEstimate"]=data["startedAt"]+gone/frac 243 244 cData.append(data) 245 except OSError: 246 print_(cName,"is unreadable") 247 248 if self.opts.progress: 249 print_("Sorting data") 250 251 if self.opts.reverse: 252 cData.sort(lambda x,y:cmp(y[self.opts.sort],x[self.opts.sort])) 253 else: 254 cData.sort(lambda x,y:cmp(x[self.opts.sort],y[self.opts.sort])) 255 256 if len(cData)==0: 257 print_("No cases found") 258 return 259 260 if self.opts.dump: 261 print_(cData) 262 return 263 264 lens={} 265 for k in list(cData[0].keys()): 266 lens[k]=len(k) 267 for c in cData: 268 for k in ["mtime","lastOutput","startedAt","endTimeEstimate"]: 269 try: 270 if c[k]!=None: 271 if self.opts.relativeTime: 272 c[k]=datetime.timedelta(seconds=long(time.time()-c[k])) 273 else: 274 c[k]=time.asctime(time.localtime(c[k])) 275 except KeyError: 276 pass 277 except TypeError: 278 c[k]=None 279 280 try: 281 c["diskusage"]=humanReadableSize(c["diskusage"]) 282 except KeyError: 283 pass 284 285 for k,v in iteritems(c): 286 lens[k]=max(lens[k],len(str(v))) 287 288 format="" 289 spec=["mtime"," | ","first"," - ","last"," (","nrSteps",") "] 290 if self.opts.parallel: 291 spec+=["| ","procs"," : ","pFirst"," - ","pLast"," (","nrParallel",") | "] 292 if self.opts.diskusage: 293 spec+=["diskusage"," | "] 294 if self.hasState: 295 spec+=["nowTime"," s ","state"," | "] 296 if self.opts.advancedState: 297 spec+=["lastOutput"," | ","startedAt"," | "] 298 if self.opts.estimateEndTime: 299 if not self.opts.advancedState: 300 spec+=["startedAt"," | "] 301 spec+=["endTimeEstimate"," | "] 302 if self.opts.startEndTime: 303 spec+=["startTime"," | ","endTime"," | "] 304 305 spec+=["name"] 306 307 for i,l in enumerate(spec): 308 if not l in list(cData[0].keys()): 309 format+=l 310 else: 311 if i<len(spec)-1: 312 format+="%%(%s)%ds" % (l,lens[l]) 313 else: 314 format+="%%(%s)s" % (l) 315 316 if self.opts.progress: 317 print_("Printing\n\n") 318 319 header=format % dict(list(zip(list(cData[0].keys()),list(cData[0].keys())))) 320 print_(header) 321 print_("-"*len(header)) 322 323 for d in cData: 324 for k in list(d.keys()): 325 d[k]=str(d[k]) 326 print_(format % d) 327 328 if self.opts.diskusage: 329 print_("Total disk-usage:",humanReadableSize(totalDiskusage))
330 331 332 # Should work with Python3 and Python2 333