示例#1
0
    def __init__(self, objAFn, objBFn, objHeader):

        if objAFn is None:
            raise DrpException('objAFn cannot be None')
        
        if objHeader is None:
            raise DrpException('header cannot be None')
            
        self.objAFn = objAFn
        self.objBFn = objBFn
        
        self.objHeader = objHeader
        
        self.baseNames = {}
        
        if self.objAFn is not None and self.objBFn is not None:
            self.isPair = True
            self.frames = ['A', 'B', 'AB']
            self.baseNames['A'] = self.__deriveBaseName(self.objAFn)
            self.baseNames['B'] = self.__deriveBaseName(self.objBFn)
            self.baseNames['AB'] = self.__combineBaseNames(
                    self.baseNames['A'], self.baseNames['B'])
        else:
            self.isPair = False
            self.frames = ['A']
            self.baseNames['A'] = self.__deriveBaseName(self.objAFn)

        
        self.flatFns = []
        self.darkFns = []
示例#2
0
def __find_spatial_profile_and_peak(order):
    """
    """

    MARGIN = 5

    for frame in order.frames:

        # find spatial profile(s)
        order.spatialProfile[frame] = order.ffObjImg[frame].mean(axis=1)
        if len(order.spatialProfile[frame]) < (2 * MARGIN) + 2:
            raise DrpException.DrpException(
                'cannot find spatial profile for frame {} order {}'.format(
                    frame, order.flatOrder.orderNum))

        # find peak locations
        order.peakLocation[frame] = np.argmax(
            order.spatialProfile[frame][MARGIN:-MARGIN]) + MARGIN
        logger.info('frame {} spatial profile peak intensity row {:d}'.format(
            frame, order.peakLocation[frame]))

        # fit peak to Gaussian, save Gaussian parameters and real centroid
        # location
        p0 = order.peakLocation[frame] - (config.params['obj_window'] // 2)
        p1 = order.peakLocation[frame] + (config.params['obj_window'] // 2)
        order.centroid[frame] = (scipy.ndimage.measurements.center_of_mass(
            order.spatialProfile[frame][p0:p1]))[0] + p0
        logger.info('frame {} spatial profile peak centroid row {:.1f}'.format(
            frame, float(order.centroid[frame])))

    return
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 process_frame(fn1, fn2, obj_B_fn, out_dir):

    flat_fn = None
    obj_fn = None

    fn1_header = fits.PrimaryHDU.readfrom(fn1, ignore_missing_end=True).header
    fn2_header = fits.PrimaryHDU.readfrom(fn2, ignore_missing_end=True).header

    if fn1_header['flat'] == 1 and fn1_header['calmpos'] == 1:
        flat_fn = fn1
        obj_fn = fn2
        obj_header = fn2_header
        flat_header = fn1_header
    if fn2_header['flat'] == 1 and fn2_header['calmpos'] == 1:
        if flat_fn is not None:
            raise DrpException.DrpException('two flats, no object frame')
        else:
            flat_fn = fn2
            obj_fn = fn1
            obj_header = fn1_header
            flat_header = fn2_header
    if flat_fn is None:
        raise DrpException.DrpException('no flat')

    if obj_header['ECHLPOS'] > 100:
        print('ERROR: cannot reduce low-resolution image (ECHLPOS > 100')
        exit(1)

    if obj_header['NAXIS1'] != nirspec_constants.N_COLS:
        raise DrpException.DrpException('NAXIS1 != {}'.format(
            nirspec_constants.N_COLS))
    if obj_header['NAXIS2'] != nirspec_constants.N_ROWS:
        raise DrpException.DrpException('NAXIS2 != {}'.format(
            nirspec_constants.N_COLS))
    if obj_header['FILNAME'].upper() not in nirspec_constants.filter_names:
        raise DrpException.DrpException('unsupported filter: {}'.format(
            obj_header['FILNAME']))

    if create_raw_data_sets.flat_criteria_met(
            obj_header, flat_header, ignore_dispers=True) is False:
        raise DrpException.DrpException(
            'flat is not compatible with object frame')

    if obj_B_fn is not None:
        # confirm that A and B are not the same files
        if obj_fn == obj_B_fn:
            raise DrpException.DrpException('frames A and B are the same')

        obj_B_header = fits.PrimaryHDU.readfrom(obj_B_fn,
                                                ignore_missing_end=True).header
        if create_raw_data_sets.is_valid_pair(obj_header, obj_B_header):
            #print('Reducing AB pair, A=' + obj_fn + ', B=' + obj_B_fn)
            rawDataSet = RawDataSet.RawDataSet(obj_fn, obj_B_fn, obj_header)
        else:
            raise DrpException.DrpException(
                'frames A and B are not a valid pair')
    else:
        rawDataSet = RawDataSet.RawDataSet(obj_fn, None, obj_header)

    rawDataSet.flatFns.append(flat_fn)

    if not os.path.exists(out_dir):
        try:
            os.mkdir(out_dir)
        except:
            msg = 'output directory {} does not exist and cannot be created'.format(
                out_dir)
            raise IOError(msg)

    logger = logging.getLogger('main')

    # generate reduced data set by reducing raw data set
    reducedDataSet = reduce_frame.reduce_frame(rawDataSet, out_dir)

    # write reduction summary to log file
    write_summary(reducedDataSet)

    # produce data products from reduced data set
    if config.params['no_products'] is True:
        logger.info('data product generation inhibited by command line switch')
    else:
        products.gen(reducedDataSet, out_dir)

    # if diagnostics mode is enabled, then produce diagnostic data products
    if config.params['dgn'] is True:
        logger.info(
            'diagnostic mode enabled, generating diagnostic data products')
        dgn.gen(reducedDataSet, out_dir)

    return
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)
示例#6
0
def process_frame(fn1, fn2, obj_B_fn, out_dir, dark=None, eta=None, arc=None, override=False):

    logger = logging.getLogger('main')
   
    flat_fn    = None
    obj_fn     = None
    
    fn1_header = fits.PrimaryHDU.readfrom(fn1, ignore_missing_end=True).header
    fn2_header = fits.PrimaryHDU.readfrom(fn2, ignore_missing_end=True).header

    # Get the observation date to determine if this is upgraded NIRSPEC
    if datetime.strptime(fn1_header['date-obs'], '%Y-%m-%d') > datetime.strptime('2018-10-10', '%Y-%m-%d'):
        nirspec_constants.upgrade = True

    # Do the case for the etalon lamp
    if eta is not None:
        eta_header = fits.PrimaryHDU.readfrom(eta, ignore_missing_end=True).header
        if nirspec_constants.upgrade:
            if eta_header['etalon'] == 'On' and eta_header['calmpos'] == 'In':
                eta_fn = eta
        else:
            if eta_header['etalon'] == 1 and eta_header['calmpos'] == 1:
                eta_fn = eta

    # Do the case for the arc lamp
    if arc is not None:
        arc_header = fits.PrimaryHDU.readfrom(arc, ignore_missing_end=True).header
        if nirspec_constants.upgrade:
            if (arc_header['neon'] == 'On' or arc_header['argon'] == 'On' or arc_header['krypton'] == 'On' or \
                arc_header['xenon'] == 'On') and arc_header['calmpos'] == 'In':
                arc_fn = arc
        else:
            if (arc_header['neon'] == 1 or arc_header['argon'] == 1 or arc_header['krypton'] == 1 or \
                arc_header['xenon'] == 1) and arc_header['calmpos'] == 1:
                arc_fn = arc

    # Get the master dark frame if given
    if dark is not None:
        dark_header = fits.PrimaryHDU.readfrom(dark, ignore_missing_end=True).header
        if nirspec_constants.upgrade:
            if dark_header['halogen'] == 'On' and dark_header['calmpos'] == 'In' and \
               dark_header['neon'] != 'On' and dark_header['argon'] != 'On' and dark_header['krypton'] != 'On' and \
               dark_header['xenon'] != 'On':
                dark_fn = dark
        else:
            if dark_header['flat'] == 0 and dark_header['calmpos'] == 1 and \
               dark_header['neon'] != 1 and dark_header['argon'] != 1 and dark_header['krypton'] != 1 and \
               dark_header['xenon'] != 1:
                dark_fn = dark

    # Get the flat and object fits
    if nirspec_constants.upgrade:
        if fn1_header['halogen'] == 'On' and fn1_header['calmpos'] == 'In':
            flat_fn     = fn1
            obj_fn      = fn2
            obj_header  = fn2_header
            flat_header = fn1_header
        if fn1_header['halogen'] == 'On' and fn1_header['calmpos'] == 'In':
            flat_fn     = fn1
            obj_fn      = fn2
            obj_header  = fn2_header
            flat_header = fn1_header
    else:
        if fn1_header['flat'] == 1 and fn1_header['calmpos'] == 1:
            flat_fn     = fn1
            obj_fn      = fn2
            obj_header  = fn2_header
            flat_header = fn1_header
        if fn2_header['flat'] == 1 and fn2_header['calmpos'] == 1:
            if flat_fn is not None:
                raise DrpException.DrpException('two flats, no object frame')
            else:
                flat_fn     = fn2
                obj_fn      = fn1
                obj_header  = fn1_header
                flat_header = fn2_header
    if flat_fn is None:
        raise DrpException.DrpException('no flat')

    if obj_header['ECHLPOS'] > 100:
        print('ERROR: cannot reduce low-resolution image (ECHLPOS > 100')
        exit(1)
        
    # Check the array size is correct
    if nirspec_constants.upgrade:
        if obj_header['NAXIS1'] != nirspec_constants.N_COLS_upgrade:
            raise DrpException.DrpException('NAXIS1 != {}'.format(nirspec_constants.N_COLS_upgrade))
        if obj_header['NAXIS2'] != nirspec_constants.N_ROWS_upgrade:
            raise DrpException.DrpException('NAXIS2 != {}'.format(nirspec_constants.N_COLS_upgrade))
        filtername1, filtername2 = obj_header['SCIFILT2'], ''
        if obj_header['SCIFILT1'] == 'AO-stop': filtername2 = '-AO'
        if filtername1.upper()+filtername2.upper() not in nirspec_constants.filter_names:
            raise DrpException.DrpException('unsupported filter: {}'.format(obj_header['SCIFILT2']))
    else:
        if obj_header['NAXIS1'] != nirspec_constants.N_COLS:
            raise DrpException.DrpException('NAXIS1 != {}'.format(nirspec_constants.N_COLS))
        if obj_header['NAXIS2'] != nirspec_constants.N_ROWS:
            raise DrpException.DrpException('NAXIS2 != {}'.format(nirspec_constants.N_COLS))
        if obj_header['FILNAME'].upper() not in nirspec_constants.filter_names:
            raise DrpException.DrpException('unsupported filter: {}'.format(obj_header['FILNAME']))
    
    if create_raw_data_sets.flat_criteria_met(obj_header, flat_header, ignore_dispers=True) is False:
        raise DrpException.DrpException('flat is not compatible with object frame')

    if dark is not None:
        if create_raw_data_sets.dark_criteria_met(obj_header, dark_header) is False:
            raise DrpException.DrpException('dark is not compatible with object frame')
    
    if obj_B_fn is not None:
        # confirm that A and B are not the same files
        if obj_fn == obj_B_fn:
            raise DrpException.DrpException('frames A and B are the same')
        
        obj_B_header = fits.PrimaryHDU.readfrom(obj_B_fn, ignore_missing_end=True).header
        if create_raw_data_sets.is_valid_pair(obj_header, obj_B_header, override=override):
            logger.debug('Reducing AB pair, A= ' + obj_fn + ' , B= ' + obj_B_fn)
            rawDataSet = RawDataSet.RawDataSet(obj_fn, obj_B_fn, obj_header, eta=eta, arc=arc, dark=dark)

        else:
            raise DrpException.DrpException('frames A and B are not a valid pair')
    else:
        rawDataSet = RawDataSet.RawDataSet(obj_fn, None, obj_header, eta=eta, arc=arc, dark=dark)

    rawDataSet.flatFns.append(flat_fn)
     
    if not os.path.exists(out_dir):
        try: 
            os.mkdir(out_dir)
        except: 
            msg = 'output directory {} does not exist and cannot be created'.format(out_dir)
            raise IOError(msg)
                
    # generate reduced data set by reducing raw data set
    reducedDataSet = reduce_frame.reduce_frame(rawDataSet, out_dir, eta=eta, arc=arc, dark=dark)
    
    # write reduction summary to log file
    write_summary(reducedDataSet)
        
    # produce data products from reduced data set
    if config.params['no_products'] is True:
        logger.info('data product generation inhibited by command line switch')
    else:
        products.gen(reducedDataSet, out_dir, eta=eta, arc=arc)

    # if diagnostics mode is enabled, then produce diagnostic data products
    if config.params['dgn'] is True:
        logger.info('diagnostic mode enabled, generating diagnostic data products')
        dgn.gen(reducedDataSet, out_dir, eta=eta, arc=arc)
        
    return