Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extreme values in wavelength solution of single order #978

Open
JacobLuhn opened this issue Dec 5, 2024 · 2 comments
Open

Extreme values in wavelength solution of single order #978

JacobLuhn opened this issue Dec 5, 2024 · 2 comments

Comments

@JacobLuhn
Copy link

Seeing some files where the wavelength solution appears to be going to fairly extreme values. Two plots attached showing that this sometimes is seen in all traces but sometimes just a single trace
bad_order_12_trace_3
bad_order_13_all

The second one above does not pass L1 QC to check that the WLS is monotonic, so it is already flagged there. The first file is also flagged for being non-monotonic (since wavelength should decrease with increasing pixel number). The underlying issue that causes this is not something I'm set up to diagnose or fix, but I will aim to make the plots above part of the QLP for diagnostic purposes there. I also have some simple bare bones code as the start of a QC check for testing that the start and end values of each order are monotonic from order to order. I'm going to work on getting more set up with the pipeline to try to get the QLP plot and QC function implemented

@JacobLuhn
Copy link
Author

Script to produce the plots above:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from astropy.io import fits

def get_all_orders(chip):
    """This function returns the number of orders for the specified chip

    Args:
        chip (str): can be either "GREEN" or "RED"

    Returns:
        ndarray: arange array of appropriate length for the specified chip
    """
    
    if chip == "GREEN":
        norders = 35
    elif chip == "RED":
        norders = 32

    return np.arange(norders)

def get_colors(chip,orders):
    """This function creates an evenly spaced colormap for either the green or red chip,
    depending on the number of orders you want. 'start' and 'stop' values are preset to 
    leave a slight gap in the middle of the RdYlGn colormap so that the green chip orders 
    stay more green and the red chip orders stay more red

    Args:
        chip (str): can be either "GREEN" or "RED"
        orders (ndarray): array containing 0-indexed orders you want to map to colors

    Returns:
        ndarray: array of color values corresponding to each order in 'orders'
    """

    colormap = plt.get_cmap('RdYlGn')

    if chip == "GREEN":
        start = 1
        stop = 0.65
    elif chip == "RED":
        start = 0.35
        stop = 0.0
    colors=[colormap(k) for k in np.linspace(start,stop,num=len(orders))]
    return colors 

def wls_qc_plot(L1_filename, outfile="wls_qc_plot.png"):
    """Plots a summary quality control plot for the wavelength solution for each trace
    of a specified L1 file. The resulting plot is saved to the specified outfile

    Args:
        L1_filename (str): L1 file to plot the wls for
        outfile (str, optional): Filename for the saved plot. Defaults to "wls_qc_plot.png".
    """

    # Green chip colormapping
    chip = "GREEN"
    gr_orders = get_all_orders(chip)
    gr_colors = get_colors(chip,gr_orders)

    # Red chip colormapping
    chip = "RED"
    rd_orders = get_all_orders(chip)+len(gr_orders)
    rd_colors = get_colors(chip,rd_orders)

    # Concatenate green and red and reset default plot color cycling
    orders = np.concatenate((gr_orders,rd_orders))
    colors = np.concatenate((gr_colors,rd_colors))
    plt.style.use('dark_background')
    mpl.rcParams['axes.prop_cycle'] = mpl.cycler(color=colors)
    

    # Read in each trace
    norders = len(orders)
    npix = 4080
    ntrace = 3
    wv = np.zeros((norders,npix,ntrace))

    for i in np.arange(ntrace):
        trace = i+1
        wv[gr_orders,:,i] = fits.getdata(L1_filename,"GREEN_SCI_WAVE"+str(trace))
        wv[rd_orders,:,i] = fits.getdata(L1_filename,"RED_SCI_WAVE"+str(trace))
        
    # Plot the wls
    fig, axs = plt.subplots(1,ntrace, figsize=(15,4))

    for i,ax in enumerate(axs):
        ax.plot(wv[:,:,i].T)
        ax.set_title("Trace "+str(i+1),fontsize=10)
        ax.set_ylim(4400,8800)
        ax.set_facecolor("#181818")

    fig.suptitle(str(L1_filename))
    plt.savefig(outfile,dpi=300,bbox_inches='tight',facecolor="#1F1F1F")

@JacobLuhn
Copy link
Author

A quick initial function for a QC check that checks that start and ends of the orders increase monotonically from order to order:

def wls_orderwise_monotonic_check(fits_filename):
    extensions = [p + s for p in ["GREEN_", "RED_"]
                    for s in ["SCI_WAVE1", "SCI_WAVE2", "SCI_WAVE3", "SKY_WAVE", "CAL_WAVE"]]
    
    def isMonotonic(array):
        return np.all(array[:-1] <= array[1:])

    QCPass = True

    for ext in extensions:

        wls2d = fits.getdata(fits_filename,ext)
        order_mins = np.nanmin(wls2d,axis=1)
        order_maxs = np.nanmax(wls2d,axis=1)

        if not isMonotonic(order_mins) or not isMonotonic(order_maxs):
            QCPass = False
        #if not isMonotonic(order_maxs):
        #    QCPass = False

    return QCPass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant