casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
fits-import-export_regression.py
Go to the documentation of this file.
00001 #############################################################################
00002 # $Id:$
00003 # Test Name:                                                                #
00004 #    Regression Test Script for importfits/exportfits                       #
00005 #                                                                           #
00006 # Rationale for Inclusion:                                                  #
00007 #    The proper handling of the FITS standard needs to be verified          #
00008 #    using standard input files constructed based on the FITS               #
00009 #    standard version 3.0 by Mark Calabretta                                #
00010 #                                                                           # 
00011 # Features tested:                                                          #
00012 #    1) Is the import performed without raising exceptions?                 #
00013 #    2) Is the imported image properly handling the WCS?                    #
00014 #       (i.e. is the RA and DEC of the max. flux properly determined?)      #
00015 #    3) Is the export performed without raising exceptions?                 #
00016 #    4) Is the exported file compatible with the original?                  #
00017 #    5) Does the bitpix=16 feature work                                     #
00018 #    6) Is spectral WCS correctly read and written                          #
00019 #                                                                           #
00020 # Input data:                                                               #
00021 #    28 sample fits files constructed by Mark Calabretta                    #
00022 #    for all standard projections                                           #
00023 #                                                                           #
00024 #############################################################################
00025 
00026 
00027 
00028 # get the dataset name from the wrapper if possible
00029 
00030 if not (locals()).has_key('datasets'):
00031     myname = 'fits-import-export_regression :'
00032     # The default dictionary of test datasets
00033     #  Each entry is a tuple of filename (w/o extension), expected pixel position of the maximum flux,
00034     #  expected absolute position of the maximum flux (RA, DEC), name.
00035     mydict = { 1: ('1904-66_AIR', [109, 167], '19:39:23.885, -63.45.36.905', 'Airy Projection (AIR)'),
00036                2: ('1904-66_AIT', [109, 168], '19:39:41.653, -63.43.54.147', 'Hammer-Aitoff Projection (AIT)'),  
00037                3: ('1904-66_ARC', [110, 170], '19:39:28.622, -63.41.53.659', 'Zenithal Equidistant Projection (ARC)'), 
00038                4: ('1904-66_AZP', [116, 186], '19:39:21.120, -63.44.26.642', 'Zenithal Perspective Projection (AZP)'), 
00039                5: ('1904-66_BON', [108, 173], '19:39:28.718, -63.41.12.383', 'Bonne\'s Equal Area Projection (BON)'), 
00040                6: ('1904-66_CAR', [113, 168], '19:39:42.371, -63.41.36.035', 'Plate Caree Projection (CAR)'), 
00041                7: ('1904-66_CEA', [113, 167], '19:39:35.136, -63.41.56.055', 'Cylindrical Equal Area Projection (CEA)'),
00042                8: ('1904-66_COD', [109, 166], '19:39:39.760, -63.42.02.640', 'Conic Equidistant Projection (COD)'), 
00043                9: ('1904-66_COE', [112, 172], '19:39:34.041, -63.44.23.296', 'Conic Equal-Area Projection (COE)'),
00044                10: ('1904-66_COO', [109, 161], '19:39:31.237, -63.44.09.556', 'Conic Orthomorphic Projection (COO)'), 
00045                11: ('1904-66_COP', [110, 161], '19:39:28.345, -63.44.40.626', 'Conic Perspective Projection (COP)'), 
00046                12: ('1904-66_CSC', [113, 180], '19:39:41.073, -63.43.25.624', 'COBE Quadrilateralized Spherical Cube Projection (CSC)'), 
00047                13: ('1904-66_CYP', [108, 157], '19:39:12.028, -63.43.07.315', 'Cylindrical Perspective Projection (CYP)'),  
00048                14: ('1904-66_HPX', [113, 179], '19:39:16.552, -63.42.47.347', 'HEALPix Grid Projection (HPX)'), 
00049                15: ('1904-66_MER', [113, 168], '19:39:16.276, -63.42.48.107', 'Mercator Projection (MER)'), 
00050                16: ('1904-66_MOL', [109, 175], '19:39:20.341, -63.41.44.201', 'Mollweide Projection (MOL)'), 
00051                17: ('1904-66_NCP', [107, 167], '19:39:38.614, -63.42.51.577', 'North Celetial Pole (SIN spcial case) Projection (NCP)'), 
00052                18: ('1904-66_PAR', [109, 171], '19:39:32.698, -63.42.04.737', 'Parabolic Projection (PAR)'), 
00053                19: ('1904-66_PCO', [108, 174], '19:39:21.403, -63.43.49.358', 'Polyconic Projection (PCO)'), 
00054                20: ('1904-66_QSC', [120, 182], '19:39:23.808, -63.41.22.666', 'Quadrilateralized Spherical Cube Projection (QSC)'), 
00055                21: ('1904-66_SFL', [108, 167], '19:39:16.950, -63.45.15.188', 'Samson-Flamsteed Projection (SFL)'), 
00056                22: ('1904-66_SIN', [107, 167], '19:39:38.614, -63.42.51.577', 'Slant Orthographic Projection (SIN)'), 
00057                23: ('1904-66_STG', [111, 171], '19:39:14.752, -63.44.20.882', 'Stereographic Projection (STG)'), 
00058                24: ('1904-66_SZP', [110, 177], '19:39:42.475, -63.42.13.751', 'Slant Zenithal Perspective Projection (SZP)'),
00059                25: ('1904-66_TAN', [116, 177], '19:39:30.753, -63.42.59.218', 'Gnomonic Projection (TAN)'), 
00060                26: ('1904-66_TSC', [112, 160], '19:39:39.997, -63.41.14.586', 'Tangential Spherical Cube Projection (TSC)'), 
00061                27: ('1904-66_ZEA', [109, 169], '19:39:26.872, -63.43.26.060', 'Zenithal Equal Area Projection (ZEA)'), 
00062                28: ('1904-66_ZPN', [94, 150], '19:39:24.948, -63.46.43.636', 'Zenithal Polynomial Projection (ZPN)'), 
00063                29: ('1904-66_AIT-obsgeo', [109, 168], '19:39:41.653, -63.43.54.147', 'Hammer-Aitoff Projection (AIT)')
00064            }
00065 else: # the script has been called from the wrapper, don't need to output name
00066     myname = ' '
00067     mydict = (locals())['datasets']
00068 
00069 
00070 def checkimage(myfitsimage_name, maxpos_expect, maxposf_expect):
00071     global myname
00072     subtest_passed = True
00073 
00074     # import the image
00075     default('importfits')
00076     try:
00077         print myname, ' Importing ', myfitsimage_name+'.fits', ' ...'
00078         importfits(fitsimage = myfitsimage_name+'.fits',
00079                    imagename = myfitsimage_name,
00080                    overwrite = True)
00081     except:
00082         print myname, ' Error ', sys.exc_info()[0]
00083         raise    
00084     else:
00085         print myname, ' No exceptions raised! Now checking image ...'
00086         # perform a basic check of the coordinate system
00087         ia.open(myfitsimage_name)
00088         mystat = imstat(imagename = myfitsimage_name)
00089         if not (myname == ' '):
00090             print mystat
00091         if not ((mystat['maxpos']) == maxpos_expect).all():
00092             print myname, ' Error in imported image ', myfitsimage_name, ':'
00093             print myname, '    expected pixel position of maximum is ', maxpos_expect
00094             print myname, '                               but found ', mystat['maxpos'] 
00095             subtest_passed = False    
00096         if not (mystat['maxposf'] == maxposf_expect):
00097             print myname, ' Error in imported image ', myfitsimage_name, ':'
00098             print myname, '   expected absolute position of maximum is ', maxposf_expect
00099             print myname, '                                  but found ', mystat['maxposf'] 
00100             subtest_passed = False 
00101         if subtest_passed:
00102             print myname, ' imported image ', myfitsimage_name, ' as expected.'
00103 
00104             # export the image
00105             default('exportfits')
00106             try:
00107                 print 'Exporting ', myfitsimage_name, '...'
00108                 exportfits(fitsimage = myfitsimage_name + 'exp.fits',
00109                            imagename = myfitsimage_name,
00110                            overwrite = True)
00111             except:
00112                 print myname, ' Error ', sys.exc_info()[0]
00113                 raise    
00114             else:
00115                 print myname, ' No exceptions raised! Now comparing exported image with original by re-importing it ...'
00116                 # re-import the image    
00117                 default('importfits')
00118                 try:
00119                     print myname, ' Re-importing ', myfitsimage_name+'exp.fits', ' ...'
00120                     importfits(fitsimage = myfitsimage_name+'exp.fits',
00121                                imagename = myfitsimage_name+'exp',
00122                                overwrite = True)
00123                 except:
00124                     print myname, ' Error ', sys.exc_info()[0]
00125                     raise    
00126                 else:
00127                     print myname, ' No exceptions raised! Now checking image ...'
00128                     ia.open(myfitsimage_name+'exp')
00129                     csm = ia.coordsys()
00130                     csm.summary() 
00131                     mystat = imstat(imagename = myfitsimage_name+'exp')
00132                     if not ((mystat['maxpos']) == maxpos_expect).all():
00133                         print myname, ' Error in re-imported image ', myfitsimage_name+'exp', ':'
00134                         print myname, '   expected pixel position of maximum is ', maxpos_expect
00135                         print myname, '                               but found ', mystat['maxpos'] 
00136                         subtest_passed = False    
00137                     if not (mystat['maxposf'] == maxposf_expect):
00138                         print myname, ' Error in re-imported image ', myfitsimage_name+'exp', ':'
00139                         print myname, '   expected absolute position of maximum is ', maxposf_expect
00140                         print myname, '                                  but found ', mystat['maxposf'] 
00141                         subtest_passed = False 
00142                     if subtest_passed:
00143                         print myname, ' re-imported image ', myfitsimage_name+'exp', ' as expected.'
00144     return subtest_passed
00145 # end def checkimage()
00146 
00147 def checkimageb(myfitsimage_name):
00148     global myname
00149     subtest_passed = True
00150 
00151     # import the image
00152     default('importfits')
00153     try:
00154         print myname, ' Importing ', myfitsimage_name+'.fits', ' ...'
00155         importfits(fitsimage = myfitsimage_name+'.fits',
00156                    imagename = myfitsimage_name,
00157                    overwrite = True)
00158     except:
00159         print myname, ' Error ', sys.exc_info()[0]
00160         raise    
00161     else:
00162         print myname, ' No exceptions raised!'
00163         mystat = imstat(imagename = myfitsimage_name)
00164         # export the image
00165         default('exportfits')
00166         try:
00167             print 'Exporting ', myfitsimage_name, ' with bitpix=16 ...'
00168             exportfits(fitsimage = myfitsimage_name + 'exp.fits',
00169                        imagename = myfitsimage_name,
00170                        overwrite = True, bitpix=16) # with BITPIX=16 !
00171         except:
00172             print myname, ' Error ', sys.exc_info()[0]
00173             raise    
00174         else:
00175             print myname, ' No exceptions raised! Now testing minimum and maximum values ...'
00176             # re-import the image    
00177             default('importfits')
00178             try:
00179                 print myname, ' Re-importing ', myfitsimage_name+'exp.fits', ' ...'
00180                 importfits(fitsimage = myfitsimage_name+'exp.fits',
00181                            imagename = myfitsimage_name+'exp',
00182                            overwrite = True)
00183             except:
00184                 print myname, ' Error ', sys.exc_info()[0]
00185                 raise    
00186             else:
00187                 print myname, ' No exceptions raised! Now checking image ...'
00188                 myotherstat = imstat(imagename = myfitsimage_name+'exp')
00189                 if not (abs((mystat['min'] - myotherstat['min'])/mystat['min']) < 1E-6):
00190                     print myname, ' Error in re-imported image ', myfitsimage_name+'exp', ':'
00191                     print myname, '   expected  minimum is ', mystat['min']
00192                     print myname, '                               but found ', myotherstat['min'] 
00193                     subtest_passed = False    
00194                 if not (abs((mystat['max'] - myotherstat['max'])/mystat['max']) < 1E-6):
00195                     print myname, ' Error in re-imported image ', myfitsimage_name+'exp', ':'
00196                     print myname, '   expected  maximum is ', mystat['max']
00197                     print myname, '                               but found ', myotherstat['max'] 
00198                     subtest_passed = False    
00199                 if subtest_passed:
00200                     print myname, ' re-imported image ', myfitsimage_name+'exp', ' as expected.'
00201     return subtest_passed
00202 # end def checkimage()
00203 
00204 failed_tests = []
00205 passed_tests = []
00206 
00207 for i in mydict.keys():
00208 
00209     thefitsimage_name = mydict[i][0]
00210     themaxpos_expect = mydict[i][1]
00211     themaxposf_expect = mydict[i][2]
00212     print myname, ' ***********************************************************'
00213     print myname, ' Subtest ', i, ': ', mydict[i][3]
00214     passed = checkimage(thefitsimage_name, themaxpos_expect, themaxposf_expect)
00215     if passed:
00216         print myname, ' Subtest ', i, ' passed.'
00217         passed_tests.append(mydict[i][3])
00218     else:
00219         print myname, ' Subtest ', i, ' failed.'
00220         failed_tests.append(mydict[i][3])
00221     print myname, ' ***********************************************************'
00222 
00223 
00224 thefitsimage_name = mydict[1][0]
00225 print myname, ' ***********************************************************'
00226 print myname, ' Test of the BITPIX parameter:'
00227 passed = checkimageb(thefitsimage_name)
00228 if passed:
00229     print myname, ' bitpix test passed.'
00230     passed_tests.append('bitpix')
00231 else:
00232     print myname, ' bitpix test failed.'
00233     failed_tests.append('bitpix')
00234 print myname, ' ***********************************************************'
00235 
00236 print myname, ' ***********************************************************'
00237 print myname, ' Test of the stokeslast parameter and the SPECSYS keyword:'
00238 exportfits(imagename='stokeslast-test.image', fitsimage='stokeslast-test.fits', stokeslast=True)
00239 myresult0 = os.system('grep SPECSYS stokeslast-test.fits > /dev/null')
00240 specsyspresent = (myresult0 == 0)
00241 importfits(imagename='stokeslast-test2.image', fitsimage='stokeslast-test.fits')
00242 myrgn1 = rg.box([0,0,1,0],[64,64,1,0])
00243 myrgn2 = rg.box([0,0,0,1],[64,64,0,1])
00244 ia.open('stokeslast-test.image')
00245 ia.subimage(outfile='sub1.im', region = myrgn1, overwrite=True)
00246 ia.close()
00247 ia.open('stokeslast-test2.image')
00248 ia.subimage(outfile='sub2.im', region = myrgn2, overwrite=True)
00249 ia.close()
00250 myresult1 = imstat('sub1.im', verbose=False)
00251 myresult2 = imstat('sub2.im', verbose=False)
00252 # imagecalc is on strike here because the formal coordinates of the slices disagree because the order is different
00253 # so use min, max, and sum
00254 passed = (myresult1['min']==myresult2['min']) and (myresult1['max']==myresult2['max']) \
00255          and (myresult1['sum']==myresult2['sum']) and specsyspresent
00256 if passed:
00257     print myname, ' stokeslast test passed.'
00258     passed_tests.append('stokeslast')
00259 else:
00260     print myname, ' stokeslast test failed.'
00261     failed_tests.append('stokeslast')
00262 print myname, ' ***********************************************************'
00263 
00264 print myname, ' ***********************************************************'
00265 print myname, ' Test of the wavelength parameter:'
00266 ia.open('stokeslast-test.image')
00267 ia.tofits(outfile='wavelength-test.fits', wavelength=True)
00268 ia.close()
00269 passed = ia.open('wavelength-test.fits')
00270 ia.close()
00271 
00272 ia.open('stokeslast-test.image')
00273 ia.tofits(outfile='wavelength-test2.fits', wavelength=True, airwavelength=True)
00274 ia.close()
00275 passed = passed and ia.open('wavelength-test2.fits')
00276 ia.close()
00277 
00278 if passed:
00279     print myname, ' wavelength parameter test passed.'
00280     passed_tests.append('wavelength')
00281 else:
00282     print myname, ' wavelength parameter test failed.'
00283     failed_tests.append('wavelength')
00284 print myname, ' ***********************************************************'
00285 
00286 print myname, ' ***********************************************************'
00287 print myname, ' Test of export of a standard single-channel image from clean:'
00288 ia.open('xxx-clean.image')
00289 ia.tofits(outfile='xxx-test.fits')
00290 ia.tofits(outfile='xxx-test-w.fits', wavelength=True)
00291 ia.close()
00292 passed1 = ia.open('xxx-test.fits')
00293 ia.close()
00294 passed2 = ia.open('xxx-test-w.fits')
00295 ia.close()
00296 passed = passed1==True and passed2==True
00297 if passed:
00298     print myname, ' trivial export tests passed.'
00299     passed_tests.append('trivial')
00300 else:
00301     print myname, ' trivial export test failed.'
00302     failed_tests.append('trivial')
00303 print myname, ' ***********************************************************'
00304 
00305 print myname, ' ***********************************************************'
00306 print myname, ' Test of import and export of FITs images with spectral WCS:'
00307 expecta = {'freq': 2.190956850600E+11,
00308            'vrad': 2.183247880000E+11,
00309            'vopt': 2.183247880000E+11,
00310            'wave': 2.204356308820E+11,
00311            'awav': 2.203722484080E+11}
00312 expectb = {'freq': 'Hz',
00313            'vrad': 'Hz',
00314            'vopt': 'Hz',
00315            'wave': 'Hz',
00316            'awav': 'Hz'}
00317 expectc = {'freq': 'LSRK',
00318            'vrad': 'BARY',
00319            'vopt': 'LSRD',
00320            'wave': 'GALACTO',
00321            'awav': 'CMB'}
00322 passedx = {'freq': False,
00323            'vrad': False,
00324            'vopt': False,
00325            'wave': False,
00326            'awav': False}
00327 passed = True
00328 #for ctype in ['freq','vrad','wave']:
00329 for myctype in ['freq','vrad','vopt','wave','awav']:
00330     try:
00331         print 'Testing CTYPE ', myctype, ' ...'
00332         importfits(imagename=myctype+'.im', fitsimage='spec-test-'+myctype+'.fits')
00333         cond0 = ia.open(myctype+'.im')
00334         coordm = ia.coordmeasures()
00335         cond1 = (abs(coordm['measure']['spectral']['frequency']['m0']['value']-expecta[myctype])<1.) # avoid Python precision problems
00336         print 'value, expectation, diff:', coordm['measure']['spectral']['frequency']['m0']['value'],',',\
00337               expecta[myctype], ",", coordm['measure']['spectral']['frequency']['m0']['value']-expecta[myctype]
00338         cond2 = (coordm['measure']['spectral']['frequency']['m0']['unit']==expectb[myctype])
00339         cond3 = (coordm['measure']['spectral']['frequency']['refer']==expectc[myctype])
00340         print cond0, cond1, cond2, cond3
00341         passed1 = cond0 and cond1 and cond2 and cond3
00342         ia.close()
00343         if(myctype=='freq'):
00344             exportfits(imagename=myctype+'.im', fitsimage='spec-test-'+myctype+'-ex.fits')
00345         elif(myctype=='vrad'):
00346             exportfits(imagename=myctype+'.im', fitsimage='spec-test-'+myctype+'-ex.fits', velocity=True, optical=False)
00347         elif(myctype=='vopt'):
00348             exportfits(imagename=myctype+'.im', fitsimage='spec-test-'+myctype+'-ex.fits', velocity=True, optical=True)
00349         elif(myctype=='wave'):
00350             ia.open(myctype+'.im')
00351             ia.tofits(outfile='spec-test-'+myctype+'-ex.fits', wavelength=True)
00352             ia.close()
00353         elif(myctype=='awav'):
00354             ia.open(myctype+'.im')
00355             ia.tofits(outfile='spec-test-'+myctype+'-ex.fits', wavelength=True, airwavelength=True)
00356             ia.close()
00357         else:
00358             print "Skipping export test for ", myctype
00359 
00360         passed2 = True
00361 
00362         importfits(imagename=myctype+'2.im', fitsimage='spec-test-'+myctype+'-ex.fits')
00363         cond0 = ia.open(myctype+'2.im')
00364         coordm = ia.coordmeasures()
00365         cond1 = (abs(coordm['measure']['spectral']['frequency']['m0']['value']-expecta[myctype])<1.) # avoid Python precision problems
00366         print 'value, expectation, diff:', coordm['measure']['spectral']['frequency']['m0']['value'],',',\
00367               expecta[myctype], ",", coordm['measure']['spectral']['frequency']['m0']['value']-expecta[myctype]
00368         cond2 = (coordm['measure']['spectral']['frequency']['m0']['unit']==expectb[myctype])
00369         cond3 = (coordm['measure']['spectral']['frequency']['refer']==expectc[myctype])
00370         print cond0, cond1, cond2, cond3
00371         passed2 = cond0 and cond1 and cond2 and cond3
00372         ia.close()
00373             
00374         passedx[myctype] = passed1 and passed2
00375         passed = passed and passedx[myctype]
00376     except:
00377         print myname, ' Error ', sys.exc_info()[0]
00378         passedx[myctype] = False
00379         passed = False
00380         
00381 if passed:
00382     print myname, ' Spectral WCS im/export tests passed.'
00383     passed_tests.append('spectralwcs')
00384 else:
00385     print myname, ' Spectral WCS im/export tests failed.'
00386     print passedx
00387     failed_tests.append('spectralwcs')
00388 print myname, ' ***********************************************************'
00389 
00390 
00391 if len(failed_tests)>0:
00392     if len(passed_tests)>0:
00393         print myname, ' Summary of passed subtests:'
00394         for i in range(0, len(passed_tests)):
00395             print myname, '          ', passed_tests[i]            
00396     print myname, ' Summary of failed subtests:'
00397     for i in range(0, len(failed_tests)):
00398         print myname, '          ', failed_tests[i]
00399     raise Exception, repr(len(failed_tests))+' out of '+repr(len(mydict.keys()))+' subtests failed.'
00400 else:
00401     print 'All subtests passed.'
00402     print ''
00403     print 'Regression PASSED'
00404     print ''
00405 print 'Done.'
00406 
00407 
00408 #End of Script