int GetSciGrp (Hdr *hdr, double *exptime, double *midpt) { /* arguments: Hdr *hdr i: header of current imset double *exptime o: the exposure time (converted to days) double *midpt o: the time (MJD) of the middle of the exposure */ int status; double expstart, expend; int no_default = 0; /* missing keyword is fatal error */ if ((status = Get_KeyD (hdr, "EXPTIME", no_default, 0., exptime))) return (status); if (*exptime < 0.) { printf ("ERROR GetSciGrp: exposure time = %.6g is invalid.\n", *exptime); return (GENERIC_ERROR_CODE); } *exptime /= SECONDS_IN_A_DAY; if ((status = Get_KeyD (hdr, "EXPSTART", no_default, 0., &expstart))) return (status); if ((status = Get_KeyD (hdr, "EXPEND", no_default, 0., &expend))) return (status); *midpt = (expstart + expend) / 2.; return (0); }
int GetDetTemp (Hdr *hdr, int detector, double *temperature) { /* arguments: Hdr *hdr i: header of current extension int detector i: integer code for detector double *temperature o: temperature (degrees C), or -1 if not found */ /* name of keyword (depending on detector) for temperature */ char keyword[STIS_CBUF+1]; int use_def = 1; /* use default if missing keyword */ int status; FitsKw key; /* for testing whether the keyword exists */ *temperature = -1.; /* default */ if (detector == CCD_DETECTOR) { double expstart; /* MJD of exposure start time */ if ((status = Get_KeyD (hdr, "EXPSTART", use_def, -1., &expstart))) return (status); if (expstart < BEGIN_SIDE2) return (0); strcpy (keyword, "OCCDHTAV"); } else if (detector == FUV_MAMA_DETECTOR) { strcpy (keyword, "OM1CAT"); } else if (detector == NUV_MAMA_DETECTOR) { strcpy (keyword, "OM2CAT"); } key = findKw (hdr, keyword); if (key == NotFound) { printf ("Warning keyword %s not found;" \ " no temperature correction applied to sensitivity.\n", keyword); } else { if ((status = Get_KeyD (hdr, keyword, use_def, -1., temperature))) return (status); if (*temperature == -1.) { printf ( "Warning temperature (keyword %s) has default value;\n", keyword); printf ( " no temperature correction applied to sensitivity.\n"); } } return (0); }
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 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 GetGrpInfo1 (StisInfo1 *sts, Hdr *hdr) { /* arguments: StisInfo1 *sts io: calibration switches and info Hdr *hdr i: header of current extension */ int status; char *buf; /* scratch for keyword value */ int sdqflags; /* serious data quality flags */ int rsize; /* 1 for CCD, 2 for MAMA */ int corner[2]; /* subarray start points, detector coords */ double cd11, cd12, cd21, cd22; /* CD matrix */ int doppon; /* Doppler correction done on-board? */ int use_def = 1; /* use default if missing keyword */ int no_default = 0; /* missing keyword is fatal error */ int GetDetTemp (Hdr *, int, double *); int GetEPCTab (StisInfo1 *, float); /* Get generic parameters. */ /* Check whether we're processing a science file or wavecal, based on ASN_MTYP. Note that we won't reset the wavecal flag to false (it may have been set in GetKeyInfo1) if ASN_MTYP doesn't indicate that the observation is a wavecal, because this file might not be part of an association. */ 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" */ if (strstr (buf, "WAVECAL") != NULL) sts->wavecal = 1; free (buf); 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 (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 pixel size (ignore corner location) from ltm & ltv. */ rsize = (sts->detector == CCD_DETECTOR) ? 1 : 2; if ((status = GetCorner (hdr, rsize, sts->bin, corner))) return (status); /* For spectroscopic data, we want the dispersion axis and the sign of the dispersion. We'll get the latter from one element of the CD matrix. We also want the pixel size, which we compute from the CD matrix. */ sts->dispaxis = 1; /* initial values */ sts->dispsign = 1; if (strcmp (sts->obstype, "IMAGING") == 0) { if ((status = Get_KeyD (hdr, "CD1_1", use_def, 1., &cd11))) return (status); if ((status = Get_KeyD (hdr, "CD1_2", use_def, 0., &cd12))) return (status); if ((status = Get_KeyD (hdr, "CD2_1", use_def, 0., &cd21))) return (status); if ((status = Get_KeyD (hdr, "CD2_2", use_def, 1., &cd22))) return (status); sts->cdelt[0] = sqrt (cd11 * cd11 + cd21 * cd21); sts->cdelt[1] = sqrt (cd12 * cd12 + cd22 * cd22); } else if (strcmp (sts->obstype, "SPECTROSCOPIC") == 0) { if ((status = Get_KeyI (hdr, "DISPAXIS", use_def, 1, &sts->dispaxis))) return (status); if ((status = Get_KeyD (hdr, "CD1_1", use_def, 1., &cd11))) return (status); if ((status = Get_KeyD (hdr, "CD2_2", use_def, 1., &cd22))) return (status); if (sts->dispaxis == 1) { if (cd11 >= 0.) sts->dispsign = 1; else sts->dispsign = -1; sts->cdelt[0] = cd22; /* assume square pixels */ sts->cdelt[1] = cd22; } else if (sts->dispaxis == 2) { if (cd22 >= 0.) sts->dispsign = 1; else sts->dispsign = -1; sts->cdelt[0] = cd11; sts->cdelt[1] = cd11; } } sts->detector_temp = -1.; /* initial value (not defined) */ /* Get MAMA-specific parameters. */ if (sts->detector == NUV_MAMA_DETECTOR || sts->detector == FUV_MAMA_DETECTOR) { if ((status = Get_KeyD (hdr, "GLOBRATE", no_default, 0., &sts->globrate))) return (status); /* Get info if we need to do Doppler convolution of ref files. */ if (sts->doppcorr == PERFORM) { /* Was Doppler correction done on-board? */ if ((status = Get_KeyI (hdr, "DOPPON", use_def, 0, &doppon))) return (status); /* doppon could be False in timetag mode. */ if (!doppon) { if (strcmp (sts->obsmode, "TIME-TAG") == 0) { if ((status = Get_KeyD (hdr, "DOPPMAG", use_def, -1., &sts->doppmag))) return (status); doppon = (sts->doppmag > 0.); } } if (doppon) { if ((status = Get_KeyD (hdr, "DOPPZERO", no_default, 0., &sts->doppzero))) return (status); if ((status = Get_KeyD (hdr, "DOPPMAG", no_default, 0., &sts->doppmag))) return (status); if ((status = Get_KeyD (hdr, "ORBITPER", no_default, 0., &sts->orbitper))) return (status); } else { /* Silently reset the switch. */ sts->doppcorr = OMIT; } } } /* Get CCD-specific parameters. */ if (sts->detector == CCD_DETECTOR) { float occdhtav = -1.; /* if OCCDHTAV is present and > 0, then data is from Side B, * so look for EPC file. Otherwise, data is from Side A and * EPC file and temperature can be ignored. */ if (((status = Get_KeyF(hdr, "OCCDHTAV", use_def, -1., &occdhtav)) == 0) && (occdhtav >= 0.)) { char expname[81], epcname[81]; expname[0] = epcname[0] = '\0'; if ((status = Get_KeyS(hdr, "EXPNAME", no_default, "", expname, 80))) return (status); if (sts->crcorr != COMPLETE) { strncpy(epcname, expname, 8); epcname[8] = '\0'; sprintf(sts->epctab.name, "%sj_epc.fits", epcname); PrFileName("epcfile", sts->epctab.name); status = GetEPCTab(sts, 0.40); if (status && status != OPEN_FAILED) return (status); } if ((status = UpdateCCDTemperature(sts, hdr))) return (status); } } /* Get the detector temperature (or housing temperature, if CCD). Note that for side-2 CCD data this function must be called after calling UpdateCCDTemperature. */ if ((status = GetDetTemp (hdr, sts->detector, &sts->detector_temp))) { return (status); } /* If images have been combined (e.g. by cosmic-ray rejection), then determine the number of images that were combined together; we need this for bias image subtraction. (This isn't really a CCD-specific keyword, but it does only affect CCD data in the context of calstis1.) */ if ((status = Get_KeyI (hdr, "NCOMBINE", use_def, 1, &sts->ncombine))) return (status); if (sts->ncombine < 1) { printf ("Warning NCOMBINE = %d, reset to one.\n", sts->ncombine); sts->ncombine = 1; } return (0); }
int GetKeyInfo1 (StisInfo1 *sts, Hdr *phdr) { /* arguments: StisInfo1 *sts io: calibration switches and info Hdr *phdr i: primary header */ int status; int nextend; /* number of FITS extensions */ char targname[STIS_CBUF+1]; /* target name, check if BIAS or DARK */ char crcorr[STIS_CBUF+1]; /* cosmic-ray rejection keyword */ int use_def = 1; /* use default if missing keyword */ int no_default = 0; /* missing keyword is fatal error */ /* Get generic parameters. */ if ((status = Get_KeyS (phdr, "ROOTNAME", no_default, "", sts->rootname, STIS_CBUF))) return (status); if ((status = Get_KeyS (phdr, "OBSMODE", use_def, "unknown", sts->obsmode, STIS_CBUF))) return (status); if ((status = Get_KeyS (phdr, "APERTURE", use_def, "", sts->aperture, STIS_CBUF))) return (status); if ((status = Get_KeyS (phdr, "DETECTOR", no_default, "", sts->det, STIS_CBUF))) return (status); if (strcmp (sts->det, "NUV-MAMA") == 0) { sts->detector = NUV_MAMA_DETECTOR; } else if (strcmp (sts->det, "FUV-MAMA") == 0) { sts->detector = FUV_MAMA_DETECTOR; } else if (strcmp (sts->det, "CCD") == 0) { sts->detector = CCD_DETECTOR; } else { printf ("ERROR DETECTOR = %s is invalid\n", sts->det); return (HEADER_PROBLEM); } /* Grating or mirror name. */ if ((status = Get_KeyS (phdr, "OPT_ELEM", use_def, "", sts->opt_elem, STIS_CBUF))) return (status); /* If TARGNAME is BIAS or DARK, set the flag to indicate this. */ if ((status = Get_KeyS (phdr, "TARGNAME", use_def, "", targname, STIS_CBUF))) return (status); if (strcmp (targname, "BIAS") == 0) sts->bias_exposure = 1; else sts->bias_exposure = 0; if (strcmp (targname, "BIAS") == 0 || strcmp (targname, "DARK") == 0) sts->bias_or_dark = 1; else sts->bias_or_dark = 0; /* If TARGNAME indicates that this is a wavecal observation, set the wavecal flag. */ if (strcmp (targname, "WAVELINE") == 0 || strcmp (targname, "WAVEHITM") == 0) { sts->wavecal = 1; } if ((status = Get_KeyD (phdr, "RA_TARG", no_default, 0., &sts->ra_targ))) return (status); if ((status = Get_KeyD (phdr, "DEC_TARG", no_default, 0., &sts->dec_targ))) return (status); /* Check if CRCORR is complete */ if ((status = Get_KeyS (phdr, "CRCORR", use_def, "", crcorr, STIS_CBUF))) return (status); if (strcmp(crcorr, "COMPLETE") == 0) { sts->crcorr = COMPLETE; } else { sts->crcorr = PERFORM; } /* Find out how many extensions there are in this file. */ if ((status = Get_KeyI (phdr, "NEXTEND", use_def, EXT_PER_GROUP, &nextend))) return (status); /* Convert number of extensions to number of SingleGroups. */ sts->nimages = nextend / EXT_PER_GROUP; if (sts->nimages < 1) { printf ("ERROR NEXTEND = %d; must be at least three.\n", sts->nimages); return (GENERIC_ERROR_CODE); } /* If obstype is spectroscopic and photcorr is set to perform, we will reset photcorr. */ if ((status = Get_KeyS (phdr, "OBSTYPE", use_def, "", sts->obstype, STIS_CBUF))) return (status); if (strcmp (sts->obstype, "IMAGING") != 0 && strcmp (sts->obstype, "SPECTROSCOPIC") != 0) { printf ( "Warning OBSTYPE = %s; should be either IMAGING or SPECTROSCOPIC\n", sts->obstype); } /* For CCD observations, we need the APER_FOV in order to flag regions beyond the aperture for such apertures as F28X50LP. */ if ((status = Get_KeyS (phdr, "APER_FOV", use_def, "", sts->aper_fov, STIS_CBUF))) return (status); /* Get MAMA-specific parameters. */ /* there are none, at present */ /* Get CCD-specific parameters. */ if (sts->detector == CCD_DETECTOR) { if ((status = Get_KeyS (phdr, "CCDAMP", no_default, "", sts->ccdamp, STIS_CBUF-1))) return (status); if (sts->ccdamp[0] != '\0' && sts->ccdamp[1] != '\0') { printf ( "Warning Multiple amp readout `%s' is not supported.\n", sts->ccdamp); } if (islower (sts->ccdamp[0])) sts->ccdamp[0] = toupper (sts->ccdamp[0]); if (strchr ("ABCD", sts->ccdamp[0]) == NULL) { printf ("ERROR CCDAMP = `%s' is invalid.\n", sts->ccdamp); return (GENERIC_ERROR_CODE); } if ((status = Get_KeyI (phdr, "CCDGAIN", use_def, 1, &sts->ccdgain))) return (status); if ((status = Get_KeyI (phdr, "CCDOFFST", use_def, 1, &sts->ccdoffset))) return (status); if ((status = Get_KeyI (phdr, "BINAXIS1", use_def, 1, &sts->binaxis[0]))) return (status); if ((status = Get_KeyI (phdr, "BINAXIS2", use_def, 1, &sts->binaxis[1]))) return (status); } return (0); }
int doAtoD (StisInfo1 *sts, SingleGroup *x) { /* arguments: StisInfo1 *sts i: calibration switches, etc SingleGroup *x io: image to be calibrated; written to in-place */ int status; TblInfo tabinfo; /* pointer to table descriptor, etc */ TblRow tabrow; /* values read from a table row */ TblArray tabarray; /* correction array read from table row */ int foundit; /* row found in table? */ int row; /* loop index for row number */ int row_min; /* row with closest temperature (min dt) */ double ref_key_value; /* value gotten from image header */ double dt, dt_min; /* for finding temperature in table */ int ival; /* input science data value from x */ int i, j; short dq; /* a data quality value */ int no_default = 0; /* missing keyword is fatal error */ if (sts->atodcorr != PERFORM) return (0); if (sts->ncombine > 1) { printf ( "ERROR NCOMBINE is already > 1 before ATODCORR has been performed.\n"); return (GENERIC_ERROR_CODE); } /* Open the A-to-D table. */ if ((status = OpenAtoDTab (sts->atod.name, &tabinfo))) return (status); /* Find the row with value closest to the temperature. */ foundit = 0; for (row = 1; row <= tabinfo.nrows; row++) { if ((status = ReadAtoDTab (&tabinfo, row, &tabrow))) return (status); if (SameString (tabrow.ccdamp, sts->ccdamp) && SameInt (tabrow.ccdgain, sts->ccdgain)) { /* Get value from header. */ if ((status = Get_KeyD (&x->sci.hdr, tabrow.ref_key, no_default, 0., &ref_key_value))) return (status); dt = fabs (ref_key_value - tabrow.ref_key_value); if (!foundit) { foundit = 1; /* assign initial values */ dt_min = dt; row_min = row; } else if (dt < dt_min) { /* update dt_min */ dt_min = dt; row_min = row; } } } if (!foundit) { printf ( "ERROR CCD amp %s, gain %d, not found in ATODTAB `%s'.\n", sts->ccdamp, sts->ccdgain, sts->atod.name); CloseAtoDTab (&tabinfo); return (TABLE_ERROR); } /* Get pedigree & descrip from the row. */ if ((status = RowPedigree (&sts->atod, row_min, tabinfo.tp, tabinfo.cp_pedigree, tabinfo.cp_descrip))) return (status); if (sts->atod.goodPedigree == DUMMY_PEDIGREE) { sts->atodcorr = DUMMY; CloseAtoDTab (&tabinfo); return (0); } /* Reread the appropriate row to get the correction array. */ if ((status = ReadAtoDArray (&tabinfo, row_min, &tabarray))) return (status); /* Apply this correction to each pixel in the image. At this stage the values should still be integers, so assigning a value to an integer (ival) should not result in truncation. */ for (j = 0; j < x->sci.data.ny; j++) { for (i = 0; i < x->sci.data.nx; i++) { ival = (int) Pix (x->sci.data, i, j); if (ival >= tabarray.nelem) { Pix (x->sci.data, i, j) = tabarray.atod[tabarray.nelem-1]; dq = DQPix (x->dq.data, i, j) | SATPIXEL; DQSetPix (x->dq.data, i, j, dq); /* saturated */ } else if (ival >= 0) { Pix (x->sci.data, i, j) = tabarray.atod[ival]; } /* else if ival < 0, no change */ } } free (tabarray.atod); if ((status = CloseAtoDTab (&tabinfo))) return (status); return (0); }
static int FluxToNet (StisInfo6 *sts, IntensArray *inta, int sporder) { /* This is used to store information from the fflux file in a form suitable for the reference file input routines. */ StisInfo6 fsts; ApInfo slit; PhotInfo phot; IODescPtr im; Hdr phdr; double photfactor, throughput, response, dispersion; double atodgain, readnoise; float correction; int i, dispc, helc, status; int abs_starti, thr_starti; int dummy; void FreePhot6 (PhotInfo *); void FreeThroughput6 (ApInfo *); int GetAbsPhot6 (StisInfo6 *, int, PhotInfo *, int, int *); int GetApDes6 (StisInfo6 *, ApInfo *); int GetApThr6 (StisInfo6 *, ApInfo *); int Get_KeyD (Hdr *, char *, int, double, double *); int Get_KeyS (Hdr *, char *, int, char *, char *, int); int GetSwitch (Hdr *, char *, int *); double interp1d (double, double *, double *, int, int *); void StisInit6 (StisInfo6 *); photfactor = H_PLANCK * C_LIGHT / HST_AREA; /* Initialize local data structures. */ StisInit6 (&fsts); InitRefTab (&fsts.phottab); InitRefTab (&fsts.apertab); InitRefTab (&fsts.apdestab); slit.allocated = 0; slit.gac_allocated = 0; phot.allocated = 0; phot.pcorr = NULL; /* Handling the primary header here is not efficient. But keeps this new code manageable since everything new is added at a single point. In the future we may move this to outside the main loop and pass the necessary values as part of the sts structure. */ initHdr (&phdr); im = openInputImage (sts->pxtab.name, "", 0); if (hstio_err()) return (OPEN_FAILED); getHeader (im, &phdr); if (hstio_err()) return (OPEN_FAILED); closeImage (im); /* Abort if both helcorr and dispcorr weren't performed. The criterion is: if a keyword is set to either COMPLETE or PERFORM, we assume that the operation was performed. This is because UpdHdrSwitch in Do1Dx only updates the keywords to COMPLETE if they are set to PERFORM in the input file. (note: UpdHdrSwitch is no longer used) */ if ((status = GetSwitch (&phdr, "DISPCORR", &dispc))) return (status); if ((status = GetSwitch (&phdr, "HELCORR", &helc))) return (status); if (!((dispc == PERFORM || dispc == COMPLETE) && (helc == PERFORM || helc == COMPLETE))) { printf ("ERROR No DISPCORR/HELCORR in fflux file.\n"); return (ERROR_RETURN); } /* Read header keywords. */ if ((status = Get_KeyD (&phdr, "READNSE", 1, 0., &readnoise))) return (status); if ((status = Get_KeyD (&phdr, "ATODGAIN", 1, 1., &atodgain))) return (status); if ((status = Get_KeyS (&phdr, "PHOTTAB", FATAL, "", fsts.phottab.name, STIS_LINE))) return (status); if ((status = Get_KeyS (&phdr, "APDESTAB", FATAL, "", fsts.apdestab.name, STIS_LINE))) return (status); if ((status = Get_KeyS (&phdr, "APERTAB", FATAL, "", fsts.apertab.name, STIS_LINE))) return (status); /* Copy stuff from primary data structure into local one. */ fsts.x1d_o = sts->x1d_o; fsts.dispcorr = sts->dispcorr; fsts.fluxcorr = sts->fluxcorr; fsts.pctcorr = sts->pctcorr; fsts.cenwave = sts->cenwave; strcpy (fsts.opt_elem, sts->opt_elem); strcpy (fsts.aperture, sts->aperture); /* Read the required reference info. */ dummy = 0; if ((status = GetAbsPhot6 (&fsts, sporder, &phot, 0, &dummy))) return (status); if ((status = GetApDes6 (&fsts, &slit))) return (status); if ((status = GetApThr6 (&fsts, &slit))) return (status); abs_starti = 1; /* initial values */ thr_starti = 1; /* Loop over flux array. */ for (i = 0; i < inta->nelem; i++) { response = interp1d (inta->wave[i], phot.wl, phot.thru, phot.nelem, &abs_starti); throughput = interp1d (inta->wave[i], slit.wl, slit.thr, slit.nelem, &thr_starti); if (i > 0) dispersion = inta->wave[i] - inta->wave[i-1]; else dispersion = inta->wave[1] - inta->wave[0]; /* This check is provisional; final version awaits IS's words. */ if (response <= 0.0 || dispersion <= 0.0 || throughput <= 0.0) { printf ("ERROR Error in fflux file contents.\n"); return (ERROR_RETURN); } correction = (float) (photfactor / (response * throughput * inta->wave[i] * dispersion * atodgain * CM_PER_ANGSTROM)); inta->intens[i] = inta->intens[i] / correction; } FreeThroughput6 (&slit); FreePhot6 (&phot); freeHdr (&phdr); return STIS_OK; }
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); }