def main(pargs): import time from pypeit import ginga from pypeit import flatfield import subprocess # Load up flatField = flatfield.FlatField.from_master_file(pargs.master_file) try: ginga.connect_to_ginga(raise_err=True) except ValueError: subprocess.Popen(['ginga', '--modules=RC']) time.sleep(3) # Show RawFlatImage viewer, ch = ginga.show_image(flatField.rawflatimg.image, chname='Raw Flat') # PixelFlat if flatField.mspixelflat is not None: viewer, ch = ginga.show_image(flatField.mspixelflat, chname='Pixel Flat') # Illumination flat if flatField.msillumflat is not None: viewer, ch = ginga.show_image(flatField.msillumflat, chname='Illumination Flat') # Illumination flat if flatField.flat_model is not None: viewer, ch = ginga.show_image(flatField.flat_model, chname='Flat Model') print("Check your Ginga viewer")
def visual_inspect(camera='b3', idx=0, old=True): """ View an image bias-subtracted by the old or new fig Args: camera: idx: old: Returns: """ dpath = '/home/xavier/DESI/DESI_SCRATCH/minisv2/data/20200304/' bias_files = glob.glob(dpath + '000*/desi-*.fz') bias_files.sort() bias_file = bias_files[idx] print("Inspecting: {}".format(bias_file)) # Load hdul = fits.open(bias_file) hdu = hdul[camera.upper()] bias = hdu.data stack_bias, _ = grab_stack_bias_img(camera, old=old) # View ginga.show_image(bias - stack_bias)
def show(self, slits=True, wcs_match=True): """ Show all of the flat field products Args: slits (bool, optional): wcs_match (bool, optional): """ viewer, ch = ginga.show_image(self.mspixelflat, chname='pixeflat', cuts=(0.9, 1.1), wcs_match=wcs_match, clear=True) viewer, ch = ginga.show_image(self.msillumflat, chname='illumflat', cuts=(0.9, 1.1), wcs_match=wcs_match) viewer, ch = ginga.show_image(self.rawflatimg, chname='flat', wcs_match=wcs_match) viewer, ch = ginga.show_image(self.flat_model, chname='flat_model', wcs_match=wcs_match) if slits: if self.tslits_dict is not None: slit_ids = [ edgetrace.get_slitid(self.rawflatimg.shape, self.tslits_dict['slit_left'], self.tslits_dict['slit_righ'], ii)[0] for ii in range(self.tslits_dict['slit_left'].shape[1]) ] ginga.show_slits(viewer, ch, self.tslits_dict['slit_left'], self.tslits_dict['slit_righ'], slit_ids)
def show(self): """ Simple show method """ if self.image is None: msgs.warn("No image to show!") return ginga.show_image(self.image, chname='image')
def show(self): """ Show the image in a ginga viewer. """ if self.image is None: # TODO: This should fault. msgs.warn("No image to show!") return ginga.show_image(self.image, chname='image')
def get_tslits_nires(flat_files, user_settings=par, gingashow=True, tilt_root='tilt_nires'): """Precess flat files and get titlts for NIRES """ # Process flat images tImage = traceimage.TraceImage(spectrograph, file_list=flat_files, par=par['calibrations']['traceframe']) tflat = tImage.process(bias_subtract='overscan', trim=False) mstrace = tflat.copy() # Define pixlocn and bpm pixlocn = pixels.gen_pixloc(tImage.stack.shape) bpm = spectrograph.bpm(shape=tflat.shape, det=1) # Instantiate Trace tSlits = traceslits.TraceSlits(mstrace, pixlocn, par=par['calibrations']['slits'], binbpx=bpm) tslits_dict = tSlits.run(plate_scale = 0.123) if gingashow: # Look at what TraceSlits was actually trying to trace viewer, ch = ginga.show_image(tSlits.edgearr) # Look at the sawtooth convolved image viewer, ch = ginga.show_image(tSlits.siglev) tmp = tSlits.edgearr * 100. tmp[np.where(tmp == 0.)] = 1. ginga.show_image(tSlits.mstrace * tmp) ginga.show_slits(viewer, ch, tSlits.lcen, tSlits.rcen, slit_ids=np.arange(tSlits.lcen.shape[1]) + 1, pstep=50) if tilt_root is not None: # Write dict on a json file jdict = ltu.jsonify(tslits_dict.copy()) ltu.savejson(tilt_root + '.json', jdict, overwrite=True, indent=None, easy_to_read=True) print("Wrote: {:s}".format(tilt_root + '.json')) return tslits_dict
def main(args): import subprocess from astropy.io import fits from pypeit import msgs from pypeit.spectrographs import keck_lris from pypeit.spectrographs import keck_deimos from pypeit.spectrographs import gemini_gmos from pypeit import msgs from pypeit import ginga # List only? if args.list: hdu = fits.open(args.file) print(hdu.info()) return # Setup for PYPIT imports msgs.reset(verbosity=2) # RAW_LRIS?? if 'keck_lris' in args.spectrograph: # if args.spectrograph == 'keck_lris_red_orig': gen_lris = keck_lris.KeckLRISROrigSpectrograph() img = gen_lris.get_rawimage(args.file, 1)[1] else: gen_lris = keck_lris.KeckLRISRSpectrograph() # Using LRISr, but this will work for LRISb too img = gen_lris.get_rawimage(args.file, None)[1] # RAW_DEIMOS?? elif args.spectrograph == 'keck_deimos': # gen_deimos = keck_deimos.KeckDEIMOSSpectrograph() img = gen_deimos.get_rawimage(args.file, None)[1] # RAW_GEMINI?? elif 'gemini_gmos' in args.spectrograph: # TODO this routine should show the whole mosaic if no detector number is passed in! # Need to figure out the number of amps gen_gmos = gemini_gmos.GeminiGMOSSpectrograph() img = gen_gmos.get_rawimage(args.file, args.det)[1] else: hdu = fits.open(args.file) img = hdu[args.exten].data # Write ginga.show_image(img)
def show(self, item='wave'): """ Show the image Args: item (str, optional): Returns: """ if item == 'wave': if self.mswave is not None: ginga.show_image(self.mswave) else: msgs.warn("Not able to show this type of image")
def show(self, attr, slit=None, display='ginga', cname=None): """ Display an image or spectrum in TraceSlits Parameters ---------- attr : str 'fweight' -- Show the msarc image and the tilts traced by fweight 'model' -- Show the msarc image and the poylynomial model fits to the individual arc lines that were traced by fweight. 'arcmodel -- This illustrates the global final 2-d model fit to the indivdiaul models of each traced fweight arc line tilts evaluated at the location of the specific arclines that wered use for the fit. 'final_tilts' -- Show the final 2-d tilt model for all the slits that were fit. slit : int, optional -- The slit to plot. This needs to be an integer between 1 and nslit display : str (optional) 'ginga' -- Display to an RC Ginga """ viewer, ch = ginga.show_image(self.arcimg * (self.slitmask == slit), chname='Tilts') ginga.show_tilts(viewer, ch, self.trace_dict, sedges=(self.tslits_dict['slit_left'][:, slit], self.tslits_dict['slit_righ'][:, slit]), points=True, clear_canvas=True)
def show(self, attr='stack', idx=None, display='ginga'): """ Show an image Parameters ---------- attr : str, optional Internal name of the image to show proc_image, raw_image, stack idx : int, optional Specifies the index of the raw or processed image Required if proc_image or raw_image is called display : str Returns ------- """ if 'proc_image' in attr: img = self.proc_images[:, :, idx] elif 'raw_image' in attr: img = self.raw_images[idx] elif 'stack' in attr: img = self.stack else: msgs.warn("Options: proc_image, raw_image, stack") return # Show viewer, ch = ginga.show_image(img)
def main(args): import subprocess from astropy.io import fits from pypeit import msgs from pypeit.spectrographs import keck_lris from pypeit.spectrographs import keck_deimos from pypeit.spectrographs import gemini_gmos from pypeit import msgs from pypeit import ginga # List only? if args.list: hdu = fits.open(args.file) print(hdu.info()) return # Setup for PYPIT imports msgs.reset(verbosity=2) # RAW_LRIS?? if args.raw_lris: # img, _, _ = keck_lris.read_lris(args.file) # RAW_DEIMOS?? elif args.raw_deimos: # img, _, _ = keck_deimos.read_deimos(args.file) # RAW_GEMINI?? elif args.raw_gmos: # TODO this routine should show the whole mosaic if no detector number is passed in! # Need to figure out the number of amps img, _, _ = gemini_gmos.read_gmos(args.file, det=args.det) else: hdu = fits.open(args.file) img = hdu[args.exten].data # Write ginga.show_image(img)
def show(self, image, chname=None): """ Show one of the internal images Args: image : ndarray, optional User supplied image to display """ ch_name = chname if chname is not None else 'image' viewer, ch = ginga.show_image(image, chname=ch_name)
def qck_bias(cameras=['z3'], debug=False): """ Generate and write to disk a Bias image Args: cameras (list): """ dpath = '/home/xavier/DESI/DESI_SCRATCH/minisv2/data/20200304/' bias_files = glob.glob(dpath + '000*/desi-*.fz') bias_files.sort() # Load em for camera in cameras: bias_imgs = None for ss, bias_file in enumerate(bias_files): print("Loading {}".format(bias_file)) hdul = fits.open(bias_file) #- Check if this file uses amp names 1,2,3,4 (old) or A,B,C,D (new) hdu = hdul[camera.upper()] header = hdu.header if bias_imgs is None: bias_imgs = np.zeros( (len(bias_files), hdu.data.shape[0], hdu.data.shape[1]), dtype=float) bias_imgs[ss, :, :] = hdu.data.astype(float) # Stack em bias_img, _, _ = stats.sigma_clipped_stats(bias_imgs, axis=0) if debug: ginga.show_image(bias_img) embed(header='51 of qa_preproc') # Write hdu0 = fits.PrimaryHDU(bias_img) hdul = fits.HDUList([hdu0]) outfile = os.path.join(dpath, 'bias_{}.fits'.format(camera)) hdul.writeto(outfile, overwrite=True) print("Wrote: {}".format(outfile))
def main(pargs): import pdb as debugger import time from pypeit import ginga from pypeit import traceslits from pypeit.core.trace_slits import get_slitid import subprocess # Load up tslits_dict, mstrace = traceslits.load_tslits(pargs.root) import pdb pdb.set_trace() try: ginga.connect_to_ginga(raise_err=True) except ValueError: subprocess.Popen(['ginga', '--modules=RC']) time.sleep(3) # This is deprecated since the class is not stored to disk anymore. You can just debug to achieve this functionality #if pargs.show is not None: # Tslits.show(pargs.show) # print("Check your Ginga viewer") # return # Show Image viewer, ch = ginga.show_image(mstrace, chname=pargs.chname) nslits = tslits_dict['nslits'] # Get slit ids stup = (mstrace.shape, tslits_dict['slit_left'], tslits_dict['slit_righ']) if pargs.dumb_ids: slit_ids = range(nslits) else: slit_ids = [ get_slitid(stup[0], stup[1], stup[2], ii)[0] for ii in range(nslits) ] ginga.show_slits(viewer, ch, tslits_dict['slit_left'], tslits_dict['slit_righ'], slit_ids, pstep=50) print("Check your Ginga viewer")
def show_alignment(alignframe, align_traces=None, slits=None, clear=False): """ Show one of the class internals Parameters ---------- alignframe : `numpy.ndarray`_ Image to be plotted (i.e. the master align frame) align_traces : list, optional The align traces slits : :class:`pypeit.slittrace.SlitTraceSet`, optional properties of the slits, including traces. clear : bool, optional Clear the plotting window in ginga? Returns ------- """ ginga.connect_to_ginga(raise_err=True, allow_new=True) ch_name = 'alignment' viewer, channel = ginga.show_image(alignframe, chname=ch_name, clear=clear, wcs_match=False) # Display the slit edges if slits is not None and viewer is not None: left, right, mask = slits.select_edges() ginga.show_slits(viewer, channel, left, right) # Display the alignment traces if align_traces is not None and viewer is not None: for bar in range(align_traces.shape[1]): for slt in range(align_traces.shape[2]): # Alternate the colors of the slits color = 'orange' if slt % 2 == 0: color = 'magenta' # Display the trace ginga.show_trace(viewer, channel, align_traces[:, bar, slt], trc_name="", color=color)
def show_flats(pixelflat, illumflat, procflat, flat_model, wcs_match=True, slits=None): """ Interface to ginga to show a set of flat images Args: pixelflat (`numpy.ndarray`_): illumflat (`numpy.ndarray`_ or None): procflat (`numpy.ndarray`_): flat_model (`numpy.ndarray`_): wcs_match (bool, optional): slits (:class:`pypeit.slittrace.SlitTraceSet`, optional): Returns: """ ginga.connect_to_ginga(raise_err=True, allow_new=True) if slits is not None: left, right, mask = slits.select_edges() gpm = mask == 0 # Loop me clear = True for img, name, cut in zip([pixelflat, illumflat, procflat, flat_model], ['pixelflat', 'illumflat', 'flat', 'flat_model'], [(0.9, 1.1), (0.9, 1.1), None, None]): if img is None: continue # TODO: Add an option that shows the relevant stuff in a # matplotlib window. viewer, ch = ginga.show_image(img, chname=name, cuts=cut, wcs_match=wcs_match, clear=clear) if slits is not None: ginga.show_slits(viewer, ch, left[:, gpm], right[:, gpm], slit_ids=slits.spat_id[gpm]) # Turn off clear if clear: clear = False
def main(args): # List only? hdu = fits.open(args.file) head0 = hdu[0].header if args.list: hdu.info() return # Setup for PYPIT imports msgs.reset(verbosity=2) # Init sdet = get_dnum(args.det, prefix=False) # One detector, sky sub for now names = [hdu[i].name for i in range(len(hdu))] try: exten = names.index('DET{:s}-PROCESSED'.format(sdet)) except: # Backwards compatability msgs.error( 'Requested detector {:s} was not processed.\n' 'Maybe you chose the wrong one to view?\n' 'Set with --det= or check file contents with --list'.format(sdet)) sciimg = hdu[exten].data try: exten = names.index('DET{:s}-SKY'.format(sdet)) except: # Backwards compatability msgs.error( 'Requested detector {:s} has no sky model.\n' 'Maybe you chose the wrong one to view?\n' 'Set with --det= or check file contents with --list'.format(sdet)) skymodel = hdu[exten].data try: exten = names.index('DET{:s}-MASK'.format(sdet)) except ValueError: # Backwards compatability msgs.error( 'Requested detector {:s} has no bit mask.\n' 'Maybe you chose the wrong one to view?\n' 'Set with --det= or check file contents with --list'.format(sdet)) mask = hdu[exten].data try: exten = names.index('DET{:s}-IVARMODEL'.format(sdet)) except ValueError: # Backwards compatability msgs.error( 'Requested detector {:s} has no IVARMODEL.\n' 'Maybe you chose the wrong one to view?\n' + 'Set with --det= or check file contents with --list'.format(sdet)) ivarmodel = hdu[exten].data # Read in the object model for residual map try: exten = names.index('DET{:s}-OBJ'.format(sdet)) except ValueError: # Backwards compatability msgs.error( 'Requested detector {:s} has no object model.\n' 'Maybe you chose the wrong one to view?\n' + 'Set with --det= or check file contents with --list'.format(sdet)) objmodel = hdu[exten].data # Get waveimg mdir = head0['PYPMFDIR'] + '/' if not os.path.exists(mdir): mdir_base = os.path.basename(os.path.dirname(mdir)) + '/' msgs.warn('Master file dir: {0} does not exist. Using ./{1}'.format( mdir, mdir_base)) mdir = mdir_base trace_key = '{0}_{1:02d}'.format(head0['TRACMKEY'], args.det) trc_file = os.path.join( mdir, MasterFrame.construct_file_name('Trace', trace_key)) wave_key = '{0}_{1:02d}'.format(head0['ARCMKEY'], args.det) waveimg = os.path.join(mdir, MasterFrame.construct_file_name('Wave', wave_key)) tslits_dict = TraceSlits.load_from_file(trc_file)[0] slitmask = pixels.tslits2mask(tslits_dict) shape = (tslits_dict['nspec'], tslits_dict['nspat']) slit_ids = [ trace_slits.get_slitid(shape, tslits_dict['slit_left'], tslits_dict['slit_righ'], ii)[0] for ii in range(tslits_dict['slit_left'].shape[1]) ] # Show the bitmask? mask_in = mask if args.showmask else None # Object traces spec1d_file = args.file.replace('spec2d', 'spec1d') det_nm = 'DET{:s}'.format(sdet) if os.path.isfile(spec1d_file): hdulist_1d = fits.open(spec1d_file) else: hdulist_1d = [] msgs.warn('Could not find spec1d file: {:s}'.format(spec1d_file) + msgs.newline() + ' No objects were extracted.') # Unpack the bitmask bitMask = bitmask() bpm, crmask, satmask, minmask, offslitmask, nanmask, ivar0mask, ivarnanmask, extractmask \ = bitMask.unpack(mask) # Now show each image to a separate channel # SCIIMG image = sciimg # Raw science image (mean, med, sigma) = sigma_clipped_stats(image[mask == 0], sigma_lower=5.0, sigma_upper=5.0) cut_min = mean - 1.0 * sigma cut_max = mean + 4.0 * sigma chname_skysub = 'sciimg-det{:s}'.format(sdet) # Clear all channels at the beginning viewer, ch = ginga.show_image(image, chname=chname_skysub, waveimg=waveimg, bitmask=mask_in, clear=True) #, cuts=(cut_min, cut_max), wcs_match=True) ginga.show_slits(viewer, ch, tslits_dict['slit_left'], tslits_dict['slit_righ'], slit_ids) #, args.det) # SKYSUB image = (sciimg - skymodel) * (mask == 0) # sky subtracted image (mean, med, sigma) = sigma_clipped_stats(image[mask == 0], sigma_lower=5.0, sigma_upper=5.0) cut_min = mean - 1.0 * sigma cut_max = mean + 4.0 * sigma chname_skysub = 'skysub-det{:s}'.format(sdet) # Clear all channels at the beginning # TODO: JFH For some reason Ginga crashes when I try to put cuts in here. viewer, ch = ginga.show_image( image, chname=chname_skysub, waveimg=waveimg, bitmask=mask_in) #, cuts=(cut_min, cut_max),wcs_match=True) show_trace(hdulist_1d, det_nm, viewer, ch) ginga.show_slits(viewer, ch, tslits_dict['slit_left'], tslits_dict['slit_righ'], slit_ids) #, args.det) # SKRESIDS chname_skyresids = 'sky_resid-det{:s}'.format(sdet) image = (sciimg - skymodel) * np.sqrt(ivarmodel) * (mask == 0 ) # sky residual map viewer, ch = ginga.show_image(image, chname_skyresids, waveimg=waveimg, cuts=(-5.0, 5.0), bitmask=mask_in) #,wcs_match=True) show_trace(hdulist_1d, det_nm, viewer, ch) ginga.show_slits(viewer, ch, tslits_dict['slit_left'], tslits_dict['slit_righ'], slit_ids) #, args.det) # RESIDS chname_resids = 'resid-det{:s}'.format(sdet) # full model residual map image = (sciimg - skymodel - objmodel) * np.sqrt(ivarmodel) * (mask == 0) viewer, ch = ginga.show_image(image, chname=chname_resids, waveimg=waveimg, cuts=(-5.0, 5.0), bitmask=mask_in) #,wcs_match=True) show_trace(hdulist_1d, det_nm, viewer, ch) ginga.show_slits(viewer, ch, tslits_dict['slit_left'], tslits_dict['slit_righ'], slit_ids) #, args.det) # After displaying all the images sync up the images with WCS_MATCH shell = viewer.shell() out = shell.start_global_plugin('WCSMatch') out = shell.call_global_plugin_method('WCSMatch', 'set_reference_channel', [chname_resids], {}) if args.embed: IPython.embed()
slit_righ = tslits_dict['rcen'][:, slit] thismask = (tslits_dict['slitpix'] == slit + 1) inmask = None # in the future set this to the bpm sys.exit(-1) pixelflat[thismask], illumflat[thismask], flat_model[ thismask] = flat.fit_flat(flatimg, mstilts, thismask, slit_left, slit_righ, inmask=inmask, debug=debug) ginga.show_image(pixelflat, cuts=(0.9, 1.1), chname='pixeflat', wcs_match=True, clear=True) ginga.show_image(illumflat, cuts=(0.9, 1.1), chname='illumflat', wcs_match=True) ginga.show_image(flatimg, chname='flat', wcs_match=True) ginga.show_image(flat_model, chname='flat_model', wcs_match=True) ''' bkspace = 1.0/nsamp # This is the spatial sampling interval in units of fractional slit width fit_spat = thismask & inmask isrt_spat = np.argsort(ximg[fit_spat]) ximg_fit = ximg[fit_spat][isrt_spat] norm_spec_fit = norm_spec[fit_spat][isrt_spat]
def show(self, attr, image=None, showmask=False, sobjs=None, chname=None, slits=False, clear=False): """ Show one of the internal images .. todo:: Should probably put some of these in ProcessImages Parameters ---------- attr : str global -- Sky model (global) sci -- Processed science image rawvar -- Raw variance image modelvar -- Model variance image crmasked -- Science image with CRs set to 0 skysub -- Science image with global sky subtracted image -- Input image display : str, optional image : ndarray, optional User supplied image to display Returns ------- """ if showmask: mask_in = self.sciImg.fullmask bitmask_in = self.sciImg.bitmask else: mask_in = None bitmask_in = None if attr == 'global': # global sky subtraction if self.sciImg.image is not None and self.global_sky is not None and self.sciImg.fullmask is not None: # sky subtracted image image = (self.sciImg.image - self.global_sky) * (self.sciImg.fullmask == 0) mean, med, sigma = stats.sigma_clipped_stats( image[self.sciImg.fullmask == 0], sigma_lower=5.0, sigma_upper=5.0) cut_min = mean - 1.0 * sigma cut_max = mean + 4.0 * sigma ch_name = chname if chname is not None else 'global_sky_{}'.format( self.det) viewer, ch = ginga.show_image(image, chname=ch_name, bitmask=bitmask_in, mask=mask_in, clear=clear, wcs_match=True) #, cuts=(cut_min, cut_max)) elif attr == 'local': # local sky subtraction if self.sciImg.image is not None and self.skymodel is not None and self.sciImg.fullmask is not None: # sky subtracted image image = (self.sciImg.image - self.skymodel) * (self.sciImg.fullmask == 0) mean, med, sigma = stats.sigma_clipped_stats( image[self.sciImg.fullmask == 0], sigma_lower=5.0, sigma_upper=5.0) cut_min = mean - 1.0 * sigma cut_max = mean + 4.0 * sigma ch_name = chname if chname is not None else 'local_sky_{}'.format( self.det) viewer, ch = ginga.show_image(image, chname=ch_name, bitmask=bitmask_in, mask=mask_in, clear=clear, wcs_match=True) #, cuts=(cut_min, cut_max)) elif attr == 'sky_resid': # sky residual map with object included if self.sciImg.image is not None and self.skymodel is not None \ and self.objmodel is not None and self.ivarmodel is not None \ and self.sciImg.fullmask is not None: image = (self.sciImg.image - self.skymodel) * np.sqrt( self.ivarmodel) image *= (self.sciImg.fullmask == 0) ch_name = chname if chname is not None else 'sky_resid_{}'.format( self.det) viewer, ch = ginga.show_image(image, chname=ch_name, cuts=(-5.0, 5.0), bitmask=bitmask_in, mask=mask_in, clear=clear, wcs_match=True) elif attr == 'resid': # full residual map with object model subtractede if self.sciImg.image is not None and self.skymodel is not None \ and self.objmodel is not None and self.ivarmodel is not None \ and self.sciImg.fullmask is not None: # full model residual map image = (self.sciImg.image - self.skymodel - self.objmodel) * np.sqrt(self.ivarmodel) image *= (self.sciImg.fullmask == 0) ch_name = chname if chname is not None else 'resid_{}'.format( self.det) viewer, ch = ginga.show_image(image, chname=ch_name, cuts=(-5.0, 5.0), bitmask=bitmask_in, mask=mask_in, clear=clear, wcs_match=True) elif attr == 'image': ch_name = chname if chname is not None else 'image' viewer, ch = ginga.show_image(image, chname=ch_name, clear=clear, wcs_match=True) else: msgs.warn("Not an option for show") if sobjs is not None: for spec in sobjs: color = 'magenta' if spec.hand_extract_flag else 'orange' ginga.show_trace(viewer, ch, spec.TRACE_SPAT, spec.NAME, color=color) if slits and self.slits_left is not None: ginga.show_slits(viewer, ch, self.slits_left, self.slits_right)
from pypeit import ginga from astropy.io import fits from pypeit.spectrographs import keck_lris lowrdx_path = '/Users/joe/pypeit_vs_lowredux/c17_60L/Red400/' pypeit_path = '/Users/joe/python/PypeIt-development-suite/REDUX_OUT/Keck_LRIS_red/multi_400_8500_d560/' rawpath = '/Users/joe/python/PypeIt-development-suite/RAW_DATA/Keck_LRIS_red/multi_400_8500_d560/' flatfile = rawpath + 'r170320_2057.fits' flatfile_lowrdx = lowrdx_path + 'pixflat-r170320_2057.fits' flatfile_pypeit = pypeit_path + 'MF_keck_lris_red/MasterFlatField_A_01_aa.fits' flat, _, _ = keck_lris.read_lris(flatfile, det=1, TRIM=True) hdu = fits.open(flatfile_lowrdx) flat_lowrdx = hdu[0].data flat_lowrdx = flat_lowrdx[:, 0:1024] hdu = fits.open(flatfile_pypeit) flat_pypeit = hdu[0].data cuts = (0.8, 1.5) viewer, ch = ginga.show_image(flat_lowrdx, chname='LOWREDUX', cuts=cuts) viewer, ch = ginga.show_image(flat_pypeit, chname='PYPEIT', cuts=cuts) viewer, ch = ginga.show_image(flat, chname='FLAT')
def run(self, doqa=True, debug=False, show=False): """ Main driver for tracing arc lines Code flow: #. Extract an arc spectrum down the center of each slit/order #. Loop on slits/orders #. Trace and fit the arc lines (This is done twice, once with trace_crude as the tracing crutch, then again with a PCA model fit as the crutch). #. Repeat trace. #. 2D Fit to the offset from slitcen #. Save Args: doqa (bool): debug (bool): show (bool): Returns: :class:`WaveTilts`: """ # Extract the arc spectra for all slits self.arccen, self.arccen_bpm = self.extract_arcs() # TODO: Leave for now. Used for debugging # self.par['rm_continuum'] = True # debug = True # show = True # Subtract arc continuum _mstilt = self.mstilt.image.copy() if self.par['rm_continuum']: continuum = self.model_arc_continuum(debug=debug) _mstilt -= continuum if debug: # TODO: Put this into a function vmin, vmax = visualization.ZScaleInterval().get_limits(_mstilt) w,h = plt.figaspect(1) fig = plt.figure(figsize=(3*w,h)) ax = fig.add_axes([0.15/3, 0.1, 0.8/3, 0.8]) ax.imshow(self.mstilt.image, origin='lower', interpolation='nearest', aspect='auto', vmin=vmin, vmax=vmax) ax.set_title('MasterArc') ax = fig.add_axes([1.15/3, 0.1, 0.8/3, 0.8]) ax.imshow(continuum, origin='lower', interpolation='nearest', aspect='auto', vmin=vmin, vmax=vmax) ax.set_title('Continuum') ax = fig.add_axes([2.15/3, 0.1, 0.8/3, 0.8]) ax.imshow(_mstilt, origin='lower', interpolation='nearest', aspect='auto', vmin=vmin, vmax=vmax) ax.set_title('MasterArc - Continuum') plt.show() # Final tilts image self.final_tilts = np.zeros(self.shape_science,dtype=float) max_spat_dim = (np.asarray(self.par['spat_order']) + 1).max() max_spec_dim = (np.asarray(self.par['spec_order']) + 1).max() self.coeffs = np.zeros((max_spec_dim, max_spat_dim,self.slits.nslits)) self.spat_order = np.zeros(self.slits.nslits, dtype=int) self.spec_order = np.zeros(self.slits.nslits, dtype=int) # TODO sort out show methods for debugging if show: viewer,ch = ginga.show_image(self.mstilt.image*(self.slitmask > -1),chname='tilts') # Loop on all slits for slit_idx, slit_spat in enumerate(self.slits.spat_id): if self.tilt_bpm[slit_idx]: continue #msgs.info('Computing tilts for slit {0}/{1}'.format(slit, self.slits.nslits-1)) msgs.info('Computing tilts for slit {0}/{1}'.format(slit_idx, self.slits.nslits)) # Identify lines for tracing tilts msgs.info('Finding lines for tilt analysis') self.lines_spec, self.lines_spat \ = self.find_lines(self.arccen[:,slit_idx], self.slitcen[:,slit_idx], slit_idx, bpm=self.arccen_bpm[:,slit_idx], debug=debug) if self.lines_spec is None: self.slits.mask[slit_idx] = self.slits.bitmask.turn_on(self.slits.mask[slit_idx], 'BADTILTCALIB') continue thismask = self.slitmask == slit_spat # Performs the initial tracing of the line centroids as a # function of spatial position resulting in 1D traces for # each line. msgs.info('Trace the tilts') self.trace_dict = self.trace_tilts(_mstilt, self.lines_spec, self.lines_spat, thismask, self.slitcen[:, slit_idx]) # TODO: Show the traces before running the 2D fit if show: ginga.show_tilts(viewer, ch, self.trace_dict) self.spat_order[slit_idx] = self._parse_param(self.par, 'spat_order', slit_idx) self.spec_order[slit_idx] = self._parse_param(self.par, 'spec_order', slit_idx) # 2D model of the tilts, includes construction of QA # NOTE: This also fills in self.all_fit_dict and self.all_trace_dict coeff_out = self.fit_tilts(self.trace_dict, thismask, self.slitcen[:,slit_idx], self.spat_order[slit_idx], self.spec_order[slit_idx], slit_idx, doqa=doqa, show_QA=show, debug=show) self.coeffs[:self.spec_order[slit_idx]+1,:self.spat_order[slit_idx]+1,slit_idx] = coeff_out # TODO: Need a way to assess the success of fit_tilts and # flag the slit if it fails # Tilts are created with the size of the original slitmask, # which corresonds to the same binning as the science # images, trace images, and pixelflats etc. self.tilts = tracewave.fit2tilts(self.slitmask_science.shape, coeff_out, self.par['func2d']) # Save to final image thismask_science = self.slitmask_science == slit_spat self.final_tilts[thismask_science] = self.tilts[thismask_science] if debug: # TODO: Add this to the show method? vmin, vmax = visualization.ZScaleInterval().get_limits(_mstilt) plt.imshow(_mstilt, origin='lower', interpolation='nearest', aspect='auto', vmin=vmin, vmax=vmax) for slit in self.slit_idx: spat = self.all_trace_dict[slit]['tilts_spat'] spec = self.all_trace_dict[slit]['tilts'] spec_fit = self.all_trace_dict[slit]['tilts_fit'] in_fit = self.all_trace_dict[slit]['tot_mask'] not_fit = np.invert(in_fit) & (spec > 0) fit_rej = in_fit & np.invert(self.all_trace_dict[slit]['fit_mask']) fit_keep = in_fit & self.all_trace_dict[slit]['fit_mask'] plt.scatter(spat[not_fit], spec[not_fit], color='C1', marker='.', s=30, lw=0) plt.scatter(spat[fit_rej], spec[fit_rej], color='C3', marker='.', s=30, lw=0) plt.scatter(spat[fit_keep], spec[fit_keep], color='k', marker='.', s=30, lw=0) with_fit = np.invert(np.all(np.invert(fit_keep), axis=0)) for t in range(in_fit.shape[1]): if not with_fit[t]: continue l, r = np.nonzero(in_fit[:,t])[0][[0,-1]] plt.plot(spat[l:r+1,t], spec_fit[l:r+1,t], color='k') plt.show() # Record the Mask bpmtilts = np.zeros_like(self.slits.mask, dtype=self.slits.bitmask.minimum_dtype()) for flag in ['BADTILTCALIB']: bpm = self.slits.bitmask.flagged(self.slits.mask, flag) if np.any(bpm): bpmtilts[bpm] = self.slits.bitmask.turn_on(bpmtilts[bpm], flag) # Build and return DataContainer tilts_dict = {'coeffs':self.coeffs, 'func2d':self.par['func2d'], 'nslit':self.slits.nslits, 'spat_order':self.spat_order, 'spec_order':self.spec_order, 'spat_id':self.slits.spat_id, 'bpmtilts': bpmtilts, 'spat_flexure': self.spat_flexure, 'PYP_SPEC': self.spectrograph.spectrograph} return WaveTilts(**tilts_dict)
def ech_objfind(image, ivar, ordermask, slit_left, slit_righ,inmask=None,plate_scale=0.2,npca=2,ncoeff = 5,min_snr=0.0,nabove_min_snr=0, pca_percentile=20.0,snr_pca=3.0,box_radius=2.0,show_peaks=False,show_fits=False,show_trace=False): if inmask is None: inmask = (ordermask > 0) frameshape = image.shape nspec = frameshape[0] norders = slit_left.shape[1] if isinstance(plate_scale,(float, int)): plate_scale_ord = np.full(norders, plate_scale) # 0.12 binned by 3 spatially for HIRES elif isinstance(plate_scale,(np.ndarray, list, tuple)): if len(plate_scale) == norders: plate_scale_ord = plate_scale elif len(plate_scale) == 1: plate_scale_ord = np.full(norders, plate_scale[0]) else: msgs.error('Invalid size for plate_scale. It must either have one element or norders elements') else: msgs.error('Invalid type for plate scale') specmid = nspec // 2 slit_width = slit_righ - slit_left spec_vec = np.arange(nspec) slit_spec_pos = nspec/2.0 slit_spat_pos = np.zeros((norders, 2)) for iord in range(norders): slit_spat_pos[iord, :] = (np.interp(slit_spec_pos, spec_vec, slit_left[:,iord]), np.interp(slit_spec_pos, spec_vec, slit_righ[:,iord])) # Loop over orders and find objects sobjs = specobjs.SpecObjs() show_peaks=True show_fits=True # ToDo replace orderindx with the true order number here? Maybe not. Clean up slitid and orderindx! for iord in range(norders): msgs.info('Finding objects on slit # {:d}'.format(iord + 1)) thismask = ordermask == (iord + 1) inmask_iord = inmask & thismask specobj_dict = {'setup': 'HIRES', 'slitid': iord + 1, 'scidx': 0,'det': 1, 'objtype': 'science'} sobjs_slit, skymask[thismask], objmask[thismask], proc_list = \ extract.objfind(image, thismask, slit_left[:,iord], slit_righ[:,iord], inmask=inmask_iord,show_peaks=show_peaks, show_fits=show_fits, show_trace=False, specobj_dict = specobj_dict)#, sig_thresh = 3.0) # ToDO make the specobjs _set_item_ work with expressions like this spec[:].orderindx = iord for spec in sobjs_slit: spec.ech_orderindx = iord sobjs.add_sobj(sobjs_slit) nfound = len(sobjs) # Compute the FOF linking length based on the instrument place scale and matching length FOFSEP = 1.0" FOFSEP = 1.0 # separation of FOF algorithm in arcseconds FOF_frac = FOFSEP/(np.median(slit_width)*np.median(plate_scale_ord)) # Feige: made the code also works for only one object found in one order # Run the FOF. We use fake coordinaes fracpos = sobjs.spat_fracpos ra_fake = fracpos/1000.0 # Divide all angles by 1000 to make geometry euclidian dec_fake = 0.0*fracpos if nfound>1: (ingroup, multgroup, firstgroup, nextgroup) = spheregroup(ra_fake, dec_fake, FOF_frac/1000.0) group = ingroup.copy() uni_group, uni_ind = np.unique(group, return_index=True) nobj = len(uni_group) msgs.info('FOF matching found {:d}'.format(nobj) + ' unique objects') elif nfound==1: group = np.zeros(1,dtype='int') uni_group, uni_ind = np.unique(group, return_index=True) nobj = len(group) msgs.warn('Only find one object no FOF matching is needed') gfrac = np.zeros(nfound) for jj in range(nobj): this_group = group == uni_group[jj] gfrac[this_group] = np.median(fracpos[this_group]) uni_frac = gfrac[uni_ind] sobjs_align = sobjs.copy() # Now fill in the missing objects and their traces for iobj in range(nobj): for iord in range(norders): # Is there an object on this order that grouped into the current group in question? on_slit = (group == uni_group[iobj]) & (sobjs_align.ech_orderindx == iord) if not np.any(on_slit): # Add this to the sobjs_align, and assign required tags thisobj = specobjs.SpecObj(frameshape, slit_spat_pos[iord,:], slit_spec_pos, det = sobjs_align[0].det, setup = sobjs_align[0].setup, slitid = (iord + 1), scidx = sobjs_align[0].scidx, objtype=sobjs_align[0].objtype) thisobj.ech_orderindx = iord thisobj.spat_fracpos = uni_frac[iobj] thisobj.trace_spat = slit_left[:,iord] + slit_width[:,iord]*uni_frac[iobj] # new trace thisobj.trace_spec = spec_vec thisobj.spat_pixpos = thisobj.trace_spat[specmid] thisobj.set_idx() # Use the real detections of this objects for the FWHM this_group = group == uni_group[iobj] # Assign to the fwhm of the nearest detected order imin = np.argmin(np.abs(sobjs_align[this_group].ech_orderindx - iord)) thisobj.fwhm = sobjs_align[imin].fwhm thisobj.maskwidth = sobjs_align[imin].maskwidth thisobj.ech_fracpos = uni_frac[iobj] thisobj.ech_group = uni_group[iobj] thisobj.ech_usepca = True sobjs_align.add_sobj(thisobj) group = np.append(group, uni_group[iobj]) gfrac = np.append(gfrac, uni_frac[iobj]) else: # ToDo fix specobjs to get rid of these crappy loops! for spec in sobjs_align[on_slit]: spec.ech_fracpos = uni_frac[iobj] spec.ech_group = uni_group[iobj] spec.ech_usepca = False # Some code to ensure that the objects are sorted in the sobjs_align by fractional position on the order and by order # respectively sobjs_sort = specobjs.SpecObjs() for iobj in range(nobj): this_group = group == uni_group[iobj] this_sobj = sobjs_align[this_group] sobjs_sort.add_sobj(this_sobj[np.argsort(this_sobj.ech_orderindx)]) # Loop over the objects and perform a quick and dirty extraction to assess S/N. varimg = utils.calc_ivar(ivar) flux_box = np.zeros((nspec, norders, nobj)) ivar_box = np.zeros((nspec, norders, nobj)) mask_box = np.zeros((nspec, norders, nobj)) SNR_arr = np.zeros((norders, nobj)) for iobj in range(nobj): for iord in range(norders): indx = (sobjs_sort.ech_group == uni_group[iobj]) & (sobjs_sort.ech_orderindx == iord) spec = sobjs_sort[indx] thismask = ordermask == (iord + 1) inmask_iord = inmask & thismask box_rad_pix = box_radius/plate_scale_ord[iord] flux_tmp = extract.extract_boxcar(image*inmask_iord, spec.trace_spat,box_rad_pix, ycen = spec.trace_spec) var_tmp = extract.extract_boxcar(varimg*inmask_iord, spec.trace_spat,box_rad_pix, ycen = spec.trace_spec) ivar_tmp = utils.calc_ivar(var_tmp) pixtot = extract.extract_boxcar(ivar*0 + 1.0, spec.trace_spat,box_rad_pix, ycen = spec.trace_spec) mask_tmp = (extract.extract_boxcar(ivar*inmask_iord == 0.0, spec.trace_spat,box_rad_pix, ycen = spec.trace_spec) != pixtot) flux_box[:,iord,iobj] = flux_tmp*mask_tmp ivar_box[:,iord,iobj] = np.fmax(ivar_tmp*mask_tmp,0.0) mask_box[:,iord,iobj] = mask_tmp (mean, med_sn, stddev) = sigma_clipped_stats(flux_box[mask_tmp,iord,iobj]*np.sqrt(ivar_box[mask_tmp,iord,iobj]), sigma_lower=5.0,sigma_upper=5.0) SNR_arr[iord,iobj] = med_sn # Purge objects with low SNR and that don't show up in enough orders keep_obj = np.zeros(nobj,dtype=bool) sobjs_trim = specobjs.SpecObjs() uni_group_trim = np.array([],dtype=int) uni_frac_trim = np.array([],dtype=float) for iobj in range(nobj): if (np.sum(SNR_arr[:,iobj] > min_snr) >= nabove_min_snr): keep_obj[iobj] = True ikeep = sobjs_sort.ech_group == uni_group[iobj] sobjs_trim.add_sobj(sobjs_sort[ikeep]) uni_group_trim = np.append(uni_group_trim, uni_group[iobj]) uni_frac_trim = np.append(uni_frac_trim, uni_frac[iobj]) else: msgs.info('Purging object #{:d}'.format(iobj) + ' which does not satisfy min_snr > {:5.2f}'.format(min_snr) + ' on at least nabove_min_snr >= {:d}'.format(nabove_min_snr) + ' orders') nobj_trim = np.sum(keep_obj) if nobj_trim == 0: return specobjs.SpecObjs() SNR_arr_trim = SNR_arr[:,keep_obj] # Do a final loop over objects and make the final decision about which orders will be interpolated/extrapolated by the PCA for iobj in range(nobj_trim): SNR_now = SNR_arr_trim[:,iobj] indx = (sobjs_trim.ech_group == uni_group_trim[iobj]) # PCA interp/extrap if: # (SNR is below pca_percentile of the total SNRs) AND (SNR < snr_pca) # OR # (if this order was not originally traced by the object finding, see above) usepca = ((SNR_now < np.percentile(SNR_now, pca_percentile)) & (SNR_now < snr_pca)) | sobjs_trim[indx].ech_usepca # ToDo fix specobjs to get rid of these crappy loops! for iord, spec in enumerate(sobjs_trim[indx]): spec.ech_usepca = usepca[iord] if usepca[iord]: msgs.info('Using PCA to predict trace for object #{:d}'.format(iobj) + ' on order #{:d}'.format(iord)) sobjs_final = sobjs_trim.copy() # Loop over the objects one by one and adjust/predict the traces npoly_cen = 3 pca_fits = np.zeros((nspec, norders, nobj_trim)) for iobj in range(nobj_trim): igroup = sobjs_final.ech_group == uni_group_trim[iobj] # PCA predict the masked orders which were not traced pca_fits[:,:,iobj] = pca_trace((sobjs_final[igroup].trace_spat).T, usepca = None, npca = npca, npoly_cen = npoly_cen) # usepca = sobjs_final[igroup].ech_usepca, # Perform iterative flux weighted centroiding using new PCA predictions xinit_fweight = pca_fits[:,:,iobj].copy() inmask_now = inmask & (ordermask > 0) xfit_fweight = extract.iter_tracefit(image, xinit_fweight, ncoeff, inmask = inmask_now, show_fits=show_fits) # Perform iterative Gaussian weighted centroiding xinit_gweight = xfit_fweight.copy() xfit_gweight = extract.iter_tracefit(image, xinit_gweight, ncoeff, inmask = inmask_now, gweight=True,show_fits=show_fits) # Assign the new traces for iord, spec in enumerate(sobjs_final[igroup]): spec.trace_spat = xfit_gweight[:,iord] spec.spat_pixpos = spec.trace_spat[specmid] # Set the IDs sobjs_final.set_idx() if show_trace: viewer, ch = ginga.show_image(objminsky*(ordermask > 0)) for iobj in range(nobj_trim): for iord in range(norders): ginga.show_trace(viewer, ch, pca_fits[:,iord, iobj], str(uni_frac[iobj]), color='yellow') for spec in sobjs_trim: color = 'green' if spec.ech_usepca else 'magenta' ginga.show_trace(viewer, ch, spec.trace_spat, spec.idx, color=color) #for spec in sobjs_final: # color = 'red' if spec.ech_usepca else 'green' # ginga.show_trace(viewer, ch, spec.trace_spat, spec.idx, color=color) return sobjs_final
debug = True # Loop on slits for slit in gdslits: msgs.info("Computing flat field image for slit: {:d}".format(slit + 1)) slit_left = tslits_dict['lcen'][:, slit] slit_righ = tslits_dict['rcen'][:, slit] thismask = (tslits_dict['slitpix'] == slit + 1) inmask = None # in the future set this to the bpm sys.exit(-1) pixelflat[thismask], illumflat[thismask], flat_model[thismask] = flat.fit_flat(flatimg, mstilts, thismask, slit_left, slit_righ,inmask=inmask, debug = debug) ginga.show_image(pixelflat,cuts = (0.9,1.1),chname='pixeflat', wcs_match=True, clear=True) ginga.show_image(illumflat,cuts = (0.9,1.1), chname='illumflat', wcs_match=True) ginga.show_image(flatimg,chname='flat', wcs_match=True) ginga.show_image(flat_model,chname='flat_model',wcs_match = True) ''' bkspace = 1.0/nsamp # This is the spatial sampling interval in units of fractional slit width fit_spat = thismask & inmask isrt_spat = np.argsort(ximg[fit_spat]) ximg_fit = ximg[fit_spat][isrt_spat] norm_spec_fit = norm_spec[fit_spat][isrt_spat] norm_spec_ivar = np.ones_like(norm_spec_fit)/(0.03**2) sigrej_illum = 3.0 nfit_spat = np.sum(fit_spat) msgs.info('Fit to flatfield slit illumination function {:}'.format(nfit_spat) + ' pixels')
def spat_flexure_shift(sciimg, slits, debug=False, maxlag=20): """ Calculate a rigid flexure shift in the spatial dimension between the slitmask and the science image. It is *important* to use original=True when defining the slitmask as everything should be relative to the initial slits Otherwise, the WaveTilts could get out of sync with science images Args: sciimg (`numpy.ndarray`_): slits (:class:`pypeit.slittrace.SlitTraceSet`): maxlag (:obj:`int`, optional): Maximum flexure searched for Returns: float: The spatial flexure shift relative to the initial slits """ # Mask -- Includes short slits and those excluded by the user (e.g. ['rdx']['slitspatnum']) slitmask = slits.slit_img(initial=True, exclude_flag=slits.bitmask.exclude_for_flexure) _sciimg = sciimg if slitmask.shape == sciimg.shape \ else arc.resize_mask2arc(slitmask.shape, sciimg) onslits = slitmask > -1 corr_slits = onslits.astype(float).flatten() # Compute mean_sci, med_sci, stddev_sci = stats.sigma_clipped_stats(_sciimg[onslits]) thresh = med_sci + 5.0 * stddev_sci corr_sci = np.fmin(_sciimg.flatten(), thresh) lags, xcorr = utils.cross_correlate(corr_sci, corr_slits, maxlag) xcorr_denom = np.sqrt( np.sum(corr_sci * corr_sci) * np.sum(corr_slits * corr_slits)) xcorr_norm = xcorr / xcorr_denom # TODO -- Generate a QA plot tampl_true, tampl, pix_max, twid, centerr, ww, arc_cont, nsig \ = arc.detect_lines(xcorr_norm, sigdetect=3.0, fit_frac_fwhm=1.5, fwhm=5.0, cont_frac_fwhm=1.0, cont_samp=30, nfind=1, debug=debug) # No peak? -- e.g. data fills the entire detector if len(tampl) == 0: msgs.warn( 'No peak found in spatial flexure. Assuming there is none..') if debug: embed(header='68 of flexure') return 0. # Find the peak xcorr_max = np.interp(pix_max, np.arange(lags.shape[0]), xcorr_norm) lag_max = np.interp(pix_max, np.arange(lags.shape[0]), lags) msgs.info('Spatial flexure measured: {}'.format(lag_max[0])) if debug: plt.figure(figsize=(14, 6)) plt.plot(lags, xcorr_norm, color='black', drawstyle='steps-mid', lw=3, label='x-corr', linewidth=1.0) plt.plot(lag_max[0], xcorr_max[0], 'g+', markersize=6.0, label='peak') plt.title('Best shift = {:5.3f}'.format(lag_max[0]) + ', corr_max = {:5.3f}'.format(xcorr_max[0])) plt.legend() plt.show() #tslits_shift = trace_slits.shift_slits(tslits_dict, lag_max) # Now translate the tilts #slitmask_shift = pixels.tslits2mask(tslits_shift) #slitmask_shift = slits.slit_img(flexure=lag_max[0]) if debug: # Now translate the slits in the tslits_dict all_left_flexure, all_right_flexure, mask = slits.select_edges( flexure=lag_max[0]) gpm = mask == 0 viewer, ch = ginga.show_image(_sciimg) ginga.show_slits(viewer, ch, left_flexure[:, gpm], right_flexure)[:, gpm] #, slits.id) #, args.det) embed(header='83 of flexure.py') #ginga.show_slits(viewer, ch, tslits_shift['slit_left'], tslits_shift['slit_righ']) #ginga.show_slits(viewer, ch, tslits_dict['slit_left'], tslits_dict['slit_righ']) return lag_max[0]
sig_thresh=3.0, inmask=mask_AB, FWHM=FWHM, nperslit=1, trim_edg=(3, 3), show_trace=False, show_peaks=False, show_fits =False) if specobj_slit_pos is not None: specobjs_pos.add_sobj(specobj_slit_pos.specobjs.tolist()) skymask[thismask] = (skymask_pos & skymask_neg) # Show results on ginga if gingashow: # Plot the chi image chi = (diff_AB - residual_img) * np.sqrt(ivar_AB) * (slitpix > 0) * ((edgmask == False) & (mask_AB == True)) viewer, ch = ginga.show_image(chi) ginga.show_slits(viewer, ch, lcen, rcen, slit_ids=None) for islit in range(0, nslits): ginga.show_trace(viewer, ch, specobjs_pos[islit].trace_spat, trc_name=specobjs_pos[islit].idx, color='blue') ginga.show_trace(viewer, ch, specobjs_neg[islit].trace_spat, trc_name=specobjs_neg[islit].idx, color='orange') # Boxcar extraction from pypeit.core.extract import extract_boxcar outmask = (slitpix > 0) * ((edgmask == False) & (mask_AB == True)) box_rad = 8.0 # ToDo -- Check for indexes in islit [0-based or 1-based?] for islit in range(1, nslits + 1): # Positive trace
def main(args): # List only? if args.list: hdu = fits.open(args.file) hdu.info() return # Load it up spec2DObj = spec2dobj.Spec2DObj.from_file(args.file, args.det) # Setup for PYPIT imports msgs.reset(verbosity=2) # Init # TODO: get_dnum needs to be deprecated... sdet = get_dnum(args.det, prefix=False) # if not os.path.exists(mdir): # mdir_base = os.path.join(os.getcwd(), os.path.basename(mdir)) # msgs.warn('Master file dir: {0} does not exist. Using {1}'.format(mdir, mdir_base)) # mdir=mdir_base # Slits # slits_key = '{0}_{1:02d}'.format(spec2DObj.head0['TRACMKEY'], args.det) # slit_file = os.path.join(mdir, masterframe.construct_file_name(slittrace.SlitTraceSet, slits_key)) # slits = slittrace.SlitTraceSet.from_file(slit_file) # Grab the slit edges slits = spec2DObj.slits if spec2DObj.sci_spat_flexure is not None: msgs.info("Offseting slits by {}".format(spec2DObj.sci_spat_flexure)) all_left, all_right, mask = slits.select_edges( flexure=spec2DObj.sci_spat_flexure) # TODO -- This may be too restrictive, i.e. ignore BADFLTCALIB?? gpm = mask == 0 left = all_left[:, gpm] right = all_right[:, gpm] slid_IDs = spec2DObj.slits.slitord_id[gpm] bitMask = ImageBitMask() # Object traces from spec1d file spec1d_file = args.file.replace('spec2d', 'spec1d') if os.path.isfile(spec1d_file): sobjs = specobjs.SpecObjs.from_fitsfile(spec1d_file) else: sobjs = None msgs.warn('Could not find spec1d file: {:s}'.format(spec1d_file) + msgs.newline() + ' No objects were extracted.') ginga.connect_to_ginga(raise_err=True, allow_new=True) # Now show each image to a separate channel # Show the bitmask? mask_in = None if args.showmask: viewer, ch = ginga.show_image(spec2DObj.bpmmask, chname="BPM", waveimg=spec2DObj.waveimg, clear=True) #bpm, crmask, satmask, minmask, offslitmask, nanmask, ivar0mask, ivarnanmask, extractmask \ # SCIIMG image = spec2DObj.sciimg # Processed science image mean, med, sigma = sigma_clipped_stats(image[spec2DObj.bpmmask == 0], sigma_lower=5.0, sigma_upper=5.0) cut_min = mean - 1.0 * sigma cut_max = mean + 4.0 * sigma chname_skysub = 'sciimg-det{:s}'.format(sdet) # Clear all channels at the beginning viewer, ch = ginga.show_image(image, chname=chname_skysub, waveimg=spec2DObj.waveimg, clear=True) if sobjs is not None: show_trace(sobjs, args.det, viewer, ch) ginga.show_slits(viewer, ch, left, right, slit_ids=slid_IDs) # SKYSUB if args.ignore_extract_mask: # TODO -- Is there a cleaner way to do this? gpm = (spec2DObj.bpmmask == 0) | (spec2DObj.bpmmask == 2** bitMask.bits['EXTRACT']) else: gpm = spec2DObj.bpmmask == 0 image = (spec2DObj.sciimg - spec2DObj.skymodel ) * gpm #(spec2DObj.mask == 0) # sky subtracted image mean, med, sigma = sigma_clipped_stats(image[spec2DObj.bpmmask == 0], sigma_lower=5.0, sigma_upper=5.0) cut_min = mean - 1.0 * sigma cut_max = mean + 4.0 * sigma chname_skysub = 'skysub-det{:s}'.format(sdet) # Clear all channels at the beginning # TODO: JFH For some reason Ginga crashes when I try to put cuts in here. viewer, ch = ginga.show_image( image, chname=chname_skysub, waveimg=spec2DObj.waveimg, bitmask=bitMask, mask=mask_in) #, cuts=(cut_min, cut_max),wcs_match=True) if not args.removetrace and sobjs is not None: show_trace(sobjs, args.det, viewer, ch) ginga.show_slits(viewer, ch, left, right, slit_ids=slid_IDs) # SKRESIDS chname_skyresids = 'sky_resid-det{:s}'.format(sdet) image = (spec2DObj.sciimg - spec2DObj.skymodel) * np.sqrt( spec2DObj.ivarmodel) * (spec2DObj.bpmmask == 0) # sky residual map viewer, ch = ginga.show_image(image, chname_skyresids, waveimg=spec2DObj.waveimg, cuts=(-5.0, 5.0), bitmask=bitMask, mask=mask_in) if not args.removetrace and sobjs is not None: show_trace(sobjs, args.det, viewer, ch) ginga.show_slits(viewer, ch, left, right, slit_ids=slid_IDs) # RESIDS chname_resids = 'resid-det{:s}'.format(sdet) # full model residual map image = (spec2DObj.sciimg - spec2DObj.skymodel - spec2DObj.objmodel ) * np.sqrt(spec2DObj.ivarmodel) * (spec2DObj.bpmmask == 0) viewer, ch = ginga.show_image(image, chname=chname_resids, waveimg=spec2DObj.waveimg, cuts=(-5.0, 5.0), bitmask=bitMask, mask=mask_in) if not args.removetrace and sobjs is not None: show_trace(sobjs, args.det, viewer, ch) ginga.show_slits(viewer, ch, left, right, slit_ids=slid_IDs) # After displaying all the images sync up the images with WCS_MATCH shell = viewer.shell() out = shell.start_global_plugin('WCSMatch') out = shell.call_global_plugin_method('WCSMatch', 'set_reference_channel', [chname_resids], {}) if args.embed: embed()
def ech_objfind(image, ivar, ordermask, slit_left, slit_righ, inmask=None, plate_scale=0.2, npca=2, ncoeff=5, min_snr=0.0, nabove_min_snr=0, pca_percentile=20.0, snr_pca=3.0, box_radius=2.0, show_peaks=False, show_fits=False, show_trace=False): if inmask is None: inmask = (ordermask > 0) frameshape = image.shape nspec = frameshape[0] norders = slit_left.shape[1] if isinstance(plate_scale, (float, int)): plate_scale_ord = np.full( norders, plate_scale) # 0.12 binned by 3 spatially for HIRES elif isinstance(plate_scale, (np.ndarray, list, tuple)): if len(plate_scale) == norders: plate_scale_ord = plate_scale elif len(plate_scale) == 1: plate_scale_ord = np.full(norders, plate_scale[0]) else: msgs.error( 'Invalid size for plate_scale. It must either have one element or norders elements' ) else: msgs.error('Invalid type for plate scale') specmid = nspec // 2 slit_width = slit_righ - slit_left spec_vec = np.arange(nspec) slit_spec_pos = nspec / 2.0 slit_spat_pos = np.zeros((norders, 2)) for iord in range(norders): slit_spat_pos[iord, :] = (np.interp(slit_spec_pos, spec_vec, slit_left[:, iord]), np.interp(slit_spec_pos, spec_vec, slit_righ[:, iord])) # Loop over orders and find objects sobjs = specobjs.SpecObjs() show_peaks = True show_fits = True # ToDo replace orderindx with the true order number here? Maybe not. Clean up slitid and orderindx! for iord in range(norders): msgs.info('Finding objects on slit # {:d}'.format(iord + 1)) thismask = ordermask == (iord + 1) inmask_iord = inmask & thismask specobj_dict = { 'setup': 'HIRES', 'slitid': iord + 1, 'scidx': 0, 'det': 1, 'objtype': 'science' } sobjs_slit, skymask[thismask], objmask[thismask], proc_list = \ extract.objfind(image, thismask, slit_left[:,iord], slit_righ[:,iord], inmask=inmask_iord,show_peaks=show_peaks, show_fits=show_fits, show_trace=False, specobj_dict = specobj_dict)#, sig_thresh = 3.0) # ToDO make the specobjs _set_item_ work with expressions like this spec[:].orderindx = iord for spec in sobjs_slit: spec.ech_orderindx = iord sobjs.add_sobj(sobjs_slit) nfound = len(sobjs) # Compute the FOF linking length based on the instrument place scale and matching length FOFSEP = 1.0" FOFSEP = 1.0 # separation of FOF algorithm in arcseconds FOF_frac = FOFSEP / (np.median(slit_width) * np.median(plate_scale_ord)) # Feige: made the code also works for only one object found in one order # Run the FOF. We use fake coordinaes fracpos = sobjs.spat_fracpos ra_fake = fracpos / 1000.0 # Divide all angles by 1000 to make geometry euclidian dec_fake = 0.0 * fracpos if nfound > 1: (ingroup, multgroup, firstgroup, nextgroup) = spheregroup(ra_fake, dec_fake, FOF_frac / 1000.0) group = ingroup.copy() uni_group, uni_ind = np.unique(group, return_index=True) nobj = len(uni_group) msgs.info('FOF matching found {:d}'.format(nobj) + ' unique objects') elif nfound == 1: group = np.zeros(1, dtype='int') uni_group, uni_ind = np.unique(group, return_index=True) nobj = len(group) msgs.warn('Only find one object no FOF matching is needed') gfrac = np.zeros(nfound) for jj in range(nobj): this_group = group == uni_group[jj] gfrac[this_group] = np.median(fracpos[this_group]) uni_frac = gfrac[uni_ind] sobjs_align = sobjs.copy() # Now fill in the missing objects and their traces for iobj in range(nobj): for iord in range(norders): # Is there an object on this order that grouped into the current group in question? on_slit = (group == uni_group[iobj]) & (sobjs_align.ech_orderindx == iord) if not np.any(on_slit): # Add this to the sobjs_align, and assign required tags thisobj = specobjs.SpecObj(frameshape, slit_spat_pos[iord, :], slit_spec_pos, det=sobjs_align[0].det, setup=sobjs_align[0].setup, slitid=(iord + 1), scidx=sobjs_align[0].scidx, objtype=sobjs_align[0].objtype) thisobj.ech_orderindx = iord thisobj.spat_fracpos = uni_frac[iobj] thisobj.trace_spat = slit_left[:, iord] + slit_width[:, iord] * uni_frac[ iobj] # new trace thisobj.trace_spec = spec_vec thisobj.spat_pixpos = thisobj.trace_spat[specmid] thisobj.set_idx() # Use the real detections of this objects for the FWHM this_group = group == uni_group[iobj] # Assign to the fwhm of the nearest detected order imin = np.argmin( np.abs(sobjs_align[this_group].ech_orderindx - iord)) thisobj.fwhm = sobjs_align[imin].fwhm thisobj.maskwidth = sobjs_align[imin].maskwidth thisobj.ech_fracpos = uni_frac[iobj] thisobj.ech_group = uni_group[iobj] thisobj.ech_usepca = True sobjs_align.add_sobj(thisobj) group = np.append(group, uni_group[iobj]) gfrac = np.append(gfrac, uni_frac[iobj]) else: # ToDo fix specobjs to get rid of these crappy loops! for spec in sobjs_align[on_slit]: spec.ech_fracpos = uni_frac[iobj] spec.ech_group = uni_group[iobj] spec.ech_usepca = False # Some code to ensure that the objects are sorted in the sobjs_align by fractional position on the order and by order # respectively sobjs_sort = specobjs.SpecObjs() for iobj in range(nobj): this_group = group == uni_group[iobj] this_sobj = sobjs_align[this_group] sobjs_sort.add_sobj(this_sobj[np.argsort(this_sobj.ech_orderindx)]) # Loop over the objects and perform a quick and dirty extraction to assess S/N. varimg = utils.calc_ivar(ivar) flux_box = np.zeros((nspec, norders, nobj)) ivar_box = np.zeros((nspec, norders, nobj)) mask_box = np.zeros((nspec, norders, nobj)) SNR_arr = np.zeros((norders, nobj)) for iobj in range(nobj): for iord in range(norders): indx = (sobjs_sort.ech_group == uni_group[iobj]) & (sobjs_sort.ech_orderindx == iord) spec = sobjs_sort[indx] thismask = ordermask == (iord + 1) inmask_iord = inmask & thismask box_rad_pix = box_radius / plate_scale_ord[iord] flux_tmp = extract.extract_boxcar(image * inmask_iord, spec.trace_spat, box_rad_pix, ycen=spec.trace_spec) var_tmp = extract.extract_boxcar(varimg * inmask_iord, spec.trace_spat, box_rad_pix, ycen=spec.trace_spec) ivar_tmp = utils.calc_ivar(var_tmp) pixtot = extract.extract_boxcar(ivar * 0 + 1.0, spec.trace_spat, box_rad_pix, ycen=spec.trace_spec) mask_tmp = (extract.extract_boxcar(ivar * inmask_iord == 0.0, spec.trace_spat, box_rad_pix, ycen=spec.trace_spec) != pixtot) flux_box[:, iord, iobj] = flux_tmp * mask_tmp ivar_box[:, iord, iobj] = np.fmax(ivar_tmp * mask_tmp, 0.0) mask_box[:, iord, iobj] = mask_tmp (mean, med_sn, stddev) = sigma_clipped_stats( flux_box[mask_tmp, iord, iobj] * np.sqrt(ivar_box[mask_tmp, iord, iobj]), sigma_lower=5.0, sigma_upper=5.0) SNR_arr[iord, iobj] = med_sn # Purge objects with low SNR and that don't show up in enough orders keep_obj = np.zeros(nobj, dtype=bool) sobjs_trim = specobjs.SpecObjs() uni_group_trim = np.array([], dtype=int) uni_frac_trim = np.array([], dtype=float) for iobj in range(nobj): if (np.sum(SNR_arr[:, iobj] > min_snr) >= nabove_min_snr): keep_obj[iobj] = True ikeep = sobjs_sort.ech_group == uni_group[iobj] sobjs_trim.add_sobj(sobjs_sort[ikeep]) uni_group_trim = np.append(uni_group_trim, uni_group[iobj]) uni_frac_trim = np.append(uni_frac_trim, uni_frac[iobj]) else: msgs.info( 'Purging object #{:d}'.format(iobj) + ' which does not satisfy min_snr > {:5.2f}'.format(min_snr) + ' on at least nabove_min_snr >= {:d}'.format(nabove_min_snr) + ' orders') nobj_trim = np.sum(keep_obj) if nobj_trim == 0: return specobjs.SpecObjs() SNR_arr_trim = SNR_arr[:, keep_obj] # Do a final loop over objects and make the final decision about which orders will be interpolated/extrapolated by the PCA for iobj in range(nobj_trim): SNR_now = SNR_arr_trim[:, iobj] indx = (sobjs_trim.ech_group == uni_group_trim[iobj]) # PCA interp/extrap if: # (SNR is below pca_percentile of the total SNRs) AND (SNR < snr_pca) # OR # (if this order was not originally traced by the object finding, see above) usepca = ((SNR_now < np.percentile(SNR_now, pca_percentile)) & (SNR_now < snr_pca)) | sobjs_trim[indx].ech_usepca # ToDo fix specobjs to get rid of these crappy loops! for iord, spec in enumerate(sobjs_trim[indx]): spec.ech_usepca = usepca[iord] if usepca[iord]: msgs.info('Using PCA to predict trace for object #{:d}'.format( iobj) + ' on order #{:d}'.format(iord)) sobjs_final = sobjs_trim.copy() # Loop over the objects one by one and adjust/predict the traces npoly_cen = 3 pca_fits = np.zeros((nspec, norders, nobj_trim)) for iobj in range(nobj_trim): igroup = sobjs_final.ech_group == uni_group_trim[iobj] # PCA predict the masked orders which were not traced pca_fits[:, :, iobj] = pca_trace((sobjs_final[igroup].trace_spat).T, usepca=None, npca=npca, npoly_cen=npoly_cen) # usepca = sobjs_final[igroup].ech_usepca, # Perform iterative flux weighted centroiding using new PCA predictions xinit_fweight = pca_fits[:, :, iobj].copy() inmask_now = inmask & (ordermask > 0) xfit_fweight = extract.iter_tracefit(image, xinit_fweight, ncoeff, inmask=inmask_now, show_fits=show_fits) # Perform iterative Gaussian weighted centroiding xinit_gweight = xfit_fweight.copy() xfit_gweight = extract.iter_tracefit(image, xinit_gweight, ncoeff, inmask=inmask_now, gweight=True, show_fits=show_fits) # Assign the new traces for iord, spec in enumerate(sobjs_final[igroup]): spec.trace_spat = xfit_gweight[:, iord] spec.spat_pixpos = spec.trace_spat[specmid] # Set the IDs sobjs_final.set_idx() if show_trace: viewer, ch = ginga.show_image(objminsky * (ordermask > 0)) for iobj in range(nobj_trim): for iord in range(norders): ginga.show_trace(viewer, ch, pca_fits[:, iord, iobj], str(uni_frac[iobj]), color='yellow') for spec in sobjs_trim: color = 'green' if spec.ech_usepca else 'magenta' ginga.show_trace(viewer, ch, spec.trace_spat, spec.idx, color=color) #for spec in sobjs_final: # color = 'red' if spec.ech_usepca else 'green' # ginga.show_trace(viewer, ch, spec.trace_spat, spec.idx, color=color) return sobjs_final
def process(self, par, bpm=bpm, flatimages=None, bias=None, slits=None, debug=False, dark=None): """ Process the image Note: The processing step order is currently 'frozen' as is. We may choose to allow optional ordering Here are the allowed steps, in the order they will be applied: subtract_overscan -- Analyze the overscan region and subtract from the image trim -- Trim the image down to the data (i.e. remove the overscan) orient -- Orient the image in the PypeIt orientation (spec, spat) with blue to red going down to up subtract_bias -- Subtract a bias image apply_gain -- Convert to counts, amp by amp flatten -- Divide by the pixel flat and (if provided) the illumination flat extras -- Generate the RN2 and IVAR images crmask -- Generate a CR mask Args: par (:class:`pypeit.par.pypeitpar.ProcessImagesPar`): Parameters that dictate the processing of the images. See :class:`pypeit.par.pypeitpar.ProcessImagesPar` for the defaults. bpm (`numpy.ndarray`_, optional): flatimages (:class:`pypeit.flatfield.FlatImages`): bias (`numpy.ndarray`_, optional): Bias image slits (:class:`pypeit.slittrace.SlitTraceSet`, optional): Used to calculate spatial flexure between the image and the slits Returns: :class:`pypeit.images.pypeitimage.PypeItImage`: """ self.par = par self._bpm = bpm # Get started # Standard order # -- May need to allow for other order some day.. if par['use_overscan']: self.subtract_overscan() if par['trim']: self.trim() if par['orient']: self.orient() if par['use_biasimage']: # Bias frame, if it exists, is *not* trimmed nor oriented self.subtract_bias(bias) if par['use_darkimage']: # Dark frame, if it exists, is TODO:: check: trimmed, oriented (and oscan/bias subtracted?) self.subtract_dark(dark) if par['apply_gain']: self.apply_gain() # This needs to come after trim, orient # Calculate flexure -- May not be used, but always calculated when slits are provided if slits is not None and self.par['spat_flexure_correct']: self.spat_flexure_shift = flexure.spat_flexure_shift( self.image, slits) # Generate the illumination flat, as needed illum_flat = None if self.par['use_illumflat']: if flatimages is None: msgs.error( "Cannot illumflatten, no such image generated. Add one or more illumflat images to your PypeIt file!!" ) if slits is None: msgs.error("Need to provide slits to create illumination flat") illum_flat = flatimages.fit2illumflat( slits, flexure_shift=self.spat_flexure_shift) if debug: from pypeit import ginga left, right = slits.select_edges( flexure=self.spat_flexure_shift) viewer, ch = ginga.show_image(illum_flat, chname='illum_flat') ginga.show_slits(viewer, ch, left, right) # , slits.id) # orig_image = self.image.copy() viewer, ch = ginga.show_image(orig_image, chname='orig_image') ginga.show_slits(viewer, ch, left, right) # , slits.id) # Flat field -- We cannot do illumination flat without a pixel flat (yet) if self.par['use_pixelflat'] or self.par['use_illumflat']: if flatimages is None or flatimages.pixelflat is None: msgs.error("Flat fielding desired but not generated/provided.") else: self.flatten(flatimages.pixelflat, illum_flat=illum_flat, bpm=self.bpm) # Fresh BPM bpm = self.spectrograph.bpm(self.filename, self.det, shape=self.image.shape) # Extras self.build_rn2img() self.build_ivar() # Generate a PypeItImage pypeitImage = pypeitimage.PypeItImage( self.image, ivar=self.ivar, rn2img=self.rn2img, bpm=bpm, detector=self.detector, spat_flexure=self.spat_flexure_shift, PYP_SPEC=self.spectrograph.spectrograph) pypeitImage.rawheadlist = self.headarr pypeitImage.process_steps = [ key for key in self.steps.keys() if self.steps[key] ] # Mask(s) if par['mask_cr']: pypeitImage.build_crmask(self.par) # nonlinear_counts = self.spectrograph.nonlinear_counts( self.detector, apply_gain=self.par['apply_gain']) # Build pypeitImage.build_mask(saturation=nonlinear_counts) # Return return pypeitImage
from pypeit import ginga from astropy.io import fits from pypeit.spectrographs import keck_lris lowrdx_path = '/Users/joe/pypeit_vs_lowredux/c17_60L/Red400/' pypeit_path = '/Users/joe/python/PypeIt-development-suite/REDUX_OUT/Keck_LRIS_red/multi_400_8500_d560/' rawpath = '/Users/joe/python/PypeIt-development-suite/RAW_DATA/Keck_LRIS_red/multi_400_8500_d560/' flatfile = rawpath + 'r170320_2057.fits' flatfile_lowrdx = lowrdx_path + 'pixflat-r170320_2057.fits' flatfile_pypeit = pypeit_path + 'MF_keck_lris_red/MasterFlatField_A_01_aa.fits' flat, _, _ = keck_lris.read_lris(flatfile, det = 1, TRIM=True) hdu = fits.open(flatfile_lowrdx) flat_lowrdx = hdu[0].data flat_lowrdx = flat_lowrdx[:,0:1024] hdu = fits.open(flatfile_pypeit) flat_pypeit = hdu[0].data cuts = (0.8,1.5) viewer, ch = ginga.show_image(flat_lowrdx, chname='LOWREDUX',cuts = cuts) viewer, ch = ginga.show_image(flat_pypeit, chname='PYPEIT',cuts = cuts) viewer, ch = ginga.show_image(flat, chname='FLAT')
def show(self, attr='edges', pstep=50, extras=None): """ Display an image or spectrum in TraceSlits Args: attr (str, optional): 'edges' -- Show the mstrace image and the edges 'binarr' -- Show the binarr image 'edgearr' -- Show the edgearr image 'siglev' -- Show the Sobolev image 'traces' -- Show the traces at an intermediate stage 'refined_edges' -- Show the traces at an intermediate stage in _pca_refine() 'xset' -- Check the output from the trace crude extras: anything Extra bits and pieces needed for plotting """ if attr == 'edges': viewer, ch = ginga.show_image(self.mstrace, chname='edges') if self.slit_left is not None: ginga.show_slits(viewer, ch, self.slit_left, self.slit_righ, slit_ids=(np.arange(self.slit_left.shape[1]).astype(int) + 1).tolist(), pstep=pstep) elif attr == 'binarr': ginga.show_image(self.binarr, chname='binarr') elif attr == 'xset': viewer, ch = ginga.show_image(self.mstrace, chname='slit_xset') color = dict(left='green', right='red') viewer, ch = ginga.show_image(self.mstrace) for side in ['left', 'right']: for kk in range(self.tc_dict[side]['xset'].shape[1]): ginga.show_trace(viewer, ch, self.tc_dict[side]['xset'][:, kk], trc_name=side+ str(kk),color=color[side]) elif attr == 'refined_edges': # Used in _pca_refine() edges_dict = extras # color = dict(left='green', right='red') viewer, ch = ginga.show_image(self.mstrace, chname='refined_edges') if edges_dict['show'] == 'both': for side in ['left', 'right']: for kk in range(edges_dict[side]['nstart']): ginga.show_trace(viewer, ch, edges_dict[side]['trace'][:, kk], trc_name=side + str(kk), color=color[side]) else: for side in [edges_dict['show']]: for kk in range(edges_dict[side]['nstart']): ginga.show_trace(viewer, ch, edges_dict[side]['trace'][:, kk], trc_name='left_' + str(kk), color=color[side]) elif attr == 'traces': viewer, ch = ginga.show_image(self.mstrace, chname='slit_traces') color = dict(left='green', right='red') viewer, ch = ginga.show_image(self.mstrace) for side in ['left', 'right']: for kk in range(self.tc_dict[side]['traces'].shape[1]): ginga.show_trace(viewer, ch, self.tc_dict[side]['traces'][:, kk], trc_name=side+ str(kk),color=color[side], pstep=pstep) elif attr == 'edgearr': if np.min(self.edgearr) == -1: # Ungrouped tmp = self.mstrace.copy() # Left edges left = self.edgearr == -1 tmp[left] = -99999. # Right edges right = self.edgearr == 1 tmp[right] = 99999. viewer, ch = ginga.show_image(tmp, chname='edgearr') else: # Grouped viewer, ch = ginga.show_image(self.siglev, chname='edgearr') # Traces all_uni = np.unique(self.edgearr[self.edgearr != 0]) for uni in all_uni: # Color clr = 'green' if uni < 0 else 'red' # Do it tidx = np.where(self.edgearr == uni) ginga.show_trace(viewer, ch, tidx[1], trc_name=str(uni), yval=tidx[0], color=clr) elif attr == 'siglev': ginga.show_image(self.siglev, chname='siglev')
def show(self, attr, image=None, align_traces=None, chname=None, slits=False, clear=False): """ Show one of the class internals Parameters ---------- attr : str image - plot the master align frame image : ndarray Image to be plotted (i.e. the master align frame) align_traces : list The align traces chname : str The channel name sent to ginga slits : bool Overplot the slit edges? clear : bool Clear the plotting window in ginga? Returns: """ if attr == 'image': ch_name = chname if chname is not None else 'align_traces' self.viewer, self.channel = ginga.show_image(image, chname=ch_name, clear=clear, wcs_match=False) elif attr == 'overplot': pass else: msgs.warn("Not an option for show") if align_traces is not None and self.viewer is not None: for spec in align_traces: color = 'magenta' if spec.hand_extract_flag else 'orange' ginga.show_trace(self.viewer, self.channel, spec.TRACE_SPAT, trc_name="", color=color) if slits: if self.tslits_dict is not None and self.viewer is not None: slit_ids = [ edgetrace.get_slitid(image.shape, self.tslits_dict['slit_left'], self.tslits_dict['slit_righ'], ii)[0] for ii in range(self.tslits_dict['slit_left'].shape[1]) ] ginga.show_slits(self.viewer, self.channel, self.tslits_dict['slit_left'], self.tslits_dict['slit_righ'], slit_ids) return