예제 #1
0
def __rectify_spectral(order):
    """
    """        
    for frame in order.frames:
        order.objImg[frame] = image_lib.rectify_spectral(order.objImg[frame], order.spectralTrace)
        order.ffObjImg[frame] = image_lib.rectify_spectral(
                order.ffObjImg[frame], order.spectralTrace)
        
    return     
예제 #2
0
def reduce_order(order, flat_order):
        
    # flatten obj but keep original for noise calc
    order.flattenedObjImg = np.array(order.objCutout / flat_order.normFlatImg)
    if np.amin(order.flattenedObjImg) < 0:
        order.flattenedObjImg -= np.amin(order.flattenedObjImg)
    order.flattened = True
    order.objImg = np.array(order.objCutout) # should probably use objImg instead of objCutout to begin with
    logger.info('order has been flat fielded')
 
    # rectify flat, normalized flat, obj and flattened obj in spatial dimension
    order.objImg = image_lib.rectify_spatial(order.objImg, flat_order.smoothedSpatialTrace)
    order.flattenedObjImg = image_lib.rectify_spatial(
            order.flattenedObjImg, flat_order.smoothedSpatialTrace)
 
    # trim rectified order
    order.objImg = order.objImg[flat_order.botTrim:flat_order.topTrim, :]
    order.flattenedObjImg = order.flattenedObjImg[flat_order.botTrim:flat_order.topTrim, :]
    
    order.srNormFlatImg = flat_order.rectFlatImg
    order.srFlatObjImg = order.flattenedObjImg
    
    order.spatialRectified = True
    
    # find spatial profile and peak
    find_spatial_profile_and_peak(order)
    
    # characterize spatial profile by fitting to Gaussian
    characterize_spatial_profile(order)

    # find and smooth spectral trace
    try:
        order.spectralTrace = nirspec_lib.smooth_spectral_trace(
                nirspec_lib.find_spectral_trace(
                        order.flattenedObjImg), order.flattenedObjImg.shape[0])
    except Exception as e:
        logger.warning('not rectifying order {} in spectral dimension'.format(order.orderNum))
 
    else:
        flat_order.rectFlatImg = image_lib.rectify_spectral(flat_order.rectFlatImg, order.spectralTrace)
        order.objImg = image_lib.rectify_spectral(order.objImg, order.spectralTrace)
        order.objImgFlattened = image_lib.rectify_spectral(order.flattenedObjImg, order.spectralTrace)
        order.spectralRectified = True
     
    # compute noise image
    order.noiseImg = nirspec_lib.calc_noise_img(
            order.objImg, flat_order.rectFlatImg, order.integrationTime)
    
    # extract spectra
    extract_spectra(order, flat_order)
            
    # calculate SNR
    bg = 0.0
    if order.topBgMean is not None:
        bg += order.topBgMean
    if order.botBgMean is not None:
        bg += order.botBgMean
    if order.topBgMean is not None and order.botBgMean is not None:
        bg /= 2
    order.snr = np.absolute(np.mean(order.flattenedObjImg[order.peakLocation:order.peakLocation + 1, :]) / bg)
    logger.info('signal-to-noise ratio = {:.1f}'.format(order.snr))
            
    # find and identify sky lines   
    line_pairs = None # line_pairs are (column number, accepted wavelength
    try:
        oh_wavelengths, oh_intensities = wavelength_utils.get_oh_lines()
    except IOError as e:
        logger.critical('cannot read OH line file: ' + str(e))
        raise
        
    try:
        # synthesize sky spectrum and store in order object
        order.synthesizedSkySpec = wavelength_utils.synthesize_sky(
                oh_wavelengths, oh_intensities, order.gratingEqWaveScale)
         
        # identify lines and return list of (column number, accepted wavelength) tuples
        line_pairs = wavelength_utils.line_id(order, oh_wavelengths, oh_intensities)
        
    except (IOError, ValueError) as e:
        logger.warning('sky line matching failed: ' + str(e))
        
    if line_pairs is not None:
        
        logger.info(str(len(line_pairs)) + ' matched sky lines found in order')

        # add line pairs to Order object as Line objects
        for line_pair in line_pairs:
            col, waveAccepted = line_pair
            peak = order.skySpec[col]
            cent = image_lib.centroid(order.skySpec, 1024, 5, col)
            line = Line.Line(order.frame, order.orderNum, waveAccepted, col, cent, peak)
            order.lines.append(line)
            
        if len(order.lines) >= 3:
            # do local wavelength fit
            measured = []
            accepted = []
            for line in order.lines:
                measured.append(order.gratingEqWaveScale[line.col])
                accepted.append(line.waveAccepted)
            (order.orderCalSlope, order.orderCalIncpt, order.orderCalCorrCoeff, p, e) = \
                    scipy.stats.linregress(np.array(measured), np.array(accepted))  
            order.orderCalNLines = len(order.lines)       
            logger.info('per order wavelength fit: n = {}, a = {:.6f}, b = {:.6f}, r = {:.6f}'.format(
                    len(order.lines), order.orderCalIncpt, order.orderCalSlope, 
                    order.orderCalCorrCoeff))

            for line in order.lines:
                line.orderWaveFit = order.orderCalIncpt + \
                    (order.orderCalSlope * order.gratingEqWaveScale[line.col])    
                line.orderFitRes = abs(line.orderWaveFit - line.waveAccepted)  
                line.orderFitSlope = (order.orderCalSlope * 
                    (order.gratingEqWaveScale[1023] - order.gratingEqWaveScale[0]))/1024.0
    else:
        logger.warning('no matched sky lines in order ' + str(order.orderNum))
        order.orderCal = False 
                        
    return
