casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
sdutil.py
Go to the documentation of this file.
00001 import os
00002 from casac import casac
00003 from taskinit import casalog
00004 import asap as sd
00005 from asap import _to_list
00006 from asap.scantable import is_scantable, is_ms
00007 import numpy as np
00008 import traceback
00009 import string
00010 from taskinit import gentools
00011 
00012 qatl = casac.quanta()
00013 
00014 class sdtask_interface(object):
00015     """
00016     The sdtask_interface defines a common interface for sdtask_worker
00017     class. All worker classes can be used as follows:
00018 
00019        worker = sdtask_worker(**locals())
00020        worker.initialize()
00021        worker.execute()
00022        worker.finalize()
00023        del worker
00024 
00025     Derived classes must implement the above three methods: initialize(),
00026     execute(), and finalize().
00027     """
00028     def __init__(self, **kwargs):
00029         for (k,v) in kwargs.items():
00030             setattr(self, k, v)
00031 
00032     def initialize(self):
00033         raise NotImplementedError('initialize is abstract method')
00034 
00035     def execute(self):
00036         raise NotImplementedError('execute is abstract method')
00037 
00038     def finalize(self):
00039         raise NotImplementedError('finalize is abstract method')
00040 
00041 class sdtask_template(sdtask_interface):
00042     """
00043     The sdtask_template is a template class for standard worker
00044     class of non-imaging sdtasks. It partially implement initialize()
00045     and finalize() using internal methods that must be implemented
00046     in the derived classes. For initialize(), derived classes
00047     must implement initialize_scan(), which initializes scantable
00048     object and set it to self.scan. You can implement paramter_check()
00049     to do any task specific parameter check in initialize().
00050     For finalize(), derived classes can implement save() and cleanup().
00051     """
00052     def __init__(self, **kwargs):
00053         super(sdtask_template,self).__init__(**kwargs)
00054         if not hasattr(self, 'outform'):
00055             self.outform = 'undefined'
00056         self.is_disk_storage = (sd.rcParams['scantable.storage'] == 'disk')
00057 
00058     def initialize(self):
00059         if hasattr(self, 'infile'):
00060             assert_infile_exists(self.infile)
00061         elif hasattr(self, 'infiles'):
00062             if isinstance(self.infiles,str):
00063                 assert_infile_exists(self.infiles)
00064             else:
00065                 for f in self.infiles:
00066                     assert_infile_exists(f)
00067         if hasattr(self, 'suffix'):
00068             if hasattr(self, 'infile'):
00069                 self.project = get_default_outfile_name(self.infile,self.outfile,self.suffix)
00070             elif hasattr(self, 'infiles'):
00071                 self.project = get_default_outfile_name(self.infiles[0],self.outfile,self.suffix)
00072         elif hasattr(self, 'outfile') and len(self.outfile) > 0:
00073             self.project = self.outfile
00074 ##         if hasattr(self, 'outfile') and len(self.outfile) > 0:
00075 ##             assert_outfile_canoverwrite_or_nonexistent(self.outfile,self.outform,self.overwrite)
00076         if hasattr(self, 'project'):
00077             assert_outfile_canoverwrite_or_nonexistent(self.project,self.outform,self.overwrite)
00078 
00079         # task specific parameter check
00080         self.parameter_check()
00081         
00082         # set self.scan
00083         self.initialize_scan()
00084 
00085     def finalize(self):
00086         # Save result on disk if necessary
00087         self.save()
00088 
00089         # some cleanup should be defined here
00090         self.cleanup()
00091 
00092     def initialize_scan(self):
00093         # initialize scantable object to work with
00094         raise NotImplementedError('initialize_scan is abstract method')
00095 
00096     def parameter_check(self):
00097         # do nothing by default
00098         pass
00099 
00100     def save(self):
00101         # do nothing by default
00102         pass
00103         
00104     def cleanup(self):
00105         # do nothing by default
00106         pass
00107         
00108     def get_selector(self):
00109         attributes = ['scanlist','iflist','pollist','beamlist',
00110                       'rowlist','field']
00111         for a in attributes:
00112             if not hasattr(self,a): setattr(self,a,None)
00113         return get_selector(in_scans=self.scanlist, in_ifs=self.iflist,
00114                             in_pols=self.pollist, in_beams=self.beamlist,
00115                             in_rows=self.rowlist, in_field=self.field)
00116 
00117     def set_to_scan(self):
00118         if hasattr(self,'fluxunit'):
00119             set_fluxunit(self.scan, self.fluxunit, self.telescopeparm)
00120         if hasattr(self,'frame'):
00121             set_freqframe(self.scan, self.frame)
00122         if hasattr(self,'doppler'):
00123             set_doppler(self.scan,self.doppler)
00124         if hasattr(self,'specunit'):
00125             set_spectral_unit(self.scan,self.specunit)
00126             if hasattr(self,'restfreq'):
00127                 rfset = self.restfreq not in ['',[]]
00128                 if self.specunit == 'km/s':
00129                     if len(self.scan.get_restfreqs()[0]) == 0 and not rfset:
00130                         raise Exception('Restfreq must be given')
00131                     if rfset:
00132                         fval = normalise_restfreq(self.restfreq)
00133                         casalog.post( 'Set rest frequency to %s Hz' % str(fval) )
00134                         self.scan.set_restfreqs(freqs=fval)
00135 
00136 class sdtask_template_imaging(sdtask_interface):
00137     """
00138     The sdtask_template_imaging is a template class for worker
00139     class of imaging related sdtasks. It partially implement initialize()
00140     and finalize() using internal methods that must be implemented
00141     in the derived classes. For initialize(), derived classes
00142     must implement compile(), which sets up imaging parameters.
00143     You can implement paramter_check() to do any task specific parameter
00144     check in initialize().
00145     For finalize(), derived classes can implement cleanup().
00146     """
00147     def __init__(self, **kwargs):
00148         super(sdtask_template_imaging,self).__init__(**kwargs)
00149         self.is_table_opened = False
00150         self.is_imager_opened = False
00151         self.table, self.imager = gentools(['tb','im'])
00152         self.__set_subtable_name()
00153 
00154     def __del__(self):
00155         # table and imager must be closed when the instance
00156         # is deleted
00157         self.close_table()
00158         self.close_imager()
00159 
00160     def open_table(self, name, nomodify=True):
00161         if self.is_table_opened:
00162             casalog.post('Close table before re-open', priority='WARN')
00163             return
00164         self.table.open(name, nomodify=nomodify)
00165         self.is_table_opened = True
00166 
00167     def close_table(self):
00168         if self.is_table_opened:
00169             self.table.close()
00170         self.is_table_opened = False
00171 
00172     def open_imager(self, name):
00173         if self.is_imager_opened:
00174             casalog.post('Close imager before re-open', priority='WARN')
00175             return
00176         self.imager.open(name)
00177         self.is_imager_opened = True
00178 
00179     def close_imager(self):
00180         if self.is_imager_opened:
00181             self.imager.close()
00182         self.is_imager_opened = False
00183 
00184     def initialize(self):
00185         # infile must be MS
00186         if not is_ms(self.infile):
00187             msg='infile must be in MS format'
00188             raise Exception, msg
00189         
00190         self.parameter_check()
00191         self.compile()
00192 
00193     def finalize(self):
00194         self.cleanup()
00195         self.close_table()
00196         self.close_imager()
00197 
00198     def parameter_check(self):
00199         pass
00200 
00201     def compile(self):
00202         pass
00203 
00204     def cleanup(self):
00205         pass
00206         
00207     def __set_subtable_name(self):
00208         self.open_table(self.infile)
00209         keys = self.table.getkeywords()
00210         self.close_table()
00211         self.field_table = get_subtable_name(keys['FIELD'])
00212         self.spw_table = get_subtable_name(keys['SPECTRAL_WINDOW'])
00213         self.source_table = get_subtable_name(keys['SOURCE'])
00214         self.antenna_table = get_subtable_name(keys['ANTENNA'])
00215         self.polarization_table = get_subtable_name(keys['POLARIZATION'])
00216         self.observation_table = get_subtable_name(keys['OBSERVATION'])
00217         self.pointing_table = get_subtable_name(keys['POINTING'])
00218         self.data_desc_table = get_subtable_name(keys['DATA_DESCRIPTION'])
00219 
00220 class sdtask_engine(object):
00221     def __init__(self, worker):
00222         # set worker instance to work with
00223         self.worker = worker
00224 
00225         # copy worker attributes except scan
00226         # use worker.scan to access scantable
00227         for (k,v) in self.worker.__dict__.items():
00228             if k == 'scan': continue
00229             setattr(self, k, v)
00230 
00231     def prologue(self):
00232         pass
00233 
00234     def drive(self):
00235         pass
00236 
00237     def epilogue(self):
00238         pass
00239     
00240 class parameter_registration(object):
00241     def __init__(self, worker, arg_is_value=False):
00242         self.worker = worker
00243         self.registered = {}
00244         self.arg_is_value = arg_is_value
00245 
00246     def register(self, key, *args, **kwargs):
00247         arg_is_none = (len(args) == 0 or args[0] == None)
00248         arg_is_value = self.arg_is_value
00249         if kwargs.has_key('arg_is_value'):
00250             arg_is_value = bool(kwargs['arg_is_value'])
00251         if not arg_is_none:
00252             attr = args[0]
00253             if arg_is_value:
00254                 self.__register(key, attr)
00255             elif isinstance(attr, str) and hasattr(self.worker, attr):
00256                 self.__register(key, getattr(self.worker, attr))
00257             else:
00258                 self.__register(key, attr)
00259         elif hasattr(self.worker, key):
00260             self.__register(key, getattr(self.worker, key))
00261         else:
00262             self.__register(key, None)
00263 
00264     def __register(self, key, val):
00265         self.registered[key] = val
00266 
00267     def clear(self):
00268         self.registered.clear()
00269 
00270     def get_registered(self):
00271         return self.registered
00272         
00273 
00274 def get_abspath(filename):
00275     return os.path.abspath(expand_path(filename))
00276 
00277 def expand_path(filename):
00278     return os.path.expanduser(os.path.expandvars(filename))
00279 
00280 def assert_infile_exists(infile=None):
00281     if (infile == ""):
00282         raise Exception, "infile is undefined"
00283 
00284     filename = get_abspath(infile)
00285     if not os.path.exists(filename):
00286         mesg = "File '%s' not found." % (infile)
00287         raise Exception, mesg
00288 
00289 
00290 def get_default_outfile_name(infile=None, outfile=None, suffix=None):
00291     if (outfile == ""):
00292         res = infile.rstrip("/") + suffix
00293     else:
00294         res = outfile.rstrip("/")
00295     return res
00296 
00297 
00298 def assert_outfile_canoverwrite_or_nonexistent(outfile=None, outform=None, overwrite=None):
00299     if not overwrite and (outform.upper() != "ASCII"):
00300         filename = get_abspath(outfile)
00301         if os.path.exists(filename):
00302             mesg = "Output file '%s' exists." % (outfile)
00303             raise Exception, mesg
00304 
00305 
00306 def get_listvalue(value):
00307     return _to_list(value, int) or []
00308 
00309 def get_selector(in_scans=None, in_ifs=None, in_pols=None, \
00310                  in_field=None, in_beams=None, in_rows=None):
00311     scans = get_listvalue(in_scans)
00312     ifs   = get_listvalue(in_ifs)
00313     pols  = get_listvalue(in_pols)
00314     beams = get_listvalue(in_beams)
00315     rows = get_listvalue(in_rows)
00316     selector = sd.selector(scans=scans, ifs=ifs, pols=pols, beams=beams,
00317                            rows=rows)
00318 
00319     if (in_field != ""):
00320         # NOTE: currently can only select one
00321         # set of names this way, will probably
00322         # need to do a set_query eventually
00323         selector.set_name(in_field)
00324 
00325     return selector
00326 
00327 
00328 def get_restfreq_in_Hz(s_restfreq):
00329     if not qatl.isquantity(s_restfreq):
00330         mesg = "Input value is not a quantity: %s" % (str(s_restfreq))
00331         raise Exception, mesg
00332     if qatl.compare(s_restfreq,'Hz'):
00333         return qatl.convert(s_restfreq, 'Hz')['value']
00334     elif qatl.quantity(s_restfreq)['unit'] == '':
00335         return float(s_restfreq)
00336     else:
00337         mesg = "wrong unit of restfreq."
00338         raise Exception, mesg
00339 ###############################################################
00340 # def get_restfreq_in_Hz(s_restfreq):
00341 #     value = 0.0
00342 #     unit = ""
00343 #     s = s_restfreq.replace(" ","")
00344 # 
00345 #     for i in range(len(s))[::-1]:
00346 #         if s[i].isalpha():
00347 #             unit = s[i] + unit
00348 #         else:
00349 #             value = float(s[0:i+1])
00350 #             break
00351 # 
00352 #     if (unit == "") or (unit.lower() == "hz"):
00353 #         return value
00354 #     elif (len(unit) == 3) and (unit[1:3].lower() == "hz"):
00355 #         unitprefix = unit[0]
00356 #         factor = 1.0
00357 # 
00358 #         if (unitprefix == "a"):
00359 #             factor = 1.0e-18
00360 #         elif (unitprefix == "f"):
00361 #             factor = 1.0e-15
00362 #         elif (unitprefix == "p"):
00363 #             factor = 1.0e-12
00364 #         elif (unitprefix == "n"):
00365 #             factor = 1.0e-9
00366 #         elif (unitprefix == "u"):
00367 #             factor = 1.0e-6
00368 #         elif (unitprefix == "m"):
00369 #             factor = 1.0e-3
00370 #         elif (unitprefix == "k"):
00371 #             factor = 1.0e+3
00372 #         elif (unitprefix == "M"):
00373 #             factor = 1.0e+6
00374 #         elif (unitprefix == "G"):
00375 #             factor = 1.0e+9
00376 #         elif (unitprefix == "T"):
00377 #             factor = 1.0e+12
00378 #         elif (unitprefix == "P"):
00379 #             factor = 1.0e+15
00380 #         elif (unitprefix == "E"):
00381 #             factor = 1.0e+18
00382 #         
00383 #         return value*factor
00384 #     else:
00385 #         mesg = "wrong unit of restfreq."
00386 #         raise Exception, mesg
00387 ###############################################################
00388 
00389 def normalise_restfreq(in_restfreq):
00390     if isinstance(in_restfreq, float):
00391         return in_restfreq
00392     elif isinstance(in_restfreq, int) or isinstance(in_restfreq, long):
00393         return float(in_restfreq)
00394     elif isinstance(in_restfreq, str):
00395         return get_restfreq_in_Hz(in_restfreq)
00396     elif isinstance(in_restfreq, list) or isinstance(in_restfreq, np.ndarray):
00397         if isinstance(in_restfreq, np.ndarray):
00398             if len(in_restfreq.shape) > 1:
00399                 mesg = "given in numpy.ndarray, in_restfreq must be 1-D."
00400                 raise Exception, mesg
00401         
00402         res = []
00403         for i in xrange(len(in_restfreq)):
00404             elem = in_restfreq[i]
00405             if isinstance(elem, float):
00406                 res.append(elem)
00407             elif isinstance(elem, int) or isinstance(elem, long):
00408                 res.append(float(elem))
00409             elif isinstance(elem, str):
00410                 res.append(get_restfreq_in_Hz(elem))
00411             elif isinstance(elem, dict):
00412                 if isinstance(elem["value"], float):
00413                     res.append(elem)
00414                 elif isinstance(elem["value"], int):
00415                     dictelem = {}
00416                     dictelem["name"]  = elem["name"]
00417                     dictelem["value"] = float(elem["value"])
00418                     res.append(dictelem)
00419                 elif isinstance(elem["value"], str):
00420                     dictelem = {}
00421                     dictelem["name"]  = elem["name"]
00422                     dictelem["value"] = get_restfreq_in_Hz(elem["value"])
00423                     res.append(dictelem)
00424             else:
00425                 mesg = "restfreq elements must be float, int, or string."
00426                 raise Exception, mesg
00427         return res
00428     else:
00429         mesg = "wrong type of restfreq given."
00430         raise Exception, mesg
00431 
00432 def set_restfreq(s, restfreq):
00433     rfset = (restfreq != '') and (restfreq != [])
00434     if rfset:
00435         s.set_restfreqs(normalise_restfreq(restfreq))
00436 
00437 def set_spectral_unit(s, specunit):
00438     if (specunit != ''):
00439         s.set_unit(specunit)
00440 
00441 def set_doppler(s, doppler):
00442     if (doppler != ''):
00443         if (doppler in ['radio', 'optical', 'z']):
00444             ddoppler = doppler.upper()
00445         else:
00446             ddoppler = doppler
00447         s.set_doppler(ddoppler)
00448     else:
00449         casalog.post('Using current doppler conversion')
00450 
00451 def set_freqframe(s, frame):
00452     if (frame != ''):
00453         s.set_freqframe(frame)
00454     else:
00455         casalog.post('Using current frequency frame')
00456 
00457 def set_fluxunit(s, fluxunit, telescopeparm, insitu=True):
00458     ret = None
00459     
00460     # check current fluxunit
00461     # for GBT if not set, set assumed fluxunit, Kelvin
00462     antennaname = s.get_antennaname()
00463     fluxunit_now = s.get_fluxunit()
00464     if (antennaname == 'GBT'):
00465         if (fluxunit_now == ''):
00466             casalog.post('No fluxunit in the data. Set to Kelvin.')
00467             s.set_fluxunit('K')
00468             fluxunit_now = s.get_fluxunit()
00469     casalog.post('Current fluxunit = %s'%(fluxunit_now))
00470 
00471     # convert flux
00472     # set flux unit string (be more permissive than ASAP)
00473     if (fluxunit == 'k'):
00474         fluxunit_local = 'K'
00475     elif (fluxunit.upper() == 'JY'):
00476         fluxunit_local = 'Jy'
00477     else:
00478         fluxunit_local = fluxunit
00479 
00480         
00481     # fix the fluxunit if necessary
00482     if ( telescopeparm == 'FIX' or telescopeparm == 'fix' ):
00483         if ( fluxunit_local != '' ):
00484             if ( fluxunit_local == fluxunit_now ):
00485                 #print "No need to change default fluxunits"
00486                 casalog.post( "No need to change default fluxunits" )
00487             else:
00488                 s.set_fluxunit(fluxunit_local)
00489                 #print "Reset default fluxunit to "+fluxunit
00490                 casalog.post( "Reset default fluxunit to "+fluxunit_local )
00491                 fluxunit_now = s.get_fluxunit()
00492         else:
00493             #print "Warning - no fluxunit for set_fluxunit"
00494             casalog.post( "no fluxunit for set_fluxunit", priority = 'WARN' )
00495 
00496 
00497     elif ( fluxunit_local=='' or fluxunit_local==fluxunit_now ):
00498         if ( fluxunit_local==fluxunit_now ):
00499             #print "No need to convert fluxunits"
00500             casalog.post( "No need to convert fluxunits" )
00501 
00502     elif ( type(telescopeparm) == list ):
00503         # User input telescope params
00504         if ( len(telescopeparm) > 1 ):
00505             D = telescopeparm[0]
00506             eta = telescopeparm[1]
00507             #print "Use phys.diam D = %5.1f m" % (D)
00508             #print "Use ap.eff. eta = %5.3f " % (eta)
00509             casalog.post( "Use phys.diam D = %5.1f m" % (D) )
00510             casalog.post( "Use ap.eff. eta = %5.3f " % (eta) )
00511             ret = s.convert_flux(eta=eta,d=D,insitu=insitu)
00512         elif ( len(telescopeparm) > 0 ):
00513             jypk = telescopeparm[0]
00514             #print "Use gain = %6.4f Jy/K " % (jypk)
00515             casalog.post( "Use gain = %6.4f Jy/K " % (jypk) )
00516             ret = s.convert_flux(jyperk=jypk,insitu=insitu)
00517         else:
00518             #print "Empty telescope list"
00519             casalog.post( "Empty telescope list" )
00520 
00521     elif ( telescopeparm=='' ):
00522         if ( antennaname == 'GBT'):
00523             # needs eventually to be in ASAP source code
00524             #print "Convert fluxunit to "+fluxunit
00525             casalog.post( "Convert fluxunit to "+fluxunit_local )
00526             # THIS IS THE CHEESY PART
00527             # Calculate ap.eff eta at rest freq
00528             # Use Ruze law
00529             #   eta=eta_0*exp(-(4pi*eps/lambda)**2)
00530             # with
00531             #print "Using GBT parameters"
00532             casalog.post( "Using GBT parameters" )
00533             eps = 0.390  # mm
00534             eta_0 = 0.71 # at infinite wavelength
00535             # Ideally would use a freq in center of
00536             # band, but rest freq is what I have
00537             rf = s.get_restfreqs()[0][0]*1.0e-9 # GHz
00538             eta = eta_0*np.exp(-0.001757*(eps*rf)**2)
00539             #print "Calculated ap.eff. eta = %5.3f " % (eta)
00540             #print "At rest frequency %5.3f GHz" % (rf)
00541             casalog.post( "Calculated ap.eff. eta = %5.3f " % (eta) )
00542             casalog.post( "At rest frequency %5.3f GHz" % (rf) )
00543             D = 104.9 # 100m x 110m
00544             #print "Assume phys.diam D = %5.1f m" % (D)
00545             casalog.post( "Assume phys.diam D = %5.1f m" % (D) )
00546             ret = s.convert_flux(eta=eta,d=D,insitu=insitu)
00547             
00548             #print "Successfully converted fluxunit to "+fluxunit
00549             casalog.post( "Successfully converted fluxunit to "+fluxunit_local )
00550         elif ( antennaname in ['AT','ATPKSMB', 'ATPKSHOH', 'ATMOPRA', 'DSS-43', 'CEDUNA', 'HOBART']):
00551             ret = s.convert_flux(insitu=insitu)
00552             
00553         else:
00554             # Unknown telescope type
00555             #print "Unknown telescope - cannot convert"
00556             casalog.post( "Unknown telescope - cannot convert", priority = 'WARN' )
00557 
00558     return ret
00559     
00560 def save(s, outfile, outform, overwrite):
00561     assert_outfile_canoverwrite_or_nonexistent(outfile,
00562                                                outform,
00563                                                overwrite)
00564     outform_local = outform.upper()
00565     if outform_local == 'MS': outform_local = 'MS2'
00566     if outform_local not in ['ASAP','ASCII','MS2','SDFITS']:
00567         outform_local = 'ASAP'
00568 
00569     outfilename = get_abspath(outfile)
00570     if overwrite and os.path.exists(outfilename):
00571         os.system('rm -rf %s' % outfilename)
00572 
00573     s.save(outfile, outform_local, overwrite)
00574 
00575     if outform_local!='ASCII':
00576         casalog.post('Wrote output %s file %s'%(outform_local,outfile))
00577 
00578 def doopacity(s, tau):
00579     antennaname = s.get_antennaname()
00580     if (tau > 0.0):
00581         if (antennaname != 'GBT'):
00582             s.recalc_azel()
00583         s.opacity(tau, insitu=True)
00584 
00585 def dochannelrange(s, channelrange):
00586     # channel splitting
00587     if ( channelrange != [] ):
00588         if ( len(channelrange) == 1 ):
00589             #print "Split spectrum in the range [%d, %d]" % (0, channelrange[0])
00590             casalog.post( "Split spectrum in the range [%d, %d]" % (0, channelrange[0]) )
00591             s._reshape( 0, int(channelrange[0]) )
00592         else:
00593             #print "Split spectrum in the range [%d, %d]" % (channelrange[0], channelrange[1])
00594             casalog.post( "Split spectrum in the range [%d, %d]" % (channelrange[0], channelrange[1]) )
00595             s._reshape( int(channelrange[0]), int(channelrange[1]) )
00596 
00597 
00598 def doaverage(s, scanaverage, timeaverage, tweight, polaverage, pweight,
00599               averageall=False, docopy=False):
00600     # Average in time if desired
00601     sret = None
00602     if ( timeaverage ):
00603         if tweight=='none':
00604             errmsg = "Please specify weight type of time averaging"
00605             raise Exception,errmsg
00606         stave=sd.average_time(s,weight=tweight,scanav=scanaverage,compel=averageall)
00607         # Now average over polarizations;
00608         if ( polaverage ):
00609             if pweight=='none':
00610                 errmsg = "Please specify weight type of polarization averaging"
00611                 raise Exception,errmsg
00612             np = len(stave.getpolnos())
00613             if ( np > 1 ):
00614                 sret=stave.average_pol(weight=pweight)
00615             else:
00616                 # only single polarization
00617                 #print "Single polarization data - no need to average"
00618                 casalog.post( "Single polarization data - no need to average" )
00619                 sret = stave
00620         else:
00621             sret = stave
00622         #    spave=stave.copy()
00623         
00624     else:
00625         #if ( scanaverage ):
00626         #        # scan average if the input is a scantable
00627         #        spave=sd.average_time(scal,weight=pweight,scanav=True)
00628         #        scal=spave.copy()
00629         if ( polaverage ):
00630             if pweight=='none':
00631                 errmsg = "Please specify weight type of polarization averaging"
00632                 raise Exception,errmsg
00633             np = s.npol()
00634             if ( np > 1 ):
00635                 if not scanaverage:
00636                     sret = sd.average_time(s,weight=pweight)
00637                 else:
00638                     sret = s
00639                 sret=sret.average_pol(weight=pweight)
00640             else:
00641                 # only single polarization
00642                 #print "Single polarization data - no need to average"
00643                 casalog.post( "Single polarization data - no need to average" )
00644                 #spave=scal.copy()
00645                 sret = s
00646         else:
00647             if scanaverage:
00648                 sret=sd.average_time(s,scanav=True)
00649             else:
00650                 #spave=scal.copy()
00651                 sret = s
00652     if docopy and (sret == s):
00653         sret = s.copy()
00654     return sret
00655 
00656 def plot_scantable(s, pltfile, plotlevel, comment=None):
00657     # reset plotter
00658     if sd.plotter._plotter:
00659         sd.plotter._plotter.quit()
00660     visible = sd.plotter._visible
00661     sd.plotter.__init__(visible=visible)
00662     # each IF is separate panel, pols stacked
00663     sd.plotter.set_mode(stacking='p',panelling='i',refresh=False)
00664     sd.plotter.set_histogram(hist=True,linewidth=1,refresh=False)
00665     sd.plotter.plot(s)
00666     if comment is not None:
00667         # somehow I need to put text() twice in order to the second
00668         # text() actually displays on the plot...
00669         sd.plotter.text(0.0, 1.0,'',coords='relative')
00670         #sd.plotter.text(0.0, 1.0,'Raw spectra', coords='relative')
00671         sd.plotter.text(0.0, 1.0,comment, coords='relative')
00672     #sd.plotter.axhline(color='r',linewidth=2)
00673     if ( plotlevel < 0 ):
00674         # Hardcopy - currently no way w/o screen display first
00675         #pltfile=project+'_'+suffix+'.eps'
00676         sd.plotter.save(pltfile)
00677 
00678 def scantable_restore_factory(s, infile, fluxunit, specunit, frame, doppler, restfreq=''):
00679     storage = sd.rcParams['scantable.storage']
00680     isscantable = is_scantable(infile)
00681     if storage == 'memory' or isscantable == False:
00682         return scantable_restore_null(s, fluxunit, specunit, frame, doppler, restfreq)
00683     else:
00684         return scantable_restore_impl(s, fluxunit, specunit, frame, doppler, restfreq)
00685 
00686 class scantable_restore_interface(object):
00687     def __init__(self, s=None, fluxunit=None, specunit=None, frame=None, doppler=None, restfreq=None):
00688         pass
00689 
00690     def restore(self):
00691         raise NotImplementedError('scantable_restore.restore() is not implemented')
00692 
00693 class scantable_restore_null(scantable_restore_interface):
00694     def __init__(self, s, fluxunit, specunit, frame, doppler, restfreq=''):
00695         super(scantable_restore_null,self).__init__()
00696 
00697     def restore(self):
00698         pass
00699     
00700         
00701 class scantable_restore_impl(scantable_restore_interface):
00702     def __init__(self, s, fluxunit, specunit, frame, doppler, restfreq=''):
00703         super(scantable_restore_impl,self).__init__()
00704         self.scntab = s
00705         self.fluxunit = s.get_fluxunit()
00706         self.specunit = s.get_unit()
00707         self.coord = s._getcoordinfo()
00708         self.frame = self.coord[1]
00709         self.doppler = self.coord[2]
00710         self.molids = s._getmolidcol_list()
00711         self.rfset = ((restfreq != '') and (restfreq != []))
00712         self.frameset = frame != '' or frame != self.frame
00713         self.dopplerset = doppler != '' or doppler != self.doppler
00714         self.fluxset = self.fluxunit != '' and \
00715                        (fluxunit != '' or fluxunit != self.fluxunit)
00716         self.specset = specunit != '' or specunit != self.specunit
00717         self.restore_not_done = True
00718 
00719     def __del__(self):
00720         # do restore when the instance is deleted
00721         self.restore()
00722 
00723     def restore(self):
00724         if self.restore_not_done:
00725             self.scntab.set_selection()
00726         
00727             casalog.post('Restoreing header information in input scantable')
00728             self._restore()
00729 
00730         self.restore_not_done = False
00731                          
00732     def _restore(self):
00733         if self.fluxset:
00734             self.scntab.set_fluxunit(self.fluxunit)
00735         if self.specset:
00736             self.scntab.set_unit(self.specunit)
00737         if self.dopplerset:
00738             self.scntab.set_doppler(self.doppler)
00739         if self.frameset:
00740             self.scntab.set_freqframe(self.frame)
00741         if self.rfset:
00742             self.scntab._setmolidcol_list(self.molids)
00743 
00744 def interactive_mask(s, masklist, invert=False, purpose=None):
00745     new_mask = init_interactive_mask(s, masklist, invert)
00746     msk = get_interactive_mask(new_mask, purpose)
00747     finalize_interactive_mask(new_mask)
00748     del new_mask
00749     return msk
00750 
00751 def init_interactive_mask(s, masklist, invert=False):
00752     new_mask = sd.interactivemask(scan=s)
00753     if (len(masklist) > 0):
00754         new_mask.set_basemask(masklist=masklist,invert=invert)
00755     new_mask.select_mask(once=False,showmask=True)
00756     return new_mask
00757 
00758 def get_interactive_mask(obj, purpose=None):
00759     # Wait for user to finish mask selection
00760     finish=raw_input("Press return %s.\n"%(purpose))
00761     return obj.get_mask()
00762 
00763 def finalize_interactive_mask(obj):
00764     obj.finish_selection()
00765     
00766 def process_exception(e):
00767     casalog.post(traceback.format_exc(),'SEVERE')
00768     casalog.post(str(e),'ERROR')
00769 
00770 def get_plotter(plotlevel=0):
00771     from matplotlib import rc as rcp
00772     rcp('lines', linewidth=1)
00773     from asap.asapplotter import new_asaplot
00774     visible = sd.rcParams['plotter.gui']
00775     if plotlevel > 0 and (not visible):
00776         casalog.post("GUI plot not available", priority = "ERROR")
00777 ##     visible = (plotlevel > 0) if plotlevel else sd.rcParams['plotter.gui']
00778     plotter = new_asaplot(visible=visible)
00779     return plotter
00780 
00781 def get_nx_ny(n):
00782     nl = _to_list(n, int)
00783     if len(nl) == 1:
00784         nx = ny = nl[0]
00785     else:
00786         nx = nl[0]
00787         ny = nl[1]
00788     return (nx,ny)
00789 
00790 def get_cellx_celly(c,unit='arcsec'):
00791     if isinstance(c, str):
00792         cellx = celly = c
00793     elif isinstance(c, list) or isinstance(c, numpy.ndarray):
00794         if len(c) == 1:
00795             cellx = celly = __to_quantity_string(c[0],unit)
00796         elif len(c) > 1:
00797             cellx = __to_quantity_string(c[0],unit)
00798             celly = __to_quantity_string(c[1],unit)
00799         else:
00800             cellx = celly = ''
00801     else:
00802         cellx = celly = __to_quantity_string(c,unit)
00803     return (cellx, celly)
00804                 
00805 def get_map_center(c,frame='J2000',unit='rad'):
00806     map_center = ''
00807     if isinstance(c, str):
00808         if len(c) > 0:
00809             s = c.split()
00810             if len(s) == 2:
00811                 map_center = 'J2000 '+c
00812             elif len(s) == 3:
00813                 if s[0].upper() != 'J2000':
00814                     raise ValueError, 'Currently only J2000 is supported'
00815                 map_center = c
00816             else:
00817                 raise ValueError, 'Invalid map center: %s'%(c)
00818     else:
00819         l = [frame]
00820         for i in xrange(2):
00821             if isinstance(c[i], str):
00822                 l.append(c[i])
00823             else:
00824                 l.append('%s%s'%(c[i],unit))
00825         map_center = string.join(l)
00826     return map_center
00827 
00828 def __to_quantity_string(v,unit='arcsec'):
00829     if isinstance(v, str):
00830         return v
00831     else:
00832         return '%s%s'%(v,unit)
00833 
00834 def get_subtable_name(v):
00835     return v.replace('Table:','').strip()