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; }
static int getHalo (StisInfo6 *sts, int nelem, double wavelength[], float net[], CTICorrInfo *cti) { /* arguments: StisInfo6 *sts i: calibration switches and info int nelem i: size of arrays double wavelength[] i: wavelength at each pixel float net[] i: net count rate CTICorrInfo *cti io: nelem and haloterm will be assigned */ PhotInfo phot_200; /* PCT info for extrheight = 200 */ double extrheight = 200.; /* 200 pixel extraction height */ double net_to_electrons; int i; int warn = WARN; /* yes, print a warning if appropriate */ int status; void FreePhot6 (PhotInfo *); int GetPCT6 (StisInfo6 *, PhotInfo *, double, int); cti->nelem = nelem; cti->haloterm = calloc (nelem, sizeof (double)); if (cti->haloterm == NULL) return (OUT_OF_MEMORY); cti->allocated = 1; if (sts->ctecorr != PERFORM) return (0); if (strcmp (sts->opt_elem, "G750L") != 0 && strcmp (sts->opt_elem, "G750M") != 0) { return (0); } /* wl, thru, and error must be allocated, and the wl array must have the wavelengths we want. */ phot_200.nelem = nelem; phot_200.wl = malloc (nelem * sizeof (double)); phot_200.thru = malloc (nelem * sizeof (double)); phot_200.error = malloc (nelem * sizeof (double)); phot_200.pcorr = NULL; /* allocated in GetPCT6 */ phot_200.allocated = 1; if (phot_200.wl == NULL || phot_200.thru == NULL || phot_200.error == NULL) { return (OUT_OF_MEMORY); } /* copy the wavelengths, converting back to observed wavelength */ for (i = 0; i < nelem; i++) phot_200.wl[i] = wavelength[i] / sts->hfactor; /* This function will get the PC factors and interpolate them onto the wavelength scale we just assigned in phot_200. */ if ((status = GetPCT6 (sts, &phot_200, extrheight, warn)) != 0) { FreePhot6 (&phot_200); return (status); } net_to_electrons = sts->atodgain * sts->exptime / sts->ncombine; for (i = 0; i < nelem; i++) { cti->haloterm[i] = ((phot_200.pcorr[i] - 1.) / 2. - cti->halominfrac) * net[i] * net_to_electrons; if (cti->haloterm[i] < 0.) cti->haloterm[i] = 0.; else cti->haloterm[i] *= cti->halofac; } FreePhot6 (&phot_200); return (0); }