예제 #3
0
def reduce_order(order):
            
    # normalize flat
    order.normalizedFlatImg, order.flatMean =  image_lib.normalize(
            order.flatCutout, order.onOrderMask, order.offOrderMask)
    order.flatNormalized = True
    logger.info('flat normalized, flat mean = ' + str(round(order.flatMean, 1)))
        
    # flatten obj but keep original for noise calc
    order.flattenedObjImg = np.array(order.objCutout / order.normalizedFlatImg)
    if np.amin(order.flattenedObjImg) < 0:
        order.flattenedObjImg -= np.amin(order.flattenedObjImg)
    order.flattened = True
    order.objImg = np.array(order.objCutout) # should probably use objImg instead of objCutout to begin with
    order.flatImg = np.array(order.flatCutout)
    logger.info('order has been flat fielded')
    
    # smooth spatial trace
    # this should probably be done where the trace is first found    
    order.smoothedTrace, order.traceMask = nirspec_lib.smooth_spatial_trace(order.avgTrace)
    logger.info('spatial trace smoothed, ' + str(order.objImg.shape[1] - np.count_nonzero(order.traceMask)) + 
            ' points ignored')

    
    # rectify flat, normalized flat, obj and flattened obj in spatial dimension
    order.flatImg = image_lib.rectify_spatial(order.flatImg, order.smoothedTrace)
    order.normalizedFlatImg = image_lib.rectify_spatial(order.normalizedFlatImg, order.smoothedTrace)
    order.objImg = image_lib.rectify_spatial(order.objImg, order.smoothedTrace)
    order.flattenedObjImg = image_lib.rectify_spatial(order.flattenedObjImg, order.smoothedTrace)
 
    if order.lowestPoint > order.padding:
        top = order.highestPoint - order.lowestPoint + order.padding - 3
    else:
        top = order.highestPoint - 3
    h = np.amin(order.topTrace - order.botTrace)
    bot = top - h + 3
 

    bot = max(0, bot)
    top = min(top, 1023)
    
    order.flatImg = order.flatImg[bot:top, :]
    order.normalizedFlatImg = order.normalizedFlatImg[bot:top, :]
    order.objImg = order.objImg[bot:top, :]
    order.flattenedObjImg = order.flattenedObjImg[bot:top, :]
    
    order.srNormFlatImg = order.normalizedFlatImg
    order.srFlatObjImg = order.flattenedObjImg
    
    order.spatialRectified = True
    
    # find spatial profile and peak
    order.spatialProfile = order.flattenedObjImg.mean(axis=1)
    
