int GetGrpInfo6 (StisInfo6 *sts, Hdr *hdr) { /* arguments: StisInfo6 *sts io: calibration switches and info Hdr *hdr i: header of current IMSET */ int status; int sdqflags; /* serious data quality flags */ char *buf; /* scratch for keyword value */ int use_def = 1; /* use default if missing keyword */ int no_default = 0; /* missing keyword is fatal error */ int GetDetTemp (Hdr *, int, double *); /* Get the dispersion axis. */ if ((status = Get_KeyI (hdr, "DISPAXIS", use_def, 1, &sts->dispaxis))) return (status); if (sts->dispaxis < 1 || sts->dispaxis > 2) { printf ("ERROR Dispaxis = %d is invalid\n", sts->dispaxis); return (INVALID); } /* This should be SCIENCE or WAVECAL. */ if ((buf = (char *) calloc (STIS_FNAME+1, sizeof(char))) == NULL) return (OUT_OF_MEMORY); if ((status = Get_KeyS (hdr, "ASN_MTYP", use_def, "unknown", buf, STIS_FNAME))) return (status); sts->wavecal = (strcmp (buf, "WAVECAL") == 0); free (buf); /* Exposure info. */ if ((status = Get_KeyD (hdr, "EXPTIME", no_default, 0., &sts->exptime))) return (status); if (sts->exptime < 0.) { printf ("ERROR Exposure time is invalid: %14.6g\n", sts->exptime); return (INVALID); } if ((status = Get_KeyD (hdr, "EXPSTART", no_default, 0., &sts->expstart))) return (status); if ((status = Get_KeyD (hdr, "EXPEND", no_default, 0., &sts->expend))) return (status); if ((status = Get_KeyD (hdr, "DOPPMAG", use_def, 0., &sts->doppmag))) return (status); if (sts->doppmag > 0. && strcmp (sts->obsmode, "TIME-TAG") != 0) { /* doppon could be False in timetag mode; otherwise, reset doppzero to zero if on-board Doppler correction was not done. */ int doppon; if ((status = Get_KeyI (hdr, "DOPPON", use_def, 0, &doppon))) return (status); if (!doppon) sts->doppmag = 0.; } if ((status = Get_KeyD (hdr, "DOPPZERO", use_def, 0., &sts->doppzero))) return (status); if ((status = Get_KeyD (hdr, "ORBITPER", use_def, 1., &sts->orbitper))) return (status); /* Find out which data quality bits are considered serious; default value means all bits are serious. */ if ((status = Get_KeyI (hdr, "SDQFLAGS", use_def, ALL_BITS, &sdqflags))) return (status); sdqflags &= ~HOTPIX; /* hot (but probably just warm) pixel */ sdqflags &= ~SMALLBLEM; /* too small to be concerned about */ sts->sdqflags_orig = (short) sdqflags; sts->cc_sdqflags = (short) sdqflags; /* This turns off the data quality flag checking everywhere except in crosscorrelation module. */ sts->sdqflags = 0; /* Get the "plate scale" coefficients. */ if ((status = Get_KeyD (hdr, "CD1_1", no_default, 0., &sts->cd[0]))) return (status); if ((status = Get_KeyD (hdr, "CD2_2", no_default, 0., &sts->cd[1]))) return (status); if ((status = Get_KeyD (hdr, "CRPIX1", no_default, 1., &sts->crpix[0]))) return (status); if ((status = Get_KeyD (hdr, "CRVAL1", no_default, 0., &sts->crval[0]))) return (status); /* Get the linear transformation (zero indexed) from the reference coordinate system to current image pixel coordinates. */ if ((status = GetLT0 (hdr, sts->ltm, sts->ltv))) return (status); /* Get the detector temperature (or housing temperature, if CCD). */ if (sts->fluxcorr == PERFORM) { if ((status = GetDetTemp (hdr, sts->detector, &sts->detector_temp))) { return (status); } } else { sts->detector_temp = -1.; } /* Get the MSM slop. */ if (sts->wavecal) { sts->msm_offset[0] = 0.0; sts->msm_offset[1] = 0.0; } else { if ((status = Get_KeyD (hdr, "SHIFTA1", use_def, 0., &sts->msm_offset[0]))) return (status); if ((status = Get_KeyD (hdr, "SHIFTA2", use_def, 0., &sts->msm_offset[1]))) return (status); } /* Get the mean dark count rate and the number of combined images for CTI correction. */ if ((status = Get_KeyD(hdr, "MEANDARK", no_default, 0., &sts->meandark))) return status; if ((status = Get_KeyI(hdr, "NCOMBINE", no_default, 0., &sts->ncombine))) return status; return (0); }
int doDQI (StisInfo1 *sts, SingleGroup *x) { /* arguments: StisInfo1 *sts i: calibration switches, etc SingleGroup *x io: image to be calibrated; DQ array written to in-place */ int status; TblInfo tabinfo; /* pointer to table descriptor, etc */ TblRow tabrow; /* values read from a table row */ ShortTwoDArray ydq; /* scratch space */ /* mappings from one coordinate system to another */ double ri_m[2], ri_v[2]; /* reference to image */ double rs_m[2], rs_v[2]; /* reference to scratch */ double si_m[2], si_v[2]; /* scratch to image */ /* for copying from scratch array (only copy overlap region): */ int first[2], last[2]; /* corners of overlap region in image coords */ int sfirst[2]; /* lower left corner of overlap in scratch */ int rbin[2]; /* bin size of image relative to ref bin size */ int snpix[2]; /* size of scratch array */ int npix[2]; /* size of current image */ float *ds; /* Doppler smearing array */ int nds, d0; /* size of ds and index in ds of zero point */ int k, kmin, kmax; /* loop index; range of indexes in ds */ int doppmin, doppmax; /* Doppler offsets relative to d0 */ int in_place; /* true if same bin size and no Doppler */ int high_res; /* true if Doppler or either axis is high-res */ int i, j, i0, j0; /* indexes for scratch array ydq */ int m, n; /* indexes for data quality array in x */ short sum_dq; /* for binning data quality array */ int row; /* loop index for row number */ void FlagFilter (StisInfo1 *, ShortTwoDArray *, int, int, double *, double *); int MakeDopp (double, double, double, double, double, int, float *, int *, int *); /* We could still flag saturation even if the bpixtab was dummy. */ if (sts->dqicorr != PERFORM && sts->dqicorr != DUMMY) return (0); /* For the CCD, check for and flag saturation. */ if (sts->detector == CCD_DETECTOR) { for (j = 0; j < x->sci.data.ny; j++) { for (i = 0; i < x->sci.data.nx; i++) { if ((int) Pix (x->sci.data, i, j) > sts->saturate) { sum_dq = DQPix (x->dq.data, i, j) | SATPIXEL; DQSetPix (x->dq.data, i, j, sum_dq); /* saturated */ } } } } /* Get the linear transformation between reference and input image. */ if ((status = GetLT0 (&x->sci.hdr, ri_m, ri_v))) /* zero indexed LTV */ return (status); /* Flag regions beyond the bounderies of the aperture, for CCD data. */ if (sts->detector == CCD_DETECTOR) { FlagFilter (sts, &x->dq.data, x->dq.data.nx, x->dq.data.ny, ri_m, ri_v); } /* There might not be any bad pixel table. If not, quit now. */ if (sts->bpix.exists == EXISTS_NO || sts->dqicorr != PERFORM) return (0); initShortData (&ydq); /* In some cases we can set the data quality flags directly in the DQ array, but in other cases we must create a scratch array and copy back to the original. Either the original or the scratch may be in high-res mode. */ if (sts->detector == CCD_DETECTOR) { if (sts->bin[0] == 1 && sts->bin[1] == 1) in_place = 1; /* no binning */ else in_place = 0; high_res = 0; } else { /* MAMA */ if (sts->doppcorr == PERFORM) { high_res = 1; if (sts->bin[0] == 1 && sts->bin[1] == 1) in_place = 1; /* high-res in both axes */ else in_place = 0; } else { /* no Doppler convolution */ if (sts->bin[0] == 2 && sts->bin[1] == 2) { high_res = 0; /* both axes low-res */ in_place = 1; } else if (sts->bin[0] == 1 && sts->bin[1] == 1) { high_res = 1; /* both axes high-res */ in_place = 1; } else { high_res = 1; /* low-res in one axis */ in_place = 0; } } } /* Get the other linear transformations (ri_m & ri_v were gotten earlier, just after checking for saturation.) */ if (!in_place) { if (high_res) { /* DQ array is binned finer than reference coords */ rs_m[0] = 2.; rs_m[1] = 2.; rs_v[0] = 0.5; rs_v[1] = 0.5; /* assumes rs_m = 2, rs_v = 0.5 */ si_m[0] = ri_m[0] * 0.5; si_m[1] = ri_m[1] * 0.5; si_v[0] = ri_v[0] - ri_m[0] * 0.25; si_v[1] = ri_v[1] - ri_m[1] * 0.25; } else { /* scratch is in reference coords */ rs_m[0] = 1.; rs_m[1] = 1.; rs_v[0] = 0.; rs_v[1] = 0.; /* assumes rs_m = 1, rs_v = 0 */ si_m[0] = ri_m[0]; si_m[1] = ri_m[1]; si_v[0] = ri_v[0]; si_v[1] = ri_v[1]; } } if (sts->doppcorr == PERFORM) { /* Compute the Doppler smearing array, if we need it. We need the size (nds) and zero point (d0), not the array itself. */ nds = 2 * (sts->doppmag + 1) + 21; /* reassigned by makeDopp */ ds = (float *) calloc (nds, sizeof (float)); if ((status = MakeDopp (sts->doppzero, sts->doppmag, sts->orbitper, sts->expstart, sts->exptime, sts->dispsign, ds, &nds, &d0))) return (status); /* Find the range of non-zero elements in ds. */ kmin = nds - 1; /* initial values */ kmax = 0; for (k = 0; k < nds; k++) { if (ds[k] > 0.) { /* there will be no negative values */ if (k < kmin) kmin = k; if (k > kmax) kmax = k; } } /* It's the indexes relative to d0 that are important. */ doppmin = kmin - d0; doppmax = kmax - d0; free (ds); } else { doppmin = 0; doppmax = 0; } /* Open the data quality initialization table, find columns, etc. */ if ((status = OpenBpixTab (sts->bpix.name, &tabinfo))) return (status); /* Size of scratch image */ if (high_res) { snpix[0] = 2 * tabinfo.axlen1; snpix[1] = 2 * tabinfo.axlen2; } else { snpix[0] = tabinfo.axlen1; snpix[1] = tabinfo.axlen2; } /* size of current image */ npix[0] = x->dq.data.nx; npix[1] = x->dq.data.ny; if (!in_place) { /* Allocate space for a scratch array. */ allocShortData (&ydq, snpix[0], snpix[1], True); if (hstio_err()) { printf ( "ERROR (doDQI) couldn't allocate data quality array.\n"); return (OUT_OF_MEMORY); } for (j = 0; j < snpix[1]; j++) for (i = 0; i < snpix[0]; i++) DQSetPix (ydq, i, j, 0); /* initially OK */ } /* Read each row of the table, and fill in data quality values. */ for (row = 1; row <= tabinfo.nrows; row++) { if ((status = ReadBpixTab (&tabinfo, row, &tabrow))) { printf ("ERROR Error reading BPIXTAB.\n"); return (status); } if (!SameString (tabrow.opt_elem, sts->opt_elem)) continue; if (tabrow.xstart < 0 || tabrow.xstart >= tabinfo.axlen1 || tabrow.ystart < 0 || tabrow.ystart >= tabinfo.axlen2) { printf ( "Warning Starting pixel (%d,%d) in BPIXTAB is out of range.\n", tabrow.xstart+1, tabrow.ystart+1); continue; /* ignore this row */ } /* Assign the flag value to all relevant pixels. */ if (in_place) { if (high_res) DQIHigh (&x->dq.data, ri_v, &tabrow, doppmin, doppmax); else DQINormal (&x->dq.data, ri_v, &tabrow); } else { /* use scratch array */ if (high_res) DQIHigh (&ydq, rs_v, &tabrow, doppmin, doppmax); else DQINormal (&ydq, rs_v, &tabrow); } } if ((status = CloseBpixTab (&tabinfo))) /* done with the table */ return (status); if (!in_place) { /* Get corners of region of overlap between image and scratch array. */ FirstLast (si_m, si_v, snpix, npix, rbin, first, last, sfirst); /* We have been writing to a scratch array ydq. Now copy or bin the values down to the actual size of x. */ j0 = sfirst[1]; for (n = first[1]; n <= last[1]; n++) { i0 = sfirst[0]; for (m = first[0]; m <= last[0]; m++) { sum_dq = DQPix (x->dq.data, m, n); for (j = j0; j < j0+rbin[1]; j++) for (i = i0; i < i0+rbin[0]; i++) sum_dq |= DQPix (ydq, i, j); DQSetPix (x->dq.data, m, n, sum_dq); i0 += rbin[0]; } j0 += rbin[1]; } freeShortData (&ydq); /* done with ydq */ } return (0); }
int GetGrpInfo4 (StisInfo4 *sts, Hdr *hdr) { /* arguments: StisInfo4 *sts io: calibration switches and info Hdr *hdr i: header of current imset */ int status; int sdqflags; /* serious data quality flags */ int use_def = 1; /* use default if missing keyword */ Bool value; /* value of IMSET_OK keyword */ /* Get IMSET_OK, which will be false if the current imset was flagged as having zero exptime or constant pixel values. */ if ((status = Get_KeyB (hdr, "IMSET_OK", use_def, True, &value)) != 0) return status; if (value) sts->imset_ok = 1; else sts->imset_ok = 0; /* Get the dispersion axis. */ if ((status = Get_KeyI (hdr, "DISPAXIS", use_def, 1, &sts->dispaxis))) return (status); if (sts->dispaxis < 1 || sts->dispaxis > 2) { printf ( "ERROR DISPAXIS = %d is invalid for spectroscopic data.\n", sts->dispaxis); return (GENERIC_ERROR_CODE); } /* Find out which data quality bits (all, by default) are considered serious. Note that we reset some bits, so that we can include pixels that are flagged with these conditions. */ if ((status = Get_KeyI (hdr, "SDQFLAGS", use_def, 32767, &sdqflags))) return (status); sdqflags &= ~DATAMASKED; /* behind occulting bar */ sdqflags &= ~HOTPIX; /* hot (but probably just warm) pixel */ sdqflags &= ~SMALLBLEM; /* too small to be concerned about */ sts->sdqflags = (short) sdqflags; /* Get the LTMi_i and LTVi keywords, converted to zero indexing. */ if ((status = GetLT0 (hdr, sts->ltm, sts->ltv))) return (status); sts->scale[0] = 1. / sts->ltm[0]; sts->scale[1] = 1. / sts->ltm[1]; /* Get the coordinate parameters. */ if (sts->disp_type == PRISM_DISP) { /* For prism data prior to 2-D rectification, the coordinate parameters in the header are for RA & Dec, but we need cross-dispersion spatial coordinates. */ GetSDC (sts); sts->crpix[1] = sts->crpix[1] * sts->ltm[1] + sts->ltv[1]; sts->cdelt[1] /= sts->ltm[1]; } else { if ((status = Get_KeyD (hdr, "CRPIX1", use_def, 0., &sts->crpix[0]))) return (status); if ((status = Get_KeyD (hdr, "CRPIX2", use_def, 0., &sts->crpix[1]))) return (status); if ((status = Get_KeyD (hdr, "CRVAL1", use_def, 0., &sts->crval[0]))) return (status); if ((status = Get_KeyD (hdr, "CRVAL2", use_def, 0., &sts->crval[1]))) return (status); if ((status = Get_KeyD (hdr, "CD1_1", use_def, 1., &sts->cdelt[0]))) return (status); if ((status = Get_KeyD (hdr, "CD2_2", use_def, 1., &sts->cdelt[1]))) return (status); /* Convert CRPIX to zero index. */ sts->crpix[0]--; sts->crpix[1]--; } /* We only need the exposure time to verify that it's greater than zero. That's why the default is zero. */ if ((status = Get_KeyD (hdr, "EXPTIME", use_def, 0., &sts->exptime))) return (status); /* Exposure start time is needed for trace rotation */ if ((status = Get_KeyD (hdr, "EXPSTART", 0, 0., &sts->expstart))) return (status); return (0); }
int GetGrpInfo7 (StisInfo7 *sts, Hdr *hdr) { /* arguments: StisInfo7 *sts io: calibration switches and info Hdr *hdr i: header of current imset */ int status; int sdqflags; /* serious data quality flags */ char *buf; /* scratch for keyword value */ int use_def = 1; /* use default if missing keyword */ int no_default = 0; /* missing keyword is fatal error */ int GetDetTemp (Hdr *, int, double *); /* Get generic parameters. */ /* This should be SCIENCE or WAVECAL. */ if ((buf = calloc (STIS_FNAME+1, sizeof(char))) == NULL) return (OUT_OF_MEMORY); if ((status = Get_KeyS (hdr, "ASN_MTYP", use_def, "unknown", buf, STIS_FNAME))) return (status); /* Possible values for wavecals are "AUTO-WAVECAL" and "GO-WAVECAL" */ sts->wavecal = (strstr (buf, "WAVECAL") != NULL); free (buf); if ((status = Get_KeyD (hdr, "EXPTIME", no_default, 0., &sts->exptime))) return (status); if (sts->exptime < 0.) { printf ("ERROR Exposure time %.6g is invalid.\n", sts->exptime); return (GENERIC_ERROR_CODE); } if ((status = Get_KeyD (hdr, "EXPSTART", no_default, 0., &sts->expstart))) return (status); if ((status = Get_KeyD (hdr, "EXPEND", no_default, 0., &sts->expend))) return (status); /* Find out which data quality bits are considered serious; default value means all bits are serious. */ if ((status = Get_KeyI (hdr, "SDQFLAGS", use_def, 32767, &sdqflags))) return (status); sts->sdqflags = (short) sdqflags; /* Get the linear transformation (zero indexed) from the reference coordinate system to current image pixel coordinates. */ if ((status = GetLT0 (hdr, sts->ltm, sts->ltv))) return (status); if ((status = Get_KeyD (hdr, "CRPIX1", use_def, 0., &sts->crpix[0]))) return (status); if ((status = Get_KeyD (hdr, "CRPIX2", use_def, 0., &sts->crpix[1]))) return (status); sts->crpix[0]--; /* convert to zero-indexed */ sts->crpix[1]--; /* Get the detector temperature (or housing temperature, if CCD). */ if (sts->fluxcorr == PERFORM) { if ((status = GetDetTemp (hdr, sts->detector, &sts->detector_temp))) { return (status); } } else { sts->detector_temp = -1.; } /* Get the MSM offset found during wavecal processing. */ if (sts->wavecal) { sts->msm_slop[0] = 0.; sts->msm_slop[1] = 0.; } else { if ((status = Get_KeyD (hdr, "SHIFTA1", use_def, 0., &sts->msm_slop[0]))) return (status); if (sts->wx2dcorr == COMPLETE) { /* shifta2 has already been accounted for by wx2d */ sts->msm_slop[1] = 0.; } else { if ((status = Get_KeyD (hdr, "SHIFTA2", use_def, 0., &sts->msm_slop[1]))) return (status); } } if (sts->obstype == SPECTROSCOPIC_TYPE) { /* Get the dispersion axis. */ if ((status = Get_KeyI (hdr, "DISPAXIS", use_def, 1, &sts->dispaxis))) return (status); if (sts->dispaxis < 1 || sts->dispaxis > 2) { printf ("ERROR Dispaxis = %d is invalid.\n", sts->dispaxis); return (GENERIC_ERROR_CODE); } } else { sts->dispaxis = 0; } return (0); }