# include # include /* malloc */ # include # include # include "../acs.h" # include "../acsinfo.h" # include "../acserr.h" typedef struct { IRAFPointer tp; /* pointer to table descriptor */ /* column descriptors */ IRAFPointer cp_filter1; /* filter1 */ IRAFPointer cp_filter2; /* filter2 */ 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 filter1[ACS_CBUF]; char filter2[ACS_CBUF]; } TblRow; static int OpenPhotTab (char *, 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: FILTER: filter name (string) NELEM: actual number of elements in arrays (int) WAVELENGTH: array of wavelengths (read as float) THROUGHPUT: array of throughputs (float) The table is read to find the row for which the value of FILTER is the same as in the input image header. For that row, the number of elements NELEM is read, and the arrays of wavelength and throughput are read. The synphot routine phopar is then called to determine the inverse sensitivity, reference magnitude (actually a constant), pivot wavelength, and RMS bandwidth. These are written to keywords in the primary header. Warren Hack, 1998 June 12: Initial ACS version. Selects on both filter names in one row... */ int GetPhot (ACSInfo *acs2d, PhotInfo *phot) { /* arguments: ACSInfo *acs2d i: calibration switches, etc PhotInfo *phot o: QE throughput values are allocated and assigned */ extern int status; TblInfo tabinfo; /* pointer to table descriptor, etc */ TblRow tabrow; /* values read from a table row */ int row; /* loop index */ int foundit; /* true if parameters found in table */ int RowPedigree (RefTab *, int, IRAFPointer, IRAFPointer, IRAFPointer); int SameString (char *, char *); /* Open the photometry table. */ if (OpenPhotTab (acs2d->phot.name, &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. */ foundit = 0; for (row = 1; row <= tabinfo.nrows; row++) { if (ReadPhotTab (&tabinfo, row, &tabrow)) return (status); /* WE ARE GOING TO HAVE BOTH FILTERS ON ONE ROW... */ if (SameString (tabrow.filter1, acs2d->filter1) && SameString (tabrow.filter2, acs2d->filter2)) { foundit = 1; /* Get pedigree & descrip from the row. */ if (RowPedigree (&acs2d->phot, row, tabinfo.tp, tabinfo.cp_pedigree, tabinfo.cp_descrip)) return (status); if (acs2d->phot.goodPedigree == DUMMY_PEDIGREE) { acs2d->photcorr = DUMMY; ClosePhotTab (&tabinfo); return (status); } /* Read wavelengths and throughputs into phot. */ if (ReadPhotArray (&tabinfo, row, phot)) return (status); break; } } if (ClosePhotTab (&tabinfo)) return (status); if (!foundit) { sprintf (MsgText, "FILTER %s not found in PHOTTAB %s", acs2d->filter1, acs2d->phot.name); trlerror (MsgText); return (status = ROW_NOT_FOUND); } return (status); } /* 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, TblInfo *tabinfo) { extern int status; tabinfo->tp = c_tbtopn (tname, IRAF_READ_ONLY, 0); if (c_iraferr()) { sprintf (MsgText, "PHOTTAB `%s' not found.", tname); trlerror (MsgText); return (status = OPEN_FAILED); } tabinfo->nrows = c_tbpsta (tabinfo->tp, TBL_NROWS); /* Find the columns. */ c_tbcfnd1 (tabinfo->tp, "FILTER1", &tabinfo->cp_filter1); c_tbcfnd1 (tabinfo->tp, "FILTER2", &tabinfo->cp_filter2); 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_filter1 == 0 || tabinfo->cp_filter2 == 0 || tabinfo->cp_nelem == 0 || tabinfo->cp_wl == 0 || tabinfo->cp_thru == 0) { trlerror ("Column not found in PHOTTAB.\n"); c_tbtclo (tabinfo->tp); return (status = COLUMN_NOT_FOUND); } /* Pedigree and descrip are optional columns. */ c_tbcfnd1 (tabinfo->tp, "PEDIGREE", &tabinfo->cp_pedigree); c_tbcfnd1 (tabinfo->tp, "DESCRIP", &tabinfo->cp_descrip); return (status); } /* This routine reads the filter name, which is used to select the correct row. */ static int ReadPhotTab (TblInfo *tabinfo, int row, TblRow *tabrow) { extern int status; c_tbegtt (tabinfo->tp, tabinfo->cp_filter1, row, tabrow->filter1, ACS_CBUF-1); c_tbegtt (tabinfo->tp, tabinfo->cp_filter2, row, tabrow->filter2, ACS_CBUF-1); if (c_iraferr()) return (status = TABLE_ERROR); return (status); } /* This routine reads the array data from one row. The number of elements in the arrays is gotten, the array is allocated, and the wavelengths and throughputs are read into the arrays. */ static int ReadPhotArray (TblInfo *tabinfo, int row, PhotInfo *phot) { extern int status; 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->p_nelem); if (c_iraferr()) return (status = TABLE_ERROR); phot->p_wl = calloc (phot->p_nelem, sizeof(float)); phot->p_thru = calloc (phot->p_nelem, sizeof(float)); if (phot->p_wl == NULL || phot->p_thru == NULL) return (status = OUT_OF_MEMORY); nwl = c_tbagtr (tabinfo->tp, tabinfo->cp_wl, row, phot->p_wl, 1, phot->p_nelem); if (status = c_iraferr()) return (status = TABLE_ERROR); nthru = c_tbagtr (tabinfo->tp, tabinfo->cp_thru, row, phot->p_thru, 1, phot->p_nelem); if (status = c_iraferr()) return (status = TABLE_ERROR); if (nwl < phot->p_nelem || nthru < phot->p_nelem) { c_tbtclo (tabinfo->tp); trlerror ("Not all coefficients were read from PHOTTAB."); return (status = TABLE_ERROR); } return (status); } /* This routine closes the phottab table. */ static int ClosePhotTab (TblInfo *tabinfo) { extern int status; c_tbtclo (tabinfo->tp); if (c_iraferr()) return (status = TABLE_ERROR); return (status); }