#     import pylab as pl
#     
#     pl.figure()
#     pl.cla()
#     pl.imshow(order.flattenedObjImg)
#     pl.show()
#     
#     pl.figure(str(order.orderNum))
#     pl.cla()
#     pl.plot(order.spatialProfile)
#     pl.show()
    
    order.peakLocation = np.argmax(order.spatialProfile[5:-5]) + 5
    logger.info('spatial profile peak intensity row {:d}'.format(order.peakLocation))
    p0 = order.peakLocation - (config.params['obj_window'] / 2)
    p1 = order.peakLocation + (config.params['obj_window'] / 2)
    order.centroid = (scipy.ndimage.measurements.center_of_mass(
            order.spatialProfile[p0:p1]))[0] + p0 
    logger.info('spatial profile peak centroid row {:.1f}'.format(float(order.centroid)))
    
    # characterize spatial profile by fitting to Gaussian
    try:
        for w in range(10, 30, 10):
            logger.debug('gaussian window width = {}'.format(2 * w))
            x0 = max(0, order.peakLocation - w)
            x1 = min(len(order.spatialProfile) - 1, order.peakLocation + w)
            x = range(x1 - x0)
            order.gaussianParams, pcov = scipy.optimize.curve_fit(
                    image_lib.gaussian, x, order.spatialProfile[x0:x1] - np.amin(order.spatialProfile[x0:x1]))
            order.gaussianParams[1] += x0
            if order.gaussianParams[2] > 1.0:
                break
    except Exception as e:
        logger.warning('cannot fit spatial profile to Gaussian')
        order.gaussianParams = None
    else:
        logger.info('spatial peak width = {:.1f} pixels'.format(abs(order.gaussianParams[2])))


    # find and smooth spectral trace
    try:
        order.spectral_trace = nirspec_lib.smooth_spectral_trace(
                nirspec_lib.find_spectral_trace(
                        order.flattenedObjImg, order.padding), order.flattenedObjImg.shape[0])
    except Exception as e:
        logger.warning('not rectifying order in spectral dimension')
 
    else:
        # rectify flat, normalized flat, obj and flattened obj in spectral dimension 
        order.flatImg = image_lib.rectify_spectral(order.flatImg, order.spectral_trace)
        order.normalizedFlatImg = image_lib.rectify_spectral(order.normalizedFlatImg, order.spectral_trace)
        order.objImg = image_lib.rectify_spectral(order.objImg, order.spectral_trace)
        order.objImgFlattened = image_lib.rectify_spectral(order.flattenedObjImg, order.spectral_trace)
        order.spectralRectified = True
     
    # compute noise image
    order.noiseImg = nirspec_lib.calc_noise_img(
            order.objImg, order.normalizedFlatImg, order.integrationTime)
    
    # extract spectra
    order.objWindow, order.topSkyWindow, order.botSkyWindow = \
        image_lib.get_extraction_ranges(order.objImg.shape[0], order.peakLocation,
        config.params['obj_window'], config.params['sky_window'], config.params['sky_separation'])
        
    logger.info('extraction window width = {}'.format(str(len(order.objWindow))))
    logger.info('top background window width = {}'.format(str(len(order.topSkyWindow))))
    if len(order.topSkyWindow) > 0:
        logger.info('top background window separation = {}'.format(
                str(order.topSkyWindow[0] - order.objWindow[-1])))
    logger.info('bottom background window width = {}'.format(str(len(order.botSkyWindow))))
    if len(order.botSkyWindow) > 0:
        logger.info('bottom background window separation = {}'.format(
                str(order.objWindow[0] - order.botSkyWindow[-1])))
    
    order.objSpec, order.flatSpec, order.skySpec, order.noiseSpec, order.topBgMean, \
            order.botBgMean = image_lib.extract_spectra(
                order.flattenedObjImg, order.normalizedFlatImg, order.noiseImg, 
                order.objWindow, order.topSkyWindow, order.botSkyWindow)
            
    # calculate SNR
    bg = 0.0
    if order.topBgMean is not None:
        bg += order.topBgMean
    if order.botBgMean is not None:
        bg += order.botBgMean
    if order.topBgMean is not None and order.botBgMean is not None:
        bg /= 2
    order.snr = np.absolute(np.mean(order.flattenedObjImg[order.peakLocation:order.peakLocation + 1, :]) / bg)
    logger.info('signal-to-noise ratio = {:.1f}'.format(order.snr))
            
    # find and identify sky lines   
    line_pairs = None # line_pairs are (column number, accepted wavelength
    try:
        oh_wavelengths, oh_intensities = wavelength_utils.get_oh_lines(config.params['oh_filename'])
    except IOError as e:
        logger.critical('cannot read OH line file: ' + str(e))
        raise
        
    try:
        # synthesize sky spectrum and store in order object
        order.synthesizedSkySpec = wavelength_utils.synthesize_sky(
                oh_wavelengths, oh_intensities, order.wavelengthScaleCalc)
         
        # identify lines and return list of (column number, accepted wavelength) tuples
        line_pairs = wavelength_utils.line_id(order, oh_wavelengths, oh_intensities)
        
    except (IOError, ValueError) as e:
        logger.warning('sky line matching failed: ' + str(e))
        
    if line_pairs is not None:
        
        logger.info(str(len(line_pairs)) + ' matched sky lines found in order')

        # add line pairs to Order object as Line objects
        for line_pair in line_pairs:
            line = Line.Line()
            line.col, line.acceptedWavelength = line_pair
            line.peak = order.skySpec[line.col]
            
            # find centroid of peak
            w = 5
            p0 = max(0, line.col - (w / 2))
            p1 = min(1023, line.col + (w / 2)) + 1
            line.centroid = p0 + scipy.ndimage.center_of_mass(order.skySpec[p0:p1])[0]
            
            if abs(line.centroid - line.col) > 1:
                logger.warning('sky line centroid error, col = {}, centroid = {:.3f}'.format(
                        line.col, line.centroid))
                line.centroid = line.col                
            
            order.lines.append(line)
            
        if len(order.lines) >= 3:
            # do local wavelength fit
            measured = []
            accepted = []
            for line in order.lines:
                measured.append(order.wavelengthScaleCalc[line.col])
                accepted.append(line.acceptedWavelength)
            (order.perOrderSlope, order.perOrderIntercept, order.perOrderCorrCoeff, p, e) = \
                    scipy.stats.linregress(np.array(measured), np.array(accepted))  
                    
            logger.info('per order wavelength fit: n = {}, a = {:.6f}, b = {:.6f}, r = {:.6f}'.format(
                    len(order.lines), order.perOrderIntercept, order.perOrderSlope, 
                    order.perOrderCorrCoeff))

            for line in order.lines:
                line.localFitWavelength = order.perOrderIntercept + \
                    (order.perOrderSlope * order.wavelengthScaleCalc[line.col])    
                line.localFitResidual = abs(line.localFitWavelength - line.acceptedWavelength)  
                line.localFitSlope = (order.perOrderSlope * (order.wavelengthScaleCalc[1023] - order.wavelengthScaleCalc[0]))/1024.0
    else:
        logger.warning('no matched sky lines in order ' + str(order.orderNum))
                        
    return
         
    
