# include # include /* malloc */ # include /* strcpy */ # include # include # include "../stis.h" # include "calstis7.h" # include "../stiserr.h" typedef struct { IRAFPointer tp; /* pointer to table descriptor */ /* column descriptors */ IRAFPointer cp_opt_elem; /* mirror or grating */ IRAFPointer cp_cenwave; IRAFPointer cp_sporder; IRAFPointer cp_nelem; IRAFPointer cp_wl; IRAFPointer cp_thru; IRAFPointer cp_pedigree; IRAFPointer cp_descrip; int nrows; /* number of rows in table */ } TblInfo; typedef struct { char opt_elem[STIS_CBUF+1]; int cenwave; int sporder; } TblRow; static int OpenPhotTab (char *, int, TblInfo *); static int ReadPhotTab (TblInfo *, int, TblRow *); static int ReadPhotArray (TblInfo *, int, PhotInfo *); static int ClosePhotTab (TblInfo *); /* This routine gets the absolute flux conversion from PHOTTAB and saves the info in the photometry information structure. The absolute-flux table should contain the following: header parameters: none used columns: OPT_ELEM: grating name (string) CENWAVE: central wavelength (int) SPORDER: spectral order (int) NELEM: actual number of elements in arrays (int) WAVELENGTH: array of wavelengths (double) THROUGHPUT: array of throughputs (float) The table is read to find the row for which the value of OPT_ELEM is the same as in the input image header. For spectroscopic data, CENWAVE is also compared with the header, and SPORDER must be the current spectral order being processed. For that row, the number of elements NELEM is read, memory is allocated in the phot structure for the arrays of wavelength and throughput, and those arrays are read. When done, the memory should be freed by calling freePhot. Phil Hodge, 2000 Jan 13: Add one to opt_elem buffer size. */ int GetAbsPhot (StisInfo7 *sts, int sporder, PhotInfo *phot) { /* arguments: StisInfo *sts i: calibration switches and info int sporder i: current order number PhotInfo *phot o: factors to convert to absolute flux */ int status; TblInfo tabinfo; /* pointer to table descriptor, etc */ TblRow tabrow; /* values read from a table row */ int row; /* loop index */ int foundit = 0; /* true if parameters found in table */ int RowPedigree (RefTab *, int, IRAFPointer, IRAFPointer, IRAFPointer); int SameInt (int, int); int SameString (char *, char *); /* Assign the units for the calibrated data. */ strcpy (phot->bunit, "erg /s /cm**2 /angstrom /arcsec**2"); /* Open the photometry table. */ if (status = OpenPhotTab (sts->phottab.name, sts->obstype, &tabinfo)) return (status); /* Check each row for a match with keyword values, then read the arrays of wavelength and throughput if there's a match. */ for (row = 1; row <= tabinfo.nrows; row++) { if (status = ReadPhotTab (&tabinfo, row, &tabrow)) return (status); if (sts->obstype == SPECTROSCOPIC_TYPE) { if (!SameInt (tabrow.cenwave, sts->cenwave) || !SameInt (tabrow.sporder, sporder)) continue; } if (SameString (tabrow.opt_elem, sts->opt_elem)) { foundit = 1; /* Get pedigree & descrip from the row. */ if (status = RowPedigree (&sts->phottab, row, tabinfo.tp, tabinfo.cp_pedigree, tabinfo.cp_descrip)) return (status); if (sts->phottab.goodPedigree == DUMMY_PEDIGREE) { printf ("Warning DUMMY pedigree in row %d of %s.\n", row, sts->phottab.name); sts->x2dcorr_o = DUMMY; ClosePhotTab (&tabinfo); return (0); } /* Read wavelengths and throughputs into phot. */ if (status = ReadPhotArray (&tabinfo, row, phot)) return (status); break; } } if (status = ClosePhotTab (&tabinfo)) return (status); if (!foundit) { printf ("Warning Matching row not found in PHOTTAB %s; \\\n", sts->phottab.name); if (sts->obstype == SPECTROSCOPIC_TYPE) { printf ("Warning OPT_ELEM %s, CENWAVE %d, SPORDER %d.\n", sts->opt_elem, sts->cenwave, sporder); } else { printf ("Warning OPT_ELEM %s\n", sts->opt_elem); } sts->x2dcorr_o = OMIT; } return (0); } /* This routine opens the throughput table, finds the columns that we need, and gets the total number of rows in the table. */ static int OpenPhotTab (char *tname, int obstype, TblInfo *tabinfo) { tabinfo->tp = c_tbtopn (tname, IRAF_READ_ONLY, 0); if (c_iraferr()) { printf ("ERROR PHOTTAB `%s' not found.\n", tname); return (OPEN_FAILED); } tabinfo->nrows = c_tbpsta (tabinfo->tp, TBL_NROWS); /* Find the columns. */ c_tbcfnd1 (tabinfo->tp, "OPT_ELEM", &tabinfo->cp_opt_elem); c_tbcfnd1 (tabinfo->tp, "NELEM", &tabinfo->cp_nelem); c_tbcfnd1 (tabinfo->tp, "WAVELENGTH", &tabinfo->cp_wl); c_tbcfnd1 (tabinfo->tp, "THROUGHPUT", &tabinfo->cp_thru); if (tabinfo->cp_opt_elem == 0 || tabinfo->cp_nelem == 0 || tabinfo->cp_wl == 0 || tabinfo->cp_thru == 0) { printf ("ERROR Column not found in PHOTTAB.\n"); c_tbtclo (tabinfo->tp); return (COLUMN_NOT_FOUND); } if (obstype == SPECTROSCOPIC_TYPE) { c_tbcfnd1 (tabinfo->tp, "CENWAVE", &tabinfo->cp_cenwave); c_tbcfnd1 (tabinfo->tp, "SPORDER", &tabinfo->cp_sporder); if (tabinfo->cp_cenwave == 0 || tabinfo->cp_sporder == 0) { printf ( "ERROR Column (CENWAVE or SPORDER) not found in PHOTTAB.\n"); c_tbtclo (tabinfo->tp); return (COLUMN_NOT_FOUND); } } else { /* Flag the fact that we didn't try to find these columns. */ tabinfo->cp_cenwave = 0; tabinfo->cp_sporder = 0; } /* Pedigree and descrip are optional columns. */ c_tbcfnd1 (tabinfo->tp, "PEDIGREE", &tabinfo->cp_pedigree); c_tbcfnd1 (tabinfo->tp, "DESCRIP", &tabinfo->cp_descrip); return (0); } /* This routine reads the columns used to select the correct row. The grating name, central wavelength, and spectral order number are gotten. */ static int ReadPhotTab (TblInfo *tabinfo, int row, TblRow *tabrow) { c_tbegtt (tabinfo->tp, tabinfo->cp_opt_elem, row, tabrow->opt_elem, STIS_CBUF); if (c_iraferr()) return (TABLE_ERROR); if (tabinfo->cp_cenwave != 0) { c_tbegti (tabinfo->tp, tabinfo->cp_cenwave, row, &tabrow->cenwave); if (c_iraferr()) return (TABLE_ERROR); c_tbegti (tabinfo->tp, tabinfo->cp_sporder, row, &tabrow->sporder); if (c_iraferr()) return (TABLE_ERROR); } else { tabrow->cenwave = 0; tabrow->sporder = 0; } return (0); } /* This routine reads the array data from one row. The number of elements in the arrays is gotten, the arrays are allocated, and the wavelengths and throughputs are read into the arrays. */ static int ReadPhotArray (TblInfo *tabinfo, int row, PhotInfo *phot) { int nwl, nthru; /* number of elements actually read */ /* Find out how many elements there are in the throughput arrays, and allocate space for the arrays to be read from the table. */ c_tbegti (tabinfo->tp, tabinfo->cp_nelem, row, &phot->nelem); if (c_iraferr()) return (TABLE_ERROR); phot->wl = (double *) malloc (phot->nelem * sizeof(double)); phot->thru = (double *) malloc (phot->nelem * sizeof(double)); if (phot->wl == NULL || phot->thru == NULL) return (OUT_OF_MEMORY); nwl = c_tbagtd (tabinfo->tp, tabinfo->cp_wl, row, phot->wl, 1, phot->nelem); if (c_iraferr()) return (TABLE_ERROR); nthru = c_tbagtd (tabinfo->tp, tabinfo->cp_thru, row, phot->thru, 1, phot->nelem); if (c_iraferr()) return (TABLE_ERROR); if (nwl < phot->nelem || nthru < phot->nelem) { c_tbtclo (tabinfo->tp); free (phot->wl); free (phot->thru); printf ("ERROR Not all coefficients were read from PHOTTAB.\n"); return (TABLE_ERROR); } phot->allocated = 1; /* set flag */ return (0); } /* This routine closes the phottab table. */ static int ClosePhotTab (TblInfo *tabinfo) { c_tbtclo (tabinfo->tp); if (c_iraferr()) return (TABLE_ERROR); return (0); }