# include # include # include /* defines HST I/O functions */ # include "calnic.h" /* defines NICMOS data structures */ # include "calnica.h" /* defines CALNICA data structures */ /* N_INSTCAL: Applies CALNICA instrumental calibration steps to an input ** data group. All calibration steps modify the input image data in-place. ** ** Revision history: ** H.Bushouse Sept. 1995 Build 1 ** H.Bushouse Aug. 1996 Upgraded for Build 2 (Version 2.0) ** H.Bushouse 27-Jan-1997 Modified updateTrailer and updateSciHdr in ** n_calReport to use new ref.dummy variable. ** (Version 2.1) ** H.Bushouse 28-Jul-1997 Added new n_zsigcalc routine; added use of zsig ** image in n_nlincorr; added n_satcheck routine ** (Version 3.0) ** H.Bushouse 12-Sep-1997 Changed "group" to "imset" in messages (Vsn 3.0) ** H.Bushouse 28-Oct-1997 Added checks for dummy dark data when calling ** zsigcalc routine (Version 3.0) ** H.Bushouse 13-Feb-1998 Added call to n_calReport for ZSIG step; removed ** zsig from argument list of this routine - zsig ** is now local to this routine; changed name of ** n_zsigcalc to n_zsigcorr (Version 3.2) ** H.Bushouse 06-Oct-1998 Removed checks for dummy ref data when calling ** n_zsigcorr since it's now handled in ** n_getRefData; added dark ref image as argument ** to n_noiscalc (Version 3.3) ** H.Bushouse 09-Oct-1998 Added call to new n_barscorr routine (Vsn 3.3) ** H.Bushouse 09-Feb-1999 Updated use of putKey routines for HSTIO v2.1 ** (Version 3.2.2) */ int n_InstCal (NicInfo *nic, MultiNicmosGroup *input, SingleNicmosGroup *zoff, SingleNicmosGroup *mask, SingleNicmosGroup *nois, SingleNicmosGroup *dark, NlinData *nlin, SingleNicmosGroup *flat) { /* Arguments: ** nic i: NICMOS info structure ** input io: input image data ** zoff i: MULTIACCUM zero-read image ** mask i: bad pixel mask ** nois i: read-noise image ** dark i: dark current image ** nlin i: non-linearity coefficients ** flat i: flat field image */ /* Local variables */ static SingleNicmosGroup zsig; /* zero-read signal image */ /* Function definitions */ int n_zsigcorr (NicInfo *, MultiNicmosGroup *, SingleNicmosGroup *, SingleNicmosGroup *, SingleNicmosGroup *, NlinData *, SingleNicmosGroup *); int n_zoffcorr (NicInfo *, SingleNicmosGroup *, SingleNicmosGroup *); int n_maskcorr (NicInfo *, SingleNicmosGroup *, SingleNicmosGroup *); int n_biascorr (NicInfo *, SingleNicmosGroup *); int n_noiscalc (NicInfo *, SingleNicmosGroup *, SingleNicmosGroup *, SingleNicmosGroup *); int n_darkcorr (NicInfo *, SingleNicmosGroup *, SingleNicmosGroup *); int n_nlincorr (NicInfo *, NlinData * , SingleNicmosGroup *, SingleNicmosGroup *); int n_barscorr (NicInfo *, SingleNicmosGroup *); int n_flatcorr (NicInfo *, SingleNicmosGroup *, SingleNicmosGroup *); int n_unitcorr (NicInfo *, SingleNicmosGroup *); int n_calReport (CalStep *, int, Hdr *, Hdr *); void n_satcheck (NicInfo *, SingleNicmosGroup *, SingleNicmosGroup *); int n_getDarkImage (NicInfo *, SingleNicmosGroup *, int); /* Do MultiAccum zero-read signal correction; this is done ** only once, before the normal processing of the zeroth-read group ** (Version 3.0) */ if (nic->ZSIG.corr == PERFORM && nic->group == nic->ngroups) { /* Get the dark image for the first read */ if (n_getDarkImage (nic, dark, nic->ngroups-1)) return (status); /* Calculate signal in zeroth read */ if (n_zsigcorr (nic, input, mask, nois, dark, nlin, &zsig)) return (status); /* Get the dark image for zeroth read again */ if (n_getDarkImage (nic, dark, nic->ngroups)) return (status); } n_calReport(&nic->ZSIG, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do MultiAccum zero-read subtraction */ if (nic->ZOFF.corr == PERFORM) { if (n_zoffcorr (nic, zoff, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->ZOFF, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do bad pixel masking */ if (nic->MASK.corr == PERFORM) { if (n_maskcorr (nic, mask, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->MASK, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do BIAS subtraction */ if (nic->BIAS.corr == PERFORM) { if (n_biascorr (nic, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->BIAS, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do noise (error) calculation */ if (nic->NOIS.corr == PERFORM) { if (n_noiscalc (nic, nois, dark, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->NOIS, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do dark subtraction */ if (nic->DARK.corr == PERFORM) { if (n_darkcorr (nic, dark, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->DARK, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do linearity correction */ if (nic->NLIN.corr == PERFORM) { if (n_nlincorr (nic, nlin, &(input->group[nic->group-1]), &zsig)) return (status); /* Flag pixels in the next group as saturated if they're ** flagged as saturated in this group */ if (nic->obsmode == MULTIACCUM && nic->group-1 > 0) n_satcheck (nic, &(input->group[nic->group-1]), &(input->group[nic->group-2])); } n_calReport(&nic->NLIN, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do BARS flagging */ if (nic->BARS.corr == PERFORM) { if (n_barscorr (nic, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->BARS, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do flat fielding */ if (nic->FLAT.corr == PERFORM) { if (n_flatcorr (nic, flat, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->FLAT, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Do units conversion */ if (nic->UNIT.corr == PERFORM) { if (n_unitcorr (nic, &(input->group[nic->group-1]))) return (status); } n_calReport(&nic->UNIT, nic->group, &input->group[nic->group-1].sci.hdr, input->group[nic->group-1].globalhdr); /* Free the zsig image data after processing the last group */ if (nic->group == 1 && nic->ZSIG.corr == PERFORM) freeSingleNicmosGroup (&zsig); /* Successful return */ return (status = 0); } /* N_CALREPORT: Reports calibration step information to processing log ** and to output SCI header history keywords. Also updates the calibration ** indicator and reference file pedigree keywords in the primary header. */ int n_calReport (CalStep *step, int group, Hdr *scihdr, Hdr *prihdr) { /* Arguments: ** step io: calibration step information structure ** group i: data group number ** scihdr io: science image header ** prihdr io: primary header */ /* Function definitions */ void updateTrailer (CalStep *, int); int updateSciHdr (CalStep *, Hdr *); int updatePriHdr (CalStep *, Hdr *); /* Write processing information to trailer file */ if (group != -1) updateTrailer (step, group); /* Write calibration step and reference file info to history ** records in science image header */ if (group != 0) { if (updateSciHdr (step, scihdr)) return (status); } /* Update calibration indicator and reference file pedigree ** keywords in primary header */ if (group == 0 || group == 1) { if (updatePriHdr (step, prihdr)) return (status); } /* Successful return */ return (status = 0); } void updateTrailer (CalStep *step, int group) { /* Arguments: ** step i: calibration step information ** group i: data group number */ /* Local variables */ char text[80]; /* Report calibration step info to screen and trailer file */ if (step->corr == PERFORM) { sprintf (MsgText, " %s performed", step->swname); if (group > 0) { sprintf (text, " for imset %d", group); strcat (MsgText, text); } if (step->ref.name[0] != '\0') { sprintf (text, " using %s", step->ref.name); strcat (MsgText, text); } n_message (MsgText); } else if (step->corr == SKIP) { sprintf (MsgText, "%s skipped", step->swname); if (group > 0) { sprintf (text, " for imset %d", group); strcat (MsgText, text); } if (step->ref.name[0] != '\0' && step->ref.dummy) { sprintf (text, "; %s is dummy", step->ref.name); strcat (MsgText, text); } n_warn (MsgText); } return; } /* UPDATESCIHDR: Check whether pedigree indicates that the calibration file is dummy, and log history info accordingly. From one to three history records will be logged: the status of the calibration step (i.e. "omitted", "skipped", or "performed"), the value of the pedigree keyword, and the value of the descrip keyword. */ int updateSciHdr (CalStep *step, Hdr *scihdr) { /* Arguments: ** step i: calibration step information structure ** scihdr io: science extension image header */ /* Local variables */ char history[SZ_LIN+1]; /* history record */ /* Function definitions */ int savHist (char *); int putHist (Hdr *); /* If this step was omitted, don't print any information */ if (step->corr == OMIT) return (status = 0); /* Does this step use a reference file? */ if (step->ref.name[0] != '\0') { /* Is this a dummy reference file? */ if (step->ref.dummy) sprintf (history, "%s skipped because %s is dummy", step->swname, step->ref.name); else sprintf (history, "%s performed using %s", step->swname, step->ref.name); if (savHist (history)) /* save history info */ return (status); /* Save pedigree as history */ if (step->ref.pedigree[0] != '\0') { sprintf (history, " %s", step->ref.pedigree); if (savHist (history)) return (status); } /* Save descrip as history */ if (step->ref.descrip[0] != '\0') { sprintf (history, " %s", step->ref.descrip); if (savHist (history)) return (status); } } else { /* No reference file used with this step */ if (step->corr == PERFORM) sprintf (history, "%s performed", step->swname); else sprintf (history, "%s skipped", step->swname); if (savHist (history)) return (status); } /* Write the history records to the science image header */ if (putHist (scihdr)) return (status); /* Successful return */ return (status = 0); } /* UPDATEPRIHDR: Update the values of the calibration indicator and ** reference file pedigree keywords in the primary header */ int updatePriHdr (CalStep *step, Hdr *prihdr) { /* Arguments: step i: calibration step information prihdr io: primary header */ /* Update calibration indicator keyword if step was performed */ if (step->corr == PERFORM) { if (putKeyS (prihdr, step->indname, "PERFORMED", "")) return (status = 1); /* Update the reference file pedigree keyword for this step */ if (step->ref.pedigree[0] != '\0') { if (putKeyS (prihdr, step->pdname, step->ref.pedigree, "")) return (status = 1); } } /* If this step was performed in a previous run, don't set ** the keyword value back to SKIPPED or OMITTED */ if (step->done == PERFORMED) return (status = 0); if (step->corr == SKIP) { if (putKeyS (prihdr, step->indname, "SKIPPED", "")) return (status = 1); /* Update the reference file pedigree keyword for this step */ if (step->ref.pedigree[0] != '\0') { if (putKeyS (prihdr, step->pdname, step->ref.pedigree, "")) return (status = 1); } } else if (step->corr == OMIT) { if (putKeyS (prihdr, step->indname, "OMITTED", "")) return (status = 1); } /* Successful return */ return (status = 0); }