Exemple #1
0
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")
Exemple #2
0
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)
Exemple #3
0
    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)
Exemple #4
0
 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')
Exemple #5
0
 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
Exemple #7
0
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)
Exemple #8
0
    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")
Exemple #9
0
    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)
Exemple #10
0
    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)
Exemple #11
0
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)
Exemple #12
0
    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)
Exemple #13
0
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))
Exemple #14
0
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")
Exemple #15
0
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)
Exemple #16
0
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
Exemple #17
0
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()
Exemple #18
0
    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]
Exemple #19
0
    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)
Exemple #20
0
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')
Exemple #21
0
    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')
Exemple #24
0
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
Exemple #26
0
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
Exemple #28
0
    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')

Exemple #30
0
    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')
Exemple #31
0
    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