Package multidrizzle :: Module mdrizpars
[hide private]
[frames] | no frames]

Source Code for Module multidrizzle.mdrizpars

  1  from __future__ import division # confidence high 
  2   
  3  import procstep as ps 
  4  import mdzhandler 
  5  import string 
  6  import sys,types,os 
  7   
  8  import numpy as np 
  9   
 10  from pytools import fileutil 
 11  from pydrizzle import traits102 
 12  from pydrizzle.traits102 import * 
 13  from pydrizzle.traits102.tktrait_sheet import TraitEditorBoolean, \ 
 14                          TraitEditorText, TraitGroup 
 15   
 16  from procstep import ProcSteps 
 17   
18 -def toBoolean(flag):
19 if (flag == 1): 20 return True 21 return False 22
23 -def cleanNaN(value):
24 a = np.array(value) 25 # b = np.where(np.isnan(a)) 26 if np.any(np.isnan(a)): return None 27 return value
28
29 -def cleanInt(value):
30 # THIS MAY BE MACHINE-DEPENDENT !!! 31 if value == -2147483647: 32 # Try to use 'sys.maxint' as value (WJH) 33 #if value == -sys.maxint: 34 return None 35 return value
36
37 -def cleanBlank(value):
38 if value.strip() == '': 39 return None 40 return value
41
42 -def findFormat(format):
43 # Parses record array format string for type 44 _fmt = None 45 for ltr in string.letters: 46 if format.find(ltr) > -1: 47 _fmt = ltr 48 break 49 return _fmt
50 51
52 -class MDrizPars (HasTraits):
53 """ This class defines the default values for all MultiDrizzle 54 parameters, and provides the mechanisms for updating them 55 from any of the available interfaces: EPAR, MDRIZTAB, or 56 directly from the Python interface. 57 58 It defines a dictionary containing all the input parameters 59 for MultiDrizzle. The MultiDrizzle class inputs all but the 60 three required parameters as a variable-length argument 61 dictionary. The input parameter dictionary from MultiDrizzle 62 then gets used to initialize this class which then updates 63 the default values it already knows about with the values 64 passed in upon initialization. It can perform parameter name 65 checking in case of typos upon input, recognize the use of an 66 MDRIZTAB and pull the values from that table, then update the 67 master dictionary. This master dictionary would then serve as 68 the primary attribute which would be used to set the desired 69 attributes in the MultiDrizzle class. 70 71 A method supports resetting these values based on 72 new inputs, such as from MDRIZTAB. 73 74 Another method supports resetting ProcStep settings, as they 75 need to be handled differently from regular MultiDrizzle attributes 76 since they rely on another class. 77 """ 78 true_boolean = Trait('true', 79 TraitComplex( 80 TraitPrefixMap( { 81 'true':1, 'yes':1, 82 'false':0, 'no':0 } ), 83 TraitMap({1:True,0:False} ))) 84 bit_editor = TraitEditorBoolean() 85 86 87 # The following enumerated lists are only necessary 88 # to replace the use of TraitEnum for versions of Pmw 89 # earlier than 1.3, versions which have a bug. 90 enum_stat = Trait('median',TraitPrefixMap({ 91 'median': 'median', 92 'mode': 'mode', 93 'mean': 'mean',}) 94 ) 95 enum_kernel = Trait('square',TraitPrefixMap({ 96 'square': 'square', 97 'point': 'point', 98 'gaussian': 'gaussian', 99 'turbo': 'turbo', 100 'tophat':'tophat', 101 'lanczos3': 'lanczos3'}) 102 ) 103 enum_wht = Trait('',TraitPrefixMap({ 104 'ERR': 'ERR', 105 'IVM': 'IVM', 106 'EXP': 'EXP'}) 107 ) 108 109 enum_combine = Trait('minmed',TraitPrefixMap({ 110 'median': 'median', 111 'sum': 'sum', 112 'minmed': 'minmed', 113 'minimum': 'minimum'}) 114 ) 115 enum_interp = Trait('poly5',TraitPrefixMap({ 116 'nearest': 'nearest', 117 'linear': 'linear', 118 'poly3': 'poly3', 119 'poly5': 'poly5', 120 'sinc':'sinc'}) 121 ) 122 123 enum_finalunits = Trait('cps',TraitPrefixMap({ 124 'cps': 'cps', 125 'counts': 'counts'}) 126 ) 127 128 enum_procunit = Trait('native',TraitPrefixMap({ 129 'native': 'native', 130 'electrons': 'electrons'}) 131 ) 132 133 text_editor = TraitEditorText() 134 135 __traits__ = {'input':Trait('flt.fits',TraitString()), 136 'output':Trait('',TraitString()), 137 'mdriztab':Trait(False, true_boolean, editor=bit_editor), 138 'refimage':Trait('',AnyValue), 139 'runfile':Trait('multidrizzle.run',TraitString()), 140 'workinplace':Trait(False, true_boolean, editor=bit_editor), 141 'updatewcs':Trait(True, true_boolean, editor=bit_editor), 142 'proc_unit':Trait('native',enum_procunit, editor=text_editor), 143 'context':Trait(True, true_boolean, editor=bit_editor), 144 'clean':Trait(False, true_boolean, editor=bit_editor), 145 'group':Trait('',AnyValue), 146 'ra':Trait('',AnyValue), 147 'dec':Trait('',AnyValue), 148 'coeffs':Trait('header',TraitString()), 149 'build':Trait(True, true_boolean, editor=bit_editor), 150 'shiftfile':Trait('',AnyValue), 151 'staticfile':Trait('',AnyValue), 152 'static_sig':Trait(4.0,TraitRange(0.0,9.0)), 153 'skywidth':Trait(0.1,TraitRange(0.0,1.0)), 154 'skystat':Trait('median',enum_stat, editor=text_editor), 155 'skylower':Trait(None,AnyValue), 156 'skyupper':Trait(None,AnyValue), 157 'skyclip':Trait(5,AnyValue), 158 'skylsigma':Trait(4.0,TraitRange(0.0,9.0)), 159 'skyusigma':Trait(4.0,TraitRange(0.0,9.0)), 160 'skyuser':Trait('',TraitString()), 161 'driz_sep_outnx':Trait('',AnyValue), 162 'driz_sep_outny':Trait('',AnyValue), 163 'driz_sep_kernel':Trait('turbo',enum_kernel, editor=text_editor), 164 'driz_sep_wt_scl':Trait('exptime',TraitString()), 165 'driz_sep_pixfrac':Trait(1.0,TraitRange(0.0,2.0)), 166 'driz_sep_scale':Trait('',AnyValue), 167 'driz_sep_rot':Trait('',AnyValue), 168 'driz_sep_fillval':Trait('INDEF',TraitString()), 169 'driz_sep_bits':Trait(0,AnyValue), 170 'median_newmasks':Trait(True, true_boolean, editor=bit_editor), 171 'combine_type':Trait('minmed',enum_combine, editor=text_editor), 172 'combine_nsigma':Trait('4 3',TraitString()), 173 'combine_nlow':Trait(0,AnyValue), 174 'combine_nhigh':Trait(1,AnyValue), 175 'combine_lthresh':Trait('',AnyValue), 176 'combine_hthresh':Trait('',AnyValue), 177 'combine_grow':Trait(1.0,TraitRange(0.0,21.0)), 178 'combine_maskpt':Trait(0.7,TraitRange(0.0,1.0)), 179 'blot_interp':Trait('poly5',enum_interp, editor=text_editor), 180 'blot_sinscl':Trait(1.0,TraitRange(0.0,21.0)), 181 'driz_cr_corr':Trait(False, true_boolean, editor=bit_editor), 182 'driz_cr_snr': Trait('3.5 3.0',TraitString()), 183 'driz_cr_scale':Trait('1.2 0.7',TraitString()), 184 'driz_cr_grow':Trait(1,TraitRange(1,10)), 185 'driz_cr_ctegrow':Trait(0,TraitRange(0,30)), 186 'driz_final_wht_type':Trait('EXP',enum_wht, editor=text_editor), 187 'driz_final_outnx':Trait('',AnyValue), 188 'driz_final_outny':Trait('',AnyValue), 189 'driz_final_kernel':Trait('square',enum_kernel, editor=text_editor), 190 'driz_final_wt_scl':Trait('exptime',TraitString()), 191 'driz_final_pixfrac':Trait(1.0,TraitRange(0.0,2.0)), 192 'driz_final_scale':Trait('',AnyValue), 193 'driz_final_rot':Trait(0.0,AnyValue), 194 'driz_final_fillval':Trait('INDEF',TraitString()), 195 'driz_final_bits':Trait(0,AnyValue), 196 'driz_final_units':Trait('cps',enum_finalunits, editor=text_editor), 197 'gain':Trait('',AnyValue), 198 'gnkeyword':Trait('',AnyValue), 199 'rdnoise':Trait('',AnyValue), 200 'rnkeyword':Trait('',AnyValue), 201 'exptime':Trait('',AnyValue), 202 'expkeyword':Trait('',AnyValue), 203 'crbit': Trait('',AnyValue), 204 'static':Trait(True, true_boolean, editor=bit_editor), 205 'skysub':Trait(True, true_boolean, editor=bit_editor), 206 'driz_separate':Trait(True, true_boolean, editor=bit_editor), 207 'median':Trait(True, true_boolean, editor=bit_editor), 208 'blot':Trait(True, true_boolean, editor=bit_editor), 209 'driz_cr':Trait(True, true_boolean, editor=bit_editor), 210 'driz_combine':Trait(True, true_boolean, editor=bit_editor), 211 'timing':Trait(True, true_boolean, editor=bit_editor) 212 } 213 214 __editable_traits__= TraitGroup( 215 TraitGroup( 216 TraitGroup( 217 'input','output','mdriztab','refimage','runfile', 218 'workinplace','context', 'clean','group', 'updatewcs', 219 'proc_unit','ra', 'dec','coeffs', 'build', 'shiftfile','staticfile', 220 'timing', 221 label='Init'), 222 TraitGroup('static', 223 'static_sig', 224 label='Static Mask'), 225 TraitGroup('skysub', 226 'skywidth', 'skystat', 'skylower', 227 'skyupper', 'skyclip', 'skylsigma', 228 'skyusigma', 'skyuser', 229 label='Sky') 230 ), 231 TraitGroup( 232 TraitGroup('driz_separate', 233 'driz_sep_outnx', 'driz_sep_outny', 'driz_sep_kernel', 234 'driz_sep_wt_scl', 'driz_sep_pixfrac', 'driz_sep_scale', 235 'driz_sep_rot', 'driz_sep_fillval','driz_sep_bits', 236 label='Separate Drizzle'), 237 TraitGroup('median', 238 'median_newmasks', 'combine_type', 'combine_nsigma', 239 'combine_nlow', 'combine_nhigh','combine_lthresh', 240 'combine_hthresh', 'combine_grow', 'combine_maskpt', 241 label='Median') 242 ), 243 TraitGroup( 244 TraitGroup('blot', 245 'blot_interp', 'blot_sinscl', 246 label='Blot'), 247 TraitGroup('driz_cr', 248 'driz_cr_corr','driz_cr_snr', 'driz_cr_scale', 'driz_cr_grow', 'driz_cr_ctegrow', 249 label='Driz CR'), 250 TraitGroup('driz_combine','driz_final_wht_type', 251 'driz_final_outnx', 'driz_final_outny', 252 'driz_final_kernel', 'driz_final_wt_scl', 253 'driz_final_pixfrac','driz_final_scale', 254 'driz_final_rot', 'driz_final_fillval', 255 'driz_final_bits', 'driz_final_units', 256 label='Final Drizzle'), 257 TraitGroup( 258 'gain', 'gnkeyword','rdnoise', 'rnkeyword', 259 'exptime','expkeyword', 'crbit', 260 label='Instrument') 261 ), 262 orientation='horizontal') 263 264 input_list = ['input','output'] 265 266 switches_list = ['static', 'skysub', 'driz_separate', 267 'median', 'blot', 'driz_cr', 'driz_combine','timing'] 268 269 master_list = ['mdriztab','refimage','runfile','workinplace','updatewcs', 270 'proc_unit','context', 'clean','group', 'bits', 'ra', 'dec', 271 'coeffs', 'build', 'shiftfile', 272 'staticfile', 'static_sig', 273 'skywidth', 'skystat', 'skylower', 274 'skyupper', 'skyclip', 'skylsigma', 275 'skyusigma', 'skyuser', 276 'driz_sep_outnx', 'driz_sep_outny', 'driz_sep_kernel', 'driz_sep_wt_scl', 277 'driz_sep_pixfrac','driz_sep_scale', 'driz_sep_rot', 278 'driz_sep_fillval', 'driz_sep_bits', 279 'median_newmasks', 'combine_type', 'combine_nsigma', 280 'combine_nlow', 'combine_nhigh','combine_lthresh', 281 'combine_hthresh', 'combine_grow', 'combine_maskpt', 282 'blot_interp', 'blot_sinscl', 283 'driz_cr_corr','driz_cr_snr', 'driz_cr_scale','driz_final_wht_type', 284 'driz_final_outnx', 'driz_final_outny', 'driz_cr_grow', 'driz_cr_ctegrow', 285 'driz_final_kernel', 'driz_final_wt_scl', 'driz_final_pixfrac', 286 'driz_final_scale', 'driz_final_rot', 287 'driz_final_fillval', 'driz_final_bits', 'driz_final_units', 288 'gain', 'gnkeyword','rdnoise', 'rnkeyword', 289 'exptime','expkeyword', 'crbit'] 290 # 291 # List of parameter names for which blank values need to be 292 # converted to a value of None in the master_par dictionary. 293 # 294 clean_string_list = [ 'output', 'group', 'shiftfile', 'staticfile', 295 'ra', 'dec', 'coeffs', 'combine_lthresh', 'combine_hthresh', 296 'driz_sep_scale', 'driz_sep_rot', 'driz_sep_bits', 297 'driz_final_bits', 'driz_final_scale', 298 'driz_final_rot'] 299 300 attribute_list = ['switches','input','_set_trait_value','_set_event_value', 301 'steps','output','master_pars'] 302
303 - def __init__(self, input, output, dict=None, files = None):
304 """ The input parameter 'dict' needs to be a Python dictionary 305 of attributes whose values need to be updated. 306 """ 307 self.input = input 308 self.output = output 309 310 # Initialize switches and master_pars dictionaries 311 # based on defaults set up using the traits 312 self.switches = {} 313 self.master_pars = {} 314 self.updateMasterPars() 315 316 # Now, apply any new values input through keywords 317 # upon start up. This will further override any previous 318 # settings for those parameters. 319 if dict != None: 320 self.updatePars(dict) 321 322 # Initialize ProcSteps here as well 323 self.steps = ps.ProcSteps() 324 self.setProcSteps() 325 326 # MDRIZTAB must be opened here, now that the final form of the 327 # input files has been determined and 328 # before the association is built. 329 if self.master_pars['mdriztab']: 330 record = mdzhandler.getMultidrizzleParameters(files) 331 tabdict = self._handleMdriztab(record) 332 self.updatePars(tabdict)
333
334 - def verifyPar(self,kw,value):
335 if value == 'None' or (kw in self.clean_string_list and value == ''): 336 value = None 337 if isinstance(value,types.StringType): 338 if value.isdigit(): 339 value = int(value) 340 if value == 'INDEF' and kw.find('fillval') < 0: value = None 341 342 return value
343
344 - def updateMasterPars(self):
345 for _par in self.switches_list: 346 _val = getattr(self,_par) 347 self.switches[_par] = _val 348 349 for _par in self.master_list: 350 if _par != 'bits': 351 value = self.verifyPar(_par,getattr(self,_par)) 352 self.master_pars[_par] = value
353
354 - def updatePars(self,dict):
355 356 # Verify that all inputs correspond to keywords in the 357 # master dictionary, otherwise, raise an exception 358 359 self.verifyInput(dict) 360 361 # Copy values for input keywords into master dictionary 362 # 363 # NOTE: 364 # Updating these values later will require copying the 365 # values to two places: these dictionaries and to __dict__ 366 # 367 for k in dict.keys(): 368 #print "keys updated in master dictionary: ",k 369 # Update value of trait and coerce the 370 # TraitType on the value in the process 371 # 372 if k[-1] != '_': 373 374 setattr(self,k,dict[k]) 375 376 if k in self.switches_list: 377 # If key is a processing switch, update the 378 # switches dictionary 379 self.switches[k] = getattr(self,k) 380 elif k in self.master_list: 381 # If it is not a switch, update its value 382 # in the master list. 383 value = self.verifyPar(k,getattr(self,k)) 384 self.master_pars[k] = value 385 386 if 'bits' in dict.keys(): 387 if 'driz_final_bits' not in dict.keys(): 388 self.master_pars['driz_final_bits'] = int(dict['bits']) 389 self.master_pars['driz_sep_bits'] = None
390
391 - def verifyInput(self,dict):
392 """ Verifies that all entries provided in the input dictionary 393 correspond to keys in the master dictionary. 394 395 If there are mismatches, then it will report those errant 396 keywords and raise an Exception. This comparison will be 397 case-insensitive, for simplicity. 398 """ 399 if dict != None: 400 _err_str = 'MultiDrizzle inputs which are not recognized:\n' 401 _num_invalid = 0 402 for k in dict.keys(): 403 if k[-1] != '_' and k not in self.attribute_list: 404 if (not k.lower() in self.master_list and 405 not k.lower() in self.switches_list ): 406 _err_str += 'Unrecognized key: '+str(k)+'\n' 407 _num_invalid += 1 408 if _num_invalid > 0: 409 print _err_str 410 raise ValueError
411
412 - def setProcSteps(self, **switches):
413 """ Update the master parameter list with the step settings 414 given in 'switches', then update the ProcStep 415 instance 'self.steps' appropriately. 416 417 """ 418 # Start by updating the master list of values for 419 # the switch settings, 420 # after verifying that all entries are valid. 421 self.verifyInput(switches) 422 423 for k in switches: 424 # Only update the switch setting if it has been set 425 # to something other than None. 426 if switches[k] != None: 427 self.switches[k] = switches[k] 428 429 # Now, update the step settings for the class 430 self.steps.addSteps(self.switches['static'], 431 self.switches['skysub'], 432 self.switches['driz_separate'], 433 self.switches['median'], 434 self.switches['blot'], 435 self.switches['driz_cr'], 436 self.switches['driz_combine'])
437
438 - def getDrizPars(self,prefix='driz_sep',keylist=None):
439 """ Returns a dictionary of values used for the drizzle 440 processing steps. The prefix defines which set of 441 keywords from the master parameter list needs 442 to be returned. 443 444 The member names in the output dictionary, though, will 445 not include the specified prefix as required by PyDrizzle. 446 447 Additional keywords used for this dictionary are listed 448 in the module parameter 'driz_keys'. 449 """ 450 _driz_dict = {} 451 _prefix_len = len(prefix)+1 452 for kw in self.master_pars.keys(): 453 if self.master_pars[kw] == '': 454 self.master_pars[kw] = None 455 if kw.find(prefix) > -1: 456 _kwname = kw[_prefix_len:] 457 if _kwname != 'fillval': 458 _driz_dict[_kwname] = self.master_pars[kw] 459 else: 460 _driz_dict[_kwname] = str(self.master_pars[kw]) 461 462 # Append any values for keywords provided by user in keylist 463 if keylist != None: 464 for kw in keylist: 465 if kw == 'group' and self.master_pars[kw] is not None: 466 # Always set up group as a list, if specified 467 group = [] 468 glist = str(self.master_pars[kw]).split(',') 469 for g in glist: group.append(int(g)) 470 _driz_dict[kw] = group 471 else: 472 _driz_dict[kw] = self.master_pars[kw] 473 474 return _driz_dict
475
476 - def getParList(self,keylist,prefix=None):
477 """ Returns a dictionary of values used for setting 478 the parameters listed in keylist. 479 480 If a prefix is specified, then remove that prefix 481 from the master parameter name when creating the 482 output dictionary. 483 """ 484 485 _instr_dict = {} 486 for kw in keylist: 487 if prefix != None and kw.find(prefix) > -1: 488 _kw = kw[len(prefix):] 489 else: 490 _kw = kw 491 492 if kw in self.input_list: 493 _instr_dict[_kw] = self.__dict__[kw] 494 elif self.master_pars.has_key(kw): 495 _instr_dict[_kw] = self.master_pars[kw] 496 elif self.switches.has_key(kw): 497 _instr_dict[_kw] = self.switches[kw] 498 else: 499 _instr_dict[_kw] = None 500 501 return _instr_dict
502
503 - def _handleMdriztab(self, rec):
504 """ 505 Collect task parameters from the MDRIZTAB record and 506 update the master parameters list with those values 507 508 Note that parameters read from the MDRIZTAB record must 509 be cleaned up in a similar way that parameters read 510 from the user interface are. 511 """ 512 tabdict = {} 513 # for each entry in the record... 514 for indx in xrange(len(rec.array.names)): 515 # ... get the name, format, and value. 516 _name = rec.array.names[indx] 517 _format = rec.array.formats[indx] 518 _value = rec.field(_name) 519 520 # Translate names from MDRIZTAB columns names to 521 # input parameter names found in IRAF par file. 522 # 523 if _name.find('final') > -1: _name = 'driz_'+_name 524 elif _name == 'subsky': _name = 'skysub' 525 elif _name == 'crbitval': _name = 'crbit' 526 elif _name == 'readnoise': _name = 'rdnoise' 527 528 # We do not care about the first two columns at this point 529 # as they are only used for selecting the rows 530 if _name != 'filter' and _name != 'numimages': 531 # start by determining the format type of the parameter 532 _fmt = findFormat(_format) 533 534 # Based on format type, apply proper conversion/cleaning 535 if (_fmt == 'a') or (_fmt == 'A'): 536 _val = cleanBlank(_value) 537 if _val == None: _val = '' 538 elif (_format == 'i1') or (_format=='1L'): 539 _val = toBoolean(_value) 540 elif (_format == 'i4') or (_format == '1J'): 541 _val = cleanInt(_value) 542 elif (_format == 'f4') or (_format == '1E'): 543 _val = cleanNaN(_value) 544 else: 545 print 'MDRIZTAB column ',_name,' has unrecognized format',_format 546 raise ValueError 547 if _name.find('fillval') > -1 and _val == None: 548 _val = 'INDEF' 549 tabdict[_name] = _val 550 551 return tabdict
552