casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
sdfit_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_sdfit import sdfit
00016 from task_sdfit import casalog
00017 
00018 class sdfit_pg_:
00019     __name__ = "sdfit"
00020 
00021     def __init__(self) :
00022        self.__bases__ = (sdfit_pg_,)
00023        self.__doc__ = self.__call__.__doc__
00024 
00025 
00026     def __call__(self, infile=None, antenna=None, fluxunit=None, telescopeparm=None, specunit=None, restfreq=None, frame=None, doppler=None, scanlist=None, field=None, iflist=None, pollist=None, fitfunc=None, fitmode=None, maskline=None, invertmask=None, nfit=None, thresh=None, min_nchan=None, avg_limit=None, box_size=None, edge=None, outfile=None, overwrite=None, plotlevel=None, async=None):
00027 
00028         """ASAP SD task: fit a spectral line
00029         Keyword arguments:
00030         infile -- name of input SD dataset
00031                 default: none - must input file name
00032                 example: 'mysd.asap'
00033                          See sdcal for allowed formats.
00034         antenna -- antenna name or id (only effective for MS input). 
00035         fluxunit -- units for line flux
00036                 options: (str) 'K','Jy',''
00037                 default: '' (keep current fluxunit)
00038                 WARNING: For GBT data, see description below.
00039             >>> fluxunit expandable parameter
00040                  telescopeparm -- the telescope characteristics
00041                         options: (str) name or (list) list of gain info
00042                         default: '' (none set)
00043                         example: if telescopeparm='', it tries to get the telescope
00044                                  name from the data.
00045                                  Full antenna parameters (diameter,ap.eff.) known
00046                                  to ASAP are
00047                                  'ATPKSMB', 'ATPKSHOH', 'ATMOPRA', 'DSS-43',
00048                                  'CEDUNA','HOBART'. For GBT, it fixes default fluxunit
00049                                  to 'K' first then convert to a new fluxunit.
00050                                  telescopeparm=[104.9,0.43] diameter(m), ap.eff.
00051                                  telescopeparm=[0.743] gain in Jy/K
00052                                  telescopeparm='FIX' to change default fluxunit
00053                                  see description below
00054 
00055         specunit -- units for spectral axis
00056                 options: (str) 'channel','km/s','GHz','MHz','kHz','Hz',''
00057                 default: '' (=current)
00058                 example: this will be the units for maskline
00059             >>> specunit expandable parameters
00060                  restfreq -- rest frequency
00061                          available type includes float, int, string, list of float, 
00062                          list of int, list of string, and list of dictionary. the 
00063                          default unit of restfreq in case of float, int, or string 
00064                          without unit is Hz. string input can be a value only 
00065                          (treated as Hz) or a value followed by unit for which 'GHz',
00066                          'MHz','kHz',and 'Hz' are available. 
00067                          a list can be used to set different rest frequencies for 
00068                          each IF. the length of list input must be nIF. dictionary 
00069                          input should be a pair of molecule name and frequency with 
00070                          keys of 'name' and 'value', respectively. values in the 
00071                          dictionary input follows the same manner as for single 
00072                          float or string input. 
00073                          example: 345.796
00074                                   '1420MHz'
00075                                   [345.8, 347.0, 356.7]
00076                                   ['345.8MHz', '347.0MHz', '356.7MHz']
00077                                   [{'name':'CO','value':345}]
00078         frame -- frequency frame for spectral axis
00079                 options: (str) 'LSRK','REST','TOPO','LSRD','BARY',
00080                          'GEO','GALACTO','LGROUP','CMB'
00081                 default: currently set frame in scantable
00082                 WARNING: frame='REST' not yet implemented
00083         doppler -- doppler mode
00084                 options: (str) 'RADIO','OPTICAL','Z','BETA','GAMMA'
00085                 default: currently set doppler in scantable
00086         scanlist -- list of scan numbers to process
00087                 default: [] (use all scans)
00088                 example: [21,22,23,24]
00089         field -- selection string for selecting scans by name
00090                 default: '' (no name selection)
00091                 example: 'FLS3a*'
00092                 this selection is in addition to scanlist and iflist
00093         iflist -- list of IF id numbers to select
00094                 default: [] (use all IFs)
00095                 example: [15]
00096         pollist -- list of polarization id numbers to select
00097                 default: [] (use all polarizations)
00098                 example: [1]
00099         fitfunc -- function for fitting
00100                 options: (str) 'gauss','lorentz'
00101                 default: 'gauss'
00102         fitmode -- mode for fitting
00103                 options: (str) 'list','auto','interact'
00104                 default: 'auto'
00105                 example: 'list' will use maskline to define regions to
00106                                 fit for lines with nfit in each
00107                          'auto' will use the linefinder to fit for lines
00108                                 using the following parameters
00109                          'interact' allows adding and deleting mask 
00110                                 regions by drawing rectangles on the plot 
00111                                 with mouse. Draw a rectangle with LEFT-mouse 
00112                                 to ADD the region to the mask and with RIGHT-mouse 
00113                                 to DELETE the region. 
00114 
00115             >>> fitmode expandable parameters             
00116                  thresh -- S/N threshold for linefinder
00117                          default: 5
00118                          example: a single channel S/N ratio above which the channel is
00119                                   considered to be a detection
00120                  min_nchan -- minimum number of consecutive channels for linefinder
00121                          default: 3
00122                          example: minimum number of consecutive channels required to pass threshold
00123                  avg_limit -- channel averaging for broad lines
00124                          default: 4
00125                          example: a number of consecutive channels not greater than
00126                                   this parameter can be averaged to search for broad lines
00127                  box_size -- running mean box size
00128                          default: 0.2
00129                          example: a running mean box size specified as a fraction
00130                                   of the total spectrum length
00131                  edge -- channels to drop at beginning and end of spectrum
00132                          default: 0
00133                          example: [1000] drops 1000 channels at beginning AND end
00134                                   [1000,500] drops 1000 from beginning and 500 from end
00135 
00136                  Note: For bad baselines threshold should be increased,
00137                  and avg_limit decreased (or even switched off completely by
00138                  setting this parameter to 1) to avoid detecting baseline
00139                  undulations instead of real lines.
00140 
00141         maskline -- list of mask regions to INCLUDE in LINE fitting
00142                 default: all
00143                 example: maskline=[[3900,4300]] for a single region, or
00144                          maskline=[[3900,4300],[5000,5400]] for two, etc.
00145         invertmask -- invert mask (EXCLUDE masklist instead)
00146                 options: (bool) True, False
00147                 default: False
00148                 example: invertmask=True, then will make one region that is
00149                          the exclusion of the maskline regions
00150         nfit -- list of number of gaussian/lorentzian lines to fit in in maskline region (ignored when fitmode='auto')
00151                 default: 0 (no fitting)
00152                 example: nfit=[1] for single line in single region,
00153                          nfit=[2] for two lines in single region,
00154                          nfit=[1,1] for single lines in each of two regions, etc.
00155         outfile -- name of output file for fit results
00156                 default: no output fit file
00157                 example: 'mysd.fit'
00158         overwrite -- overwrite the outfile if already exists
00159                 options: (bool) True, False
00160                 default: False
00161         plotlevel -- control for plotting of results
00162                 options: (int) 0=none, 1=some, 2=more
00163                 default: 0 (no plotting)
00164                 example: plotlevel=1 plots fit
00165                          plotlevel=2 plots fit and residual 
00166                          no hardcopy available for fitter
00167                 WARNING: be careful plotting OTF data with lots of fields
00168 
00169         -------------------------------------------------------------------
00170         Returns a Python dictionary of line statistics
00171                 keys:    'peak','cent','fwhm','nfit'
00172                 example: each value is a list of lists with one list of
00173                          2 entries [fitvalue,error] per component.
00174                          e.g. xstat['peak']=[[234.9, 4.8],[234.2, 5.3]]
00175                          for 2 components.
00176 
00177 
00178         DESCRIPTION:
00179 
00180         Task sdfit is a basic line-fitter for single-dish spectra.
00181         It assumes that the spectra have been calibrated in sdcal
00182         or sdreduce.
00183 
00184         Furthermore, it assumes that any selection of scans, IFs,
00185         polarizations, and time and channel averaging/smoothing has
00186         also already been done (in other sd tasks) as there are no controls
00187         for these.  Note that you can use sdsave to do selection, writing
00188         out a new scantable.
00189 
00190         Note that multiple scans, IFs, and polarizations can in principle 
00191         be handled, but we recommend that you use scanlist, field, iflist, 
00192         and pollist to give a single selection for each fit.
00193 
00194         Currently, you can choose Gaussian or Lorentzian profile as a 
00195         fitting model. 
00196 
00197         For complicated spectra, sdfit does not do a good job of
00198         "auto-guessing" the starting model for the fit.  We recommend
00199         you use sd.fitter in the toolkit which has more options, such
00200         as fixing components in the fit and supplying starting guesses
00201         by hand.
00202 
00203         WARNING: sdfit will currently return the fit for the first
00204         row in the scantable.
00205 
00206         ASAP recognizes the data of the "AT" telescopes, but currently
00207         does not know about the GBT or any other telescope. This task
00208         does know about GBT. Telescope name is obtained from the data.
00209         If you wish to change the fluxunit (see below), and telescopeparm='',
00210         for the AT telescopes it will use internal telescope parameters for
00211         flux conversion. For GBT, it will use an approximate aperture
00212         efficiency conversion.  If you give telescopeparm a list, then 
00213         if the list has a single float it is assumed to be the gain in Jy/K, 
00214         if two or more elements they are assumed to be telescope diameter (m) 
00215         and aperture efficiency respectively.
00216 
00217         WARNING for the GBT raw SDFITS format data as input:
00218         SDtasks are able to handle GBT raw SDFITS format data since the 
00219         data filler is available. However, the functionality is not well 
00220         tested yet, so that there may be unknown bugs.  
00221 
00222   
00223         """
00224         a=inspect.stack()
00225         stacklevel=0
00226         for k in range(len(a)):
00227           if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0):
00228                 stacklevel=k
00229                 break
00230         myf=sys._getframe(stacklevel).f_globals
00231         myf['__last_task'] = 'sdfit'
00232         myf['taskname'] = 'sdfit'
00233         ###
00234         myf['update_params'](func=myf['taskname'],printtext=False)
00235         ###
00236         ###
00237         #Handle globals or user over-ride of arguments
00238         #
00239         function_signature_defaults=dict(zip(self.__call__.func_code.co_varnames,self.__call__.func_defaults))
00240         useLocalDefaults = False
00241 
00242         for item in function_signature_defaults.iteritems():
00243                 key,val = item
00244                 keyVal = eval(key)
00245                 if (keyVal == None):
00246                         #user hasn't set it - use global/default
00247                         pass
00248                 else:
00249                         #user has set it - use over-ride
00250                         if (key != 'self') :
00251                            useLocalDefaults = True
00252                         #myf[key]=keyVal
00253 
00254         myparams = {}
00255         if useLocalDefaults :
00256            for item in function_signature_defaults.iteritems():
00257                key,val = item
00258                keyVal = eval(key)
00259                exec('myparams[key] = keyVal')
00260                if (keyVal == None):
00261                    exec('myparams[key] = '+ key + ' = self.itsdefault(key)')
00262                    keyVal = eval(key)
00263                    if(type(keyVal) == dict) :
00264                       exec('myparams[key] = ' + key + ' = keyVal[len(keyVal)-1][\'value\']')
00265 
00266         else :
00267             uselessvariable = None 
00268             myparams['infile'] = infile = myf['infile']
00269             myparams['antenna'] = antenna = myf['antenna']
00270             myparams['fluxunit'] = fluxunit = myf['fluxunit']
00271             myparams['telescopeparm'] = telescopeparm = myf['telescopeparm']
00272             myparams['specunit'] = specunit = myf['specunit']
00273             myparams['restfreq'] = restfreq = myf['restfreq']
00274             myparams['frame'] = frame = myf['frame']
00275             myparams['doppler'] = doppler = myf['doppler']
00276             myparams['scanlist'] = scanlist = myf['scanlist']
00277             myparams['field'] = field = myf['field']
00278             myparams['iflist'] = iflist = myf['iflist']
00279             myparams['pollist'] = pollist = myf['pollist']
00280             myparams['fitfunc'] = fitfunc = myf['fitfunc']
00281             myparams['fitmode'] = fitmode = myf['fitmode']
00282             myparams['maskline'] = maskline = myf['maskline']
00283             myparams['invertmask'] = invertmask = myf['invertmask']
00284             myparams['nfit'] = nfit = myf['nfit']
00285             myparams['thresh'] = thresh = myf['thresh']
00286             myparams['min_nchan'] = min_nchan = myf['min_nchan']
00287             myparams['avg_limit'] = avg_limit = myf['avg_limit']
00288             myparams['box_size'] = box_size = myf['box_size']
00289             myparams['edge'] = edge = myf['edge']
00290             myparams['outfile'] = outfile = myf['outfile']
00291             myparams['overwrite'] = overwrite = myf['overwrite']
00292             myparams['plotlevel'] = plotlevel = myf['plotlevel']
00293 
00294         if type(scanlist)==int: scanlist=[scanlist]
00295         if type(iflist)==int: iflist=[iflist]
00296         if type(pollist)==int: pollist=[pollist]
00297         if type(nfit)==int: nfit=[nfit]
00298         if type(edge)==int: edge=[edge]
00299 
00300         result = None
00301 
00302 #
00303 #    The following is work around to avoid a bug with current python translation
00304 #
00305         mytmp = {}
00306 
00307         mytmp['infile'] = infile
00308         mytmp['antenna'] = antenna
00309         mytmp['fluxunit'] = fluxunit
00310         mytmp['telescopeparm'] = telescopeparm
00311         mytmp['specunit'] = specunit
00312         mytmp['restfreq'] = restfreq
00313         mytmp['frame'] = frame
00314         mytmp['doppler'] = doppler
00315         mytmp['scanlist'] = scanlist
00316         mytmp['field'] = field
00317         mytmp['iflist'] = iflist
00318         mytmp['pollist'] = pollist
00319         mytmp['fitfunc'] = fitfunc
00320         mytmp['fitmode'] = fitmode
00321         mytmp['maskline'] = maskline
00322         mytmp['invertmask'] = invertmask
00323         mytmp['nfit'] = nfit
00324         mytmp['thresh'] = thresh
00325         mytmp['min_nchan'] = min_nchan
00326         mytmp['avg_limit'] = avg_limit
00327         mytmp['box_size'] = box_size
00328         mytmp['edge'] = edge
00329         mytmp['outfile'] = outfile
00330         mytmp['overwrite'] = overwrite
00331         mytmp['plotlevel'] = plotlevel
00332         pathname='file:///'+os.environ.get('CASAPATH').split()[0]+'/share/xml/'
00333         trec = casac.utils().torecord(pathname+'sdfit.xml')
00334 
00335         casalog.origin('sdfit')
00336         if not trec.has_key('sdfit') or not casac.utils().verify(mytmp, trec['sdfit']) :
00337             return False
00338 
00339 
00340         try :
00341           casalog.post('')
00342           casalog.post('##########################################')
00343           casalog.post('##### Begin Task: sdfit           #####')
00344           casalog.post('')
00345           result = sdfit(infile, antenna, fluxunit, telescopeparm, specunit, restfreq, frame, doppler, scanlist, field, iflist, pollist, fitfunc, fitmode, maskline, invertmask, nfit, thresh, min_nchan, avg_limit, box_size, edge, outfile, overwrite, plotlevel)
00346           casalog.post('')
00347           casalog.post('##### End Task: sdfit           #####')
00348           casalog.post('##########################################')
00349 
00350 
00351 # saveinputs for individule engine has no use
00352 # saveinputs should alos be removed from casa_in_py.py
00353 #
00354 #
00355 #          saveinputs = myf['saveinputs']
00356 #          saveinputs('sdfit', 'sdfit.last', myparams)
00357 #
00358 #
00359         except Exception, instance:
00360           #print '**** Error **** ',instance
00361           pass
00362 
00363         gc.collect()
00364         return result
00365 #
00366 #
00367 ##
00368 #    def paramgui(self, useGlobals=True):
00369 #        """
00370 #        Opens a parameter GUI for this task.  If useGlobals is true, then any relevant global parameter settings are used.
00371 #        """
00372 #        import paramgui
00373 #
00374 #        a=inspect.stack()
00375 #        stacklevel=0
00376 #        for k in range(len(a)):
00377 #          if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0):
00378 #            stacklevel=k
00379 #            break
00380 #        myf = sys._getframe(stacklevel).f_globals
00381 #
00382 #        if useGlobals:
00383 #            paramgui.setGlobals(myf)
00384 #        else:
00385 #            paramgui.setGlobals({})
00386 #
00387 #        paramgui.runTask('sdfit', myf['_ip'])
00388 #        paramgui.setGlobals({})
00389 #
00390 #
00391 #
00392 #
00393     def defaults(self, param=None):
00394         a=inspect.stack()
00395         stacklevel=0
00396         for k in range(len(a)):
00397           if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0):
00398                 stacklevel=k
00399                 break
00400         myf=sys._getframe(stacklevel).f_globals
00401         a = odict()
00402         a['infile']  = ''
00403         a['antenna']  = 0
00404         a['fluxunit']  = ''
00405         a['specunit']  = ''
00406         a['frame']  = ''
00407         a['doppler']  = ''
00408         a['scanlist']  = []
00409         a['field']  = ''
00410         a['iflist']  = []
00411         a['pollist']  = []
00412         a['fitfunc']  = 'gauss'
00413         a['fitmode']  = 'auto'
00414         a['maskline']  = []
00415         a['invertmask']  = False
00416         a['nfit']  = []
00417         a['outfile']  = ''
00418         a['overwrite']  = False
00419         a['plotlevel']  = 0
00420 
00421         a['async']=False
00422         a['fluxunit'] = {
00423                     0:{'value':''}, 
00424                     1:odict([{'value':'K'}, {'telescopeparm':''}]), 
00425                     2:odict([{'value':'k'}, {'telescopeparm':''}]), 
00426                     3:odict([{'value':'Jy'}, {'telescopeparm':''}]), 
00427                     4:odict([{'value':'jy'}, {'telescopeparm':''}])}
00428         a['specunit'] = {
00429                     0:{'value':''}, 
00430                     1:{'value':'channel'}, 
00431                     2:{'value':'GHz'}, 
00432                     3:{'value':'MHz'}, 
00433                     4:{'value':'kHz'}, 
00434                     5:{'value':'Hz'}, 
00435                     6:odict([{'value':'km/s'}, {'restfreq':''}])}
00436         a['fitmode'] = {
00437                     0:odict([{'value':'auto'}, {'thresh':5.0}, {'min_nchan':3}, {'avg_limit':4}, {'box_size':0.2}, {'edge':[0]}]), 
00438                     1:{'value':'list'}, 
00439                     2:{'value':'interact'}}
00440 
00441 ### This function sets the default values but also will return the list of
00442 ### parameters or the default value of a given parameter
00443         if(param == None):
00444                 myf['__set_default_parameters'](a)
00445         elif(param == 'paramkeys'):
00446                 return a.keys()
00447         else:
00448                 if(a.has_key(param)):
00449                    #if(type(a[param]) == dict) :
00450                    #   return a[param][len(a[param])-1]['value']
00451                    #else :
00452                       return a[param]
00453 
00454 
00455 #
00456 #
00457     def check_params(self, param=None, value=None):
00458       a=inspect.stack() 
00459       stacklevel=0
00460       for k in range(len(a)):
00461         if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0):
00462             stacklevel=k
00463             break
00464       myf=sys._getframe(stacklevel).f_globals
00465 
00466 #      print 'param:', param, 'value:', value
00467       try :
00468          if str(type(value)) != "<type 'instance'>" :
00469             value0 = value
00470             value = myf['cu'].expandparam(param, value)
00471             matchtype = False
00472             if(type(value) == numpy.ndarray):
00473                if(type(value) == type(value0)):
00474                   myf[param] = value.tolist()
00475                else:
00476                   #print 'value:', value, 'value0:', value0
00477                   #print 'type(value):', type(value), 'type(value0):', type(value0)
00478                   myf[param] = value0
00479                   if type(value0) != list :
00480                      matchtype = True
00481             else :
00482                myf[param] = value
00483             value = myf['cu'].verifyparam({param:value})
00484             if matchtype:
00485                value = False
00486       except Exception, instance:
00487          #ignore the exception and just return it unchecked
00488          myf[param] = value
00489       return value
00490 
00491 #
00492 #
00493     def description(self, key='sdfit', subkey=None):
00494         desc={'sdfit': 'ASAP SD task: fit a spectral line',
00495                'infile': 'name of input SD dataset',
00496                'antenna': 'antenna name or id (only effective for MS input)',
00497                'fluxunit': 'units for line flux (K,Jy) (''=current)',
00498                'telescopeparm': 'param of telescope for flux conversion',
00499                'specunit': 'units for spectral axis (channel,km/s,GHz)',
00500                'restfreq': 'rest frequency (default unit: Hz)',
00501                'frame': 'frequency reference frame, e.g. LSRK (''=current)',
00502                'doppler': 'doppler convention, e.g. RADIO (''=current)',
00503                'scanlist': 'list of scans to use (e.g. [1,2,3,4])',
00504                'field': 'string for selection by source name',
00505                'iflist': 'list of IF ids to select (e.g. [0,1])',
00506                'pollist': 'list of polarization ids to select (e.g. [1])',
00507                'fitfunc': 'function for fitting',
00508                'fitmode': 'mode for fitting',
00509                'maskline': 'list of mask regions to INCLUDE in LINE fitting',
00510                'invertmask': 'invert mask (EXCLUDE masklist instead)',
00511                'nfit': 'list of number of gaussian/lorentzian lines to fit in in maskline region (ignored when fitmode="auto")',
00512                'thresh': 'S/N threshold for linefinder',
00513                'min_nchan': 'minimum number of consecutive channels for linefinder',
00514                'avg_limit': 'channel averaging for broad lines',
00515                'box_size': 'running mean box size',
00516                'edge': 'channels to drop at beginning and end of spectrum',
00517                'outfile': 'name of output file for fit results',
00518                'overwrite': 'overwrite the outfile if already exists',
00519                'plotlevel': 'control for plotting of results',
00520 
00521                'async': 'If true the taskname must be started using sdfit(...)'
00522               }
00523 
00524 #
00525 # Set subfields defaults if needed
00526 #
00527 
00528         if(desc.has_key(key)) :
00529            return desc[key]
00530 
00531     def itsdefault(self, paramname) :
00532         a = {}
00533         a['infile']  = ''
00534         a['antenna']  = 0
00535         a['fluxunit']  = ''
00536         a['telescopeparm']  = ''
00537         a['specunit']  = ''
00538         a['restfreq']  = ''
00539         a['frame']  = ''
00540         a['doppler']  = ''
00541         a['scanlist']  = []
00542         a['field']  = ''
00543         a['iflist']  = []
00544         a['pollist']  = []
00545         a['fitfunc']  = 'gauss'
00546         a['fitmode']  = 'auto'
00547         a['maskline']  = []
00548         a['invertmask']  = False
00549         a['nfit']  = []
00550         a['thresh']  = 5.0
00551         a['min_nchan']  = 3
00552         a['avg_limit']  = 4
00553         a['box_size']  = 0.2
00554         a['edge']  = [0]
00555         a['outfile']  = ''
00556         a['overwrite']  = False
00557         a['plotlevel']  = 0
00558 
00559         if a.has_key(paramname) :
00560               return a[paramname]
00561 sdfit_pg = sdfit_pg_()