casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
test_imcollapse.py
Go to the documentation of this file.
00001 ##########################################################################
00002 # imfit_test.py
00003 #
00004 # Copyright (C) 2008, 2009
00005 # Associated Universities, Inc. Washington DC, USA.
00006 #
00007 # This script is free software; you can redistribute it and/or modify it
00008 # under the terms of the GNU Library General Public License as published by
00009 # the Free Software Foundation; either version 2 of the License, or (at your
00010 # option) any later version.
00011 #
00012 # This library is distributed in the hope that it will be useful, but WITHOUT
00013 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00015 # License for more details.
00016 #
00017 # You should have received a copy of the GNU Library General Public License
00018 # along with this library; if not, write to the Free Software Foundation,
00019 # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00020 #
00021 # Correspondence concerning AIPS++ should be adressed as follows:
00022 #        Internet email: aips2-request@nrao.edu.
00023 #        Postal address: AIPS++ Project Office
00024 #                        National Radio Astronomy Observatory
00025 #                        520 Edgemont Road
00026 #                        Charlottesville, VA 22903-2475 USA
00027 #
00028 # <author>
00029 # Dave Mehringer
00030 # </author>
00031 #
00032 # <summary>
00033 # Test suite for the CASA task imcollapse
00034 # </summary>
00035 #
00036 # <reviewed reviwer="" date="" tests="" demos="">
00037 # </reviewed
00038 #
00039 # <prerequisite>
00040 # <ul>
00041 #   <li> <linkto class="task_imcollapse.py:description">imcollapse</linkto> 
00042 # </ul>
00043 # </prerequisite>
00044 #
00045 # <etymology>
00046 # Test for the imcollapse task
00047 # </etymology>
00048 #
00049 # <synopsis>
00050 # Test the imcollapse task and the ia.collapse() method upon which it is built.
00051 # </synopsis> 
00052 #
00053 # <example>
00054 #
00055 # This test runs as part of the CASA python unit test suite and can be run from
00056 # the command line via eg
00057 # 
00058 # `echo $CASAPATH/bin/casapy | sed -e 's$ $/$'` --nologger --log2term -c `echo $CASAPATH | awk '{print $1}'`/code/xmlcasa/scripts/regressions/admin/runUnitTest.py test_imcollapse[test1,test2,...]
00059 #
00060 # </example>
00061 #
00062 # <motivation>
00063 # To provide a test standard for the imcollapse task to ensure
00064 # coding changes do not break the associated bits 
00065 # </motivation>
00066 #
00067 
00068 ###########################################################################
00069 import shutil
00070 import casac
00071 from tasks import *
00072 from taskinit import *
00073 from __main__ import *
00074 import unittest
00075 
00076 good_image = "collapse_in.fits"
00077 masked_image = "im_w_mask.im"
00078 datapath=os.environ.get('CASAPATH').split()[0]+'/data/regression/unittest/imcollapse/'
00079 
00080 
00081 def run_collapse(
00082     imagename, function, axes, outfile, region, box, chans,
00083     stokes, mask, overwrite, stretch=False
00084 ):
00085     myia = iatool()
00086     myia.open(imagename)
00087     res = myia.collapse(
00088         function=function, axes=axes, outfile=outfile,
00089         region=region, box=box, chans=chans, stokes=stokes,
00090         mask=mask, overwrite=overwrite, stretch=stretch
00091     )
00092     myia.close()
00093     myia.done()
00094     return res
00095 
00096 def run_imcollapse(
00097     imagename, function, axes, outfile, region, box, chans,
00098     stokes, mask, overwrite, wantreturn, stretch=False
00099 ):
00100     return imcollapse(
00101         imagename=imagename, function=function, axes=axes,
00102         outfile=outfile, region=region, box=box, chans=chans,
00103         stokes=stokes, mask=mask, overwrite=overwrite,
00104         wantreturn=wantreturn, stretch=stretch
00105     )
00106 
00107 class imcollapse_test(unittest.TestCase):
00108     
00109     def setUp(self):
00110         shutil.copy(datapath + good_image, good_image)
00111         self.tabular_spectral_image = datapath + "longZax"
00112 
00113     def tearDown(self):
00114         os.remove(good_image)
00115 
00116     def checkImage(self, gotImage, expectedName):
00117         expected = iatool()                                
00118         expected.open(expectedName)
00119         got = iatool()
00120         if type(gotImage) == str:
00121             got.open(gotImage)
00122         else:
00123             got = gotImage
00124         self.assertTrue(all(got.shape() == expected.shape()))
00125         diffData = got.getchunk() - expected.getchunk()
00126         self.assertTrue(abs(diffData).max() == 0)
00127         gotCsys = got.coordsys()
00128         expectedCsys = expected.coordsys()
00129         diffPixels = gotCsys.referencepixel()['numeric'] - expectedCsys.referencepixel()['numeric']
00130         self.assertTrue(abs(diffPixels).max() == 0)
00131         fracDiffRef = (
00132             gotCsys.referencevalue()['numeric'] - expectedCsys.referencevalue()['numeric']
00133         )/expectedCsys.referencevalue()['numeric'];
00134         self.assertTrue(abs(fracDiffRef).max() <= 1.5e-6)
00135         beam = got.restoringbeam()
00136         self.assertTrue(len(beam) == 3)
00137         self.assertTrue(abs(beam["major"]["value"] - 1) < 1.5e-6)
00138         self.assertTrue(abs(beam["minor"]["value"] - 1) < 1.5e-6)
00139         self.assertTrue(abs(beam["positionangle"]["value"] - 40) < 1.5e-6)
00140         got.close()
00141         got.done()
00142         expected.close()
00143         expected.done()
00144 
00145     def test_exceptions(self):
00146         """imcollapse: Test various exception cases"""
00147         
00148         bogus = "mybogus.im"
00149         def testit(
00150             imagename, function, axes, outfile, region,
00151             box, chans, stokes, mask, overwrite, wantreturn
00152         ):
00153             for i in [0,1]:
00154                 if (i==0 and len(imagename) > 0 and imagename != bogus):
00155                     self.assertRaises(
00156                         Exception, run_collapse, imagename,
00157                         function, axes, outfile, region, box,
00158                         chans, stokes, mask, overwrite
00159                     )
00160                 else:
00161                     self.assertFalse(
00162                         run_imcollapse(
00163                             imagename, function, axes,
00164                             outfile, region, box, chans,
00165                             stokes, mask, overwrite,
00166                             wantreturn
00167                         )
00168                     )
00169         # no image name given
00170         testit("", "mean", 0, "", "", "", "", "", "", False, True)
00171         # bad image name given
00172         testit(bogus, "mean", 0, "", "", "", "", "", "", False, True)
00173         # no function given
00174         testit(good_image, "", 0, "", "", "", "", "", "", False, True)
00175         # bogus function given
00176         testit(good_image, "bogus function", 0, "", "", "", "", "", "", False, True)
00177         # bogus region given
00178         testit(good_image, "mean", 0, "", "bogus_region", "", "", "", "", False, True)
00179         #bogus box
00180         testit(good_image, "mean", 0, "", "", "abc", "", "", "", False, True)
00181         # another bogus box
00182         testit(good_image, "mean", 0, "", "", "0,0,1000,1000", "", "", "", False, True)
00183         # no axes
00184         testit(good_image, "mean", "", "", "", "", "", "", "", False, True)
00185         # bogus axes
00186         testit(good_image, "mean", 10, "", "", "", "", "", "", False, True)
00187 
00188     def test_1(self):
00189         """imcollapse: average full image collapse along axis 0"""
00190         expected = "collapse_avg_0.fits"
00191         shutil.copy(datapath + expected, expected)
00192         for i in [0, 1]:
00193             for axis in (0 ,"r", "right"):
00194                 outname = "test_1_" + str(i) + "_" + str(axis) + ".im"
00195                 if i == 0:
00196                     mytool = run_collapse(
00197                         good_image, "mean", axis, outname, "", "",
00198                         "", "", "", False
00199                     )
00200                     self.assertTrue(type(mytool) == type(ia))
00201                     self.checkImage(mytool, expected)
00202                     self.checkImage(outname, expected)
00203                 else:
00204                     for wantreturn in [True, False]:
00205                         outname = outname + str(wantreturn)
00206                         mytool = run_imcollapse(
00207                             good_image, "mean", 0, outname, "", "",
00208                             "", "", "", False, wantreturn
00209                         )
00210                         if (wantreturn):
00211                             self.assertTrue(type(mytool) == type(ia))
00212                             self.checkImage(mytool, expected)
00213                         else:
00214                             self.assertTrue(mytool == None)
00215                         self.checkImage(outname, expected)
00216                 shutil.rmtree(outname)
00217 
00218     def test_2(self):
00219         """imcollapse: average full image collapse along axis 2"""
00220         expected = "collapse_avg_2.fits"
00221         shutil.copy(datapath + expected, expected)
00222         for i in [0, 1]:
00223             for axis in (2, "f", "freq"):
00224                 outname = "test_2_" + str(i) + str(axis) + ".im"
00225                 if i == 0:
00226                     mytool = run_collapse(
00227                         good_image, "mean", axis, outname, "", "",
00228                         "", "", "", False
00229                     )
00230                     self.assertTrue(type(mytool) == type(ia))
00231                     self.checkImage(mytool, expected)
00232                     self.checkImage(outname, expected)
00233                 else:
00234                     for wantreturn in [True, False]:
00235                         outname = outname + str(wantreturn)
00236                         mytool = run_imcollapse(
00237                             good_image, "mean", 2, outname, "", "",
00238                             "", "", "", False, wantreturn
00239                         )
00240                         if (wantreturn):
00241                             self.assertTrue(type(mytool) == type(ia))
00242                             self.checkImage(mytool, expected)
00243                         else:
00244                             self.assertTrue(mytool == None)
00245                         self.checkImage(outname, expected)
00246                 shutil.rmtree(outname)
00247 
00248     def test_3(self):
00249         """imcollapse: average full image collapse along axis 2 and check output overwritability"""
00250         expected = "collapse_sum_1.fits"
00251         shutil.copy(datapath + expected, expected)
00252         box = "1,1,2,2"
00253         chans = "1~2"
00254         stokes = "qu"
00255         for i in [0, 1]:
00256             outname = "test_3_" + str(i) + ".im"
00257             if i == 0:
00258                 mytool = run_collapse(
00259                     good_image, "sum", 1, outname, "", box,
00260                     chans, stokes, "", False
00261                 )
00262                 # check that can overwrite previous output. Then check output image
00263                 mytool = run_collapse(
00264                     good_image, "sum", 1, outname, "", box,
00265                     chans, stokes, "", True
00266                 )
00267                 self.assertTrue(type(mytool) == type(ia))
00268                 self.checkImage(mytool, expected)
00269                 self.checkImage(outname, expected)
00270             else:
00271                 for wantreturn in [True, False]:
00272                     outname = outname + str(wantreturn)
00273                     # check that can overwrite previous output. Then check output image
00274                     mytool = run_imcollapse(
00275                         good_image, "sum", 1, outname, "", box,
00276                         chans, stokes, "", False, wantreturn
00277                     )
00278                     mytool = run_imcollapse(
00279                         good_image, "sum", 1, outname, "", box,
00280                         chans, stokes, "", True, wantreturn
00281                     )
00282                     if (wantreturn):
00283                         self.assertTrue(type(mytool) == type(ia))
00284                         self.checkImage(mytool, expected)
00285                     else:
00286                         self.assertTrue(mytool == None)
00287                     self.checkImage(outname, expected)
00288             shutil.rmtree(outname)
00289 
00290     def test_4(self):
00291         """imcollapse: not specifying an output image is ok"""
00292         expected = "collapse_avg_2.fits"
00293         shutil.copy(datapath + expected, expected)
00294         for i in [0, 1]:
00295             if i == 0:
00296                 mytool = run_collapse(
00297                     good_image, "mean", 2, "", "", "",
00298                     "", "", "", False
00299                 )
00300                 self.assertTrue(type(mytool) == type(ia))
00301                 self.checkImage(mytool, expected)
00302             else:
00303                 mytool = run_imcollapse(
00304                     good_image, "mean", 2, "", "", "",
00305                     "", "", "", False, True
00306                 )
00307                 self.assertTrue(type(mytool) == type(ia))
00308                 self.checkImage(mytool, expected)
00309 
00310     def test_5(self):
00311         """imcollapse: not wanting a tool returned results in None being returned"""
00312         expected = "collapse_avg_2.fits"
00313         shutil.copy(datapath + expected, expected)
00314         mytool = run_imcollapse(
00315             good_image, "mean", 2, "", "", "",
00316             "", "", "", False, False
00317         )
00318         self.assertTrue(mytool == None)
00319 
00320         
00321     def test_6(self):
00322         """imcollapse: memory only images can be collapsed"""
00323         mytool = run_collapse(
00324             good_image, "mean", 2, "", "", "",
00325             "", "", "", False
00326         )
00327         mytool2 = mytool.collapse("mean", 3)
00328         expected = [3, 3, 1, 1]
00329         self.assertTrue(all(mytool2.shape() == expected))
00330         
00331         mytool = run_imcollapse(
00332             good_image, "mean", 2, "", "", "",
00333             "", "", "", False, True
00334         )
00335         mytool2 = mytool.collapse("mean", 3)
00336         expected = [3, 3, 1, 1]
00337         self.assertTrue(all(mytool2.shape() == expected))
00338  
00339     def test_7(self):
00340         """imcollapse: verify collapsing along multiple axes works"""
00341         expected = "collapse_avg_0_1.fits"
00342         shutil.copy(datapath + expected, expected)
00343         for i in [0, 1]:
00344             for axes in ([0, 1], ["r", "d"], ["right", "dec"]):
00345                 if i == 0:
00346                     mytool = run_collapse(
00347                         good_image, "mean", axes, "", "", "",
00348                         "", "", "", False
00349                     )
00350                     self.assertTrue(type(mytool) == type(ia))
00351                     self.checkImage(mytool, expected)
00352                 else:
00353                     mytool = run_imcollapse(
00354                         good_image, "mean", [0, 1], "", "", "",
00355                         "", "", "", False, True
00356                     )
00357                     self.assertTrue(type(mytool) == type(ia))
00358                     self.checkImage(mytool, expected)
00359 
00360     def test_8(self):
00361         """imcollapse: test both OTF and permanent masking works"""
00362         xx = iatool()
00363         good_image_im = "collapse_in.im"
00364         xx.fromfits(good_image_im, good_image)
00365         xx.calcmask(good_image_im + "<78")
00366         xx.close()
00367         xx.done()
00368         mytool = F
00369         axes = 3
00370         for i in [0,1]:
00371             for j in [0, 1, 2]:
00372                 mask = good_image_im + ">7"
00373                 if j == 0:
00374                     xx.open(good_image_im)
00375                     xx.maskhandler("set", "")
00376                     xx.close()
00377                     xx.done()
00378                 if j == 1:
00379                     mask = ""
00380                     xx.open(good_image_im)
00381                     xx.maskhandler("set", "mask0")
00382                     xx.close()
00383                     xx.done()
00384                 for func in ["mean", "median"]:
00385                     for outfile in ["", "test_8_"+str(i) + str(j) + func]:
00386                         if i == 0:
00387                             mytool = run_collapse(
00388                                 good_image_im, func, axes, outfile, "", "",
00389                                 "", "", mask, False
00390                             )
00391                             self.assertTrue(type(mytool) == type(ia))
00392                         else:
00393                             mytool = run_imcollapse(
00394                                 good_image_im, func, axes, outfile, "", "",
00395                                 "", "", mask, False, True
00396                             )
00397                             self.assertTrue(type(mytool) == type(ia))
00398                         npts = mytool.statistics()["npts"]
00399                         mytool.close()
00400                         mytool.done()
00401                         if (j == 0):
00402                             self.assertTrue(npts == 25)
00403                         elif (j == 1):
00404                             self.assertTrue(npts == 26)
00405                         else:
00406                             self.assertTrue(npts == 24)
00407 
00408     def test_CAS_3418(self):
00409         """imcollapse: Test seperate code for median due to performance issues"""
00410         for i in range(0,4):
00411             xx = iatool()
00412             xx.open(good_image)
00413             exp = xx.statistics(robust=T, axes=i)["median"]
00414             xx.done()
00415             mytool = run_collapse(
00416                 good_image, "median", i, "", "", "",
00417                 "", "", "", False
00418             )
00419             zz = mytool.subimage("", dropdeg=T)
00420             got = zz.getchunk()
00421             self.assertTrue((got == exp).all())
00422             
00423             mytool = run_imcollapse(
00424                 good_image, "median", i, "", "", "",
00425                 "", "", "", False, True
00426             )
00427             zz = mytool.subimage("", dropdeg=T)
00428             got = zz.getchunk()
00429             self.assertTrue((got == exp).all())
00430             mytool.done()
00431             zz.done()
00432             
00433     def test_stretch(self):
00434         """ imcollapse: Test stretch parameter"""
00435         yy = iatool()
00436         yy.open(good_image)
00437         mycs = yy.coordsys().torecord()
00438         yy.done()
00439         maskim = "ymask"
00440         yy.fromshape(maskim,[3,3,1,1])
00441         yy.addnoise()
00442         yy.setcoordsys(mycs)
00443         yy.done()
00444         for i in [0,1]:
00445             if i == 1:
00446                 yy = run_collapse(
00447                     good_image, "mean", 0, "", "", "", "",
00448                     "", maskim + ">0", False, stretch=True
00449                 )
00450             else:
00451                 yy = run_imcollapse(
00452                     good_image, "mean", 0, "", "", "", "",
00453                     "", maskim + ">0", False, True, True
00454                 )
00455             self.assertTrue(type(yy) == type(ia))
00456             
00457     def test_CAS3737(self):
00458         """ imcollapse: test tabular spectral axis has correct collapsed reference value """
00459         image = self.tabular_spectral_image
00460         chans = "2445~2555"
00461         mytool = run_collapse(
00462             image, "mean", 2, "", "", "",
00463             chans, "", "", False
00464         )
00465         expected = 98318505973583.641
00466         got = mytool.toworld([0,0,0])["numeric"][2]
00467         mytool.done()
00468         frac = got/expected - 1
00469         self.assertTrue(frac < 1e-6 and frac > -1e-6)
00470         
00471         mytool = run_imcollapse(
00472             image, "mean", 2, "", "", "",
00473             chans, "", "", False, True
00474         )
00475         got = mytool.toworld([0,0,0])["numeric"][2]
00476         mytool.done()
00477         frac = got/expected - 1
00478         self.assertTrue(frac < 1e-6 and frac > -1e-6)
00479         
00480     def test_beams(self):
00481         """test per plane beams"""
00482         myia = iatool()
00483         myia.fromshape("", [10, 10, 10, 4])
00484         myia.setrestoringbeam(
00485             major="4arcsec", minor="3arcsec",
00486             pa="20deg", channel=1, polarization=1
00487         )
00488         for i in range (myia.shape()[2]):
00489             for j in range(myia.shape()[3]):
00490                 major = qa.quantity(4 + i + j, "arcsec")
00491                 minor = qa.quantity(2 + i + 0.5*j, "arcsec")
00492                 pa = qa.quantity(10*i + j, "deg")
00493                 myia.setrestoringbeam(
00494                     major=major, minor=minor, pa=pa,
00495                     channel=i, polarization=j
00496                 )
00497         reg = rg.box(blc=[1,1,1,1], trc=[2,2,2,2])
00498         collapsed = myia.collapse(function="mean", axes=2, outfile="", region=reg)
00499         beam = collapsed.restoringbeam()
00500         self.assertTrue(len(beam) == 3)
00501         self.assertTrue(beam["major"] == qa.quantity(6, "arcsec"))
00502         self.assertTrue(beam["minor"] == qa.quantity(3.5, "arcsec"))
00503         self.assertTrue(beam["positionangle"] == qa.quantity(11, "deg"))
00504         myia.done()
00505         collapsed.done()
00506 
00507 
00508 
00509 def suite():
00510     return [imcollapse_test]