/***********************************************************************//** * @brief Save point spread function table into FITS file * * @param[in] filename FITS file name. * @param[in] clobber Overwrite existing file? (default: false) * * Saves point spread function into a FITS file. If a file with the given * @p filename does not yet exist it will be created, otherwise the method * opens the existing file. The method will create a (or replace an existing) * point spread function extension. The extension name can be specified as * part of the @p filename, or if no extension name is given, is assumed to * be "POINT SPREAD FUNCTION". * * An existing file will only be modified if the @p clobber flag is set to * true. ***************************************************************************/ void GCTAPsfTable::save(const GFilename& filename, const bool& clobber) const { // Get extension name std::string extname = filename.extname("POINT SPREAD FUNCTION"); // Open or create FITS file (without extension name since the requested // extension may not yet exist in the file) GFits fits(filename.url(), true); // Remove extension if it exists already if (fits.contains(extname)) { fits.remove(extname); } // Create binary table GFitsBinTable table; // Write the background table write(table); // Set binary table extension name table.extname(extname); // Append table to FITS file fits.append(table); // Save to file fits.save(clobber); // Return return; }
/***********************************************************************//** * @brief Write energy boundaries into FITS object * * @param[in] file FITS file. * @param[in] extname Energy boundary extension name (defaults to "EBOUNDS") * @param[in] unit Energy units (defaults to "keV") * * Writes the energy boundaries into a FITS object. The @p unit parameter * specifies in which unit the energies are written. By default, the energy * units are keV. * * @todo Write header keywords. ***************************************************************************/ void GEbounds::write(GFits& file, const std::string& extname, const std::string& unit) const { // Create energy boundary columns GFitsTableDoubleCol cemin = GFitsTableDoubleCol("E_MIN", m_num); GFitsTableDoubleCol cemax = GFitsTableDoubleCol("E_MAX", m_num); // Fill energy boundary columns for (int i = 0; i < m_num; ++i) { cemin(i) = m_min[i](unit); cemax(i) = m_max[i](unit); } // Set energy units cemin.unit(unit); cemax.unit(unit); // Create binary table GFitsBinTable* table = new GFitsBinTable(m_num); table->append(cemin); table->append(cemax); table->extname(extname); // Write to FITS file file.append(*table); // Free table delete table; // Return return; }
/***********************************************************************//** * @brief Write Good Time Intervals and time reference into FITS object * * @param[in] file FITS file. * @param[in] extname GTI extension name (defaults to "GTI") * * Saves Good Time Intervals and time reference into a FITS object. If the * file does not exist it is created. If the file exists the GTI is appended * as extension. If another GTI exists already it is overwritten if * @p clobber=true. * * @todo Implement clobber method for overwriting of existing GTIs. ***************************************************************************/ void GGti::write(GFits& file, const std::string& extname) const { // Create GTI columns GFitsTableDoubleCol cstart = GFitsTableDoubleCol("START", m_num); GFitsTableDoubleCol cstop = GFitsTableDoubleCol("STOP", m_num); // Fill GTI columns in specified time reference for (int i = 0; i < m_num; ++i) { cstart(i) = m_start[i].convert(m_reference); cstop(i) = m_stop[i].convert(m_reference); } // Create GTI table GFitsBinTable* table = new GFitsBinTable(m_num); table->append(cstart); table->append(cstop); table->extname(extname); // Write time reference m_reference.write(*table); // Write to FITS file file.append(*table); // Free table delete table; // Return return; }
/***********************************************************************//** * @brief Save PSF table into FITS file * * @param[in] filename PSF table FITS file name. * @param[in] clobber Overwrite existing file? (true=yes) * * Save the PSF table into a FITS file. ***************************************************************************/ void GCTAPsf2D::save(const std::string& filename, const bool& clobber) const { // Create binary table GFitsBinTable table; table.extname("POINT SPREAD FUNCTION"); // Write the PSF table write(table); // Create FITS file, append table, and write into the file GFits fits; fits.append(table); fits.saveto(filename, clobber); // Return return; }
/***********************************************************************//** * @brief Write Auxiliary Response File * * @param[in] fits FITS file. * * Writes the Auxiliary Response File into the `SPECRESP` extension of the * FITS file. An existing extension with the same name will be removed from * the FITS file before writing. * * The method writes the boundaries of the true energy bins into the * `ENERG_LO` and `ENERG_HI` columns, response information will be written * into the `SPECRESP` column. * * See * http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/docs/memos/cal_gen_92_002/cal_gen_92_002.html#tth_sEc4 * for details about the Auxiliary Response File format. ***************************************************************************/ void GArf::write(GFits& fits) const { // If the FITS object contains already an extension with the same // name then remove now this extension if (fits.contains("SPECRESP")) { fits.remove("SPECRESP"); } // Set column length int length = size(); // Continue only if there are bins if (length > 0) { // Create new binary table GFitsBinTable hdu; // Allocate floating point vector columns GFitsTableFloatCol energy_lo("ENERG_LO", length); GFitsTableFloatCol energy_hi("ENERG_HI", length); GFitsTableFloatCol specresp("SPECRESP", length); // Fill columns for (int i = 0; i < length; ++i) { energy_lo(i) = (float)m_ebounds.emin(i).keV(); energy_hi(i) = (float)m_ebounds.emax(i).keV(); specresp(i) = (float)m_specresp[i]; } // Set column units energy_lo.unit("keV"); energy_hi.unit("keV"); specresp.unit("cm^2"); // Set table attributes hdu.extname("SPECRESP"); // Append columns to table hdu.append(energy_lo); hdu.append(energy_hi); hdu.append(specresp); // Append any additional columns for (int icol = 0; icol < columns(); ++icol) { // Allocate floating point vector columns GFitsTableFloatCol column(m_colnames[icol], length); // Fill columns for (int i = 0; i < length; ++i) { column(i) = (float)m_coldata[icol][i]; } // Append columns to table hdu.append(column); } // endfor: looped over all additional columns // Append HDU to FITS file fits.append(hdu); } // endif: there were data to write // Return return; }
/***********************************************************************//** * @brief Write Pulse Height Analyzer spectrum * * @param[in] fits FITS file. * * Writes the Pulse Height Analyzer spectrum into `SPECTRUM` and `EBOUNDS` * extensions of the FITS file. Extensions with these names will be removed * from the FITS file before writing. * * The columns `CHANNEL`, `COUNTS`, `STAT_ERR`, `SYS_ERR`, `QUALITY`, * `GROUPING`, `AREASCAL`, and `BACKSCAL` will be written into the `SPECTRUM` * extension, but only the `CHANNEL` and `COUNTS` columns will be filled with * values. Note that the channels start from 1 in the Pulse Height Analyzer * spectrum. * * See * https://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/spectra/ogip_92_007/node5.html * for details about the PHA file format. ***************************************************************************/ void GPha::write(GFits& fits) const { // Remove extensions if they exist already if (fits.contains("EBOUNDS")) { fits.remove("EBOUNDS"); } if (fits.contains("SPECTRUM")) { fits.remove("SPECTRUM"); } // Set column length int length = size(); // Continue only if there are bins if (length > 0) { // Create new binary table GFitsBinTable hdu; // Allocate floating point vector columns GFitsTableShortCol col_chan("CHANNEL", length); GFitsTableFloatCol col_data("COUNTS", length); GFitsTableFloatCol col_stat("STAT_ERR", length); GFitsTableFloatCol col_syst("SYS_ERR", length); GFitsTableShortCol col_qual("QUALITY", length); GFitsTableShortCol col_grpg("GROUPING", length); GFitsTableFloatCol col_area("AREASCAL", length); GFitsTableFloatCol col_back("BACKSCAL", length); // Fill columns for (int i = 0; i < length; ++i) { col_chan(i) = i+1; // Channels start at 1 col_data(i) = float(m_counts[i]); } // Set table attributes hdu.extname("SPECTRUM"); // Append columns to table hdu.append(col_chan); hdu.append(col_data); hdu.append(col_stat); hdu.append(col_syst); hdu.append(col_qual); hdu.append(col_grpg); hdu.append(col_area); hdu.append(col_back); // Write keywords hdu.card("EXPOSURE", m_exposure, "[s] Deadtime corrected exposure time"); // Append HDU to FITS file fits.append(hdu); // Optionally append energy boundaries if (m_ebounds.size() > 0) { m_ebounds.write(fits); } } // endif: there were data to write // Return return; }