00001 import os
00002 import numpy
00003 import sys
00004 import shutil
00005 from __main__ import default
00006 from tasks import *
00007 from taskinit import *
00008
00009 import unittest
00010
00011 '''
00012 Unit tests for task uvcontsub.
00013
00014 Features tested:
00015 1. uvcontsub will use DATA if CORRECTED_DATA is absent.
00016 2. It gets the right answer for a known line + 0th order continuum.
00017 3. It gets the right answer for a known line + 4th order continuum.
00018 4. It gets the right answer for a known line + 0th order continuum,
00019 even when fitorder = 4.
00020 '''
00021 datapath = os.environ.get('CASAPATH').split()[0] + '/data/regression/unittest'
00022 uvcdatadir = 'uvcontsub'
00023
00024
00025 testmms = False
00026 if os.environ.has_key('TEST_DATADIR'):
00027 testmms = True
00028 DATADIR = str(os.environ.get('TEST_DATADIR'))
00029 if os.path.isdir(DATADIR):
00030 datapath = DATADIR
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 class UVContsubUnitTestBase(unittest.TestCase):
00064 """
00065 uvcontsub unittest base class (refactored)
00066 """
00067 def initialize(self,inpms):
00068 """
00069 initialize
00070 """
00071
00072 global testmms
00073
00074 if testmms:
00075 print "Testing on MMSs."
00076
00077 self.inpms = uvcdatadir+'/'+inpms
00078 if not os.path.exists(uvcdatadir):
00079 os.system('mkdir '+ uvcdatadir)
00080
00081 if not os.path.exists(self.inpms):
00082 try:
00083 shutil.copytree(datapath + '/' + self.inpms, self.inpms)
00084 except Exception, e:
00085 raise Exception, "Missing input MS: " + datapath + '/' + self.inpms
00086
00087
00088 def cleanup(self):
00089 """
00090 clean up the test dir
00091 """
00092 if os.path.exists(self.inpms):
00093 shutil.rmtree(self.inpms)
00094
00095
00096 def check_eq(self, val, expval, tol=None):
00097 """Checks that val matches expval within tol."""
00098 if type(val) == dict:
00099 for k in val:
00100 check_eq(val[k], expval[k], tol)
00101 else:
00102 try:
00103 if tol and hasattr(val, '__rsub__'):
00104 are_eq = abs(val - expval) < tol
00105 else:
00106 are_eq = val == expval
00107 if hasattr(are_eq, 'all'):
00108 are_eq = are_eq.all()
00109 if not are_eq:
00110 raise ValueError, '!='
00111 except ValueError:
00112 errmsg = "%r != %r" % (val, expval)
00113 if (len(errmsg) > 66):
00114 errmsg = "\n%r\n!=\n%r" % (val, expval)
00115 raise ValueError, errmsg
00116 except Exception, e:
00117 print "Error comparing", val, "to", expval
00118 raise e
00119
00120
00121
00122 class zeroth(UVContsubUnitTestBase):
00123 """Test zeroth order fit"""
00124
00125 def setUp(self):
00126 self.initialize('known0.ms')
00127
00128 def tearDown(self):
00129 self.cleanup()
00130
00131 def test_zeroth(self):
00132
00133 record = {}
00134 pnrows = {}
00135 try:
00136 print "\nRunning uvcontsub"
00137 uvran = uvcontsub(self.inpms, fitspw='0:0~5;18~23',
00138 fitorder=0, want_cont=True,
00139 async=False)
00140 except Exception, e:
00141 print "Error running uvcontsub"
00142 raise e
00143
00144
00145 for spec in ('cont', 'contsub'):
00146 specms = self.inpms + '.' + spec
00147 tb.open(specms)
00148 record[spec] = tb.getcell('DATA', 52)
00149 tb.close()
00150 tb.open(self.inpms+'.'+spec+'/POINTING')
00151 pnrows[spec] = tb.nrows()
00152 tb.close()
00153 shutil.rmtree(specms)
00154
00155
00156 self.assertEqual(uvran,True)
00157
00158 print "Continuum estimate in line-free region"
00159 self.check_eq(record['cont'][:,3],
00160 numpy.array([ 2.+3.j, 4.+5.j]), 0.0001)
00161
00162 print "Continuum estimate in line region"
00163 self.check_eq(record['cont'][:,13],
00164 numpy.array([ 2.+3.j, 4.+5.j]), 0.0001)
00165
00166 print "Continuum-subtracted data in line-free region"
00167 self.check_eq(record['contsub'][:,21],
00168 numpy.array([ 0.+0.j, 0.+0.j]), 0.0001)
00169
00170 print "Continuum-subtracted data in line region"
00171 self.check_eq(record['contsub'][:,9],
00172 numpy.array([87.+26.j, 31.+20.j]), 0.0001)
00173
00174 print "Non-empty pointing table (for MMS case)"
00175 self.assertEqual(pnrows['cont'], 1)
00176 self.assertEqual(pnrows['contsub'], 1)
00177
00178
00179 class fourth(UVContsubUnitTestBase):
00180
00181 def setUp(self):
00182 self.initialize('known4.ms')
00183
00184 def tearDown(self):
00185 self.cleanup()
00186
00187 def test_fourth(self):
00188
00189 infitorder=4
00190 record = {}
00191 try:
00192 print "\nRunning uvcontsub"
00193 uvran = uvcontsub(self.inpms, fitspw='0:0~5;18~23',
00194 fitorder=infitorder, want_cont=True,
00195 async=False)
00196 except Exception, e:
00197 print "Error running uvcontsub"
00198 raise e
00199
00200
00201 for spec in ('cont', 'contsub'):
00202 specms = self.inpms + '.' + spec
00203 tb.open(specms)
00204 record[spec] = tb.getcell('DATA', 52)
00205 tb.close()
00206 shutil.rmtree(specms)
00207
00208
00209 self.assertEqual(uvran,True)
00210
00211 print "Continuum estimate"
00212 self.check_eq(record['cont'],
00213 numpy.array([[20.00000-10.j, 12.50660-10.00000j,
00214 7.10324-10.00000j, 3.35941-10.j,
00215 0.89944-10.j, -0.59741-10.j,
00216 -1.39700-10.j, -1.71032-10.j,
00217 -1.69345-10.j, -1.44760-10.j,
00218 -1.01907-10.j, -0.39929-10.j,
00219 0.47521-10.j, 1.72278-10.j,
00220 3.51665-10.j, 6.08496-10.j,
00221 9.71073-10.j, 14.73187-10.j,
00222 21.54116-10.j, 30.58629-10.j,
00223 42.36984-10.j, 57.44926-10.00000j,
00224 76.43690-10.00000j,100.00000-10.j],
00225 [-10.00000+5.j, -6.25330+5.j,
00226 -3.55162+5.00000j, -1.67970+5.00000j,
00227 -0.44972+5.00000j, 0.29870+5.j,
00228 0.69850+5.j, 0.85516+5.j,
00229 0.84673+5.j, 0.72380+5.j,
00230 0.50953+5.j, 0.19964+5.j,
00231 -0.23760+5.j, -0.86139+5.j,
00232 -1.75832+5.j, -3.04248+5.j,
00233 -4.85537+5.j, -7.36593+5.j,
00234 -10.77058+5.j, -15.29315+5.00000j,
00235 -21.18492+5.00000j, -28.72463+5.00000j,
00236 -38.21845+5.j, -50.00000+5.j]]),
00237 0.0001)
00238
00239 print "Continuum-subtracted data"
00240 self.check_eq(record['contsub'],
00241 numpy.array([[0.00000+0.00000j, 0.00000+0.00000j,
00242 0.00000+0.00000j, 0.00000+0.00000j,
00243 0.00000+0.00000j, 0.00000+0.00000j,
00244 30.86956-0.10000j, 34.34782-0.10000j,
00245 37.82608-0.10000j, 41.30434-0.10000j,
00246 44.78260-0.10000j, 48.26086-0.10000j,
00247 48.26086-0.10000j, 44.78260-0.10000j,
00248 41.30434-0.10000j, 37.82608-0.10000j,
00249 34.34782-0.10000j, 30.86956-0.10000j,
00250 0.00000+0.00000j, 0.00000+0.00000j,
00251 0.00000+0.00000j, 0.00000+0.00000j,
00252 0.00000+0.00000j, 0.00000+0.00000j],
00253 [0.00000+0.00000j, 0.00000+0.00000j,
00254 0.00000+0.00000j, 0.00000+0.00000j,
00255 0.00000+0.00000j, 0.00000+0.00000j,
00256 -30.86956+0.10000j, -34.34782+0.10000j,
00257 -37.82608+0.10000j, -41.30434+0.10000j,
00258 -44.78260+0.10000j, -48.26086+0.10000j,
00259 -48.26086+0.10000j, -44.78260+0.10000j,
00260 -41.30434+0.10000j, -37.82608+0.10000j,
00261 -34.34782+0.10000j, -30.86956+0.10000j,
00262 0.00000+0.00000j, 0.00000+0.00000j,
00263 0.00000+0.00000j, 0.00000+0.00000j,
00264 0.00000+0.00000j, 0.00000+0.00000j]]),
00265 0.0001)
00266
00267
00268 class combspw(UVContsubUnitTestBase):
00269
00270 def setUp(self):
00271 self.initialize('combspw.ms')
00272
00273 def tearDown(self):
00274 self.cleanup()
00275
00276
00277 def test_combspw(self):
00278 fitorders = [0, 1]
00279 record = {}
00280 for infitorder in fitorders:
00281 record[infitorder]={}
00282 try:
00283 print "\nRunning uvcontsub"
00284 uvran = uvcontsub(self.inpms, fitspw='1~10:5~122,15~22:5~122',
00285 spw='6~14', combine='spw',
00286 fitorder=infitorder, want_cont=False,
00287 async=False)
00288 except Exception, e:
00289 print "Error running uvcontsub"
00290 raise e
00291
00292 specms = self.inpms + '.contsub'
00293 tb.open(specms)
00294 record[infitorder]['contsub'] = tb.getcell('DATA', 52)[0][73]
00295 tb.close()
00296 shutil.rmtree(specms)
00297
00298
00299 self.assertEqual(uvran,True)
00300
00301 print "combspw fitorder=0 line estimate"
00302 self.check_eq(record[0]['contsub'], -6.2324+17.9865j, 0.001)
00303
00304 print "combspw fitorder=1 line estimate"
00305 self.check_eq(record[1]['contsub'], -6.2533+17.6584j, 0.001)
00306
00307 def suite():
00308 return [zeroth, fourth, combspw]