include include include include include "ccdred.h" # SET_OVERSCAN -- Set the overscan vector. # # 1. Return immediately if the overscan correction is not requested or # if the image has been previously corrected. # 2. Determine the overscan columns or lines. This may be specifed # directly or indirectly through the image header or symbol table. # 3. Average the overscan columns or lines. # 4. Fit a function with the ICFIT routines to smooth the overscan vector. # 5. Set the processing flag. # 6. Log the operation (to user, logfile, and output image header). procedure set_overscan (ccd) pointer ccd # CCD structure pointer int i, j, nsec, navg, npts, first, last int nc, nl, c1, c2, l1, l2 pointer sp, str, errstr, buf, overscan, x, y, z real asumr() bool clgetb(), ccdflag() pointer imgl2r() errchk imgl2r, fit_overscan begin # Check if the user wants this operation or if it has been done. if (!clgetb ("overscan") || ccdflag (IN_IM(ccd), "overscan")) return call smark (sp) call salloc (str, SZ_LINE, TY_CHAR) call salloc (errstr, SZ_LINE, TY_CHAR) call imstats (IN_IM(ccd), IM_IMAGENAME, Memc[str], SZ_LINE) # Check bias section. nc = IM_LEN(IN_IM(ccd),1) nl = IM_LEN(IN_IM(ccd),2) c1 = BIAS_C1(ccd) c2 = BIAS_C2(ccd) l1 = BIAS_L1(ccd) l2 = BIAS_L2(ccd) navg = c2 - c1 + 1 npts = CCD_L2(ccd) - CCD_L1(ccd) + 1 nsec = max (1, IN_NSEC(ccd)) do i = 1, nsec { if (BIAS_SEC(ccd) != NULL) { c1 = BIAS_SC1(ccd,i) c2 = BIAS_SC2(ccd,i) l1 = BIAS_SL1(ccd,i) l2 = BIAS_SL2(ccd,i) } if ((c1 < 1) || (c2 > nc) || (l1 < 1) || (l2 > nl)) { call sprintf (Memc[errstr], SZ_LINE, "Error in bias section: image=%s[%d,%d], biassec=[%d:%d,%d:%d]") call pargstr (Memc[str]) call pargi (nc) call pargi (nl) call pargi (c1) call pargi (c2) call pargi (l1) call pargi (l2) call error (0, Memc[errstr]) } if ((c1 == 1) && (c2 == nc) && (l1 == 1) && (l2 == nl)) { call error (0, "Bias section not specified or given as full image") } # If no processing is desired then print overscan strip and return. if (clgetb ("noproc")) { call eprintf ( " [TO BE DONE] Overscan section is [%d:%d,%d:%d].\n") call pargi (c1) call pargi (c2) call pargi (l1) call pargi (l2) call sfree (sp) return } } # Determine the overscan section parameters. The readout axis # determines the type of overscan. The step sizes are ignored. # The limits in the long dimension are replaced by the trim limits. if (READAXIS(ccd) == 1) { call salloc (buf, nsec*nl, TY_REAL) z = buf do i = 1, nl { y = imgl2r (IN_IM(ccd), i) do j = 1, nsec { if (BIAS_SEC(ccd) != NULL) { l1 = BIAS_SL1(ccd,j) l2 = BIAS_SL2(ccd,j) if (i < l1 || i > l2) next c1 = BIAS_SC1(ccd,j) c2 = BIAS_SC2(ccd,j) navg = c2 - c1 + 1 z = buf + (j - 1) * nl } Memr[z+i-1] = asumr (Memr[y+c1-1], navg) } } # Trim the overscan vector and set the pixel coordinate. call salloc (x, nl, TY_REAL) call malloc (overscan, nsec*nl, TY_REAL) y = overscan do i = 1, nsec { if (BIAS_SEC(ccd) != NULL) { c1 = BIAS_SC1(ccd,i) c2 = BIAS_SC2(ccd,i) l1 = BIAS_SL1(ccd,i) l2 = BIAS_SL2(ccd,i) navg = c2 - c1 + 1 npts = l2 - l1 + 1 y = overscan + (i - 1) * nl z = buf + (i - 1) * nl } if (navg > 1) call adivkr (Memr[z+l1-1], real (navg), Memr[z+l1-1], npts) call trim_overscan (Memr[z], npts, l1, Memr[x], Memr[y]) call fit_overscan (Memc[str], c1, c2, l1, l2, Memr[x], Memr[y], npts) } } else { first = l1 last = l2 navg = last - first + 1 npts = nc call salloc (buf, npts, TY_REAL) call aclrr (Memr[buf], npts) do i = first, last call aaddr (Memr[imgl2r(IN_IM(ccd),i)], Memr[buf], Memr[buf], npts) if (navg > 1) call adivkr (Memr[buf], real (navg), Memr[buf], npts) # Trim the overscan vector and set the pixel coordinate. npts = CCD_C2(ccd) - CCD_C1(ccd) + 1 call malloc (overscan, npts, TY_REAL) call salloc (x, npts, TY_REAL) call trim_overscan (Memr[buf], npts, IN_C1(ccd), Memr[x], Memr[overscan]) call fit_overscan (Memc[str], c1, c2, l1, l2, Memr[x], Memr[overscan], npts) } # Set the CCD structure overscan parameters. CORS(ccd, OVERSCAN) = O COR(ccd) = YES OVERSCAN_VEC(ccd) = overscan # Log the operation. call strcpy ("overscan", Memc[errstr], SZ_LINE) y = overscan do i = 1, nsec { if (BIAS_SEC(ccd) != NULL) { c1 = BIAS_SC1(ccd,i) c2 = BIAS_SC2(ccd,i) l1 = BIAS_SL1(ccd,i) l2 = BIAS_SL2(ccd,i) y = overscan + (i - 1) * nl npts = c2 - c1 + 1 if (i > 1) { call sprintf (Memc[errstr], SZ_LINE, "ovrscn%d") call pargi (i) } } call sprintf (Memc[str], SZ_LINE, "Overscan section is [%d:%d,%d:%d] with mean=%g") call pargi (c1) call pargi (c2) call pargi (l1) call pargi (l2) call pargr (asumr (Memr[y], npts) / npts) call timelog (Memc[str], SZ_LINE) call ccdlog (IN_IM(ccd), Memc[str]) call hdmpstr (OUT_IM(ccd), Memc[errstr], Memc[str]) } call sfree (sp) end # FIT_OVERSCAN -- Fit a function to smooth the overscan vector. # The fitting uses the ICFIT procedures which may be interactive. # Changes to these parameters are "learned". The user is queried with a four # valued logical query (XT_ANSWER routine) which may be turned off when # multiple images are processed. procedure fit_overscan (image, c1, c2, l1, l2, x, overscan, npts) char image[ARB] # Image name for query and title int c1, c2, l1, l2 # Overscan strip real x[npts] # Pixel coordinates of overscan real overscan[npts] # Input overscan and output fitted overscan int npts # Number of data points int interactive, fd pointer sp, str, w, ic, cv, gp, gt int clgeti(), ic_geti(), open() real clgetr(), ic_getr() pointer gopen(), gt_init() errchk gopen, open begin call smark (sp) call salloc (str, SZ_LINE, TY_CHAR) call salloc (w, npts, TY_REAL) call amovkr (1., Memr[w], npts) # Open the ICFIT procedures, get the fitting parameters, and # set the fitting limits. call ic_open (ic) call clgstr ("function", Memc[str], SZ_LINE) call ic_pstr (ic, "function", Memc[str]) call ic_puti (ic, "order", clgeti ("order")) call clgstr ("sample", Memc[str], SZ_LINE) call ic_pstr (ic, "sample", Memc[str]) call ic_puti (ic, "naverage", clgeti ("naverage")) call ic_puti (ic, "niterate", clgeti ("niterate")) call ic_putr (ic, "low", clgetr ("low_reject")) call ic_putr (ic, "high", clgetr ("high_reject")) call ic_putr (ic, "grow", clgetr ("grow")) call ic_putr (ic, "xmin", min (x[1], x[npts])) call ic_putr (ic, "xmax", max (x[1], x[npts])) call ic_pstr (ic, "xlabel", "Pixel") call ic_pstr (ic, "ylabel", "Overscan") # If the fitting is done interactively set the GTOOLS and GIO # pointers. Also "learn" the fitting parameters since they may # be changed when fitting interactively. call sprintf (Memc[str], SZ_LINE, "Fit overscan vector for %s[%d:%d,%d:%d] interactively") call pargstr (image) call pargi (c1) call pargi (c2) call pargi (l1) call pargi (l2) call set_interactive (Memc[str], interactive) if ((interactive == YES) || (interactive == ALWAYSYES)) { gt = gt_init () call sprintf (Memc[str], SZ_LINE, "Overscan vector for %s from section [%d:%d,%d:%d]\n") call pargstr (image) call pargi (c1) call pargi (c2) call pargi (l1) call pargi (l2) call gt_sets (gt, GTTITLE, Memc[str]) call gt_sets (gt, GTTYPE, "line") call gt_setr (gt, GTXMIN, x[1]) call gt_setr (gt, GTXMAX, x[npts]) call clgstr ("graphics", Memc[str], SZ_FNAME) gp = gopen (Memc[str], NEW_FILE, STDGRAPH) call icg_fit (ic, gp, "cursor", gt, cv, x, overscan, Memr[w], npts) call ic_gstr (ic, "function", Memc[str], SZ_LINE) call clpstr ("function", Memc[str]) call clputi ("order", ic_geti (ic, "order")) call ic_gstr (ic, "sample", Memc[str], SZ_LINE) call clpstr ("sample", Memc[str]) call clputi ("naverage", ic_geti (ic, "naverage")) call clputi ("niterate", ic_geti (ic, "niterate")) call clputr ("low_reject", ic_getr (ic, "low")) call clputr ("high_reject", ic_getr (ic, "high")) call clputr ("grow", ic_getr (ic, "grow")) call gclose (gp) call gt_free (gt) } else call ic_fit (ic, cv, x, overscan, Memr[w], npts, YES, YES, YES, YES) # Make a log of the fit in the plot file if given. call clgstr ("plotfile", Memc[str], SZ_LINE) call xt_stripwhite (Memc[str]) if (Memc[str] != EOS) { fd = open (Memc[str], APPEND, BINARY_FILE) gp = gopen ("stdvdm", NEW_FILE, fd) gt = gt_init () call sprintf (Memc[str], SZ_LINE, "Overscan vector for %s from section [%d:%d,%d:%d]\n") call pargstr (image) call pargi (c1) call pargi (c2) call pargi (l1) call pargi (l2) call gt_sets (gt, GTTITLE, Memc[str]) call gt_sets (gt, GTTYPE, "line") call gt_setr (gt, GTXMIN, 1.) call gt_setr (gt, GTXMAX, real (npts)) call icg_graphr (ic, gp, gt, cv, x, overscan, Memr[w], npts) call gclose (gp) call close (fd) call gt_free (gt) } # Replace the raw overscan vector with the smooth fit. call cvvector (cv, x, overscan, npts) # Finish up. call ic_closer (ic) call cvfree (cv) call sfree (sp) end # TRIM_OVERSCAN -- Trim the overscan vector. procedure trim_overscan (data, npts, start, x, overscan) real data[ARB] # Full overscan vector int npts # Length of trimmed vector int start # Trim start real x[npts] # Trimmed pixel coordinates (returned) real overscan[npts] # Trimmed overscan vector (returned) int i, j begin do i = 1, npts { j = start + i - 1 x[i] = j overscan[i] = data[j] } end