Example #1
0
def compute_lincor_model(hdu, pix_x, pix_y, ndegree=3):
    """
    Compute the lineary correction model

    Parameters
    ----------
    hdu : astropy.fits.hdu
        header data unit

    pix_x, pix_y: int
        x, y pixel coordiates

    Returns
    -------
    cormod : astropy.modeling.model
        model the linearity correction with x = measured DN
    """
    # for fitting
    x = []
    y = []

    # get all the diffs
    for k in range(nints):
        gnum, ydata = get_ramp(hdu, pix_x, pix_y, k)
        ggnum, gdata, aveDN, diffDN = get_good_ramp(gnum, ydata)

        # accumulate data
        x.append(aveDN)
        y.append(diffDN)

        # find the ramp that spans the largest range of DN
        # and save some info -> needed for creating the correction
        # if (gdata.max() - gdata.min()) > mm_delta:
        #    mm_delta = gdata.max() - gdata.min()
        if k == 3:
            max_ramp_k = k
            # max_ramp_gdata = gdata
            max_ramp_aveDN = aveDN

    # fit the aveDN versus diffDN combined data from all integrations
    x = np.concatenate(x)
    y = np.concatenate(y)
    mod = fit_diffs(x, y, ndegree=ndegree - 1)

    # determine the startDN for all ramps (all not actually needed)
    startDNvals = np.arange(0.0, 20000.0, 200.0)
    chival = np.zeros((nints, len(startDNvals)))
    ints = range(nints)
    for i, startDN in enumerate(startDNvals):
        (DN_exp, cor, cor_mod) = calc_lincor(mod[1],
                                             max_ramp_aveDN,
                                             startDN,
                                             ndegree=ndegree)
        for k in ints:
            gnum, ydata = get_ramp(hdu, pix_x, pix_y, k)
            ggnum, gdata, aveDN, diffDN = get_good_ramp(gnum, ydata)
            # correct the ramps
            ycor = cor_mod(gdata)
            gdata_cor = gdata * ycor
            # calculate the chisqr for each integration set of differences
            # from the expected flat line
            diffDN = np.diff(gdata_cor)
            aveDN = 0.5 * (gdata[:-1] + gdata[1:])
            cindxs, = np.where(aveDN > 10000.0)
            chival[k, i] = np.sum((diffDN[aveDN > 15000.0] - mod[1].c0)**2)

    minindx = np.zeros((nints), dtype=int)
    for k in ints[1:]:
        minindx[k] = np.argmin(chival[k, :])

    # only use the startDN from one ramp
    startDN = startDNvals[minindx[max_ramp_k]]

    # get the correction
    (DN_exp, cor, cor_mod) = calc_lincor(mod[1], max_ramp_aveDN, startDN)

    return cor_mod
            # plot the 2pt diffs versus average DN
            # ax[1].plot(aveDN, diffDN, label=f"Int #{k+1}", color=pcol[k])

            # if k == 0:
            #    ax[1].set_ylim(0.9 * min(diffDN), 1.4 * max(diffDN))

            # accumulate data for fitting
            x.append(aveDN)
            y.append(diffDN)

        if z == 0:
            # fit the aveDN versus diffDN combined data from all integrations
            # e.g., derive the non-linearity correction
            x = np.concatenate(x)
            y = np.concatenate(y)
            mod = fit_diffs(x, y, noexp=noexp)
            if noexp:
                polymod = mod
            else:
                polymod = mod[2]
            lincormod = polymod

        # more plots
        ints = range(nints)

        # setup ramp fit
        line_init = Linear1D()
        fit_line = LinearLSQFitter()
        mult_comp = False

        intslopes = np.zeros((nints))
Example #3
0
        x.append(aveDN)
        y.append(diffDN)

        # find the ramp that spans the largest range of DN
        # and save some info -> needed for creating the correction
        # if (gdata.max() - gdata.min()) > mm_delta:
        #    mm_delta = gdata.max() - gdata.min()
        if k == 3:
            max_ramp_k = k
            max_ramp_gdata = gdata
            max_ramp_aveDN = aveDN

    # fit the aveDN versus diffDN combined data from all integrations
    x = np.concatenate(x)
    y = np.concatenate(y)
    mod = fit_diffs(x, y)
    polymod = mod[2]

    # plot the model
    mod_x = np.linspace(0.0, 65000.0, num=100)

    # for k in range(nints):
    #    gnum, ydata = get_ramp(hdu[0], pix_x, pix_y, k)
    #    ggnum, gdata, aveDN, diffDN = get_good_ramp(gnum, ydata)

    #    (DN_exp, cor, cor_mod) = calc_lincor(mod[1], gdata, args.startDN)
    #    ax[3].plot(DN_exp, cor, "--", label=f"Int #{k+1}")

    startDNvals = np.arange(0.0, 20000.0, 200.0)
    chival = np.zeros((nints, len(startDNvals)))
    ints = range(nints)