casa
$Rev:20696$
|
00001 from casac import casac 00002 from taskinit import casalog 00003 from imageTest import * 00004 from visTest import * 00005 from testbase import * 00006 from tableMaker import * 00007 import time 00008 import os 00009 import shutil 00010 import commands 00011 import sys 00012 import signal 00013 import pdb 00014 import traceback 00015 import re 00016 import cProfile 00017 00018 PYVER = str(sys.version_info[0]) + "." + str(sys.version_info[1]) 00019 00020 imager = casac.imager() 00021 image = casac.image() 00022 quantity=casac.quanta() 00023 00024 AIPS_DIR = os.environ["CASAPATH"].split()[0] 00025 00026 if os.access(AIPS_DIR+'/lib64', os.F_OK): 00027 SCRIPT_REPOS = AIPS_DIR+'/lib64/python'+PYVER+'/regressions/' 00028 UTILS_DIR = AIPS_DIR+'/lib64/casapy/bin/' 00029 elif os.access(AIPS_DIR+'/lib', os.F_OK): 00030 SCRIPT_REPOS = AIPS_DIR+'/lib/python'+PYVER+'/regressions/' 00031 UTILS_DIR = AIPS_DIR+'/lib/casapy/bin/' 00032 elif os.access(AIPS_DIR + '/' + os.environ["CASAPATH"].split()[1] + '/python/' + PYVER + '/regressions/', os.F_OK): 00033 # devel 00034 SCRIPT_REPOS = AIPS_DIR + '/' + os.environ["CASAPATH"].split()[1] + '/python/' + PYVER + '/regressions/' 00035 UTILS_DIR = '' 00036 else: #Mac release 00037 SCRIPT_REPOS = AIPS_DIR+'/Resources/python/regressions/' 00038 UTILS_DIR = AIPS_DIR+'/MacOS/' 00039 # because casapy releases have a different directory structure 00040 00041 00042 # set to True to skip the test execution and reuse product files 00043 #dry=True 00044 dry = False 00045 00046 class runTest: 00047 def __init__(self, test, \ 00048 DATA_REPOS=[AIPS_DIR+'/data'], \ 00049 WORKING_DIR='/tmp/casa_regression_work/', \ 00050 RESULT_DIR='/tmp/casa_regression_result/', \ 00051 retemplate=False, 00052 cleanup=True, 00053 CPP_PROFILE=False, 00054 RESULT_SUBDIR='', 00055 REDIRECT=True, 00056 PY_PROFILE=True): 00057 """cleanup: set to False to keep data around. 00058 CPP_PROFILE: set to True to enable C++ profiling. This requires that the command 'sudo opcontrol' must work. You also need the 'dot' tool distributed as part of graphviz. Run 'dot -Txxx' to verify that your dot installation supports PNG images. 00059 Note, a profile is created only for the casapy process. If you want to include profiles for async / child processes, refer to the documentation for opreport.""" 00060 casalog.showconsole(onconsole=True) 00061 00062 TEMPLATE_RESULT_DIR=AIPS_DIR+'/data/regression/' 00063 tests = [test] 00064 if type(tests) != type([]): 00065 raise TypeError 00066 self.resultdir=RESULT_DIR 00067 self.imdir=WORKING_DIR+'/IMAGES/' 00068 self.tester=testbase(WORKING_DIR) 00069 self.imagertests=[] 00070 self.result=[] 00071 self.numTests=0 00072 ####Get the directories right 00073 self.tester.setDataBaseDir(DATA_REPOS) 00074 self.tester.setScriptsDir(SCRIPT_REPOS) 00075 self.tester.setResultDir(RESULT_DIR) 00076 self.tester.setWorkingDir(WORKING_DIR) 00077 self.resultsubdir = '' 00078 00079 print SCRIPT_REPOS 00080 00081 if((len(tests)==1) and (tests[0]=='all')): 00082 self.numTests=self.tester.locateTests() 00083 else: 00084 self.numTests=self.tester.locateTests(tests) 00085 testName='' 00086 00087 #pdb.set_trace() 00088 for k in range(self.numTests) : 00089 ### cleanup before each test 00090 if not dry and cleanup: 00091 self.tester.cleanup() 00092 00093 self.tester.createDirs() 00094 00095 uname1 = os.uname()[1] 00096 00097 if self.tester.testname(k)[0:6] == 'tests/': 00098 testName=string.split(self.tester.testname(k)[6:], ".py")[0] 00099 else: 00100 testName=string.split(self.tester.testname(k), ".py")[0] 00101 if not RESULT_SUBDIR: 00102 self.resultsubdir = self.resultdir + "/result-" + \ 00103 testName + "-" + \ 00104 uname1 + "-" + \ 00105 time.strftime('%Y_%m_%d_%H_%M') 00106 else: 00107 self.resultsubdir = self.resultdir + "/" + RESULT_SUBDIR 00108 00109 if not os.path.isdir(self.resultsubdir): 00110 os.mkdir(self.resultsubdir) 00111 00112 logfilename = testName+'.log' 00113 if (os.path.isfile(self.resultsubdir+'/'+logfilename)): 00114 os.remove(self.resultsubdir+'/'+logfilename) 00115 00116 # redirect stdout and stderr and casalog 00117 print 'Run test '+testName 00118 if REDIRECT: 00119 print "Redirect stdout/stderr to", self.resultsubdir+'/'+logfilename 00120 save_stdout = sys.stdout 00121 save_stderr = sys.stderr 00122 fsock = open(self.resultsubdir+'/'+logfilename, 'w') 00123 sys.stdout = logger("STDOUT", [save_stdout, fsock]) 00124 sys.stderr = logger("STDERR", [save_stderr, fsock]) 00125 00126 testlog = self.tester.workingDirectory+"/test.log" 00127 open(testlog, "w").close() # create empty file 00128 casalog.setlogfile(testlog) # seems to append to an existing file 00129 00130 try: 00131 self.tester.getTest(self.tester.testname(k), testName) 00132 00133 if PY_PROFILE: 00134 if RESULT_SUBDIR != testName: 00135 profilepage = RESULT_DIR+'/'+time.strftime('%Y_%m_%d/')+testName+'_profile.html' 00136 else: 00137 profilepage = RESULT_DIR+'/'+RESULT_SUBDIR+'/'+'profile.html' 00138 00139 process_data = "%s/profile.txt" % self.tester.workingDirectory 00140 00141 os.system("echo -n > " + process_data) 00142 pp = SCRIPT_REPOS + '/profileplot.py' # for release 00143 if not os.path.isfile(pp): 00144 pp = SCRIPT_REPOS + '/../profileplot.py' # for devel 00145 pyt = UTILS_DIR + '/python' # for release 00146 if not os.path.isfile(pyt): 00147 lib = "lib64" if os.uname()[4] == 'x86_64' else "lib" 00148 pyt = '/usr/' + lib + '/casapy/bin/python' 00149 if not os.path.isfile(pyt): 00150 pyt = '/usr/lib64/casapy/bin/python' # for devel 00151 if not os.path.isfile(pyt): 00152 pyt = '/usr/lib/casapy/bin/python' # for devel 00153 if not os.path.isfile(pyt): 00154 pyt = commands.getoutput('which python') # Mac devel 00155 profileplot_pid=os.spawnlp(os.P_NOWAIT, 00156 pyt, 00157 pyt, 00158 pp, 00159 testName, RESULT_DIR + ("/" + RESULT_SUBDIR if RESULT_SUBDIR == testName else ''), 00160 profilepage, 00161 process_data, 00162 str(os.getpid())) 00163 prof = cProfile.Profile() 00164 else: 00165 prof = False 00166 00167 presentDir=os.getcwd() 00168 os.chdir(self.tester.workingDirectory) 00169 00170 short_description = self.tester.getDescription(testName, k) 00171 if short_description != None and short_description.find("'") >= 0: 00172 print >> sys.stderr, \ 00173 "Warning: Short description contains ': '%s'" % \ 00174 short_description 00175 short_description = short_description.replace("'", "") 00176 00177 try: 00178 self.op_init(CPP_PROFILE) 00179 time1=time.time() 00180 mem1 = commands.getoutput('ps -p ' + str(os.getpid()) + ' -o rss | tail -1') 00181 if prof: 00182 #prof.runctx("(leResult, leImages)=self.tester.runtests(testName, k, dry)", globals(), locals()) 00183 #prof.runctx("(leResult, leImages)=self.tester.runtests(testName, k, dry)", gl, lo) 00184 #prof.run("(leResult, leImages) = self.tester.runtests(testName, k, dry)") 00185 (leResult, leImages) = prof.runcall(self.tester.runtests, testName, k, dry) 00186 else: 00187 (leResult, leImages) = self.tester.runtests(testName, k, dry) 00188 00189 # returns absolute_paths, relative_paths 00190 exec_success = True 00191 except: 00192 leResult=[] 00193 exec_success = False 00194 print >> sys.stderr, "%s failed, dumping traceback:" % testName 00195 traceback.print_exc() # print and swallow exception 00196 00197 mem2 = commands.getoutput('ps -p ' + str(os.getpid()) + ' -o rss | tail -1') 00198 time2=time.time() 00199 time2=(time2-time1)/60.0 00200 00201 print "Net memory allocated:", (int(mem2) - int(mem1))/1024, "MB" 00202 00203 if prof: 00204 try: 00205 prof.dump_stats(self.resultsubdir+'/cProfile.profile') 00206 except: 00207 print >> sys.stderr, "Failed to write profiling data!" 00208 00209 self.op_done(CPP_PROFILE) 00210 00211 # Dump contents of any *.log file produced 00212 # by the regression script 00213 # 00214 # !! Does not handle out of diskspace 00215 # 00216 files = os.listdir('.') 00217 for f in files: 00218 if f != 'casapy.log' and \ 00219 re.compile('.log$').search(f) != None: 00220 00221 for line in open(f, 'r'): 00222 #print f + ' ddd'+line 00223 if REDIRECT: 00224 fsock.write(f + ': ' + line.rstrip( )) 00225 else: 00226 print f + ': ' + line.rstrip( ) 00227 00228 # 00229 # Report and deal with out of diskspace 00230 # 00231 space_left = commands.getoutput( \ 00232 "df -kP " + self.tester.workingDirectory + \ 00233 " | awk '{print $4}' | tail -1") 00234 space_left_h = commands.getoutput( \ 00235 "df -hP " + self.tester.workingDirectory + \ 00236 " | awk '{print $4}' | tail -1") 00237 space_used = commands.getoutput( \ 00238 "du -kc " + self.tester.workingDirectory + \ 00239 " | tail -1 | awk '{print $1}'") 00240 space_used_h = commands.getoutput( \ 00241 "du -hc " + self.tester.workingDirectory + \ 00242 " | tail -1 | awk '{print $1}'") 00243 00244 if int(space_left) < 1000*1000: 00245 print >> sys.stderr, "Warning: Only " + \ 00246 space_left_h + ' disk space left, ' + \ 00247 space_used_h + ' used' 00248 # Clean up early, so that this infrastructure can continue 00249 if not exec_success and cleanup: 00250 self.tester.cleanup() 00251 00252 # Copy C++ profiling info 00253 if CPP_PROFILE: 00254 os.system('cp cpp_profile.* ' + self.resultsubdir) 00255 00256 os.chdir(presentDir) 00257 00258 if PY_PROFILE: 00259 # Terminate profiling process 00260 os.kill(profileplot_pid,signal.SIGHUP) 00261 status = os.waitpid(profileplot_pid, 0)[1] 00262 #print str(profileplot_pid) + ' exit: ' + str(status) 00263 00264 pagename=time.strftime('%Y_%m_%d/')+testName+'_profile.html' 00265 00266 # entries common for all tests based on this run 00267 self.result_common = {} 00268 self.result_common['CASA'] = "'" + self.get_casa_version() + "'", "CASA version" 00269 self.result_common['host'] = uname1, "os.uname[1]" 00270 self.result_common['platform'] = "'" + self.get_platform()[0] + " " + self.get_platform()[1] + "'", "OS" 00271 00272 self.result_common['date'] = time.strftime('%Y_%m_%d_%H_%M'), "" 00273 self.result_common['testid'] = testName, "test name" 00274 if short_description != None: 00275 self.result_common['description'] = "'" + short_description + "'", "test short description" 00276 00277 # Figure out data repository version 00278 if os.system("which svnversion >/dev/null") == 0: 00279 (errorcode, datasvnr) = commands.getstatusoutput('cd '+DATA_REPOS[0]+' && svnversion 2>&1 | grep -vi warning') 00280 else: 00281 errorcode = 1 00282 if errorcode != 0 or datasvnr == "exported": 00283 # If that didn't work, look at ./version in the toplevel dir 00284 (errorcode, datasvnr) = commands.getstatusoutput( \ 00285 'cd '+DATA_REPOS[0]+" && grep -E 'Rev:' version" \ 00286 ) 00287 if errorcode != 0: 00288 datasvnr = "Unknown version" 00289 00290 self.result_common['data_version'] = "'"+datasvnr+"'", "Data repository version" 00291 00292 # execution test 00293 exec_result = self.result_common.copy() 00294 exec_result['version'] = 2, "version of this file" 00295 exec_result['type'] = "exec", "test type" 00296 exec_result['time'] = time2*60, "execution time in seconds" 00297 exec_result['disk'] = space_used, "disk space (KB) in use after test" 00298 exec_result['runlog'] = logfilename, "execution logfile" 00299 00300 00301 if PY_PROFILE: 00302 # read time/memory data 00303 mem = "" 00304 try: 00305 process_file = open(process_data, "r") 00306 except: 00307 print "Warning: Failed to open file:", process_data 00308 process_file = None 00309 else: 00310 process_file = None 00311 00312 if process_file != None: 00313 lineno = 0 00314 for line in process_file: 00315 lineno += 1 00316 if len(line) > 0 and line[0] != '#': 00317 try: 00318 (t, m_virtual, m_resident, nfiledesc, 00319 cpu_us, cpu_sy, cpu_id, cpu_wa) = line.split() 00320 mem = mem + \ 00321 str(t) + ',' + \ 00322 str(m_virtual) + ',' + \ 00323 str(m_resident) + ',' + \ 00324 str(nfiledesc) + ',' + \ 00325 str(cpu_us) + ',' + \ 00326 str(cpu_sy) + ',' + \ 00327 str(cpu_id) + ',' + \ 00328 str(cpu_wa) + ';' 00329 except: 00330 print >> sys.stderr, "Error parsing %s:%d: '%s'" % \ 00331 (process_data, lineno, line) 00332 process_file.close() 00333 exec_result['resource'] = mem, "time(s),virtual(Mbytes),resident(Mbytes),nfiledesc,cpu_us,cpu_sy,cpu_id,cpu_wa" 00334 00335 whatToTest=self.tester.whatQualityTest() 00336 keys=[] 00337 #if len(whatToTest) != 0: 00338 # keys=whatToTest.keys() 00339 # print 'THE KEYS ARE ', keys 00340 for j in range(len(leResult)) : 00341 templateImage=TEMPLATE_RESULT_DIR+"/"+testName+"/reference/"+leImages[j] 00342 if retemplate: 00343 if os.access(templateImage, os.F_OK): 00344 shutil.rmtree(templateImage) 00345 print 'TemplateImage '+templateImage 00346 print 'theImage '+leResult[j] 00347 print 'theImage '+leImages[j] 00348 00349 product_exists = os.access(leResult[j], os.F_OK) 00350 template_exists = os.access(templateImage, os.F_OK) 00351 00352 if product_exists and retemplate: 00353 print 'Create template from', leResult[j] 00354 if not os.path.isdir(TEMPLATE_RESULT_DIR+"/"+testName): 00355 os.mkdir(TEMPLATE_RESULT_DIR+"/"+testName) 00356 shutil.copytree(leResult[j], templateImage) 00357 00358 if not product_exists: 00359 print >> sys.stderr, leResult[j], 'missing!' 00360 exec_success = False 00361 whatToTest[leResult[j]] = [] 00362 00363 if not template_exists: 00364 print >> sys.stderr, templateImage, 'missing!' 00365 00366 for leQualityTest in whatToTest[leResult[j]] : 00367 print leResult[j]+' WHAT : ', whatToTest[leResult[j]] 00368 self.result=self.result_common.copy() 00369 self.result['version'] = 1, "version of this file" 00370 self.result['type'] = leQualityTest, "test type" 00371 self.result['image'] = leImages[j], "test image" 00372 00373 if not product_exists: 00374 self.result['status'] = 'fail', "result of regression test" 00375 self.result['reason'] = "'Product image missing'", "reason of failure" 00376 elif not template_exists: 00377 self.result['status'] = 'fail', "result of regression test" 00378 self.result['reason'] = "'Reference image missing'", "reason of failure" 00379 else: 00380 if os.access(self.imdir, os.F_OK): 00381 shutil.rmtree(self.imdir) 00382 00383 if(leQualityTest=='simple'): 00384 self.simpleStats(leResult[j], templateImage, testName, WORKING_DIR, RESULT_DIR) 00385 elif(leQualityTest=='pol2'): 00386 self.polImageTest(leResult[j], templateImage, testName, WORKING_DIR, RESULT_DIR, 2) 00387 elif(leQualityTest=='pol4'): 00388 self.polImageTest(leResult[j], templateImage, testName, WORKING_DIR, RESULT_DIR, 4) 00389 elif(leQualityTest=='cube'): 00390 self.cubeImageTest(leResult[j], templateImage, testName, WORKING_DIR, RESULT_DIR) 00391 elif(leQualityTest=='ms'): 00392 self.visStats(leResult[j], templateImage, testName, WORKING_DIR, RESULT_DIR) 00393 # RI add visStats method here, image ones use ImageTest so going to have to build a MSTest class 00394 else: 00395 self.polImageTest(leResult[j], templateImage, testName, WORKING_DIR, RESULT_DIR, 1) 00396 00397 # Pick up any images produced in test 00398 if os.path.isdir(self.imdir): 00399 i = 0 00400 for image in os.listdir(self.imdir): 00401 i = i + 1 00402 shutil.copy(self.imdir + '/' + image, \ 00403 self.resultsubdir+'/'+os.path.basename(image)) 00404 self.result['imagefile_'+str(i)] = "'"+os.path.basename(image)+"'", 'regression image '+str(i) 00405 00406 self.create_log(leImages[j].replace('/', '-')) 00407 00408 # Create exec log now that we now if 00409 # required images were produced 00410 exec_result['status'] = ("fail", "pass") [exec_success], "execution status" 00411 self.result = exec_result 00412 self.create_log("") 00413 00414 # Restore stdout/stderr 00415 if REDIRECT: 00416 sys.stderr = save_stderr 00417 sys.stdout = save_stdout 00418 fsock.close() 00419 00420 casalog.setlogfile("casapy.log") 00421 os.system("sed 's/^/casapy.log: /' "+testlog+" >> "+self.resultsubdir+'/'+logfilename) 00422 00423 if not dry and cleanup: 00424 self.tester.cleanup() 00425 except: 00426 if REDIRECT: 00427 sys.stderr = save_stderr 00428 sys.stdout = save_stdout 00429 fsock.close() 00430 casalog.setlogfile("casapy.log") 00431 os.system("sed 's/^/casapy.log: /' "+testlog+" >> "+self.resultsubdir+'/'+logfilename) 00432 00433 print "Unexpected error:", sys.exc_info()[0] 00434 raise 00435 00436 # end for k... 00437 00438 print "Created ", self.resultsubdir 00439 00440 00441 def op_init(self, oprofile): 00442 if oprofile: 00443 os.system("sudo opcontrol --deinit && sudo opcontrol --init && sudo opcontrol --reset && sudo opcontrol --start --callgraph=999 --no-vmlinux --separate=lib --event=\"default\"") 00444 00445 def op_done(self, oprofile): 00446 if oprofile: 00447 casapy = os.environ["CASAPATH"].split()[0] + '/' + \ 00448 os.environ["CASAPATH"].split()[1] + '/bin/casapy' 00449 00450 gprof2dot = SCRIPT_REPOS + "/../gprof2dot.py" 00451 00452 os.system("sudo opcontrol --stop && sudo opcontrol --dump") 00453 os.system("opreport -clf image-exclude:/no-vmlinux " + casapy + " > cpp_profile.txt") 00454 os.system("cat cpp_profile.txt | " + gprof2dot + " -e0.1 -n1 -f oprofile > cpp_profile.dot") 00455 os.system("cat cpp_profile.dot | dot -Tpng -o cpp_profile.png") 00456 os.system("opannotate --source > cpp_profile.cc") 00457 00458 00459 def polImageTest(self, imageName, templateImage, testName, WORKING_DIR, RESULT_DIR, numPol=2): 00460 a = ImageTest(imageName, write=True, 00461 resultDir = self.resultdir, 00462 imDir=self.imdir) 00463 b = ImageTest(templateImage, write=False, 00464 resultDir = self.resultdir, 00465 imDir=self.imdir) 00466 status = 1 00467 pol=['I', 'V'] 00468 if(numPol==4): 00469 pol=['I','Q','U','V'] 00470 quickresult='<pre>' 00471 ##do only the 'I' subtraction 00472 for k in range(1): 00473 print 'POL TEST ', k, 'numpol ', numPol 00474 out1, rms1 = a.bmodel(plane=k) 00475 out2, rms2 = b.bmodel(plane=k) 00476 # rms1=a.subtract(plane=k) 00477 # rms2=b.subtract(plane=k) 00478 00479 # quickresult+=('Pol #%s\n Image coord: [%.3f,%.3f]\n FWHM in x: %.6f\n FWHM in y: %.6f\n'%(pol[k],out1[0][0],out1[0][1],out1[0][2],out1[0][3])) 00480 # quickresult+=('Pol #%s\n Template coord: [%.3f,%.3f]\n FWHM in x: %.6f\n FWHM in y: %.6f\n'%(pol[k],out2[0][0],out2[0][1],out2[0][2],out2[0][3])) 00481 if(out1[0] != False and out2[0] != False): 00482 quickresult+=('Pol %s : Component Found in Image :\nra %s dec %s \nbmax %s bmin %s \nbpa %s flux %s \n'% \ 00483 (pol[k],\ 00484 out1[0][0],out1[0][1],\ 00485 out1[0][2],out1[0][3],\ 00486 out1[0][4],out1[0][5])) 00487 quickresult+=('Pol %s : Component Found in Template:\nra %s dec %s \nbmax %s bmin %s \nbpa %s flux %s \n'% \ 00488 (pol[k],out2[0][0],out2[0][1],out2[0][2],out2[0][3],out2[0][4],out2[0][5])) 00489 00490 self.result['image_'+pol[k]+'_ra'] = "'"+out1[0][0]+"'", pol[k]+" component RA" 00491 self.result['image_'+pol[k]+'_dec'] = "'"+out1[0][1]+"'", pol[k]+" component DEC" 00492 self.result['image_'+pol[k]+'_bmax'] = "'"+out1[0][2]+"'", "major axis" 00493 self.result['image_'+pol[k]+'_bmin'] = "'"+out1[0][3]+"'", "minor axis" 00494 self.result['image_'+pol[k]+'_bpa'] = "'"+out1[0][4]+"'", "position angle" 00495 self.result['image_'+pol[k]+'_flux'] = "'"+out1[0][5]+"'", "flux" 00496 00497 # Duplicate of above 00498 self.result['ref_'+pol[k]+'_ra'] = "'"+out2[0][0]+"'", pol[k]+" component RA" 00499 self.result['ref_'+pol[k]+'_dec'] = "'"+out2[0][1]+"'", pol[k]+" component DEC" 00500 self.result['ref_'+pol[k]+'_bmax'] = "'"+out2[0][2]+"'", "major axis" 00501 self.result['ref_'+pol[k]+'_bmin'] = "'"+out2[0][3]+"'", "minor axis" 00502 self.result['ref_'+pol[k]+'_bpa'] = "'"+out2[0][4]+"'", "position angle" 00503 self.result['ref_'+pol[k]+'_flux'] = "'"+out2[0][5]+"'", "flux" 00504 00505 00506 if(abs(rms2-rms1) > rms2/2.0): 00507 status=0 00508 else: 00509 quickresult+=('Image fitting did not converge \n') 00510 print >> sys.stderr, 'Image fitting did not converge' 00511 status=2 00512 ### Do a simple stats for pol Q,U,V 00513 for k in range(1, numPol): 00514 rms1,max1,min1,returnFlag1=b.simple_stats(plane=k) 00515 rms2,max2,min2,returnFlag=a.simple_stats(plane=k, sigma=rms1) 00516 quickresult+='Image Pol %s min: %f\nmax: %f\nrms: %f \n' %\ 00517 (pol[k],min2,max2,rms2) 00518 quickresult+='Template Pol %s min: %f\nmax: %f\nrms: %f \n' %\ 00519 (pol[k],min1,max1,rms1) 00520 00521 self.result['image_'+pol[k]+'_min'] = min2, pol[k]+" min" 00522 self.result['image_'+pol[k]+'_max'] = max2, pol[k]+" max" 00523 self.result['image_'+pol[k]+'_rms'] = rms2, pol[k]+" rms" 00524 00525 self.result['ref_'+pol[k]+'_min'] = min1, pol[k]+" min" 00526 self.result['ref_'+pol[k]+'_max'] = max1, pol[k]+" max" 00527 self.result['ref_'+pol[k]+'_rms'] = rms1, pol[k]+" rms" 00528 00529 if(not returnFlag): 00530 status=status*0 00531 if(abs(max2-max1) > rms2/2.0): 00532 status=status*0 00533 if(abs(min2-min1) > rms2/2.0): 00534 status=status*0 00535 quickresult+='</pre>' 00536 page=a.done() 00537 b.done() 00538 00539 self.result['status'] = ['fail', 'pass'][status==1], "result of regression test" 00540 00541 00542 00543 def simpleStats(self, imageName, templateImage, testname, WORKING_DIR, RESULT_DIR): 00544 a=ImageTest(imageName,write=True,resultDir=self.resultdir,imDir=self.imdir) 00545 b=ImageTest(templateImage,write=False,resultDir=self.resultdir,imDir=self.imdir) 00546 rms1,max1,min1,returnFlag1=b.simple_stats() 00547 b.done() 00548 status=1 # 1 : pass 00549 # 2 : unknown 00550 # other : fail 00551 00552 rms2,max2,min2,returnFlag=a.simple_stats(sigma=rms1) 00553 a.changeImage(templateImage) 00554 rms1,max1,min1,returnFlag1=a.simple_stats() 00555 if(not returnFlag): 00556 status=0 00557 quickresult='<pre>' 00558 quickresult+='Image min: %f\nmax: %f\nrms: %f \n' %(min2,max2,rms2) 00559 quickresult+='Template min: %f\nmax: %f\nrms: %f \n' %(min1,max1,rms1) 00560 quickresult+='</pre>' 00561 page=a.done() 00562 #b.done() 00563 00564 self.result['status'] = ['fail', 'pass'][status==1], "result of regression test" 00565 self.result['image_min'] = min2, "image min" 00566 self.result['image_max'] = max2, "image max" 00567 self.result['image_rms'] = rms2, "image rms" 00568 self.result['ref_min'] = min1, "reference min" 00569 self.result['ref_max'] = max1, "reference max" 00570 self.result['ref_rms'] = rms1, "reference rms" 00571 00572 00573 00574 def visStats(self, msName, templateMS, testname, WORKING_DIR, RESULT_DIR): 00575 a=VisTest(msName,write=True,resultDir=self.resultdir,imDir=self.imdir) 00576 b=VisTest(templateMS,write=False,resultDir=self.resultdir,imDir=self.imdir) 00577 arms1,amax1,amin1,prms1,pmax1,pmin1,returnFlag1=b.simple_stats() 00578 b.done() 00579 status=1 # 1 : pass 00580 # 2 : unknown 00581 # other : fail 00582 00583 arms2,amax2,amin2,prms2,pmax2,pmin2,returnFlag2=a.simple_stats() 00584 if(not returnFlag2): 00585 status=0 00586 quickresult='<pre>' 00587 quickresult+='MS min: %f\nmax: %f\nrms: %f \n' %(amin2,amax2,arms2) 00588 quickresult+='Template min: %f\nmax: %f\nrms: %f \n' %(amin1,amax1,arms1) 00589 quickresult+='</pre>' 00590 page=a.done() 00591 #b.done() 00592 00593 if(arms2 > 2.*arms1): 00594 status=status*0 00595 if(prms2 > 2.*prms1): 00596 status=status*0 00597 00598 if(abs(amax2-amax1) > arms2/2.0): 00599 status=status*0 00600 if(abs(amin2-amin1) > arms2/2.0): 00601 status=status*0 00602 if(abs(pmax2-pmax1) > prms2/2.0): 00603 status=status*0 00604 if(abs(pmin2-pmin1) > prms2/2.0): 00605 status=status*0 00606 00607 self.result['status'] = ['fail', 'pass'][status==1], "result of regression test" 00608 self.result['ms_amp_min'] = amin2, "ms amp min" 00609 self.result['ms_amp_max'] = amax2, "ms amp max" 00610 self.result['ms_amp_rms'] = arms2, "ms amp rms" 00611 self.result['ref_amp_min'] = amin1, "reference amp min" 00612 self.result['ref_amp_max'] = amax1, "reference amp max" 00613 self.result['ref_amp_rms'] = arms1, "reference amp rms" 00614 00615 self.result[ 'ms_pha_min'] = pmin2, "ms phase min" 00616 self.result[ 'ms_pha_max'] = pmax2, "ms phase max" 00617 self.result[ 'ms_pha_rms'] = prms2, "ms phase rms" 00618 self.result['ref_pha_min'] = pmin1, "reference phase min" 00619 self.result['ref_pha_max'] = pmax1, "reference phase max" 00620 self.result['ref_pha_rms'] = prms1, "reference phase rms" 00621 00622 00623 def cubeImageTest(self, imageName, templateImage, testname, WORKING_DIR, RESULT_DIR): 00624 a=ImageTest(imageName,write=True,resultDir=self.resultdir,imDir=self.imdir) 00625 # b=ImageTest(templateImage,write=False,resultDir=self.resultdir,imDir=self.imdir) 00626 status=1 00627 # XY1,fwhm1=a.auto_fitCube(a.b,verbose=0) 00628 XY1,fwhm1=a.auto_fitCube2() 00629 00630 a.changeImage(templateImage) 00631 00632 # XY2,fwhm2=a.auto_fitCube(a.b,verbose=0) 00633 00634 XY2,fwhm2=a.auto_fitCube2() 00635 00636 if(abs((XY1[0][0]-XY2[0][0])/XY2[0][0]) > 0.1): 00637 status=0 00638 if(abs((fwhm1[0]-fwhm2[0])/fwhm2[0]) > 0.1): 00639 status=0 00640 quickresult='<pre>' 00641 quickresult+='On image \n optimized coord: [%.3f,%.3f]\n FWHM: %.6f\n\nfit #1\n optimized coord: [%.3f,%.3f]\n FWHM: %.6f \n'%(XY1[0][0],XY1[0][1],fwhm1[0],XY1[1][0],XY1[1][1],fwhm1[1]) 00642 quickresult+='On Template \n optimized coord: [%.3f,%.3f]\n FWHM: %.6f\n\nfit #1\n optimized coord: [%.3f,%.3f]\n FWHM: %.6f \n'%(XY2[0][0],XY2[0][1],fwhm2[0],XY2[1][0],XY2[1][1],fwhm2[1]) 00643 quickresult+='</pre>' 00644 page=a.done() 00645 # b.done() 00646 00647 self.result['status'] = ['fail', 'pass'][status==1], "result of regression test" 00648 00649 self.result['image_x'] = XY1[0][0], "image optimized coord" 00650 self.result['image_y'] = XY1[0][1], "image optimized coord" 00651 self.result['image_fwhm'] = fwhm1[0], "image FWHM" 00652 self.result['image_fit1_x'] = XY1[1][0], "image fit1 optimized coord" 00653 self.result['image_fit1_y'] = XY1[1][1], "image fit1 optimized coord" 00654 self.result['image_fit1_fwhm'] = fwhm1[1], "image fit1 FWHM" 00655 00656 self.result['ref_x'] = XY2[0][0], "reference optimized coord" 00657 self.result['ref_y'] = XY2[0][1], "reference optimized coord" 00658 self.result['ref_fwhm'] = fwhm2[0], "reference FWHM" 00659 self.result['ref_fit1_x'] = XY2[1][0], "reference fit1 optimized coord" 00660 self.result['ref_fit1_y'] = XY2[1][1], "reference fit1 optimized coord" 00661 self.result['ref_fit1_fwhm'] = fwhm2[1], "reference fit1 FWHM" 00662 00663 def get_casa_version(self): 00664 a=inspect.stack() 00665 stacklevel=0 00666 for k in range(len(a)): 00667 if (string.find(a[k][1], 'ipython console') > 0): 00668 stacklevel=k 00669 myf=sys._getframe(stacklevel).f_globals 00670 00671 return "CASA Version " + myf['casa']['build']['version'] + " (r"+myf['casa']['source']['revision'] + ")" 00672 00673 def create_log(self, product_file): 00674 filename = "%s/result-%s-%s.txt" % \ 00675 (self.resultsubdir, product_file, \ 00676 self.result['type'][0]) 00677 filename = filename.replace("--", "-") 00678 00679 print "Writing file", filename 00680 try: 00681 self.logfd=open(filename, "w") 00682 except: 00683 print "Could not open file", filename 00684 raise 00685 for k, v in self.result.iteritems(): 00686 # too much output for time/mem stats: 00687 print k, "=", str(v[0])[0:100], "#", v[1] 00688 self.logfd.write("%-20s = %-40s # %-20s\n" % (k, v[0], v[1])) 00689 self.logfd.close() 00690 00691 def get_platform(self): 00692 OS = os.uname()[0] 00693 REV = os.uname()[2] 00694 MACH = os.uname()[4] 00695 if OS == 'SunOS': 00696 OS='Solaris' 00697 ARCH=commands.getoutput("uname -p") 00698 #return "%s %s (%s %s)" % (OS,REV,ARCH, commands.getoutput("uname -v")) 00699 return "%s %s" % (OS, MACH), \ 00700 "%s (%s %s)" % (REV,ARCH, commands.getoutput("uname -v")) 00701 elif OS == "AIX": 00702 return "%s %s" % (OS, MACH), \ 00703 "%s (%s)" % (commands.getoutput("oslevel"), 00704 commands.getoutput("oslevel -r")) 00705 elif OS == "Linux" or OS == "Darwin": 00706 KERNEL=REV 00707 if os.path.isfile("/etc/redhat-release"): 00708 DIST = commands.getoutput("head -1 /etc/redhat-release") 00709 elif os.path.isfile("/etc/SUSE-release"): 00710 DIST = commands.getoutput("head -1 /etc/SUSE-release") 00711 elif os.path.isfile("/etc/SuSE-release"): 00712 DIST = commands.getoutput("head -1 /etc/SuSE-release") 00713 elif os.path.isfile("/etc/mandrake-release"): 00714 DIST = commands.getoutput("head -1 /etc/mandrake-release") 00715 elif os.path.isfile("/etc/lsb-release"): 00716 DIST = \ 00717 commands.getoutput("grep DISTRIB_ID /etc/lsb-release | sed 's/.*=\s*//'") + \ 00718 ' release ' + commands.getoutput("grep DISTRIB_RELEASE /etc/lsb-release | sed 's/.*=\s*//'") + \ 00719 ' (' + commands.getoutput("grep DISTRIB_CODENAME /etc/lsb-release | sed 's/.*=\s*//'") + \ 00720 ')' 00721 elif os.path.isfile("/etc/debian_version"): 00722 DIST = commands.getoutput("head -1 /etc/debian_version") 00723 else: 00724 DIST = "???" 00725 00726 if MACH == "i686" or MACH == "i386": 00727 WORDSIZE = "32" 00728 elif MACH == "x86_64" or MACH == "ia64": 00729 WORDSIZE = "64" 00730 else: 00731 WORDSIZE = "??" 00732 00733 if OS == "Darwin": 00734 if commands.getoutput("sysctl -n hw.optional.x86_64").find("1") >= 0: 00735 WORDSIZE = "64" 00736 else: 00737 WORDSIZE = "32" 00738 00739 vers = commands.getoutput("/usr/bin/sw_vers -productVersion") 00740 if vers.find("10.4") >= 0: 00741 name = "Tiger" 00742 elif vers.find("10.5") >= 0: 00743 name = "Leopard" 00744 elif vers.find("10.6") >= 0: 00745 name = "Snow Leopard" 00746 elif vers.find("10.7") >= 0: 00747 name = "Tiger" 00748 else : 00749 name = "Unknown Mac OSX" 00750 00751 DIST = commands.getoutput("/usr/bin/sw_vers -productName") + " " + \ 00752 vers + " (" + name + " " + \ 00753 commands.getoutput("/usr/bin/sw_vers -buildVersion") + ")" 00754 00755 return "%s %s %s-bit" % (OS, MACH, WORDSIZE), DIST 00756 #return "%s %s %s (%s %s %s)" % (OS, DIST, REV, PSEUDONAME, KERNEL, MACH) 00757 #return "%s %s %s (%s)" % (OS, DIST, REV, PSEUDONAME) 00758 else: 00759 return "??? ??? ??-bit", "???" 00760 00761 00762 class logger: 00763 def __init__(self, name, ss): 00764 self.streams = ss # list of file objects where txt is sent 00765 self.name = name # for printing only 00766 self.bol = True # are we at beginning of line? 00767 def wwrite(self, txt, fback): # this method is no throw 00768 # (because it is used to 00769 # print error messages) 00770 # 00771 # fback: frame of caller 00772 try: 00773 #sys.__stderr__.write(txt) 00774 if self.bol: 00775 fb = fback 00776 if fb != None: 00777 pos = " %s:%d" % \ 00778 (os.path.basename(fb.f_code.co_filename), \ 00779 fb.f_lineno) 00780 else: 00781 pos = "" 00782 for s in self.streams: 00783 s.write("%s%s: " % \ 00784 (self.name, pos)) 00785 for s in self.streams: 00786 #s.write("'"+txt+"'") 00787 s.write(txt) 00788 s.flush() 00789 self.bol = (len(txt) > 0 and txt[-1] == '\n'); 00790 # note: doesn't handle \n in the middle of a string 00791 00792 except Exception, e: 00793 # should not happen 00794 sys.__stderr__.write(str(e) + " -- " + txt + "\n") 00795 00796 def write(self, txt): 00797 self.wwrite(txt, inspect.currentframe().f_back) 00798 00799 def writelines(self, lines): 00800 fb = inspect.currentframe().f_back 00801 for l in lines: 00802 self.wwrite(l, fb) 00803 00804 def flush(self): 00805 for s in self.streams: 00806 s.flush() 00807 00808 # fake remaining methods to make this class behave like a file 00809 #def __getattr__(self, name): 00810 # return getattr(self.streams[0], name) 00811 00812 # def __setattr__(self, name, value): 00813 # if name in dir(self): 00814 # self.__dict__[name] = value 00815 # else: 00816 # setattr(self.streams[0], name, value) 00817 00818 def __del__(self): 00819 pass 00820 #print >> sys.__stdout__, "Die", self.name