def cutOutOrder(self, flatOrder): # determine cutout padding flatOrder.cutoutPadding = config.get_cutout_padding( self.filterName, self.slit) # add extra padding for orders with large tilt tilt = abs(flatOrder.avgEdgeTrace[0] - flatOrder.avgEdgeTrace[-1]) if tilt > config.params['large_tilt_threshold']: self.logger.info('large order tilt detected, tilt = ' + str(round(tilt, 1)) + ' threshold = ' + str(config.params['large_tilt_threshold']) + ' extra padding = ' + str(config.params['large_tilt_extra_padding'])) flatOrder.cutoutPadding += config.params[ 'large_tilt_extra_padding'] self.logger.debug('cutout padding = ' + str(round(flatOrder.cutoutPadding, 0))) # determine highest point of top trace (ignore edge) if flatOrder.topEdgeTrace is None: flatOrder.topEdgeTrace = flatOrder.botEdgeTrace + \ (flatOrder.topCalc - flatOrder.botCalc) - 5 flatOrder.highestPoint = np.amax( flatOrder.topEdgeTrace[0:-config.params['overscan_width']]) if flatOrder.botEdgeTrace is None: flatOrder.botEdgeTrace = flatOrder.topEdgeTrace - \ (flatOrder.topCalc - flatOrder.botCalc) + 5 flatOrder.lowestPoint = np.amin( flatOrder.botEdgeTrace[0:-config.params['overscan_width']]) flatOrder.cutout = np.array( image_lib.cut_out(self.flatImg, flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) if float(flatOrder.lowestPoint) > float(flatOrder.cutoutPadding): flatOrder.onOrderMask, flatOrder.offOrderMask = get_masks( flatOrder.cutout.shape, flatOrder.topEdgeTrace - flatOrder.lowestPoint + flatOrder.cutoutPadding, flatOrder.botEdgeTrace - flatOrder.lowestPoint + flatOrder.cutoutPadding) else: flatOrder.onOrderMask, flatOrder.offOrderMask = get_masks( flatOrder.cutout.shape, flatOrder.topEdgeTrace, flatOrder.botEdgeTrace) flatOrder.cutout = np.ma.masked_array(flatOrder.cutout, mask=flatOrder.offOrderMask) return
def __flatten(order, eta=None, arc=None): """Flat field object image[s] but keep originals for noise calculation. """ for frame in order.frames: order.objImg[frame] = np.array(order.objCutout[frame]) order.ffObjImg[frame] = np.array(order.objCutout[frame] / order.flatOrder.normFlatImg) #Also cut out the flat fielded object order.ffObjCutout[frame] = np.array( image_lib.cut_out(order.ffObjImg[frame], order.flatOrder.highestPoint, order.flatOrder.lowestPoint, order.flatOrder.cutoutPadding)) # Add then mask it order.ffObjCutout[frame] = np.ma.masked_array( order.objCutout[frame], mask=order.flatOrder.offOrderMask) if frame != 'AB': if np.amin(order.ffObjImg[frame]) < 0: order.ffObjImg[frame] -= np.amin(order.ffObjImg[frame]) if eta is not None: if frame == 'B': order.etaImgB = np.array(order.etaCutout) order.ffEtaImgB = np.array(order.etaCutout / order.flatOrder.normFlatImg) else: order.etaImg = np.array(order.etaCutout) order.ffEtaImg = np.array(order.etaCutout / order.flatOrder.normFlatImg) if arc is not None: if frame == 'B': order.arcImgB = np.array(order.arcCutout) order.ffArcImgB = np.array(order.arcCutout / order.flatOrder.normFlatImg) else: order.arcImg = np.array(order.arcCutout) order.ffArcImg = np.array(order.arcCutout / order.flatOrder.normFlatImg) order.flattened = True logger.info('order has been flat fielded') return
def cutOutOrder(self, flatOrder): # determine cutout padding flatOrder.cutoutPadding = config.get_cutout_padding(self.filterName, self.slit) # add extra padding for orders with large tilt tilt = abs(flatOrder.avgEdgeTrace[0] - flatOrder.avgEdgeTrace[-1]) if tilt > config.params['large_tilt_threshold']: self.logger.info('large order tilt detected, tilt = ' + str(round(tilt, 1)) + ' threshold = ' + str(config.params['large_tilt_threshold']) + ' extra padding = ' + str(config.params['large_tilt_extra_padding'])) flatOrder.cutoutPadding += config.params['large_tilt_extra_padding'] self.logger.debug('cutout padding = ' + str(round(flatOrder.cutoutPadding, 0))) # determine highest point of top trace (ignore edge) if flatOrder.topEdgeTrace is None: flatOrder.topEdgeTrace = flatOrder.botEdgeTrace + \ (flatOrder.topCalc - flatOrder.botCalc) - 5 flatOrder.highestPoint = np.amax(flatOrder.topEdgeTrace[0:-config.params['overscan_width']]) if flatOrder.botEdgeTrace is None: flatOrder.botEdgeTrace = flatOrder.topEdgeTrace - \ (flatOrder.topCalc - flatOrder.botCalc) + 5 flatOrder.lowestPoint = np.amin(flatOrder.botEdgeTrace[0:-config.params['overscan_width']]) flatOrder.cutout = np.array(image_lib.cut_out( self.flatImg, flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) if float(flatOrder.lowestPoint) > float(flatOrder.cutoutPadding): flatOrder.onOrderMask, flatOrder.offOrderMask = get_masks( flatOrder.cutout.shape, flatOrder.topEdgeTrace - flatOrder.lowestPoint + flatOrder.cutoutPadding, flatOrder.botEdgeTrace - flatOrder.lowestPoint + flatOrder.cutoutPadding) else: flatOrder.onOrderMask, flatOrder.offOrderMask = get_masks( flatOrder.cutout.shape, flatOrder.topEdgeTrace, flatOrder.botEdgeTrace) flatOrder.cutout = np.ma.masked_array(flatOrder.cutout, mask=flatOrder.offOrderMask) return
def reduce_orders(reduced): """Reduces each order in the frame. Starting order is determined from a lookup table indexed by filter name. The grating equation is evaluated for y-axis location of the short wavelength end of the order on the detector. If the order is on the detector then extract_order() is called to cut out from the full frame a rectangular array of pixels containing the entire order plus padding. Then, reduce_order() is called to reduce the order. reduce_order() returns an order object which is and instance of the Order class and contains all of the reduced data for this order. The order object is then appended to the list of order objects in the ReducedDataSet object representing the current frame. After the first order that should be on the detector is found, processing continues through each order in descending order number, working toward higher pixel row numbers on the detector, until the first off-detector order is found. """ for flatOrder in reduced.Flat.flatOrders: if flatOrder.valid is not True: continue logger.info('***** order ' + str(flatOrder.orderNum) + ' *****') order = Order.Order(reduced.frames, reduced.baseNames, flatOrder) order.isPair = reduced.isPair for frame in order.frames: order.objCutout[frame] = np.array(image_lib.cut_out(reduced.objImg[frame], flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) order.integrationTime = reduced.getIntegrationTime() # used in noise calc try: # reduce order, i.e. rectify, extract spectra, identify sky lines reduce_order.reduce_order(order) # add reduced order to list of reduced orders in Reduced object reduced.orders.append(order) except DrpException.DrpException as e: logger.warning('failed to reduce order {}: {}'.format( str(flatOrder.orderNum), e.message)) # end if order is on the detector # end for each order loggers = ['obj'] if config.params['cmnd_line_mode'] is False: loggers.append('main') # for l in loggers: # logging.getLogger(l).log(INFO, 'n orders on the detector = {}'.format(n_orders_on_detector)) # logging.getLogger(l).log(INFO, 'n orders reduced = {}'.format(len(reduced.orders))) if len(reduced.orders) == 0: return for l in loggers: reduced.snrMean = sum(reduced.orders[i].snr['A'] for i in range(len(reduced.orders))) / \ len(reduced.orders) logging.getLogger(l).log(INFO, 'mean signal-to-noise ratio = {:.1f}'.format( reduced.snrMean)) snr = [] for i in range(len(reduced.orders)): snr.append(reduced.orders[i].snr['A']) for l in loggers: reduced.snrMin = np.amin(snr) logging.getLogger(l).log(INFO, 'minimum signal-to-noise ratio = {:.1f}'.format( reduced.snrMin)) try: reduced.wMean = sum(abs(reduced.orders[i].gaussianParams['A'][2]) for i in range(len(reduced.orders))) / len(reduced.orders) logging.getLogger(l).log(INFO, 'mean spatial peak width = {:.1f} pixels'.format( reduced.wMean)) except BaseException: logging.getLogger(l).log( logging.WARNING, 'mean spatial peak width = unknown') w = [] for i in range(len(reduced.orders)): if reduced.orders[i].gaussianParams['A'] is not None: w.append(reduced.orders[i].gaussianParams['A'][2]) try: reduced.wMax = np.amax(w) logging.getLogger(l).log(INFO, 'maximum spatial peak width = {:.1f} pixels'.format( reduced.wMax)) except BaseException: logging.getLogger(l).error( 'maximum spatial peak width cannot be determined') logging.getLogger(l).log( INFO, 'maximum spatial peak width = unknown') return
def reduce_orders(reduced): """ Successively reduces each order in the frame. Starting order is determined from a lookup table indexed by filter name. The grating equation is evaluated for y-axis location of the short wavelength end of the order on the detector. If the order is on the detector then extract_order() is called to cut out from the full frame a rectangular array of pixels containing the entire order plus padding. Then, reduce_order() is called to reduce the order. reduce_order() returns an order object which is and instance of the Order class and contains all of the reduced data for this order. The order object is then appended to the list of order objects in the ReducedDataSet object representing the current frame. After the first order that should be on the detector is found, processing continues through each order in descending order number, working toward higher pixel row numbers on the detector, until the first off-detector order is found. """ for flatOrder in reduced.Flat.flatOrders: if flatOrder.valid is not True: continue logger.info('***** order ' + str(flatOrder.orderNum) + ' *****') order = Order.Order(reduced.baseName, flatOrder.orderNum) order.objCutout = np.array(image_lib.cut_out(reduced.obj, flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) order.integrationTime = reduced.getIntegrationTime() # used in noise calc order.gratingEqWaveScale = flatOrder.gratingEqWaveScale #order.wavelengthScaleMeas = flatOrder.waveScaleCalc order.topTrace = flatOrder.topEdgeTrace order.botTrace = flatOrder.botEdgeTrace order.avgTrace = flatOrder.avgEdgeTrace order.smoothedTrace = flatOrder.smoothedSpatialTrace order.traceMask = flatOrder.spatialTraceMask order.flatCutout = flatOrder.cutout order.highestPoint = flatOrder.highestPoint order.lowestPoint = flatOrder.lowestPoint order.padding = flatOrder.cutoutPadding order.botMeas = flatOrder.botMeas try: # reduce order, i.e. rectify, extract spectra, identify sky lines reduce_order.reduce_order(order, flatOrder) # add reduced order to list of reduced orders in Reduced object reduced.orders.append(order) except DrpException.DrpException as e: logger.warning('failed to reduce order {}: {}'.format( str(flatOrder.orderNum), e.message)) # end if order is on the detector # end for each order loggers = ['obj'] if config.params['cmnd_line_mode'] is False: loggers.append('main') # for l in loggers: # logging.getLogger(l).log(INFO, 'n orders on the detector = {}'.format(n_orders_on_detector)) # logging.getLogger(l).log(INFO, 'n orders reduced = {}'.format(len(reduced.orders))) if len(reduced.orders) == 0: return for l in loggers: reduced.snrMean = sum(reduced.orders[i].snr for i in range(len(reduced.orders))) / \ len(reduced.orders) logging.getLogger(l).log(INFO, 'mean signal-to-noise ratio = {:.1f}'.format( reduced.snrMean)) snr = [] for i in range(len(reduced.orders)): snr.append(reduced.orders[i].snr) for l in loggers: reduced.snrMin = np.amin(snr) logging.getLogger(l).log(INFO, 'minimum signal-to-noise ratio = {:.1f}'.format( reduced.snrMin)) try: reduced.wMean = sum(abs(reduced.orders[i].gaussianParams[2]) \ for i in range(len(reduced.orders))) / len(reduced.orders) logging.getLogger(l).log(INFO, 'mean spatial peak width = {:.1f} pixels'.format( reduced.wMean)) except: logging.getLogger(l).log(logging.WARNING, 'mean spatial peak width = unknown') w = [] for i in range(len(reduced.orders)): if reduced.orders[i].gaussianParams is not None: w.append(reduced.orders[i].gaussianParams[2]) try: reduced.wMax = np.amax(w) logging.getLogger(l).log(INFO, 'maximum spatial peak width = {:.1f} pixels'.format( reduced.wMax)) except: logging.getLogger(l).error('maximum spatial peak width cannot be determined') logging.getLogger(l).log(INFO, 'maximum spatial peak width = unknown') return
def reduce_orders(reduced, eta=None, arc=None): """Reduces each order in the frame. Starting order is determined from a lookup table indexed by filter name. The grating equation is evaluated for y-axis location of the short wavelength end of the order on the detector. If the order is on the detector then extract_order() is called to cut out from the full frame a rectangular array of pixels containing the entire order plus padding. Then, reduce_order() is called to reduce the order. reduce_order() returns an order object which is and instance of the Order class and contains all of the reduced data for this order. The order object is then appended to the list of order objects in the ReducedDataSet object representing the current frame. After the first order that should be on the detector is found, processing continues through each order in descending order number, working toward higher pixel row numbers on the detector, until the first off-detector order is found. """ for flatOrder in reduced.Flat.flatOrders: if flatOrder.valid is not True: continue logger.info('*' * 20 + ' ORDER {} '.format(flatOrder.orderNum) + '*' * 20) #if flatOrder.orderNum != 32: continue #XXX #if flatOrder.orderNum != 33: continue #XXX #if flatOrder.orderNum != 37: continue #XXX #if flatOrder.orderNum != 68: continue #XXX order = Order.Order(reduced.frames, reduced.baseNames, flatOrder, etaImg=reduced.etaImg) order.isPair = reduced.isPair for frame in order.frames: ### TESTING ''' import matplotlib.pyplot as plt plt.figure() plt.imshow(reduced.objImg[frame], origin='lower') plt.axhline(flatOrder.highestPoint, c='r', ls='--') plt.axhline(flatOrder.lowestPoint, c='r', ls='--') plt.figure() plt.imshow(reduced.Flat.flatImg, origin='lower') plt.axhline(flatOrder.highestPoint, c='r', ls='--') plt.axhline(flatOrder.lowestPoint, c='r', ls='--') plt.show() ''' ### TESTING ### TEST to mask out pixels outside of trace # Mask out the pixels above and below the trace #onOrderMask, offOrderMask = Flat.get_masks( # flatOrder.cutout.shape, flatOrder.topEdgeTrace, flatOrder.botEdgeTrace) if float(flatOrder.lowestPoint) > float(flatOrder.cutoutPadding): onOrderMask, offOrderMask = Flat.get_masks( flatOrder.cutout.shape, flatOrder.topEdgeTrace - flatOrder.lowestPoint + flatOrder.cutoutPadding, flatOrder.botEdgeTrace - flatOrder.lowestPoint + flatOrder.cutoutPadding) else: onOrderMask, offOrderMask = Flat.get_masks( flatOrder.cutout.shape, flatOrder.topEdgeTrace, flatOrder.botEdgeTrace) ### TEST to mask out pixels outside of trace order.objCutout[frame] = np.array( image_lib.cut_out(reduced.objImg[frame], flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) ''' import matplotlib.pyplot as plt plt.figure(64781) plt.imshow(order.objCutout[frame], origin='lower', aspect='auto') #plt.plot(np.arange(2048), topTrace, c='b', ls=':') #plt.plot(np.arange(2048), botTrace, c='r', ls=':') #plt.axhline(top, c='b', ls='--') #plt.axhline(bot, c='r', ls='--') plt.show(block=False) ''' order.objCutout[frame] = np.ma.masked_array(order.objCutout[frame], mask=offOrderMask) ''' plt.figure(64782) plt.imshow(order.objCutout[frame], origin='lower', aspect='auto') #plt.plot(np.arange(2048), topTrace, c='b', ls=':') #plt.plot(np.arange(2048), botTrace, c='r', ls=':') #plt.axhline(top, c='b', ls='--') #plt.axhline(bot, c='r', ls='--') plt.show() ''' if eta is not None: order.etaCutout = np.array( image_lib.cut_out(reduced.etaImg, flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) if arc is not None: order.arcCutout = np.array( image_lib.cut_out(reduced.arcImg, flatOrder.highestPoint, flatOrder.lowestPoint, flatOrder.cutoutPadding)) order.integrationTime = reduced.getIntegrationTime( ) # used in noise calc try: # reduce order, i.e. rectify, extract spectra, identify sky lines reduce_order.reduce_order(order, eta=eta, arc=arc) # add reduced order to list of reduced orders in Reduced object reduced.orders.append(order) except DrpException.DrpException as e: logger.warning('failed to reduce order {}: {}'.format( str(flatOrder.orderNum), e.message)) # end if order is on the detector # end for each order loggers = ['obj'] if config.params['cmnd_line_mode'] is False: loggers.append('main') # for l in loggers: # logging.getLogger(l).log(INFO, 'n orders on the detector = {}'.format(n_orders_on_detector)) # logging.getLogger(l).log(INFO, 'n orders reduced = {}'.format(len(reduced.orders))) if len(reduced.orders) == 0: return for l in loggers: reduced.snrMean = sum(reduced.orders[i].snr['A'] for i in range(len(reduced.orders))) / \ len(reduced.orders) logging.getLogger(l).log( INFO, 'mean signal-to-noise ratio = {:.1f}'.format(reduced.snrMean)) snr = [] for i in range(len(reduced.orders)): snr.append(reduced.orders[i].snr['A']) for l in loggers: reduced.snrMin = np.amin(snr) logging.getLogger(l).log( INFO, 'minimum signal-to-noise ratio = {:.1f}'.format(reduced.snrMin)) try: reduced.wMean = sum(abs(reduced.orders[i].gaussianParams['A'][2]) \ for i in range(len(reduced.orders))) / len(reduced.orders) logging.getLogger(l).log( INFO, 'mean spatial peak width = {:.1f} pixels'.format( reduced.wMean)) except: logging.getLogger(l).log(logging.WARNING, 'mean spatial peak width = unknown') w = [] for i in range(len(reduced.orders)): if reduced.orders[i].gaussianParams['A'] is not None: w.append(reduced.orders[i].gaussianParams['A'][2]) try: reduced.wMax = np.amax(w) logging.getLogger(l).log( INFO, 'maximum spatial peak width = {:.1f} pixels'.format( reduced.wMax)) except: logging.getLogger(l).error( 'maximum spatial peak width cannot be determined') logging.getLogger(l).log(INFO, 'maximum spatial peak width = unknown') return