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