예제 #4
0
def reduce_order(order):

    # flatten object images for this order
    __flatten(order)

    # rectify obj and flattened obj in spatial dimension
    __rectify_spatial(order)

    # trim rectified order
    __trim(order)

    # save rectified images before spectral rectify for diagnostics
    order.srNormFlatImg = order.flatOrder.rectFlatImg
    for frame in order.frames:
        order.srFfObjImg[frame] = order.ffObjImg[frame]

    # find spatial profile and peak
    __find_spatial_profile_and_peak(order)

    # characterize spatial profile by fitting to Gaussian
    __characterize_spatial_profile(order)

    # Find and smooth spectral trace, always use frame A
    try:
        order.spectralTrace = nirspec_lib.smooth_spectral_trace(
            nirspec_lib.find_spectral_trace(order.ffObjImg['A']),
            order.ffObjImg['A'].shape[0])
    except Exception as e:
        logger.warning('not rectifying order {} in spectral dimension'.format(
            order.flatOrder.orderNum))

    else:
        order.flatOrder.rectFlatImg = image_lib.rectify_spectral(
            order.flatOrder.rectFlatImg, order.spectralTrace)
        __rectify_spectral(order)
        order.spectralRectified = True

    # compute noise image
    order.noiseImg = nirspec_lib.calc_noise_img(order.objImg['A'],
                                                order.flatOrder.rectFlatImg,
                                                order.integrationTime)

    # extract spectra
    __extract_spectra(order)

    # calculate approximate SNR
    __calc_approximate_snr(order)

    # find and identify sky lines
    line_pairs = None  # line_pairs are (column number, accepted wavelength)
    try:
        oh_wavelengths, oh_intensities = wavelength_utils.get_oh_lines()
    except IOError as e:
        logger.critical('cannot read OH line file: ' + str(e))
        raise

    try:
        # synthesize sky spectrum and store in order object
        order.synthesizedSkySpec = wavelength_utils.synthesize_sky(
            oh_wavelengths, oh_intensities, order.flatOrder.gratingEqWaveScale)

        # identify lines and return list of (column number, accepted
        # wavelength) tuples
        line_pairs = wavelength_utils.line_id(order, oh_wavelengths,
                                              oh_intensities)

    except (IOError, ValueError) as e:
        logger.warning('sky line matching failed: ' + str(e))

    if line_pairs is not None:

        logger.info(str(len(line_pairs)) + ' matched sky lines found in order')

        # add line pairs to Order object as Line objects
        for line_pair in line_pairs:
            col, waveAccepted = line_pair
            peak = order.skySpec['A'][col]
            cent = image_lib.centroid(order.skySpec['A'], 1024, 5, col)
            line = Line.Line(order.baseNames['A'], order.flatOrder.orderNum,
                             waveAccepted, col, cent, peak)
            order.lines.append(line)

        if len(order.lines) >= 3:
            # do local wavelength fit
            measured = []
            accepted = []
            for line in order.lines:
                measured.append(order.flatOrder.gratingEqWaveScale[line.col])
                accepted.append(line.waveAccepted)
            (order.orderCalSlope, order.orderCalIncpt, order.orderCalCorrCoeff, p, e) = \
                scipy.stats.linregress(np.array(measured), np.array(accepted))
            order.orderCalNLines = len(order.lines)
            logger.info(
                'per order wavelength fit: n = {}, a = {:.6f}, b = {:.6f}, r = {:.6f}'
                .format(len(order.lines), order.orderCalIncpt,
                        order.orderCalSlope, order.orderCalCorrCoeff))

            for line in order.lines:
                line.orderWaveFit = order.orderCalIncpt + \
                    (order.orderCalSlope *
                     order.flatOrder.gratingEqWaveScale[line.col])
                line.orderFitRes = abs(line.orderWaveFit - line.waveAccepted)
                line.orderFitSlope = (
                    order.orderCalSlope *
                    (order.flatOrder.gratingEqWaveScale[1023] -
                     order.flatOrder.gratingEqWaveScale[0])) / 1024.0
    else:
        logger.warning('no matched sky lines in order ' +
                       str(order.flatOrder.orderNum))
        order.orderCal = False

    return
