def reduce_exposure(self, frames, bg_frames=None, std_outfile=None): """ Reduce a single exposure Args: frame (:obj:`int`): 0-indexed row in :attr:`fitstbl` with the frame to reduce. bg_frames (:obj:`list`, optional): List of frame indices for the background. std_outfile (:obj:`str`, optional): File with a previously reduced standard spectrum from PypeIt. Returns: dict: The dictionary containing the primary outputs of extraction. """ # TODO: # - bg_frames should be None by default # - change doc string to reflect that more than one frame can be # provided # if show is set, clear the ginga channels at the start of each new sci_ID if self.show: # TODO: Put this in a try/except block? ginga.clear_all() has_bg = True if bg_frames is not None and len( bg_frames) > 0 else False # Is this an IR reduction? # TODO: Why specific to IR? self.ir_redux = True if has_bg else False # TODO: JFH Why does this need to be ordered? sci_dict = OrderedDict() # This needs to be ordered sci_dict['meta'] = {} sci_dict['meta']['ir_redux'] = self.ir_redux # Print status message msgs_string = 'Reducing target {:s}'.format( self.fitstbl['target'][frames[0]]) + msgs.newline() # TODO: Print these when the frames are actually combined, # backgrounds are used, etc? msgs_string += 'Combining frames:' + msgs.newline() for iframe in frames: msgs_string += '{0:s}'.format( self.fitstbl['filename'][iframe]) + msgs.newline() msgs.info(msgs_string) if has_bg: bg_msgs_string = '' for iframe in bg_frames: bg_msgs_string += '{0:s}'.format( self.fitstbl['filename'][iframe]) + msgs.newline() bg_msgs_string = msgs.newline( ) + 'Using background from frames:' + msgs.newline( ) + bg_msgs_string msgs.info(bg_msgs_string) # Find the detectors to reduce detectors = PypeIt.select_detectors(detnum=self.par['rdx']['detnum'], ndet=self.spectrograph.ndet) if len(detectors) != self.spectrograph.ndet: msgs.warn('Not reducing detectors: {0}'.format(' '.join([ str(d) for d in set(np.arange(self.spectrograph.ndet)) - set(detectors) ]))) # Loop on Detectors for self.det in detectors: msgs.info("Working on detector {0}".format(self.det)) sci_dict[self.det] = {} # Calibrate #TODO Is the right behavior to just use the first frame? self.caliBrate.set_config(frames[0], self.det, self.par['calibrations']) self.caliBrate.run_the_steps() # Extract # TODO: pass back the background frame, pass in background # files as an argument. extract one takes a file list as an # argument and instantiates science within sci_dict[self.det]['sciimg'], sci_dict[self.det]['sciivar'], \ sci_dict[self.det]['skymodel'], sci_dict[self.det]['objmodel'], \ sci_dict[self.det]['ivarmodel'], sci_dict[self.det]['outmask'], \ sci_dict[self.det]['specobjs'], \ = self.extract_one(frames, self.det, bg_frames, std_outfile=std_outfile) # JFH TODO write out the background frame? # Return return sci_dict
def reduce_exposure(self, frames, bg_frames=[], std_outfile=None): """ Reduce a single exposure Args: frame (:obj:`int`): 0-indexed row in :attr:`fitstbl` with the frame to reduce bgframes (:obj:`list`, optional): List of frame indices for the background std_outfile (:obj:`str`, optional): the name of a file with a previously PypeIt-reduced standard spectrum. Returns: dict: The dictionary containing the primary outputs of extraction """ # if show is set, clear the ginga channels at the start of each new sci_ID if self.show: ginga.clear_all() # Save the frame self.frames = frames self.bg_frames = bg_frames # Is this an IR reduction? self.ir_redux = True if len(bg_frames) > 0 else False # JFH Why does this need to be ordered? sci_dict = OrderedDict() # This needs to be ordered sci_dict['meta'] = {} sci_dict['meta']['vel_corr'] = 0. sci_dict['meta']['ir_redux'] = self.ir_redux # Print status message msgs_string = 'Reducing target {:s}'.format(self.fitstbl['target'][self.frames[0]]) + msgs.newline() msgs_string += 'Combining frames:' + msgs.newline() for iframe in self.frames: msgs_string += '{0:s}'.format(self.fitstbl['filename'][iframe]) + msgs.newline() msgs.info(msgs_string) if len(bg_frames) > 0: bg_msgs_string = '' for iframe in self.bg_frames: bg_msgs_string += '{0:s}'.format(self.fitstbl['filename'][iframe]) + msgs.newline() bg_msgs_string = msgs.newline() + 'Using background from frames:' + msgs.newline() + bg_msgs_string msgs.info(bg_msgs_string) # Find the detectors to reduce detectors = self.select_detectors() if len(detectors) != self.spectrograph.ndet: msgs.warn('Not reducing detectors: {0}'.format(' '.join([ str(d) for d in set(np.arange(self.spectrograph.ndet))-set(detectors)]))) # Loop on Detectors for self.det in detectors: msgs.info("Working on detector {0}".format(self.det)) sci_dict[self.det] = {} # Calibrate #TODO Is the right behavior to just use the first frame? self.caliBrate.set_config(self.frames[0], self.det, self.par['calibrations']) self.caliBrate.run_the_steps() # Extract # TODO: pass back the background frame, pass in background # files as an argument. extract one takes a file list as an # argument and instantiates science within sci_dict[self.det]['sciimg'], sci_dict[self.det]['sciivar'], sci_dict[self.det]['skymodel'], \ sci_dict[self.det]['objmodel'], sci_dict[self.det]['ivarmodel'], sci_dict[self.det]['outmask'], \ sci_dict[self.det]['specobjs'], vel_corr \ = self.extract_one(self.frames, self.det, bg_frames = self.bg_frames, std_outfile = std_outfile) if vel_corr is not None: sci_dict['meta']['vel_corr'] = vel_corr # JFH TODO write out the background frame? # Return return sci_dict
def reduce_exposure(self, frames, bg_frames=None, std_outfile=None): """ Reduce a single exposure Args: frame (:obj:`int`): 0-indexed row in :attr:`fitstbl` with the frame to reduce. bg_frames (:obj:`list`, optional): List of frame indices for the background. std_outfile (:obj:`str`, optional): File with a previously reduced standard spectrum from PypeIt. Returns: dict: The dictionary containing the primary outputs of extraction. """ # TODO: # - bg_frames should be None by default # - change doc string to reflect that more than one frame can be # provided # if show is set, clear the ginga channels at the start of each new sci_ID if self.show: # TODO: Put this in a try/except block? ginga.clear_all() has_bg = True if bg_frames is not None and len( bg_frames) > 0 else False # Is this an IR reduction? # TODO: Why specific to IR? self.ir_redux = True if has_bg else False # Container for all the Spec2DObj all_spec2d = spec2dobj.AllSpec2DObj() all_spec2d['meta']['ir_redux'] = self.ir_redux # TODO -- Should we reset/regenerate self.slits.mask for a new exposure all_specobjs = specobjs.SpecObjs() # Print status message msgs_string = 'Reducing target {:s}'.format( self.fitstbl['target'][frames[0]]) + msgs.newline() # TODO: Print these when the frames are actually combined, # backgrounds are used, etc? msgs_string += 'Combining frames:' + msgs.newline() for iframe in frames: msgs_string += '{0:s}'.format( self.fitstbl['filename'][iframe]) + msgs.newline() msgs.info(msgs_string) if has_bg: bg_msgs_string = '' for iframe in bg_frames: bg_msgs_string += '{0:s}'.format( self.fitstbl['filename'][iframe]) + msgs.newline() bg_msgs_string = msgs.newline( ) + 'Using background from frames:' + msgs.newline( ) + bg_msgs_string msgs.info(bg_msgs_string) # Find the detectors to reduce detectors = PypeIt.select_detectors( detnum=self.par['rdx']['detnum'], slitspatnum=self.par['rdx']['slitspatnum'], ndet=self.spectrograph.ndet) if len(detectors) != self.spectrograph.ndet: msgs.warn('Not reducing detectors: {0}'.format(' '.join([ str(d) for d in set(np.arange(self.spectrograph.ndet)) - set(detectors) ]))) # Loop on Detectors # TODO: Attempt to put in a multiprocessing call here? for self.det in detectors: msgs.info("Working on detector {0}".format(self.det)) # Instantiate Calibrations class self.caliBrate = calibrations.Calibrations.get_instance( self.fitstbl, self.par['calibrations'], self.spectrograph, self.calibrations_path, qadir=self.qa_path, reuse_masters=self.reuse_masters, show=self.show, slitspat_num=self.par['rdx']['slitspatnum']) # These need to be separate to accomodate COADD2D self.caliBrate.set_config(frames[0], self.det, self.par['calibrations']) self.caliBrate.run_the_steps() # Extract # TODO: pass back the background frame, pass in background # files as an argument. extract one takes a file list as an # argument and instantiates science within all_spec2d[self.det], tmp_sobjs \ = self.reduce_one(frames, self.det, bg_frames, std_outfile=std_outfile) # Hold em if tmp_sobjs.nobj > 0: all_specobjs.add_sobj(tmp_sobjs) # JFH TODO write out the background frame? # TODO -- Save here? Seems like we should. Would probably need to use update_det=True # Return return all_spec2d, all_specobjs