# include # include /* for calloc */ # include # include "../acs.h" # include "../acsinfo.h" # include "../acserr.h" static int divFlat (SingleGroup *, char *, int, int, int); /* This routine divides x in-place by the flat fields. There are up to three flat fields. They are read into SingleGroups, multiplied together (leaving the result each time in y), and the product of the flat fields is divided into the input x, with the final quotient left in x. Warren Hack, 1998 June 12: Initial ACS version. */ int doFlat (ACSInfo *acs2d, int extver, SingleGroup *x) { /* arguments: ACSInfo *acs2d i: calibration switches, etc int extver i: extension/imset to be flat-fielded SingleGroup *x io: image to be calibrated; written to in-place */ extern int status; SingleGroupLine w, zl, ztrim; /* scratch space */ ACSsect lfsect, elfsect; int rx, ry; /* for binning dark down to size of x */ int x0, y0; /* offsets of sci image */ int same_size; /* true if no binning of ref image required */ int xline; /* counter for science image lines */ int chipext; /* Reference file IMSET corresponding to CCD chip id for science image */ int lf, zline; Hdr phdr; int update = NO; /* Flag to determine whether hdr info needs to be updated*/ int scilines; int FindLine (SingleGroup *, SingleGroupLine *, int *, int *, int *, int *, int *); int div1d (SingleGroup *, int, SingleGroupLine *); int allocACSsect (ACSsect *, int, int); void initACSsect (ACSsect *); void freeACSsect (ACSsect *); void closeACSsect (ACSsect *); void copySectLine (ACSsect *, int, SingleGroupLine *); void getACSsect (char *, SingleGroupLine *, int, int, ACSsect *); int unbinsect (ACSsect *, int, ACSsect *); int DetCCDChip (char *, int, int, int *); /* apply pixel-to-pixel flat, if set to PERFORM */ if (acs2d->pfltcorr == PERFORM) { if (divFlat (x, acs2d->pflt.name, acs2d->chip, acs2d->nimsets, acs2d->verbose)){ sprintf (MsgText, "Problem applying PFLTFILE %s... ", acs2d->pflt.name); trlerror(MsgText); return(status); } } /* apply delta flat, if set to PERFORM */ if (acs2d->dfltcorr == PERFORM) { if (divFlat (x, acs2d->dflt.name, acs2d->chip, acs2d->nimsets, acs2d->verbose) ){ sprintf (MsgText, "Problem applying DFLTFILE %s... ", acs2d->dflt.name); trlerror(MsgText); return (status); } } lf = 0; initHdr (&phdr); /* low-order flat */ if (acs2d->lfltcorr == PERFORM) { if (acs2d->verbose) { sprintf(MsgText, "Reading in LFLAT file..."); trlmessage (MsgText); } initSingleGroupLine (&w); /* Compute correct extension version number to extract from reference image to correspond to CHIP in science data. */ chipext = extver; if (DetCCDChip (acs2d->lflt.name, acs2d->chip, acs2d->nimsets, &chipext) ) return (status); /* Get the low-order flat field image data. */ openSingleGroupLine (acs2d->lflt.name, chipext, &w); if (hstio_err()) return (status = OPEN_FAILED); /* Compare binning of science image and reference image; get the same_size flag, and get info about binning and offset for use by bin2d. */ if (FindLine (x, &w, &same_size, &rx, &ry, &x0, &y0)) return (status); /* Now we know what IMSET corresponds to the appropriate chip, we can read in the flat-field file, expand it, combine it with the other flats, then apply it to the science data... */ /* Low-order flat is binned down more than science image, and needs to be expanded to match the image size */ /* Set up scratch spaces to expand low-order flat */ /* Input file section */ initACSsect (&lfsect); if (allocACSsect (&lfsect, w.sci.tot_nx, SECTLINES) ) { trlerror ("(doFlat) Out of memory. "); return (status = OUT_OF_MEMORY); } /* Output (expanded) file section. */ initACSsect (&elfsect); if (allocACSsect (&elfsect, w.sci.tot_nx * rx, SECTLINES * ry) ){ trlerror ("(doFlat) Out of memory. "); return (status = OUT_OF_MEMORY); } /* Set up individual lfltfile line to be applied to image */ initSingleGroupLine (&zl); allocSingleGroupLine (&zl, w.sci.tot_nx * rx); initSingleGroupLine (&ztrim); allocSingleGroupLine (&ztrim, x->sci.data.nx); xline = 0; scilines = x->sci.data.ny; while (xline <= scilines) { /* Read in lfltfile and apply to input image here */ getACSsect (acs2d->lflt.name, &w, lf, SECTLINES, &lfsect); /* Increment row counter for reference image */ lf += 1; /* Expand binned reference data accounting for offsets of subarrays */ unbinsect (&lfsect, update, &elfsect); /* For each line in expanded section, copy out a SingleGroupLine and apply it to the science image. */ for (zline=0; zline < ry; zline++) { /* Copy out individual averaged, expanded lines from reference data. */ copySectLine (&elfsect, zline, &zl); /* We now have 1 expanded low-order flat line to apply Let's check to see if we have any other flat-fields to apply... */ /* Now, apply flat-field */ div1d (x, xline, &ztrim); xline++; } /* End loop over expanded lflt lines, zline loop */ } /* End loop over input image lines, xline loop */ /* Clean up scratch areas that were used... */ closeACSsect (&lfsect); freeACSsect (&lfsect); /*closeACSsect (&elfsect); */ freeACSsect (&elfsect); closeSingleGroupLine (&w); freeSingleGroupLine (&w); freeSingleGroupLine (&zl); freeSingleGroupLine (&ztrim); /* End if (lfltcorr) */ } return (status); } static int divFlat (SingleGroup *x, char *flatname, int chip, int nimsets, int verbose) { extern int status; int pchipext; SingleGroupLine y, ytrim; /* scratch space */ int line; /* counter for science image lines */ int y_rx, y_ry; /* for binning dark down to size of x */ int y_x0, y_y0; /* offsets of sci image */ int ysame_size; /* true if no binning of ref image required */ int avg = 1; /* bin2d should average within each bin */ int update = NO; /* Flag to determine whether hdr info needs to be updated*/ int scilines; /* Number of lines in 'x' */ int FindLine (SingleGroup *, SingleGroupLine *, int *, int *, int *, int *, int *); int DetCCDChip (char *, int, int, int *); int trim1d (SingleGroupLine *, int, int, int, int, int, SingleGroupLine *); int div1d (SingleGroup *, int, SingleGroupLine *); initSingleGroupLine (&y); /* Compute correct extension version number to extract from reference image to correspond to CHIP in science data. */ if (DetCCDChip (flatname, chip, nimsets, &pchipext) ) return (status); openSingleGroupLine (flatname, pchipext, &y); if (hstio_err()) return (status = OPEN_FAILED); if (FindLine (x, &y, &ysame_size, &y_rx, &y_ry, &y_x0, &y_y0)) return (status); if (verbose){ sprintf(MsgText,"ratio of flat/input = %d,%d offset by %d,%d",y_rx,y_ry,y_x0,y_y0); trlmessage(MsgText); } /* Start reading FLAT lines at this offset row in the reference image */ line = y_y0; /* Perform one pointer operation here, instead of one for each line in the image... */ scilines = x->sci.data.ny; /* For the sake of run-time speed, the loop over lines is performed differently and separately depending on whether it is the same size or not... */ if (ysame_size) { while (line < scilines) { getSingleGroupLine (flatname, line, &y); /* Now, apply flat-field */ div1d (x, line, &y); line++; } /* End loop over input image lines, xline loop */ } else { /* We are working with a sub-array image and need to trim down the flat field lines So, we need a buffer for these flat-field lines... */ initSingleGroupLine (&ytrim); allocSingleGroupLine (&ytrim, x->sci.data.nx); while (line < scilines) { getSingleGroupLine (flatname, line, &y); /* Make sure it is the same length as science image */ trim1d (&y, y_x0, y_y0, y_rx, avg, update, &ytrim); /* Now, apply flat-field */ div1d (x, line, &ytrim); line++; } /* End loop over input image lines, xline loop */ /* Clean up buffers... */ freeSingleGroupLine (&ytrim); } closeSingleGroupLine (&y); freeSingleGroupLine (&y); return (status); }