def combineFlats(self, fns): """ Takes a list of flat file names, combines them and returns the resulting image in the form of a new FITS HDU. Keywords are added the new FITS: CLEANED, FLAT0, FLAT1, ... """ if len(fns) == 0: return None hdr = fits.getheader(fns[0]) for n in range(len(fns)): hdr['FLAT' + str(n)] = fns[n][fns[n].rfind('/')+1:fns[n].rfind('.')] # If there is more than one flat in the list then median combine them. if len(fns) == 1: data = fits.getdata(fns[0], ignore_missing_end=True) else: data = np.median([fits.getdata(fn) for fn in fns], axis=0) # If there are fewer than 3 flats in the list, then filter image hdr['CLEANED'] = 'No' if len(fns) < 3: if config.params['no_cosmic']: self.logger.info('flat cosmic ray cleaning inhibited by command line flag') else: self.logger.info('cosmic cleaning flat because < 3 flats were median combined') data = image_lib.cosmic_clean(data) hdr['CLEANED'] = 'yes' self.logger.info('cosmic ray cleaning complete') return(fits.PrimaryHDU(data, hdr))
def combineFlats(self, fns): """ Takes a list of flat file names, combines them and returns the resulting image in the form of a new FITS HDU. Keywords are added the new FITS: CLEANED, FLAT0, FLAT1, ... """ if len(fns) == 0: return None hdr = fits.getheader(fns[0]) for n in range(len(fns)): hdr["FLAT" + str(n)] = fns[n][fns[n].rfind("/") + 1 : fns[n].rfind(".")] # If there is more than one flat in the list then median combine them. if len(fns) == 1: data = fits.getdata(fns[0], ignore_missing_end=True) else: data = np.median([fits.getdata(fn) for fn in fns], axis=0) # If there are fewer than 3 flats in the list, then filter image hdr["CLEANED"] = "No" if len(fns) < 3: if config.params["no_cosmic"]: self.logger.info("flat cosmic ray cleaning inhibited by command line flag") else: self.logger.info("cosmic cleaning flat because < 3 flats were median combined") data = image_lib.cosmic_clean(data) hdr["CLEANED"] = "yes" self.logger.info("cosmic ray cleaning complete") return fits.PrimaryHDU(data, hdr)
def getFlat(raw, flatCacher): """Given a raw data set and a flat cacher, creates and returns a Flat object If there is no flat cacher then we are in command line mode where there is a single flat and the flats are not reused. In this case 1. the flat image data is read from the flat file specified in the raw data set, 2. unless cosmic ray rejection is inhibited cosmic ray artifacts are removed from the flat, and 3. a Flat object is created from the flat image data. If there is a flat cacher then a possibly cached Flat object is retrieved from it. Note that in either case, the Flat object represents a fully reduced flat, with orders on the flat identified, traced, cut out and rectified. Args: raw: A RawDataSet object containing, among other things, one or more flat file names flatCacher: A FlatCacher object or None Returns: A Flat object """ if flatCacher is None: # in command line mode with only one flat if config.params['no_cosmic']: logger.info( 'cosmic ray rejection on flat inhibited by command line flag') flat_data = fits.PrimaryHDU.readfrom(raw.flatFns[0], ignore_missing_end=True).data else: logger.info('starting cosmic ray cleaning flat') flat_data, cosmicMethod = image_lib.cosmic_clean( fits.PrimaryHDU.readfrom(raw.flatFns[0], ignore_missing_end=True).data) logger.info(cosmicMethod) logger.info('cosmic ray cleaning on flat complete') return (Flat.Flat( raw.flatFns[0], [raw.flatFns[0]], fits.PrimaryHDU.readfrom(raw.flatFns[0], ignore_missing_end=True).header, flat_data)) else: return (flatCacher.getFlat(raw.flatFns))
def getEtas(raw, etaCacher): """Given a raw data set and a etalon cacher, creates and returns a etalon object XXX Do we need this? If there is no etalon cacher then we are in command line mode where there is a single etalon and the etalons are not reused. In this case 1. the etalon image data is read from the etlon file specified in the raw data set, 2. unless cosmic ray rejection is inhibited cosmic ray artifacts are removed from the etalon, and 3. a Etalon object is created from the etalon image data. If there is a etalon cacher then a possibly cached Etalon object is retrieved from it. Note that in either case, the Etalon object represents a fully reduced etalon, with orders on the etalon identified, traced, cut out and rectified. Args: raw: A RawDataSet object containing, among other things, one or more etalon file names etaCacher: A EtalonCacher object or None Returns: A Flat object """ if etaCacher is None: # in command line mode with only one flat if config.params['no_cosmic']: logger.info( 'cosmic ray rejection on flat inhibited by command line flag') eta_data = fits.PrimaryHDU.readfrom(raw.etaFns[0], ignore_missing_end=True).data else: logger.info('starting cosmic ray cleaning flat') eta_data = image_lib.cosmic_clean( fits.PrimaryHDU.readfrom(raw.etaFns[0], ignore_missing_end=True).data) logger.info('cosmic ray cleaning on flat complete') return (Eta.Eta( raw.etaFns[0], [raw.etaFns[0]], fits.PrimaryHDU.readfrom(raw.etaFns[0], ignore_missing_end=True).header, eta_data)) else: return (etaCacher.getEta(raw.etaFns))
def cleanCosmicRayHits(self): self.obj = image_lib.cosmic_clean(self.obj) # self.flat = image_lib.cosmic_clean(self.flat) self.cosmicCleaned = True
def reduce_frame(raw, out_dir, flatCacher=None): """ Arguments: raw: RawDataSet object out_dir: Data product root directory """ # initialize per-object logger and check output directory if raw.isPair: init(raw.baseNames['AB'], out_dir) else: init(raw.baseNames['A'], out_dir) # if no flats in raw data set then fail if (len(raw.flatFns) < 1): logger.error("no flats for {}".format(raw.baseName)) raise DrpException.DrpException('no flats') # create reduced data set reduced = ReducedDataSet.ReducedDataSet(raw) # read raw object image data into reduced data set object reduced.objImg['A'] = fits.getdata(raw.objAFn, ignore_missing_end=True) if raw.isPair: reduced.objImg['B'] = fits.getdata(raw.objBFn, ignore_missing_end=True) # put object summary info into per-object log log_start_summary(reduced) # Get fully processed flat in the form of a Flat object reduced.Flat = getFlat(raw, flatCacher) logger.info('using flat {}'.format(reduced.Flat.getBaseName())) # clean cosmic ray hits on object frame(s) if config.params['no_cosmic']: logger.info( "cosmic ray rejection on object frame inhibited by command line flag") else: logger.info('cosmic ray cleaning object frame A') reduced.objImg['A'], cosmicMethod = image_lib.cosmic_clean( reduced.objImg['A']) logger.debug('cosmic ray cleaning object frame A complete') if reduced.isPair: logger.info('cosmic ray cleaning object frame B') reduced.objImg['B'] = image_lib.cosmic_clean(reduced.objImg['B']) logger.debug('cosmic ray cleaning object frame B complete') reduced.cosmicCleaned = True logger.info(cosmicMethod) # if darks are available, combine them if there are more than one # and subtract from object frame(s) and flat process_darks(raw, reduced) # if AB pair then subtract B from A if reduced.isPair: reduced.objImg['AB'] = np.subtract( reduced.objImg['A'], reduced.objImg['B']) # reduce orders try: reduce_orders(reduced) except IOError as e: # might want to do something else here raise # find and apply wavelength solution imp.reload(wavelength_utils) if find_global_wavelength_soln(reduced) is True: apply_wavelength_soln(reduced) else: logger.info('not applying wavelength solution') for order in reduced.orders: order.waveScale = order.flatOrder.gratingEqWaveScale order.calMethod = 'grating equation' return(reduced)
def reduce(raw, out_dir, flatCacher=None): """ raw - RawDataSet object out_dir - data product root directory """ # initialize per-object logger and check output directory init(raw.objFileName, out_dir) # if no flats in raw data set then fail if (len(raw.flatFileNames) < 1): logger.error("no flats") raise DrpException.DrpException('no flats'); # create reduced data set reduced = ReducedDataSet.ReducedDataSet(raw.getObjFileName(), raw.getObjHeader()) # save KOA IDs of first dark (if any) and flat(s), these are added # to FITS headers later. if len(raw.darkFileNames) > 0: reduced.darkKOAId = raw.darkFileNames[0] else: reduced.darkKOAId = 'none' for flat_name in raw.flatFileNames: reduced.flatKOAIds.append(flat_name[flat_name.rfind('/') + 1:flat_name.rfind('.')]) # put object summary info into per-object log log_start_summary(reduced) # read raw object data into reduced data set object reduced.obj = fits.getdata(raw.objFileName, ignore_missing_end=True) # combine flats and darks, if darks exist then subtract from obj and flat, # store results in processed data set #process_darks_and_flats(raw, reduced) # reduce flat if flatCacher is None: # in command line mode with only one flat if config.params['no_cosmic']: logger.info('cosmic ray rejection on flat inhibited by command line flat') flat_data = fits.PrimaryHDU.readfrom(raw.flatFileNames[0], ignore_missing_end=True).data else: logger.info('starting cosmic ray cleaning flat') flat_data = image_lib.cosmic_clean(fits.PrimaryHDU.readfrom( raw.flatFileNames[0], ignore_missing_end=True).data) logger.info('cosmic ray cleaning on flat complete') reduced.Flat = Flat.Flat( raw.flatFileNames[0], fits.PrimaryHDU.readfrom(raw.flatFileNames[0], ignore_missing_end=True).header, flat_data) else: reduced.Flat = flatCacher.getFlat(raw.flatFileNames) # clean cosmic ray hits on object frame if config.params['no_cosmic']: logger.info("cosmic ray rejection on object frame inhibited by command line flag") else: logger.info('starting cosmic ray cleaning object frame') reduced.obj = image_lib.cosmic_clean(reduced.obj) reduced.cosmicCleaned = True logger.info('cosmic ray cleaning on object frame complete') # if darks are available, combine them if there are more than one # and subtract from object and flat process_darks(raw, reduced) # reduce orders try: reduce_orders(reduced) except IOError as e: # might want to do something else here raise # find wavelength solution reload(wavelength_utils) if find_global_wavelength_soln(reduced) is True: apply_wavelength_soln(reduced) else: logger.info('not applying wavelength solution') for order in reduced.orders: order.waveScale = order.gratingEqWaveScale order.calMethodUsed = 'grating equation' return(reduced)
def reduce_frame(raw, out_dir, flatCacher=None, eta=None, arc=None, dark=None): """ Arguments: raw: RawDataSet object out_dir: Data product root directory """ # initialize per-object logger and check output directory if raw.isPair: init(raw.baseNames['AB'], out_dir) else: init(raw.baseNames['A'], out_dir) # if no flats in raw data set then fail if (len(raw.flatFns) < 1): logger.error("no flats for {}".format(raw.baseName)) raise DrpException.DrpException('no flats') # create reduced data set reduced = ReducedDataSet.ReducedDataSet(raw) # read raw object image data into reduced data set object reduced.objImg['A'] = fits.getdata(raw.objAFn, ignore_missing_end=True) #print('TEST', nirspec_constants.upgrade) if nirspec_constants.upgrade: reduced.objImg['A'] = np.rot90(reduced.objImg['A'], k=3) ### TEST PLOT XXX ''' import matplotlib.pyplot as plt from astropy.visualization import ImageNormalize, ZScaleInterval norm = ImageNormalize(reduced.objImg['A'], interval=ZScaleInterval()) plt.imshow(reduced.objImg['A'], norm=norm, origin='lower', aspect='auto') plt.show() #sys.exit() ''' ### TEST PLOT XXX if raw.isPair: reduced.objImg['B'] = fits.getdata(raw.objBFn, ignore_missing_end=True) if nirspec_constants.upgrade: reduced.objImg['B'] = np.rot90(reduced.objImg['B'], k=3) if eta is not None: reduced.etaImg = fits.getdata(raw.etaFns, ignore_missing_end=True) if nirspec_constants.upgrade: reduced.etaImg = np.rot90(reduced.etaImg, k=3) if arc is not None: reduced.arcImg = fits.getdata(raw.arcFns, ignore_missing_end=True) if nirspec_constants.upgrade: reduced.arcImg = np.rot90(reduced.arcImg, k=3) if dark is not None: reduced.hasDark = True # reduced.darkImg = fits.getdata(raw.darkFns, ignore_missing_end=True) # put object summary info into per-object log log_start_summary(reduced) # Get fully processed flat in the form of a Flat object reduced.Flat = getFlat(raw, flatCacher) logger.info('using flat {}'.format(reduced.Flat.getBaseName())) # clean cosmic ray hits on object frame(s) if config.params['no_cosmic']: logger.info( "cosmic ray rejection on object frame inhibited by command line flag" ) else: logger.info('cosmic ray cleaning object frame A') reduced.objImg['A'] = image_lib.cosmic_clean(reduced.objImg['A']) logger.debug('cosmic ray cleaning object frame A complete') if reduced.isPair: logger.info('cosmic ray cleaning object frame B') reduced.objImg['B'] = image_lib.cosmic_clean(reduced.objImg['B']) logger.debug('cosmic ray cleaning object frame B complete') if eta is not None: logger.info('cosmic ray cleaning etalon frame') reduced.etaImg = image_lib.cosmic_clean(reduced.etaImg) logger.debug('cosmic ray cleaning etalon frame complete') if arc is not None: logger.info('cosmic ray cleaning arc lamp frame') reduced.arcImg = image_lib.cosmic_clean(reduced.arcImg) logger.debug('cosmic ray cleaning arc lamp frame complete') reduced.cosmicCleaned = True # if darks are available, combine them if there are more than one # and subtract from object frame(s) and flat process_darks(raw, reduced) # if AB pair then subtract B from A if reduced.isPair: reduced.objImg['AB'] = np.subtract(reduced.objImg['A'], reduced.objImg['B']) # reduce orders try: reduce_orders(reduced, eta=eta, arc=arc) except IOError as e: # might want to do something else here raise # find and apply wavelength solution imp.reload(wavelength_utils) if find_global_wavelength_soln(reduced) is True: apply_wavelength_soln(reduced) else: logger.info('not applying wavelength solution') for order in reduced.orders: order.waveScale = order.flatOrder.gratingEqWaveScale order.calMethod = 'grating equation' return (reduced)