casa
$Rev:20696$
|
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_applycal import applycal 00018 class applycal_cli_: 00019 __name__ = "applycal" 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__ = (applycal_cli_,) 00028 self.__doc__ = self.__call__.__doc__ 00029 00030 self.parameters={'vis':None, 'field':None, 'spw':None, 'intent':None, 'selectdata':None, 'timerange':None, 'uvrange':None, 'antenna':None, 'scan':None, 'observation':None, 'msselect':None, 'gaintable':None, 'gainfield':None, 'interp':None, 'spwmap':None, 'gaincurve':None, 'opacity':None, 'parang':None, 'calwt':None, 'applymode':None, 'flagbackup':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, field=None, spw=None, intent=None, selectdata=None, timerange=None, uvrange=None, antenna=None, scan=None, observation=None, msselect=None, gaintable=None, gainfield=None, interp=None, spwmap=None, gaincurve=None, opacity=None, parang=None, calwt=None, applymode=None, flagbackup=None, async=None): 00047 00048 """Apply calibrations solutions(s) to data 00049 00050 00051 Applycal reads the specified gain calibration tables, applies 00052 them to the (raw) data column (with the specified selection), 00053 and writes the calibrated results into the corrected column. 00054 This is done in one step, so all available calibration tables must 00055 be specified. Included parang, gaincurve, and opacity are used in 00056 obtaining previous calibration tables. 00057 00058 Applycal will overwrite existing corrected data, and will flag data 00059 for which there is no calibration available. 00060 00061 All calibration tables (both temporal, frequency, polarization 00062 calibrations) are specified in the gaintable parameter. The 00063 calibration values associated with a restricted list of fields 00064 can also be selected for each table in gainfield. 00065 00066 See task accum for instructions on forming calibration 00067 incrementally. See task split for copying out any portion of the data 00068 and selected columns to a new visibility file. 00069 00070 Keyword arguments: 00071 vis -- Name of input visibility file 00072 default: < none>; example: vis='ngc5921.ms' 00073 00074 --- Data Selection: the data to which the calibration will be applied 00075 (see help par.selectdata for more detailed information) 00076 00077 field -- Select field id(s) or field name(s) to apply calibration. 00078 [run listobs to obtain the list id's or names] 00079 default: ''=all fields 00080 If field's string is an integer >=0, it is assumed to be an index 00081 otherwise, it is assumed to be a field name 00082 field='0~2'; field ids 0,1,2 00083 field='0,4,5~7'; field ids 0,4,5,6,7 00084 field='3C286,3C295'; fields named 3C286 and 3C295 00085 field = '3,4C*'; field id 3, all names starting with 4C 00086 spw -- Select spectral window/channels 00087 type 'help par.selection' for more examples. 00088 spw='0~2,4'; spectral windows 0,1,2,4 (all channels) 00089 spw='<2'; spectral windows less than 2 (i.e. 0,1) 00090 spw='0:5~61'; spw 0, channels 5 to 61, INCLUSIVE 00091 spw='*:5~61'; all spw with channels 5 to 62 00092 spw='0,10,3:3~45'; spw 0,10 all channels, spw 3, channels 3 to 45. 00093 spw='0~2:2~6'; spw 0,1,2 with channels 2 through 6 in each. 00094 spw='0:0~10;15~60'; spectral window 0 with channels 0-10,15-60 00095 NOTE ';' to separate channel selections 00096 spw='0:0~10^2,1:20~30^5'; spw 0, channels 0,2,4,6,8,10, 00097 spw 1, channels 20,25,30 00098 intent -- Select observing intent 00099 default: '' (no selection by intent) 00100 intent='*BANDPASS*' (selects data labelled with 00101 BANDPASS intent) 00102 selectdata -- Other data selection parameters 00103 default: True 00104 timerange -- Select data based on time range: 00105 default = '' (all); examples, 00106 timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss' 00107 Note: if YYYY/MM/DD is missing, date defaults to first day in 00108 data set 00109 timerange='09:14:0~09:54:0' picks 40 min on first day 00110 timerange= '25:00:00~27:30:00' picks 1 hr to 3 hr 30min on next day 00111 timerange='09:44:00' data within one integration of time 00112 timerange='>10:24:00' data after this time 00113 uvrange -- Select data within uvrange (default units meters) 00114 default: '' (all); example: 00115 uvrange='0~1000kl'; uvrange from 0-1000 kilo-lambda 00116 uvrange='>4kl';uvranges greater than 4 kilolambda 00117 antenna -- Select data based on antenna/baseline 00118 default: '' (all) 00119 If antenna's string is an integer >=0, it is taken to be an index 00120 otherwise, it is assumed to be an antenna name 00121 antenna='5&6'; baseline between antenna index 5 and index 6. 00122 antenna='VA05&VA06'; baseline between VLA antenna 5 and 6. 00123 antenna='5&6;7&8'; baseline 5-6 and 7-8 00124 antenna='5'; all baselines with antenna index 5 00125 antenna='05'; all baselines with antenna name 05--vla antenna 5. 00126 antenna='5,6,10'; all baselines with antennas 5,6 and 10 00127 scan -- Scan number range 00128 observation -- Select by observation ID(s). 00129 default: '' = all 00130 example: '0~3,6' 00131 msselect -- Optional complex data selection (ignore for now) 00132 00133 --- Calibration files to apply 00134 gaintable -- Gain calibration table(s) to apply 00135 default: '' (none); 00136 examples: gaintable='ngc5921.gcal' 00137 gaintable=['n5921.ampcal','n5921.phcal','n5921.bpass'] 00138 All gain table types: 'G', GSPLINE, 'T', 'B', 'BPOLY', 'D's' 00139 can be applied. 00140 gainfield -- Select a subset of calibrators from each gaintable 00141 default:'' ==> all sources in table; 00142 'nearest' ==> nearest (on sky) available field in table 00143 otherwise, same syntax as field 00144 example: gainfield='0~3' 00145 gainfield=['0~3','4~6'] (for multiple gaintables) 00146 interp -- Interpolation type (in time[,freq]) to use for each gaintable. 00147 When frequency interpolation is relevant (B, Df, Xf), 00148 separate time-dependent and freq-dependent interp 00149 types with a comma (freq _after_ the comma). 00150 Specifications for frequency are ignored when the 00151 calibration table has no channel-dependence. 00152 Time-dependent interp options ending in 'PD' enable a 00153 "phase delay" correction per spw for non-channel-dependent 00154 calibration types. 00155 default: '' --> 'linear,linear' for all gaintable(s) 00156 example: interp='nearest' (in time, freq-dep will be 00157 linear, if relevant) 00158 interp='linear,cubic' (linear in time, cubic 00159 in freq) 00160 interp=',spline' (spline in freq; linear in 00161 time by default) 00162 interp=['nearest,spline','linear'] (for multiple gaintables) 00163 Options: Time: 'nearest', 'linear', 'nearestPD', 'linearPD' 00164 Freq: 'nearest', 'linear', 'cubic', 'spline' 00165 spwmap -- Spectral windows combinations to form for gaintable(s) 00166 default: [] (apply solutions from each spw to that spw only) 00167 Example: spwmap=[0,0,1,1] means apply the caltable solutions 00168 from spw = 0 to the spw 0,1 and spw 1 to spw 2,3. 00169 spwmap=[[0,0,1,1],[0,1,0,1]] (for multiple gaintables) 00170 00171 Complicated example: 00172 00173 gaintable=['tab1','tab2','tab3'] 00174 gainfield='3C286' 00175 interp=['linear','nearest'] 00176 spwmap=[[],[0,0,2]] 00177 00178 This means: apply 3 cal tables, selecting only solutions for 3C286 00179 from tab1 (but all fields from tab2 and tab3, indicated by 00180 no gainfield entry for these files). Linear interpolation 00181 (in time) will be used for 'tab1' and 'tab3' (default); 'tab2' will 00182 use nearest. For the 'tab2', the calibration spws map 00183 will be mapped to the data spws according to 0->0, 0->1, 2->2. 00184 (I.e., for data spw=0 and 2, the spw mapping is one to one, 00185 but data spw 1 will be calibrated by solutions from spw 0.) 00186 00187 gaincurve -- Apply internal VLA/EVLA antenna gain curve correction (True/False) 00188 default: False; 00189 Use gaincurve=True ONLY for VLA or EVLA data 00190 opacity -- Opacity correction to apply (nepers), per spw 00191 default: [] (no opacity correction for any spw) 00192 examples: 00193 A global value for all spws: 00194 opacity=0.051 00195 Different values for spws 0,1,2: 00196 opacity=[0.051, 0.055, 0.057] 00197 (if fewer opacity values than spws are specified, 00198 then the last-specified value will be duplicated 00199 for all higher-numbered spws, e.g., in the above 00200 example, 0.057 will be used for spws 3 and higher, 00201 if they exist) 00202 Typical VLA values are: 5 GHz - 0.013, 8 GHz - 0.013 00203 15 GHz - 0.016, 23 GHz - 0.051, 43 GHz - 0.07 00204 parang -- If True, apply the parallactic angle correction. FOR ANY 00205 POLARIZATION CALIBRATION AND IMAGING, parang = True 00206 default: False 00207 calwt -- Calibrate weights along with data for all 00208 relevant calibrations 00209 default: True; example: calwt=False 00210 applymode -- Calibration apply mode: 00211 ''='calflag' (default) calibrate data and apply flags from solutions 00212 'trial' report on flags from solutions, dataset entirely unchanged 00213 'flagonly' apply flags from solutions only, data not calibrated 00214 'calonly' calibrate data only (by unflagged solutions), flags from solutions NOT applied (use with extreme caution!) 00215 flagbackup -- Back up the state of the flags before applying calibration 00216 default: True 00217 async -- Run task in a separate process 00218 default: False; example: async=True 00219 00220 00221 00222 """ 00223 if not hasattr(self, "__globals__") or self.__globals__ == None : 00224 self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals 00225 #casac = self.__globals__['casac'] 00226 casalog = self.__globals__['casalog'] 00227 #casalog = casac.casac.logsink() 00228 self.__globals__['__last_task'] = 'applycal' 00229 self.__globals__['taskname'] = 'applycal' 00230 ### 00231 self.__globals__['update_params'](func=self.__globals__['taskname'],printtext=False,ipython_globals=self.__globals__) 00232 ### 00233 ### 00234 #Handle globals or user over-ride of arguments 00235 # 00236 function_signature_defaults=dict(zip(self.__call__.func_code.co_varnames,self.__call__.func_defaults)) 00237 useLocalDefaults = False 00238 00239 for item in function_signature_defaults.iteritems(): 00240 key,val = item 00241 keyVal = eval(key) 00242 if (keyVal == None): 00243 #user hasn't set it - use global/default 00244 pass 00245 else: 00246 #user has set it - use over-ride 00247 if (key != 'self') : 00248 useLocalDefaults = True 00249 00250 myparams = {} 00251 if useLocalDefaults : 00252 for item in function_signature_defaults.iteritems(): 00253 key,val = item 00254 keyVal = eval(key) 00255 exec('myparams[key] = keyVal') 00256 self.parameters[key] = keyVal 00257 if (keyVal == None): 00258 exec('myparams[key] = '+ key + ' = self.itsdefault(key)') 00259 keyVal = eval(key) 00260 if(type(keyVal) == dict) : 00261 if len(keyVal) > 0 : 00262 exec('myparams[key] = ' + key + ' = keyVal[len(keyVal)-1][\'value\']') 00263 else : 00264 exec('myparams[key] = ' + key + ' = {}') 00265 00266 else : 00267 async = self.parameters['async'] 00268 myparams['vis'] = vis = self.parameters['vis'] 00269 myparams['field'] = field = self.parameters['field'] 00270 myparams['spw'] = spw = self.parameters['spw'] 00271 myparams['intent'] = intent = self.parameters['intent'] 00272 myparams['selectdata'] = selectdata = self.parameters['selectdata'] 00273 myparams['timerange'] = timerange = self.parameters['timerange'] 00274 myparams['uvrange'] = uvrange = self.parameters['uvrange'] 00275 myparams['antenna'] = antenna = self.parameters['antenna'] 00276 myparams['scan'] = scan = self.parameters['scan'] 00277 myparams['observation'] = observation = self.parameters['observation'] 00278 myparams['msselect'] = msselect = self.parameters['msselect'] 00279 myparams['gaintable'] = gaintable = self.parameters['gaintable'] 00280 myparams['gainfield'] = gainfield = self.parameters['gainfield'] 00281 myparams['interp'] = interp = self.parameters['interp'] 00282 myparams['spwmap'] = spwmap = self.parameters['spwmap'] 00283 myparams['gaincurve'] = gaincurve = self.parameters['gaincurve'] 00284 myparams['opacity'] = opacity = self.parameters['opacity'] 00285 myparams['parang'] = parang = self.parameters['parang'] 00286 myparams['calwt'] = calwt = self.parameters['calwt'] 00287 myparams['applymode'] = applymode = self.parameters['applymode'] 00288 myparams['flagbackup'] = flagbackup = self.parameters['flagbackup'] 00289 00290 if type(gaintable)==str: gaintable=[gaintable] 00291 if type(gainfield)==str: gainfield=[gainfield] 00292 if type(interp)==str: interp=[interp] 00293 if type(spwmap)==int: spwmap=[spwmap] 00294 if type(opacity)==float: opacity=[opacity] 00295 00296 result = None 00297 00298 # 00299 # The following is work around to avoid a bug with current python translation 00300 # 00301 mytmp = {} 00302 00303 mytmp['vis'] = vis 00304 mytmp['field'] = field 00305 mytmp['spw'] = spw 00306 mytmp['intent'] = intent 00307 mytmp['selectdata'] = selectdata 00308 mytmp['timerange'] = timerange 00309 mytmp['uvrange'] = uvrange 00310 mytmp['antenna'] = antenna 00311 mytmp['scan'] = scan 00312 mytmp['observation'] = observation 00313 mytmp['msselect'] = msselect 00314 mytmp['gaintable'] = gaintable 00315 mytmp['gainfield'] = gainfield 00316 mytmp['interp'] = interp 00317 mytmp['spwmap'] = spwmap 00318 mytmp['gaincurve'] = gaincurve 00319 mytmp['opacity'] = opacity 00320 mytmp['parang'] = parang 00321 mytmp['calwt'] = calwt 00322 mytmp['applymode'] = applymode 00323 mytmp['flagbackup'] = flagbackup 00324 pathname='file:///'+os.environ.get('CASAPATH').split()[0]+'/share/xml/' 00325 trec = casac.casac.utils().torecord(pathname+'applycal.xml') 00326 00327 casalog.origin('applycal') 00328 try : 00329 #if not trec.has_key('applycal') or not casac.casac.utils().verify(mytmp, trec['applycal']) : 00330 #return False 00331 00332 casac.casac.utils().verify(mytmp, trec['applycal'], True) 00333 scriptstr=[''] 00334 saveinputs = self.__globals__['saveinputs'] 00335 saveinputs('applycal', 'applycal.last', myparams, self.__globals__,scriptstr=scriptstr) 00336 if async : 00337 count = 0 00338 keybase = time.strftime("%y%m%d.%H%M%S") 00339 key = keybase + "_" + str(count) 00340 while self.__async__.has_key(key) : 00341 count += 1 00342 key = keybase + "_" + str(count) 00343 result = tm.execute('applycal', vis, field, spw, intent, selectdata, timerange, uvrange, antenna, scan, observation, msselect, gaintable, gainfield, interp, spwmap, gaincurve, opacity, parang, calwt, applymode, flagbackup) 00344 print "Use: " 00345 print " tm.retrieve(return_value) # to retrieve the status" 00346 print 00347 self.rkey = key 00348 self.__async__[key] = result 00349 else : 00350 tname = 'applycal' 00351 spaces = ' '*(18-len(tname)) 00352 casalog.post('\n##########################################'+ 00353 '\n##### Begin Task: ' + tname + spaces + ' #####') 00354 casalog.post(scriptstr[1][1:]+'\n', 'INFO') 00355 result = applycal(vis, field, spw, intent, selectdata, timerange, uvrange, antenna, scan, observation, msselect, gaintable, gainfield, interp, spwmap, gaincurve, opacity, parang, calwt, applymode, flagbackup) 00356 casalog.post('##### End Task: ' + tname + ' ' + spaces + ' #####'+ 00357 '\n##########################################') 00358 00359 except Exception, instance: 00360 if(self.__globals__.has_key('__rethrow_casa_exceptions') and self.__globals__['__rethrow_casa_exceptions']) : 00361 raise 00362 else : 00363 #print '**** Error **** ',instance 00364 tname = 'applycal' 00365 casalog.post('An error occurred running task '+tname+'.', 'ERROR') 00366 pass 00367 00368 gc.collect() 00369 return result 00370 # 00371 # 00372 # 00373 def paramgui(self, useGlobals=True, ipython_globals=None): 00374 """ 00375 Opens a parameter GUI for this task. If useGlobals is true, then any relevant global parameter settings are used. 00376 """ 00377 import paramgui 00378 if not hasattr(self, "__globals__") or self.__globals__ == None : 00379 self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals 00380 00381 if useGlobals: 00382 if ipython_globals == None: 00383 myf=self.__globals__ 00384 else: 00385 myf=ipython_globals 00386 00387 paramgui.setGlobals(myf) 00388 else: 00389 paramgui.setGlobals({}) 00390 00391 paramgui.runTask('applycal', myf['_ip']) 00392 paramgui.setGlobals({}) 00393 00394 # 00395 # 00396 # 00397 def defaults(self, param=None, ipython_globals=None, paramvalue=None, subparam=None): 00398 if not hasattr(self, "__globals__") or self.__globals__ == None : 00399 self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals 00400 if ipython_globals == None: 00401 myf=self.__globals__ 00402 else: 00403 myf=ipython_globals 00404 00405 a = odict() 00406 a['vis'] = '' 00407 a['field'] = '' 00408 a['spw'] = '' 00409 a['intent'] = '' 00410 a['selectdata'] = True 00411 a['gaintable'] = [''] 00412 a['gainfield'] = [''] 00413 a['interp'] = [''] 00414 a['spwmap'] = [] 00415 a['gaincurve'] = False 00416 a['opacity'] = [] 00417 a['parang'] = False 00418 a['calwt'] = True 00419 a['applymode'] = '' 00420 a['flagbackup'] = True 00421 00422 a['async']=False 00423 a['selectdata'] = { 00424 0:odict([{'value':True}, {'timerange':''}, {'uvrange':''}, {'antenna':''}, {'scan':''}, {'observation':''}, {'msselect':''}]), 00425 1:{'value':False}} 00426 00427 ### This function sets the default values but also will return the list of 00428 ### parameters or the default value of a given parameter 00429 if(param == None): 00430 myf['__set_default_parameters'](a) 00431 elif(param == 'paramkeys'): 00432 return a.keys() 00433 else: 00434 if(paramvalue==None and subparam==None): 00435 if(a.has_key(param)): 00436 return a[param] 00437 else: 00438 return self.itsdefault(param) 00439 else: 00440 retval=a[param] 00441 if(type(a[param])==dict): 00442 for k in range(len(a[param])): 00443 valornotval='value' 00444 if(a[param][k].has_key('notvalue')): 00445 valornotval='notvalue' 00446 if((a[param][k][valornotval])==paramvalue): 00447 retval=a[param][k].copy() 00448 retval.pop(valornotval) 00449 if(subparam != None): 00450 if(retval.has_key(subparam)): 00451 retval=retval[subparam] 00452 else: 00453 retval=self.itsdefault(subparam) 00454 else: 00455 retval=self.itsdefault(subparam) 00456 return retval 00457 00458 00459 # 00460 # 00461 def check_params(self, param=None, value=None, ipython_globals=None): 00462 if ipython_globals == None: 00463 myf=self.__globals__ 00464 else: 00465 myf=ipython_globals 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 def description(self, key='applycal', subkey=None): 00493 desc={'applycal': 'Apply calibrations solutions(s) to data', 00494 'vis': 'Name of input visibility file', 00495 'field': 'Select field using field id(s) or field name(s)', 00496 'spw': 'Select spectral window/channels', 00497 'intent': 'Select observing intent', 00498 'selectdata': 'Other data selection parameters', 00499 'timerange': 'Select data based on time range', 00500 'uvrange': 'Select data within uvrange (default units meters)', 00501 'antenna': 'Select data based on antenna/baseline', 00502 'scan': 'Scan number range', 00503 'observation': 'Select by observation ID(s)', 00504 'msselect': 'Optional complex data selection (ignore for now)', 00505 'gaintable': 'Gain calibration table(s) to apply on the fly', 00506 'gainfield': 'Select a subset of calibrators from gaintable(s)', 00507 'interp': 'Interp type in time[,freq], per gaintable. default=linear,linear', 00508 'spwmap': 'Spectral windows combinations to form for gaintables(s)', 00509 'gaincurve': 'Apply internal VLA antenna gain curve correction', 00510 'opacity': 'Opacity correction to apply (nepers), per spw', 00511 'parang': 'Apply parallactic angle correction', 00512 'calwt': 'Calibrate data weights from all relevant calibrations', 00513 'applymode': 'Calibration mode: ""="calflag","trial","flagonly", or "calonly"', 00514 'flagbackup': 'Automatically back up the state of flags before the run?', 00515 00516 'async': 'If true the taskname must be started using applycal(...)' 00517 } 00518 00519 # 00520 # Set subfields defaults if needed 00521 # 00522 00523 if(desc.has_key(key)) : 00524 return desc[key] 00525 00526 def itsdefault(self, paramname) : 00527 a = {} 00528 a['vis'] = '' 00529 a['field'] = '' 00530 a['spw'] = '' 00531 a['intent'] = '' 00532 a['selectdata'] = True 00533 a['timerange'] = '' 00534 a['uvrange'] = '' 00535 a['antenna'] = '' 00536 a['scan'] = '' 00537 a['observation'] = '' 00538 a['msselect'] = '' 00539 a['gaintable'] = [''] 00540 a['gainfield'] = [''] 00541 a['interp'] = [''] 00542 a['spwmap'] = [] 00543 a['gaincurve'] = False 00544 a['opacity'] = [] 00545 a['parang'] = False 00546 a['calwt'] = True 00547 a['applymode'] = '' 00548 a['flagbackup'] = True 00549 00550 #a = sys._getframe(len(inspect.stack())-1).f_globals 00551 00552 if self.parameters['selectdata'] == True: 00553 a['timerange'] = '' 00554 a['uvrange'] = '' 00555 a['antenna'] = '' 00556 a['scan'] = '' 00557 a['observation'] = '' 00558 a['msselect'] = '' 00559 00560 if a.has_key(paramname) : 00561 return a[paramname] 00562 applycal_cli = applycal_cli_()