def local_skysub_extract(self, sciimg, sciivar, tilts, waveimg, global_sky, rn2img, sobjs, spat_pix=None, maskslits=None, model_noise=True, std = False, show_profile=False, show=False): """ Perform local sky subtraction, profile fitting, and optimal extraction slit by slit Wrapper to skysub.local_skysub_extract Parameters ---------- sobjs: object Specobjs object containing Specobj objects containing information about objects found. waveimg: ndarray, shape (nspec, nspat) Wavelength map Optional Parameters ------------------- Returns: global_sky: (numpy.ndarray) image of the the global sky model """ self.sciimg = sciimg self.sciivar = sciivar self.tilts = tilts self.waveimg = waveimg self.global_sky = global_sky self.rn2img = rn2img # get the good slits and assign self.maskslits self.maskslits = self.maskslits if maskslits is None else maskslits gdslits = np.where(np.invert(self.maskslits))[0] # Allocate the images that are needed # Initialize to mask in case no objects were found self.outmask = np.copy(self.mask) # Initialize to input mask in case no objects were found self.extractmask = (self.mask == 0) # Initialize to zero in case no objects were found self.objmodel = np.zeros_like(self.sciimg) # Set initially to global sky in case no objects were found self.skymodel = np.copy(self.global_sky) # Set initially to sciivar in case no obects were found. self.ivarmodel = np.copy(self.sciivar) # Could actually create a model anyway here, but probably # overkill since nothing is extracted self.sobjs = sobjs.copy() # Loop on slits for slit in gdslits: msgs.info("Local sky subtraction and extraction for slit: {:d}".format(slit)) thisobj = (self.sobjs.slitid == slit) # indices of objects for this slit if np.any(thisobj): thismask = (self.slitmask == slit) # pixels for this slit # True = Good, False = Bad for inmask inmask = (self.mask == 0) & thismask # Local sky subtraction and extraction self.skymodel[thismask], self.objmodel[thismask], self.ivarmodel[thismask], \ self.extractmask[thismask] = skysub.local_skysub_extract( self.sciimg, self.sciivar, self.tilts, self.waveimg, self.global_sky, self.rn2img, thismask, self.tslits_dict['slit_left'][:,slit], self.tslits_dict['slit_righ'][:, slit], self.sobjs[thisobj], spat_pix=spat_pix, model_full_slit=self.redux_par['model_full_slit'], box_rad=self.redux_par['boxcar_radius']/self.spectrograph.detector[self.det-1]['platescale'], sigrej=self.redux_par['sky_sigrej'], model_noise=model_noise, std=std, bsp=self.redux_par['bspline_spacing'], sn_gauss=self.redux_par['sn_gauss'], inmask=inmask, show_profile=show_profile) # Set the bit for pixels which were masked by the extraction. # For extractmask, True = Good, False = Bad iextract = (self.mask == 0) & (self.extractmask == False) self.outmask[iextract] = processimages.ProcessImages.bitmask.turn_on(self.outmask[iextract], 'EXTRACT') # Step self.steps.append(inspect.stack()[0][3]) if show: self.show('local', sobjs = self.sobjs, slits= True) self.show('resid', sobjs = self.sobjs, slits= True) # Return return self.skymodel, self.objmodel, self.ivarmodel, self.outmask, self.sobjs
def local_skysub_extract(self, global_sky, sobjs, spat_pix=None, model_noise=True, show_resids=False, show_profile=False, show=False): """ Perform local sky subtraction, profile fitting, and optimal extraction slit by slit Wrapper to skysub.local_skysub_extract Args: global_sky (np.ndarray): sobjs (:class:`pypeit.specobjs.SpecObjs`): spat_pix (np.ndarray, optional): model_noise (bool, optional): show_resids (bool, optional): show_profile (bool, optional): show (bool, optional): Returns: tuple: skymodel (np.ndarray), objmodel (np.ndarray), ivarmodel (np.ndarray), outmask (np.ndarray), sobjs """ self.global_sky = global_sky # get the good slits gdslits = np.where(np.invert(self.reduce_bpm))[0] # Allocate the images that are needed # Initialize to mask in case no objects were found self.outmask = np.copy(self.sciImg.fullmask) # Initialize to input mask in case no objects were found self.extractmask = (self.sciImg.fullmask == 0) # Initialize to zero in case no objects were found self.objmodel = np.zeros_like(self.sciImg.image) # Set initially to global sky in case no objects were found self.skymodel = np.copy(self.global_sky) # Set initially to sciivar in case no obects were found. self.ivarmodel = np.copy(self.sciImg.ivar) # Could actually create a model anyway here, but probably # overkill since nothing is extracted self.sobjs = sobjs.copy() # WHY DO WE CREATE A COPY HERE? # Loop on slits for slit_idx in gdslits: slit_spat = self.slits.spat_id[slit_idx] msgs.info( "Local sky subtraction and extraction for slit: {:d}".format( slit_spat)) thisobj = self.sobjs.SLITID == slit_spat # indices of objects for this slit if np.any(thisobj): thismask = self.slitmask == slit_spat # pixels for this slit # True = Good, False = Bad for inmask ingpm = (self.sciImg.fullmask == 0) & thismask # Local sky subtraction and extraction self.skymodel[thismask], self.objmodel[thismask], self.ivarmodel[thismask], \ self.extractmask[thismask] = skysub.local_skysub_extract( self.sciImg.image, self.sciImg.ivar, self.tilts, self.waveimg, self.global_sky, self.sciImg.rn2img, thismask, self.slits_left[:,slit_idx], self.slits_right[:, slit_idx], self.sobjs[thisobj], ingpm, spat_pix=spat_pix, model_full_slit=self.par['reduce']['extraction']['model_full_slit'], box_rad=self.par['reduce']['extraction']['boxcar_radius']/self.get_platescale(None), sigrej=self.par['reduce']['skysub']['sky_sigrej'], model_noise=model_noise, std=self.std_redux, bsp=self.par['reduce']['skysub']['bspline_spacing'], sn_gauss=self.par['reduce']['extraction']['sn_gauss'], show_profile=show_profile, use_2dmodel_mask=self.par['reduce']['extraction']['use_2dmodel_mask']) # Set the bit for pixels which were masked by the extraction. # For extractmask, True = Good, False = Bad iextract = (self.sciImg.fullmask == 0) & (self.extractmask == False) self.outmask[iextract] = self.sciImg.bitmask.turn_on( self.outmask[iextract], 'EXTRACT') # Step self.steps.append(inspect.stack()[0][3]) if show: self.show('local', sobjs=self.sobjs, slits=True) self.show('resid', sobjs=self.sobjs, slits=True) # Return return self.skymodel, self.objmodel, self.ivarmodel, self.outmask, self.sobjs
def local_skysub_extract(self, global_sky, sobjs, spat_pix=None, model_noise=True, show_resids=False, show_profile=False, show=False): """ Perform local sky subtraction, profile fitting, and optimal extraction slit by slit. Wrapper to :func:`~pypeit.core.skysub.local_skysub_extract`. Args: global_sky (`numpy.ndarray`_): Global sky model sobjs (:class:`~pypeit.specobjs.SpecObjs`): Class containing the information about the objects found spat_pix (`numpy.ndarray`_, optional): Image containing the spatial location of pixels. If not input, it will be computed from ``spat_img = np.outer(np.ones(nspec), np.arange(nspat))``. model_noise (:obj:`bool`, optional): If True, construct and iteratively update a model inverse variance image using :func:`~pypeit.core.procimg.variance_model`. If False, a variance model will not be created and instead the input sciivar will always be taken to be the inverse variance. See :func:`~pypeit.core.skysub.local_skysub_extract` for more info. show_resids (:obj:`bool`, optional): Show the model fits and residuals. show_profile (:obj:`bool`, optional): Show QA for the object profile fitting to the screen. Note that this will show interactive matplotlib plots which will block the execution of the code until the window is closed. show (:obj:`bool`, optional): Show debugging plots Returns: :obj:`tuple`: Return the model sky flux, object flux, inverse variance, and mask as `numpy.ndarray`_ objects, and returns a :class:`~pypeit.specobjs.SpecObjs`: instance c containing the information about the objects found. """ self.global_sky = global_sky # get the good slits gdslits = np.where(np.invert(self.extract_bpm))[0] # Allocate the images that are needed # Initialize to mask in case no objects were found # NOTE: fullmask is a bit mask, make sure it's treated as such, not a # boolean (e.g., bad pixel) mask. self.outmask = np.copy(self.sciImg.fullmask) # Initialize to input mask in case no objects were found self.extractmask = self.sciImg.select_flag(invert=True) # Initialize to zero in case no objects were found self.objmodel = np.zeros_like(self.sciImg.image) # Set initially to global sky in case no objects were found self.skymodel = np.copy(self.global_sky) # Set initially to sciivar in case no obects were found. self.ivarmodel = np.copy(self.sciImg.ivar) # Could actually create a model anyway here, but probably # overkill since nothing is extracted self.sobjs = sobjs.copy() # WHY DO WE CREATE A COPY HERE? base_gpm = self.sciImg.select_flag(invert=True) # Loop on slits for slit_idx in gdslits: slit_spat = self.slits.spat_id[slit_idx] msgs.info("Local sky subtraction and extraction for slit: {:d}".format(slit_spat)) thisobj = self.sobjs.SLITID == slit_spat # indices of objects for this slit if not np.any(thisobj): continue # Setup to run local skysub thismask = self.slitmask == slit_spat # pixels for this slit # True = Good, False = Bad for inmask ingpm = base_gpm & thismask # ... Just for readability model_full_slit = self.par['reduce']['extraction']['model_full_slit'] sigrej = self.par['reduce']['skysub']['sky_sigrej'] bsp = self.par['reduce']['skysub']['bspline_spacing'] force_gauss = self.par['reduce']['extraction']['use_user_fwhm'] sn_gauss = self.par['reduce']['extraction']['sn_gauss'] use_2dmodel_mask = self.par['reduce']['extraction']['use_2dmodel_mask'] no_local_sky = self.par['reduce']['skysub']['no_local_sky'] # Local sky subtraction and extraction self.skymodel[thismask], self.objmodel[thismask], self.ivarmodel[thismask], self.extractmask[thismask] \ = skysub.local_skysub_extract(self.sciImg.image, self.sciImg.ivar, self.tilts, self.waveimg, self.global_sky, thismask, self.slits_left[:,slit_idx], self.slits_right[:, slit_idx], self.sobjs[thisobj], ingpm=ingpm, spat_pix=spat_pix, model_full_slit=model_full_slit, sigrej=sigrej, model_noise=model_noise, std=self.std_redux, bsp=bsp, force_gauss=force_gauss, sn_gauss=sn_gauss, show_profile=show_profile, use_2dmodel_mask=use_2dmodel_mask, no_local_sky=no_local_sky, base_var=self.sciImg.base_var, count_scale=self.sciImg.img_scale, adderr=self.sciImg.noise_floor) # Set the bit for pixels which were masked by the extraction. # For extractmask, True = Good, False = Bad iextract = base_gpm & np.logical_not(self.extractmask) # TODO: Change this to use the update_mask method? self.outmask[iextract] = self.sciImg.bitmask.turn_on(self.outmask[iextract], 'EXTRACT') # Step self.steps.append(inspect.stack()[0][3]) if show: self.show('local', sobjs = self.sobjs, slits= True) self.show('resid', sobjs = self.sobjs, slits= True) # Return return self.skymodel, self.objmodel, self.ivarmodel, self.outmask, self.sobjs