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))
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)