casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
peel_cli.py
Go to the documentation of this file.
00001 #
00002 # This file was generated using xslt from its XML file
00003 #
00004 # Copyright 2008, Associated Universities Inc., Washington DC
00005 #
00006 import sys
00007 import os
00008 #from casac import *
00009 import casac
00010 import string
00011 import time
00012 import inspect
00013 import gc
00014 import numpy
00015 from odict import odict
00016 from taskmanager import tm
00017 from task_peel import peel
00018 class peel_cli_:
00019     __name__ = "peel"
00020     __async__ = {}
00021     rkey = None
00022     i_am_a_casapy_task = None
00023     # The existence of the i_am_a_casapy_task attribute allows help()
00024     # (and other) to treat casapy tasks as a special case.
00025 
00026     def __init__(self) :
00027        self.__bases__ = (peel_cli_,)
00028        self.__doc__ = self.__call__.__doc__
00029 
00030        self.parameters={'vis':None, 'dirs':None, 'remove':None, 'calmode':None,  'async':None}
00031 
00032 
00033     def result(self, key=None):
00034             #### here we will scan the task-ids in __async__
00035             #### and add any that have completed...
00036             if key is not None and self.__async__.has_key(key) and self.__async__[key] is not None:
00037                ret = tm.retrieve(self.__async__[key])
00038                if ret['state'] == "done" :
00039                   self.__async__[key] = None
00040                elif ret['state'] == 'crashed' :
00041                   self.__async__[key] = None
00042                return ret
00043             return None
00044 
00045 
00046     def __call__(self, vis=None, dirs=None, remove=None, calmode=None,  async=None):
00047 
00048         """Do direction dependent selfcal(s) and optionally remove annoying sources.
00049 Unfortunately at some level gains are direction-dependent, typically
00050 because of either deviations between the true antenna voltage patterns and
00051 the models being used, and/or fluctuations in one layer or another of the
00052 Earth's atmosphere.  Bright sources located in the edges of the primary
00053 beam therefore corrupt images of the central portions of the primary beam
00054 in two ways.  The most obvious way is by throwing a corrupted version of
00055 the PSF across the image.  Since it is corrupted, it cannot be deconvolved
00056 away without first correcting the gains.  The second problem is that a
00057 bright source can dominate the solutions of "classical" selfcalibration,
00058 essentially forcing it to solve the gains for the direction of the bright
00059 source instead of the pointing center.
00060 
00061 Solving for and removing the effects of direction-dependent gains is known
00062 in various forms as "peeling", "modcal", or most prosaically,
00063 direction-dependent selfcalibration.  This task attempts
00064 direction-dependent selfcalibration in the requested list of directions,
00065 and optionally removes the associated sources.
00066 
00067 The usual risks of selfcalibration (imperfect model and possibly
00068 insufficient constraints) are particularly severe for peeling.  Approach it
00069 with trepidation and stop as soon as possible.  Peeling can ameliorate the
00070 effects of heterogeneous arrays, but it is better to use the right antenna
00071 voltage patterns a priori.
00072 
00073 Do not peel unless necessary.
00074 
00075 Still here?  All right...read carefully...
00076 
00077 Your desire to peel probably stems from the center of your "science field"
00078 being spoiled by the distorted PSFs of bright sources near the edge of the
00079 primary beam.  The fact that their PSFs are interfering with your field of
00080 interest means that your science sources are interfering with the sources
00081 to be peeled!  Thus before doing any peeling you should remove a model of
00082 your science field from the visibilities.  However, the model should not
00083 include any artifacts from the sources to be peeled.  The easiest way to
00084 produce such a model is to clean down to the threshhold of the brightest
00085 artifacts.  peel does not (yet) do this for you!  You are also of course
00086 responsible for returning the model of your science field to the
00087 visibilities once you have finished peeling.  Obviously, if your science
00088 sources are fainter than the artifacts, removing them and replacing them is
00089 not necessary.
00090 
00091 If more than one source must be peeled there is a chance (calculated using
00092 Murphy's Law) that they are interfering with each other.  peel does not yet
00093 simultaneously solve for the gains in more than direction, so interfering
00094 sources must be approached by peeling the brightest source down to the
00095 level of the brightest artifacts in its vicinity, and next peeling whatever
00096 is currently causing the worst artifacts, continuing as necessary.
00097 
00098 If the interactions are especially strong, the cycle will have to be
00099 iterated, refining the model(s) along the way.  The convergence is often
00100 safer and faster if the first iteration of the cycle only solves for the
00101 phases, and leaves phase + amplitude selfcalibration to the final
00102 iteration.
00103 
00104 Any given run of peel is nearly guaranteed to reduce the artifacts from the
00105 source being peeled, so it can be tempting to continue peeling until the
00106 artifacts drop below the noise.  Resist that temptation!  The number of
00107 fitted parameters accumulates with each peel, so repeated peels force the
00108 image toward the originally assumed model.  Even if the total number of
00109 fitted parameters remains much smaller than the number of visibilities, the
00110 interactions between peeled sources and the central field take their toll
00111 on the science field.  peel sees residual PSF sidelobes from the science
00112 region as artifacts that must be minimized.  Whether removing some flux
00113 from the science source(s) is a risk or a certainty, the number of peels
00114 should be kept down.  Overpeeling becomes easier to spot with experience,
00115 but the symptoms are strongly telescope-dependent.
00116 
00117 
00118 
00119 
00120 Example:
00121 
00122 # Start with a phase-only peel, and keep the source so it can be phase +
00123 # amplitude peeled if necessary.
00124 peel(vis='my.ms', calmode="p", remove=False)
00125 
00126 # Examine the result with viewer.
00127 
00128 # OK, do a phase + amplitude removal.
00129 peel(vis='my.ms', calmode="pa")
00130 
00131         """
00132         if not hasattr(self, "__globals__") or self.__globals__ == None :
00133            self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals
00134         #casac = self.__globals__['casac']
00135         casalog = self.__globals__['casalog']
00136         #casalog = casac.casac.logsink()
00137         self.__globals__['__last_task'] = 'peel'
00138         self.__globals__['taskname'] = 'peel'
00139         ###
00140         self.__globals__['update_params'](func=self.__globals__['taskname'],printtext=False,ipython_globals=self.__globals__)
00141         ###
00142         ###
00143         #Handle globals or user over-ride of arguments
00144         #
00145         function_signature_defaults=dict(zip(self.__call__.func_code.co_varnames,self.__call__.func_defaults))
00146         useLocalDefaults = False
00147 
00148         for item in function_signature_defaults.iteritems():
00149                 key,val = item
00150                 keyVal = eval(key)
00151                 if (keyVal == None):
00152                         #user hasn't set it - use global/default
00153                         pass
00154                 else:
00155                         #user has set it - use over-ride
00156                         if (key != 'self') :
00157                            useLocalDefaults = True
00158 
00159         myparams = {}
00160         if useLocalDefaults :
00161            for item in function_signature_defaults.iteritems():
00162                key,val = item
00163                keyVal = eval(key)
00164                exec('myparams[key] = keyVal')
00165                self.parameters[key] = keyVal
00166                if (keyVal == None):
00167                    exec('myparams[key] = '+ key + ' = self.itsdefault(key)')
00168                    keyVal = eval(key)
00169                    if(type(keyVal) == dict) :
00170                       if len(keyVal) > 0 :
00171                          exec('myparams[key] = ' + key + ' = keyVal[len(keyVal)-1][\'value\']')
00172                       else :
00173                          exec('myparams[key] = ' + key + ' = {}')
00174 
00175         else :
00176             async = self.parameters['async']
00177             myparams['vis'] = vis = self.parameters['vis']
00178             myparams['dirs'] = dirs = self.parameters['dirs']
00179             myparams['remove'] = remove = self.parameters['remove']
00180             myparams['calmode'] = calmode = self.parameters['calmode']
00181 
00182 
00183         result = None
00184 
00185 #
00186 #    The following is work around to avoid a bug with current python translation
00187 #
00188         mytmp = {}
00189 
00190         mytmp['vis'] = vis
00191         mytmp['dirs'] = dirs
00192         mytmp['remove'] = remove
00193         mytmp['calmode'] = calmode
00194         pathname='file:///'+os.environ.get('CASAPATH').split()[0]+'/share/xml/'
00195         trec = casac.casac.utils().torecord(pathname+'peel.xml')
00196 
00197         casalog.origin('peel')
00198         try :
00199           #if not trec.has_key('peel') or not casac.casac.utils().verify(mytmp, trec['peel']) :
00200             #return False
00201 
00202           casac.casac.utils().verify(mytmp, trec['peel'], True)
00203           scriptstr=['']
00204           saveinputs = self.__globals__['saveinputs']
00205           saveinputs('peel', 'peel.last', myparams, self.__globals__,scriptstr=scriptstr)
00206           if async :
00207             count = 0
00208             keybase =  time.strftime("%y%m%d.%H%M%S")
00209             key = keybase + "_" + str(count)
00210             while self.__async__.has_key(key) :
00211                count += 1
00212                key = keybase + "_" + str(count)
00213             result = tm.execute('peel', vis, dirs, remove, calmode)
00214             print "Use: "
00215             print "      tm.retrieve(return_value) # to retrieve the status"
00216             print 
00217             self.rkey = key
00218             self.__async__[key] = result
00219           else :
00220               tname = 'peel'
00221               spaces = ' '*(18-len(tname))
00222               casalog.post('\n##########################################'+
00223                            '\n##### Begin Task: ' + tname + spaces + ' #####')
00224               casalog.post(scriptstr[1][1:]+'\n', 'INFO')
00225               result = peel(vis, dirs, remove, calmode)
00226               casalog.post('##### End Task: ' + tname + '  ' + spaces + ' #####'+
00227                            '\n##########################################')
00228 
00229         except Exception, instance:
00230           if(self.__globals__.has_key('__rethrow_casa_exceptions') and self.__globals__['__rethrow_casa_exceptions']) :
00231              raise
00232           else :
00233              #print '**** Error **** ',instance
00234              tname = 'peel'
00235              casalog.post('An error occurred running task '+tname+'.', 'ERROR')
00236              pass
00237 
00238         gc.collect()
00239         return result
00240 #
00241 #
00242 #
00243     def paramgui(self, useGlobals=True, ipython_globals=None):
00244         """
00245         Opens a parameter GUI for this task.  If useGlobals is true, then any relevant global parameter settings are used.
00246         """
00247         import paramgui
00248         if not hasattr(self, "__globals__") or self.__globals__ == None :
00249            self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals
00250 
00251         if useGlobals:
00252             if ipython_globals == None:
00253                 myf=self.__globals__
00254             else:
00255                 myf=ipython_globals
00256 
00257             paramgui.setGlobals(myf)
00258         else:
00259             paramgui.setGlobals({})
00260 
00261         paramgui.runTask('peel', myf['_ip'])
00262         paramgui.setGlobals({})
00263 
00264 #
00265 #
00266 #
00267     def defaults(self, param=None, ipython_globals=None, paramvalue=None, subparam=None):
00268         if not hasattr(self, "__globals__") or self.__globals__ == None :
00269            self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals
00270         if ipython_globals == None:
00271             myf=self.__globals__
00272         else:
00273             myf=ipython_globals
00274 
00275         a = odict()
00276         a['vis']  = ''
00277         a['dirs']  = ""
00278         a['remove']  = True
00279         a['calmode']  = 'p'
00280 
00281         a['async']=False
00282 
00283 ### This function sets the default values but also will return the list of
00284 ### parameters or the default value of a given parameter
00285         if(param == None):
00286                 myf['__set_default_parameters'](a)
00287         elif(param == 'paramkeys'):
00288                 return a.keys()
00289         else:
00290             if(paramvalue==None and subparam==None):
00291                if(a.has_key(param)):
00292                   return a[param]
00293                else:
00294                   return self.itsdefault(param)
00295             else:
00296                retval=a[param]
00297                if(type(a[param])==dict):
00298                   for k in range(len(a[param])):
00299                      valornotval='value'
00300                      if(a[param][k].has_key('notvalue')):
00301                         valornotval='notvalue'
00302                      if((a[param][k][valornotval])==paramvalue):
00303                         retval=a[param][k].copy()
00304                         retval.pop(valornotval)
00305                         if(subparam != None):
00306                            if(retval.has_key(subparam)):
00307                               retval=retval[subparam]
00308                            else:
00309                               retval=self.itsdefault(subparam)
00310                      else:
00311                         retval=self.itsdefault(subparam)
00312                return retval
00313 
00314 
00315 #
00316 #
00317     def check_params(self, param=None, value=None, ipython_globals=None):
00318       if ipython_globals == None:
00319           myf=self.__globals__
00320       else:
00321           myf=ipython_globals
00322 #      print 'param:', param, 'value:', value
00323       try :
00324          if str(type(value)) != "<type 'instance'>" :
00325             value0 = value
00326             value = myf['cu'].expandparam(param, value)
00327             matchtype = False
00328             if(type(value) == numpy.ndarray):
00329                if(type(value) == type(value0)):
00330                   myf[param] = value.tolist()
00331                else:
00332                   #print 'value:', value, 'value0:', value0
00333                   #print 'type(value):', type(value), 'type(value0):', type(value0)
00334                   myf[param] = value0
00335                   if type(value0) != list :
00336                      matchtype = True
00337             else :
00338                myf[param] = value
00339             value = myf['cu'].verifyparam({param:value})
00340             if matchtype:
00341                value = False
00342       except Exception, instance:
00343          #ignore the exception and just return it unchecked
00344          myf[param] = value
00345       return value
00346 #
00347 #
00348     def description(self, key='peel', subkey=None):
00349         desc={'peel': 'Do direction dependent selfcal(s) and optionally remove annoying sources.',
00350                'vis': 'Name of the input visibility set.',
00351                'dirs': 'List of directions to peel.',
00352                'remove': 'Subtract the selfcalibrated source(s) from the data.',
00353                'calmode': 'Type of selfcal to do. (p: Phase only, a: Ampl only. ap: both',
00354 
00355                'async': 'If true the taskname must be started using peel(...)'
00356               }
00357 
00358         if(desc.has_key(key)) :
00359            return desc[key]
00360 
00361     def itsdefault(self, paramname) :
00362         a = {}
00363         a['vis']  = ''
00364         a['dirs']  = ""
00365         a['remove']  = True
00366         a['calmode']  = 'p'
00367 
00368         #a = sys._getframe(len(inspect.stack())-1).f_globals
00369 
00370         if a.has_key(paramname) :
00371               return a[paramname]
00372 peel_cli = peel_cli_()