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))
Exemple #2
0
    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)
Exemple #3
0
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))
Exemple #5
0
    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)
Exemple #7
0
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)