예제 #5
0
def __rectify_spectral(order, eta=None, arc=None):
    """
    """
    for frame in order.frames:
        #print('FRAME', frame)
        if frame == 'AB': continue
        if config.params['onoff'] == True and frame == 'B':
            order.objImg[frame], peak1 = image_lib.rectify_spectral(
                order.objImg[frame], order.spectralTrace['A'], returnpeak=True)
            order.ffObjImg[frame], peak2 = image_lib.rectify_spectral(
                order.ffObjImg[frame],
                order.spectralTrace['A'],
                returnpeak=True)
        else:
            order.objImg[frame], peak1 = image_lib.rectify_spectral(
                order.objImg[frame],
                order.spectralTrace[frame],
                returnpeak=True)
            order.ffObjImg[frame], peak2 = image_lib.rectify_spectral(
                order.ffObjImg[frame],
                order.spectralTrace[frame],
                returnpeak=True)

        if frame == 'A':
            order.flatOrder.rectFlatImg, peak0 = image_lib.rectify_spectral(
                order.flatOrder.rectFlatImg,
                order.spectralTrace[frame],
                returnpeak=True)

        if eta is not None:
            if frame == 'B':
                if config.params['onoff'] == True:
                    order.etaImgB = order.etaImg
                    order.ffEtaImgB = iorder.ffEtaImg
                else:
                    order.etaImgB = image_lib.rectify_spectral(
                        order.etaImgB, order.spectralTrace[frame], peak1)
                    order.ffEtaImgB = image_lib.rectify_spectral(
                        order.ffEtaImgB, order.spectralTrace[frame], peak2)
            else:
                order.etaImg = image_lib.rectify_spectral(
                    order.etaImg, order.spectralTrace[frame], peak1)
                order.ffEtaImg = image_lib.rectify_spectral(
                    order.ffEtaImg, order.spectralTrace[frame], peak2)

        if arc is not None:
            if frame == 'B':
                if config.params['onoff'] == True:
                    order.arcImgB = order.arcImg
                    order.ffArcImgB = iorder.ffArcImg
                else:
                    order.arcImgB = image_lib.rectify_spectral(
                        order.arcImgB, order.spectralTrace[frame], peak1)
                    order.ffArcImgB = image_lib.rectify_spectral(
                        order.ffArcImgB, order.spectralTrace[frame], peak2)
            else:
                order.arcImg = image_lib.rectify_spectral(
                    order.arcImg, order.spectralTrace[frame], peak1)
                order.ffArcImg = image_lib.rectify_spectral(
                    order.ffArcImg, order.spectralTrace[frame], peak2)

    return