Package pydrizzle :: Module outputimage
[hide private]
[frames] | no frames]

Source Code for Module pydrizzle.outputimage

  1  from __future__ import division # confidence medium 
  2  import types 
  3  import pyfits 
  4  from pytools import fileutil, readgeis 
  5   
  6  yes = True 
  7  no = False 
  8   
  9  RESERVED_KEYS = ['NAXIS','BITPIX','DATE','IRAF-TLM','XTENSION','EXTNAME','EXTVER'] 
 10   
 11  EXTLIST = ('SCI', 'WHT', 'CTX') 
 12   
 13  DTH_KEYWORDS=['CD1_1','CD1_2', 'CD2_1', 'CD2_2', 'CRPIX1', 
 14  'CRPIX2','CRVAL1', 'CRVAL2', 'CTYPE1', 'CTYPE2'] 
 15   
16 -class OutputImage:
17 """ 18 This class manages the creation of the array objects 19 which will be used by Drizzle. The three arrays, SCI/WHT/CTX, 20 will be setup either as extensions in a 21 single multi-extension FITS file, or as separate FITS 22 files. 23 """
24 - def __init__(self, plist, build=yes, wcs=None, single=no, blot=no):
25 """ 26 The object 'plist' must contain at least the following members: 27 plist['output'] - name of output FITS image (for SCI) 28 plist['outnx'] - size of X axis for output array 29 plist['outny'] - size of Y axis for output array 30 If 'single=yes', then 'plist' also needs to contain: 31 plist['outsingle'] 32 plist['outsweight'] 33 plist['outscontext'] 34 If 'blot=yes', then 'plist' also needs: 35 plist['data'] 36 plist['outblot'] 37 plist['blotnx'],plist['blotny'] 38 39 If 'build' is set to 'no', then each extension/array must be 40 in separate FITS objects. This would also require: 41 plist['outdata'] - name of output SCI FITS image 42 plist['outweight'] - name of output WHT FITS image 43 plist['outcontext'] - name of output CTX FITS image 44 45 Optionally, the overall exposure time information can be passed as: 46 plist['texptime'] - total exptime for output 47 plist['expstart'] - start time of combined exposure 48 plist['expend'] - end time of combined exposure 49 50 51 """ 52 self.build = build 53 self.single = single 54 self.parlist = plist 55 _nimgs = len(self.parlist) 56 self.bunit = None 57 self.units = 'cps' 58 59 if not blot: 60 self.output = plist[0]['output'] 61 self.shape = (plist[0]['outny'],plist[0]['outnx']) 62 else: 63 self.output = plist[0]['outblot'] 64 self.shape = (plist[0]['blotny'],plist[0]['blotnx']) 65 66 # Keep track of desired output WCS computed by PyDrizzle 67 self.wcs = wcs 68 69 # 70 # Apply special operating switches: 71 # single - separate output for each input 72 # 73 if single: 74 _outdata = plist[0]['outsingle'] 75 _outweight = plist[0]['outsweight'] 76 _outcontext = plist[0]['outscontext'] 77 # Only report values appropriate for single exposure 78 self.texptime = plist[0]['exptime'] 79 self.expstart = plist[0]['expstart'] 80 self.expend = plist[0]['expend'] 81 else: 82 _outdata = plist[0]['outdata'] 83 _outweight = plist[0]['outweight'] 84 _outcontext = plist[0]['outcontext'] 85 # Report values appropriate for entire combined product 86 self.texptime = plist[0]['texptime'] 87 self.expstart = plist[0]['texpstart'] 88 self.expend = plist[_nimgs-1]['texpend'] 89 90 91 if blot: 92 _outdata = plist[0]['outblot'] 93 94 if not self.build or single: 95 self.output = _outdata 96 97 self.outdata = _outdata 98 self.outweight = _outweight 99 self.outcontext = _outcontext
100
101 - def set_bunit(self,bunit):
102 """ Method used to update the value of the bunit attribute.""" 103 self.bunit = bunit
104
105 - def set_units(self,units):
106 """ Method used to record what units were specified by the user 107 for the output product.""" 108 self.units = units
109 110
111 - def writeFITS(self, template, sciarr, whtarr, ctxarr=None, versions=None, extlist=EXTLIST, overwrite=yes):
112 """ Generate PyFITS objects for each output extension 113 using the file given by 'template' for populating 114 headers. 115 116 The arrays will have the size specified by 'shape'. 117 """ 118 119 if fileutil.findFile(self.output): 120 if overwrite: 121 print 'Deleting previous output product: ',self.output 122 fileutil.removeFile(self.output) 123 124 else: 125 print 'WARNING: Output file ',self.output,' already exists and overwrite not specified!' 126 print 'Quitting... Please remove before resuming operations.' 127 raise IOError 128 129 # Default value for NEXTEND when 'build'== True 130 nextend = 3 131 if not self.build: 132 nextend = 0 133 if self.outweight: 134 if overwrite: 135 if fileutil.findFile(self.outweight): 136 print 'Deleting previous output WHT product: ',self.outweight 137 fileutil.removeFile(self.outweight) 138 else: 139 print 'WARNING: Output file ',self.outweight,' already exists and overwrite not specified!' 140 print 'Quitting... Please remove before resuming operations.' 141 raise IOError 142 143 144 if self.outcontext: 145 if overwrite: 146 if fileutil.findFile(self.outcontext): 147 print 'Deleting previous output CTX product: ',self.outcontext 148 fileutil.removeFile(self.outcontext) 149 else: 150 print 'WARNING: Output file ',self.outcontext,' already exists and overwrite not specified!' 151 print 'Quitting... Please remove before resuming operations.' 152 raise IOError 153 154 # Get default headers from multi-extension FITS file 155 # If input data is not in MEF FITS format, it will return 'None' 156 # and those headers will have to be generated from drizzle output 157 # file FITS headers. 158 # NOTE: These are HEADER objects, not HDUs 159 prihdr,scihdr,errhdr,dqhdr = getTemplates(template,extlist) 160 161 if prihdr == None: 162 # Use readgeis to get header for use as Primary header. 163 _indx = template.find('[') 164 if _indx < 0: 165 _data = template 166 else: 167 _data = template[:_indx] 168 169 fpri = readgeis.readgeis(_data) 170 prihdr = fpri[0].header.copy() 171 fpri.close() 172 del fpri 173 174 175 # Setup primary header as an HDU ready for appending to output FITS file 176 prihdu = pyfits.PrimaryHDU(header=prihdr,data=None) 177 178 # Start by updating PRIMARY header keywords... 179 prihdu.header.update('EXTEND',pyfits.TRUE,after='NAXIS') 180 prihdu.header.update('NEXTEND',nextend) 181 prihdu.header.update('FILENAME', self.output) 182 183 # Update the ROOTNAME with the new value as well 184 _indx = self.output.find('_drz') 185 if _indx < 0: 186 prihdu.header.update('ROOTNAME', self.output) 187 else: 188 prihdu.header.update('ROOTNAME', self.output[:_indx]) 189 190 191 # Get the total exposure time for the image 192 # If not calculated by PyDrizzle and passed through 193 # the pardict, then leave value from the template image. 194 if self.texptime: 195 prihdu.header.update('EXPTIME', self.texptime) 196 prihdu.header.update('EXPSTART', self.expstart) 197 prihdu.header.update('EXPEND', self.expend) 198 199 #Update ASN_MTYPE to reflect the fact that this is a product 200 # Currently hard-wired to always output 'PROD-DTH' as MTYPE 201 prihdu.header.update('ASN_MTYP', 'PROD-DTH') 202 203 # Update DITHCORR calibration keyword if present 204 # Remove when we can modify FITS headers in place... 205 if prihdu.header.has_key('DRIZCORR') > 0: 206 prihdu.header['DRIZCORR'] = 'COMPLETE' 207 if prihdu.header.has_key('DITHCORR') > 0: 208 prihdu.header['DITHCORR'] = 'COMPLETE' 209 210 211 prihdu.header.update('NDRIZIM',len(self.parlist), 212 comment='Drizzle, No. images drizzled onto output') 213 214 self.addDrizKeywords(prihdu.header,versions) 215 216 if scihdr: 217 del scihdr['OBJECT'] 218 if scihdr.has_key('CCDCHIP'): scihdr.update('CCDCHIP','-999') 219 if scihdr.has_key('NCOMBINE') > 0: 220 scihdr.update('NCOMBINE', self.parlist[0]['nimages']) 221 222 # If BUNIT keyword was found and reset, then 223 if self.bunit is not None: 224 scihdr.update('BUNIT',self.bunit,comment="Units of science product") 225 226 if self.wcs: 227 # Update WCS Keywords based on PyDrizzle product's value 228 # since 'drizzle' itself doesn't update that keyword. 229 scihdr.update('ORIENTAT',self.wcs.orient) 230 scihdr.update('CD1_1',self.wcs.cd11) 231 scihdr.update('CD1_2',self.wcs.cd12) 232 scihdr.update('CD2_1',self.wcs.cd21) 233 scihdr.update('CD2_2',self.wcs.cd22) 234 scihdr.update('CRVAL1',self.wcs.crval1) 235 scihdr.update('CRVAL2',self.wcs.crval2) 236 scihdr.update('CRPIX1',self.wcs.crpix1) 237 scihdr.update('CRPIX2',self.wcs.crpix2) 238 scihdr.update('VAFACTOR',1.0) 239 # Remove any reference to TDD correction 240 if scihdr.has_key('TDDALPHA'): 241 del scihdr['TDDALPHA'] 242 del scihdr['TDDBETA'] 243 # Remove '-SIP' from CTYPE for output product 244 if scihdr['ctype1'].find('SIP') > -1: 245 scihdr.update('ctype1', scihdr['ctype1'][:-4]) 246 scihdr.update('ctype2',scihdr['ctype2'][:-4]) 247 # Remove SIP coefficients from DRZ product 248 for k in scihdr.items(): 249 if (k[0][:2] in ['A_','B_']) or (k[0][:3] in ['IDC','SCD'] and k[0] != 'IDCTAB') or \ 250 (k[0][:6] in ['SCTYPE','SCRVAL','SNAXIS','SCRPIX']): 251 del scihdr[k[0]] 252 self.addPhotKeywords(scihdr,prihdu.header) 253 254 255 ########## 256 # Now, build the output file 257 ########## 258 if self.build: 259 print '-Generating multi-extension output file: ',self.output 260 fo = pyfits.HDUList() 261 262 # Add primary header to output file... 263 fo.append(prihdu) 264 265 hdu = pyfits.ImageHDU(data=sciarr,header=scihdr,name=extlist[0]) 266 fo.append(hdu) 267 268 # Build WHT extension here, if requested... 269 if errhdr: 270 errhdr.update('CCDCHIP','-999') 271 272 hdu = pyfits.ImageHDU(data=whtarr,header=errhdr,name=extlist[1]) 273 hdu.header.update('EXTVER',1) 274 if self.wcs: 275 # Update WCS Keywords based on PyDrizzle product's value 276 # since 'drizzle' itself doesn't update that keyword. 277 hdu.header.update('ORIENTAT',self.wcs.orient) 278 hdu.header.update('CD1_1',self.wcs.cd11) 279 hdu.header.update('CD1_2',self.wcs.cd12) 280 hdu.header.update('CD2_1',self.wcs.cd21) 281 hdu.header.update('CD2_2',self.wcs.cd22) 282 hdu.header.update('CRVAL1',self.wcs.crval1) 283 hdu.header.update('CRVAL2',self.wcs.crval2) 284 hdu.header.update('CRPIX1',self.wcs.crpix1) 285 hdu.header.update('CRPIX2',self.wcs.crpix2) 286 hdu.header.update('VAFACTOR',1.0) 287 288 fo.append(hdu) 289 290 # Build CTX extension here 291 # If there is only 1 plane, write it out as a 2-D extension 292 if self.outcontext: 293 if ctxarr.shape[0] == 1: 294 _ctxarr = ctxarr[0] 295 else: 296 _ctxarr = ctxarr 297 else: 298 _ctxarr = None 299 300 hdu = pyfits.ImageHDU(data=_ctxarr,header=dqhdr,name=extlist[2]) 301 hdu.header.update('EXTVER',1) 302 if self.wcs: 303 # Update WCS Keywords based on PyDrizzle product's value 304 # since 'drizzle' itself doesn't update that keyword. 305 hdu.header.update('ORIENTAT',self.wcs.orient) 306 hdu.header.update('CD1_1',self.wcs.cd11) 307 hdu.header.update('CD1_2',self.wcs.cd12) 308 hdu.header.update('CD2_1',self.wcs.cd21) 309 hdu.header.update('CD2_2',self.wcs.cd22) 310 hdu.header.update('CRVAL1',self.wcs.crval1) 311 hdu.header.update('CRVAL2',self.wcs.crval2) 312 hdu.header.update('CRPIX1',self.wcs.crpix1) 313 hdu.header.update('CRPIX2',self.wcs.crpix2) 314 hdu.header.update('VAFACTOR',1.0) 315 316 317 fo.append(hdu) 318 319 fo.writeto(self.output) 320 fo.close() 321 del fo, hdu 322 323 else: 324 print '-Generating simple FITS output: ',self.outdata 325 fo = pyfits.HDUList() 326 327 hdu = pyfits.PrimaryHDU(data=sciarr, header=prihdu.header) 328 329 # Append remaining unique header keywords from template DQ 330 # header to Primary header... 331 if scihdr: 332 for _card in scihdr.ascard: 333 if _card.key not in RESERVED_KEYS and hdu.header.has_key(_card.key) == 0: 334 hdu.header.ascard.append(_card) 335 del hdu.header['PCOUNT'] 336 del hdu.header['GCOUNT'] 337 self.addPhotKeywords(hdu.header,prihdu.header) 338 hdu.header.update('filename',self.outdata) 339 340 # Add primary header to output file... 341 fo.append(hdu) 342 fo.writeto(self.outdata) 343 del fo,hdu 344 345 if self.outweight and whtarr != None: 346 # We need to build new PyFITS objects for each WHT array 347 fwht = pyfits.HDUList() 348 349 if errhdr: 350 errhdr.update('CCDCHIP','-999') 351 352 hdu = pyfits.PrimaryHDU(data=whtarr, header=prihdu.header) 353 354 # Append remaining unique header keywords from template DQ 355 # header to Primary header... 356 if errhdr: 357 for _card in errhdr.ascard: 358 if _card.key not in RESERVED_KEYS and hdu.header.has_key(_card.key) == 0: 359 hdu.header.ascard.append(_card) 360 hdu.header.update('filename',self.outweight) 361 hdu.header.update('CCDCHIP','-999') 362 if self.wcs: 363 # Update WCS Keywords based on PyDrizzle product's value 364 # since 'drizzle' itself doesn't update that keyword. 365 hdu.header.update('ORIENTAT',self.wcs.orient) 366 hdu.header.update('CD1_1',self.wcs.cd11) 367 hdu.header.update('CD1_2',self.wcs.cd12) 368 hdu.header.update('CD2_1',self.wcs.cd21) 369 hdu.header.update('CD2_2',self.wcs.cd22) 370 hdu.header.update('CRVAL1',self.wcs.crval1) 371 hdu.header.update('CRVAL2',self.wcs.crval2) 372 hdu.header.update('CRPIX1',self.wcs.crpix1) 373 hdu.header.update('CRPIX2',self.wcs.crpix2) 374 hdu.header.update('VAFACTOR',1.0) 375 376 # Add primary header to output file... 377 fwht.append(hdu) 378 fwht.writeto(self.outweight) 379 del fwht,hdu 380 381 # If a context image was specified, build a PyFITS object 382 # for it as well... 383 if self.outcontext and ctxarr != None: 384 fctx = pyfits.HDUList() 385 386 # If there is only 1 plane, write it out as a 2-D extension 387 if ctxarr.shape[0] == 1: 388 _ctxarr = ctxarr[0] 389 else: 390 _ctxarr = ctxarr 391 392 hdu = pyfits.PrimaryHDU(data=_ctxarr, header=prihdu.header) 393 394 # Append remaining unique header keywords from template DQ 395 # header to Primary header... 396 if dqhdr: 397 for _card in dqhdr.ascard: 398 if _card.key not in RESERVED_KEYS and hdu.header.has_key(_card.key) == 0: 399 hdu.header.ascard.append(_card) 400 hdu.header.update('filename', self.outcontext) 401 if self.wcs: 402 # Update WCS Keywords based on PyDrizzle product's value 403 # since 'drizzle' itself doesn't update that keyword. 404 hdu.header.update('ORIENTAT',self.wcs.orient) 405 hdu.header.update('CD1_1',self.wcs.cd11) 406 hdu.header.update('CD1_2',self.wcs.cd12) 407 hdu.header.update('CD2_1',self.wcs.cd21) 408 hdu.header.update('CD2_2',self.wcs.cd22) 409 hdu.header.update('CRVAL1',self.wcs.crval1) 410 hdu.header.update('CRVAL2',self.wcs.crval2) 411 hdu.header.update('CRPIX1',self.wcs.crpix1) 412 hdu.header.update('CRPIX2',self.wcs.crpix2) 413 hdu.header.update('VAFACTOR',1.0) 414 415 fctx.append(hdu) 416 fctx.writeto(self.outcontext) 417 del fctx,hdu
418 419
420 - def addPhotKeywords(self,hdr,phdr):
421 """ Insure that this header contains all the necessary photometry 422 keywords, moving them into the extension header if necessary. 423 This only moves keywords from the PRIMARY header if the keywords 424 do not already exist in the SCI header. 425 """ 426 PHOTKEYS = ['PHOTFLAM','PHOTPLAM','PHOTBW','PHOTZPT','PHOTMODE'] 427 for pkey in PHOTKEYS: 428 if not hdr.has_key(pkey): 429 # Make sure there is a copy PRIMARY header, if so, copy it 430 if phdr.has_key(pkey): 431 # Copy keyword from PRIMARY header 432 hdr.update(pkey,phdr[pkey]) 433 # then delete it from PRIMARY header to avoid duplication 434 del phdr[pkey] 435 else: 436 # If there is no such keyword to be found, define a default 437 if pkey != 'PHOTMODE': 438 hdr.update(pkey,0.0) 439 else: 440 hdr.update(pkey,'')
441
442 - def addDrizKeywords(self,hdr,versions):
443 """ Add drizzle parameter keywords to header. """ 444 445 # Extract some global information for the keywords 446 _geom = 'User parameters' 447 448 _imgnum = 0 449 for pl in self.parlist: 450 451 # Start by building up the keyword prefix based 452 # on the image number for the chip 453 _imgnum += 1 454 _keyprefix = 'D%03d'%_imgnum 455 if not isinstance(pl['driz_mask'],types.StringType): 456 _driz_mask_name = 'static mask' 457 else: 458 _driz_mask_name = pl['driz_mask'] 459 460 hdr.update(_keyprefix+'VER',pl['driz_version'][:44], 461 comment='Drizzle, task version') 462 463 # Then the source of the geometric information 464 hdr.update(_keyprefix+'GEOM','User parameters', 465 comment= 'Drizzle, source of geometric information') 466 467 # Now we continue to add the other items using the same 468 # "stem" 469 hdr.update(_keyprefix+'DATA',pl['data'][:64], 470 comment= 'Drizzle, input data image') 471 472 hdr.update(_keyprefix+'DEXP',pl['exptime'], 473 comment= 'Drizzle, input image exposure time (s)') 474 475 hdr.update(_keyprefix+'OUDA',pl['outdata'][:64], 476 comment= 'Drizzle, output data image') 477 478 hdr.update(_keyprefix+'OUWE',pl['outweight'][:64], 479 comment= 'Drizzle, output weighting image') 480 481 hdr.update(_keyprefix+'OUCO',pl['outcontext'][:64], 482 comment= 'Drizzle, output context image') 483 484 hdr.update(_keyprefix+'MASK',_driz_mask_name[:64], 485 comment= 'Drizzle, input weighting image') 486 487 # Process the values of WT_SCL to be consistent with 488 # what IRAF Drizzle would output 489 if pl['wt_scl'] == 'exptime': _wtscl = pl['exptime'] 490 elif pl['wt_scl'] == 'expsq': _wtscl = pl['exptime']*pl['exptime'] 491 else: _wtscl = pl['wt_scl'] 492 493 hdr.update(_keyprefix+'WTSC',_wtscl, 494 comment= 'Drizzle, weighting factor for input image') 495 496 hdr.update(_keyprefix+'KERN',pl['kernel'], 497 comment= 'Drizzle, form of weight distribution kernel') 498 499 hdr.update(_keyprefix+'PIXF',pl['pixfrac'], 500 comment= 'Drizzle, linear size of drop') 501 502 hdr.update(_keyprefix+'COEF',pl['coeffs'][:64], 503 comment= 'Drizzle, coefficients file name ') 504 505 hdr.update(_keyprefix+'XGIM',pl['xgeoim'][:64], 506 comment= 'Drizzle, X distortion image name ') 507 508 hdr.update(_keyprefix+'YGIM',pl['ygeoim'][:64], 509 comment= 'Drizzle, Y distortion image name ') 510 511 hdr.update(_keyprefix+'LAM',pl['plam'], 512 comment='Drizzle, wavelength applied for transformation (nm)') 513 514 # Only put the next entries is we are NOT using WCS 515 hdr.update(_keyprefix+'SCAL',pl['scale'], 516 comment= 'Drizzle, scale (pixel size) of output image') 517 518 # Convert the rotation angle back to degrees 519 hdr.update(_keyprefix+'ROT',float("%0.8f"%pl['rot']), 520 comment= 'Drizzle, rotation angle, degrees anticlockwise') 521 522 # Check the SCALE and units 523 # The units are INPUT pixels on entry to this routine 524 hdr.update(_keyprefix+'XSH',pl['xsh'], 525 comment= 'Drizzle, X shift applied') 526 527 hdr.update(_keyprefix+'YSH',pl['ysh'], 528 comment= 'Drizzle, Y shift applied') 529 530 hdr.update(_keyprefix+'SFTU','output', 531 comment='Drizzle, units used for shifts') 532 533 hdr.update(_keyprefix+'SFTF','output', 534 comment= 'Drizzle, frame in which shifts were applied') 535 536 hdr.update(_keyprefix+'EXKY','EXPTIME', 537 comment= 'Drizzle, exposure keyword name in input image') 538 539 hdr.update(_keyprefix+'INUN','counts', 540 comment= 'Drizzle, units of input image - counts or cps') 541 542 hdr.update(_keyprefix+'OUUN',self.units, 543 comment= 'Drizzle, units of output image - counts or cps') 544 545 hdr.update(_keyprefix+'FVAL',pl['fillval'], 546 comment= 'Drizzle, fill value for zero weight output pix') 547 548 OFF=0.5 549 550 hdr.update(_keyprefix+'INXC',float(pl['blotnx']//2)+OFF, 551 comment= 'Drizzle, reference center of input image (X)') 552 553 hdr.update(_keyprefix+'INYC',float(pl['blotny']//2)+OFF, 554 comment= 'Drizzle, reference center of input image (Y)') 555 556 hdr.update(_keyprefix+'OUXC',float(pl['outnx']//2)+OFF, 557 comment= 'Drizzle, reference center of output image (X)') 558 559 hdr.update(_keyprefix+'OUYC',float(pl['outny']//2)+OFF, 560 comment= 'Drizzle, reference center of output image (Y)') 561 562 # Add version information as HISTORY cards to the header 563 if versions != None: 564 ver_str = "PyDrizzle processing performed using: " 565 hdr.add_history(ver_str) 566 for k in versions.keys(): 567 ver_str = ' '+str(k)+' Version '+str(versions[k]) 568 hdr.add_history(ver_str)
569 570 571
572 -def getTemplates(fname,extlist):
573 # Obtain default headers for output file 574 # If the output file already exists, use it 575 # If not, use an input file for this information. 576 # 577 # NOTE: Returns 'pyfits.Header' objects, not HDU objects! 578 # 579 if fname == None: 580 print 'No data files for creating FITS output.' 581 raise Exception 582 583 froot,fextn = fileutil.parseFilename(fname) 584 if fextn is not None: 585 fnum = fileutil.parseExtn(fextn)[1] 586 ftemplate = fileutil.openImage(froot,mode='readonly') 587 prihdr = pyfits.Header(cards=ftemplate['PRIMARY'].header.ascard.copy()) 588 del prihdr['pcount'] 589 del prihdr['gcount'] 590 591 if fname.find('.fits') > 0 and len(ftemplate) > 1: 592 593 # Setup which keyword we will use to select each 594 # extension... 595 _extkey = 'EXTNAME' 596 597 defnum = fileutil.findKeywordExtn(ftemplate,_extkey,extlist[0]) 598 # 599 # Now, extract the headers necessary for output (as copies) 600 # 1. Find the SCI extension in the template image 601 # 2. Make a COPY of the extension header for use in new output file 602 if fextn in [None,1]: 603 extnum = fileutil.findKeywordExtn(ftemplate,_extkey,extlist[0]) 604 else: 605 extnum = (extlist[0],fnum) 606 scihdr = pyfits.Header(cards=ftemplate[extnum].header.ascard.copy()) 607 scihdr.update('extver',1) 608 609 if fextn in [None,1]: 610 extnum = fileutil.findKeywordExtn(ftemplate,_extkey,extlist[1]) 611 else: 612 # there may or may not be a second type of extension in the template 613 count = 0 614 for f in ftemplate: 615 if f.header.has_key('extname') and f.header['extname'] == extlist[1]: 616 count += 1 617 if count > 0: 618 extnum = (extlist[1],fnum) 619 else: 620 # Use science header for remaining headers 621 extnum = (extlist[0],fnum) 622 errhdr = pyfits.Header(cards=ftemplate[extnum].header.ascard.copy()) 623 errhdr.update('extver',1) 624 625 if fextn in [None,1]: 626 extnum = fileutil.findKeywordExtn(ftemplate,_extkey,extlist[2]) 627 else: 628 count = 0 629 for f in ftemplate: 630 if f.header.has_key('extname') and f.header['extname'] == extlist[2]: 631 count += 1 632 if count > 0: 633 extnum = (extlist[2],fnum) 634 else: 635 # Use science header for remaining headers 636 extnum = (extlist[0],fnum) 637 dqhdr = pyfits.Header(cards=ftemplate[extnum].header.ascard.copy()) 638 dqhdr.update('extver',1) 639 640 else: 641 # Create default headers from scratch 642 scihdr = None 643 errhdr = None 644 dqhdr = None 645 646 ftemplate.close() 647 del ftemplate 648 649 # Now, safeguard against having BSCALE and BZERO 650 try: 651 del scihdr['bscale'] 652 del scihdr['bzero'] 653 del errhdr['bscale'] 654 del errhdr['bzero'] 655 del dqhdr['bscale'] 656 del dqhdr['bzero'] 657 except: 658 # If these don't work, they didn't exist to start with... 659 pass 660 661 662 # At this point, check errhdr and dqhdr to make sure they 663 # have all the requisite keywords (as listed in updateDTHKeywords). 664 # Simply copy them from scihdr if they don't exist... 665 if errhdr != None and dqhdr != None: 666 for keyword in DTH_KEYWORDS: 667 if not errhdr.has_key(keyword): 668 errhdr.update(keyword,scihdr[keyword]) 669 if not dqhdr.has_key(keyword): 670 dqhdr.update(keyword,scihdr[keyword]) 671 672 return prihdr,scihdr,errhdr,dqhdr
673