/***********************************************************************//** * @brief Load Pulse Height Analyzer spectrum * * @param[in] filename File name. * * Loads the Pulse Height Analyzer spectrum from the `SPECTRUM` extension * of the FITS file. If the file contains also an `EBOUNDS` extension the * energy boundaries of all Pulse Height Analyzer channels are also loaded. ***************************************************************************/ void GPha::load(const GFilename& filename) { // Clear spectrum clear(); // Open FITS file (without extension name as the user is not allowed // to modify the extension names) GFits fits(filename.url()); // Get PHA table const GFitsTable& pha = *fits.table("SPECTRUM"); // Read PHA data read(pha); // Optionally read EBOUNDS data if (fits.contains("EBOUNDS")) { // Get EBOUNDS table const GFitsTable& ebounds = *fits.table("EBOUNDS"); // Read EBOUNDS data m_ebounds.read(ebounds); } // endif: has EBOUNDS table // Close FITS file fits.close(); // Store filename m_filename = filename.url(); // Return return; }
/***********************************************************************//** * @brief Load effective area from performance table * * @param[in] filename Performance table file name. * * @exception GCTAExceptionHandler::file_open_error * File could not be opened for read access. * * This method loads the effective area information from an ASCII * performance table. ***************************************************************************/ void GCTAAeffPerfTable::load(const GFilename& filename) { // Clear arrays m_logE.clear(); m_aeff.clear(); // Allocate line buffer const int n = 1000; char line[n]; // Open performance table readonly FILE* fptr = std::fopen(filename.url().c_str(), "r"); if (fptr == NULL) { throw GCTAException::file_open_error(G_LOAD, filename.url()); } // Read lines while (std::fgets(line, n, fptr) != NULL) { // Split line in elements. Strip empty elements from vector. std::vector<std::string> elements = gammalib::split(line, " "); for (int i = elements.size()-1; i >= 0; i--) { if (gammalib::strip_whitespace(elements[i]).length() == 0) { elements.erase(elements.begin()+i); } } // Skip header if (elements[0].find("log(E)") != std::string::npos) { continue; } // Break loop if end of data table has been reached if (elements[0].find("----------") != std::string::npos) { break; } // Push elements in node array and vector m_logE.append(gammalib::todouble(elements[0])); m_aeff.push_back(gammalib::todouble(elements[1])*10000.0); } // endwhile: looped over lines // Close file std::fclose(fptr); // Store filename m_filename = filename; // Return return; }
/***********************************************************************//** * @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 Save Auxiliary Response File * * @param[in] filename File name. * @param[in] clobber Overwrite existing file? * * Saves the Auxiliary Response File into a FITS file. If a file with the * given @p filename does not yet exist it will be created. If the file * exists it can be overwritten if the @p clobber flag is set to `true`. * Otherwise an exception is thrown. * * The method will save the `SPECRESP` binary FITS table into the FITS file * that contains the values of the Auxiliary Response File. ***************************************************************************/ void GArf::save(const GFilename& filename, const bool& clobber) const { // Create FITS file GFits fits; // Write ARF into file write(fits); // Save to file (without extension name since the requested extension // may not yet exist in the file) fits.saveto(filename.url(), clobber); // Store filename m_filename = filename.url(); // Return return; }
/***********************************************************************//** * @brief Load Auxiliary Response File * * @param[in] filename File name. * * Loads the Auxiliary Response File from the `SPECRESP` extension of the * FITS file. ***************************************************************************/ void GArf::load(const GFilename& filename) { // Clear response clear(); // Open FITS file (without extension name as the user is not allowed // to modify the extension names) GFits fits(filename.url()); // Get ARF table const GFitsTable& table = *fits.table("SPECRESP"); // Read ARF data read(table); // Close FITS file fits.close(); // Store filename m_filename = filename.url(); // Return return; }
/***********************************************************************//** * @brief Save XML document into file * * @param[in] filename File name. * * Saves the XML document into a file by writing into the file's Unified * Resource Locator (URL). The write() method is invoked for this purpose. * * The method uses the GUrlFile file opening constructor to open the URL. * This constructor will automatically expand any environment variables that * are present in the filename. * * @todo Ideally, we would like to extract the URL type from the filename * so that any kind of URL can be used for loading. ***************************************************************************/ void GXml::save(const GFilename& filename) { // Open XML file for writing GUrlFile url(filename.url().c_str(), "w"); // Store filename in XML document m_root.filename(filename); // Write XML document write(url, 0); // Close file url.close(); // Return return; }
/***********************************************************************//** * @brief Load XML document from file * * @param[in] filename File name. * * Loads a XML document from a file by reading from the file's Unified * Resource Locator (URL). The read() method is invoked for this purpose. * * The method uses the GUrlFile file opening constructor to open the URL. * This constructor will automatically expand any environment variables that * are present in the filename. * * @todo Ideally, we would like to extract the URL type from the filename * so that any kind of URL can be used for loading. ***************************************************************************/ void GXml::load(const GFilename& filename) { // Throw an exception if file does not exist if (!filename.exists()) { throw GException::file_open_error(G_LOAD, filename); } // Open XML URL as file for reading GUrlFile url(filename.url().c_str(), "r"); // Read XML document from URL read(url); // Close URL url.close(); // Store filename in XML document m_root.filename(filename); // Return return; }
/***********************************************************************//** * @brief Load background from performance table * * @param[in] filename Performance table file name. * * @exception GException::file_open_error * File could not be opened for read access. * * Loads the background information from a performance table. ***************************************************************************/ void GCTABackgroundPerfTable::load(const GFilename& filename) { // Clear arrays m_logE.clear(); m_background.clear(); // Allocate line buffer const int n = 1000; char line[n]; // Open performance table readonly FILE* fptr = std::fopen(filename.url().c_str(), "r"); if (fptr == NULL) { throw GException::file_open_error(G_LOAD, filename.url()); } // Read lines while (std::fgets(line, n, fptr) != NULL) { // Split line in elements. Strip empty elements from vector. std::vector<std::string> elements = gammalib::split(line, " "); for (int i = elements.size()-1; i >= 0; i--) { if (gammalib::strip_whitespace(elements[i]).length() == 0) { elements.erase(elements.begin()+i); } } // Skip header if (elements[0].find("log(E)") != std::string::npos) { continue; } // Break loop if end of data table has been reached if (elements[0].find("----------") != std::string::npos) { break; } // Determine on-axis background rate (counts/s/MeV/sr) double logE = gammalib::todouble(elements[0]); double r80 = gammalib::todouble(elements[3]) * gammalib::deg2rad; double bgrate = gammalib::todouble(elements[5]); // in Hz double emin = std::pow(10.0, logE-0.1) * 1.0e6; double emax = std::pow(10.0, logE+0.1) * 1.0e6; double ewidth = emax - emin; // in MeV double solidangle = gammalib::twopi * (1.0 - std::cos(r80)); // in sr if (solidangle > 0.0) { bgrate /= (solidangle * ewidth); // counts/s/MeV/sr } else { bgrate = 0.0; } // Push elements in node array and vector m_logE.append(logE); #if defined(G_LOG_INTERPOLATION) m_background.push_back(std::log10(bgrate)); #else m_background.push_back(bgrate); #endif } // endwhile: looped over lines // Close file std::fclose(fptr); // Store filename m_filename = filename; // Return return; }
/***********************************************************************//** * @brief Load nodes from file * * @param[in] filename File name. * * @exception GException::file_function_data * File contains less than 2 nodes * @exception GException::file_function_columns * File contains less than 2 columns * @exception GException::file_function_value * File contains invalid value * * The file function is stored as a column separated value table (CSV) in an * ASCII file with (at least) 2 columns. The first column specifies the * energy in MeV while the second column specifies the intensity at this * energy in units of ph/cm2/s/MeV. * The node energies and values will be stored both linearly and as log10. * The log10 storing requires that node energies and node values are * positive. Also, at least 2 nodes and 2 columns are required in the file * function. ***************************************************************************/ void GModelSpectralFunc::load_nodes(const GFilename& filename) { // Clear nodes and values m_lin_nodes.clear(); m_log_nodes.clear(); m_lin_values.clear(); m_log_values.clear(); // Set filename m_filename = filename; // Load file GCsv csv = GCsv(filename.url()); // Check if there are at least 2 nodes if (csv.nrows() < 2) { throw GException::file_function_data(G_LOAD_NODES, filename.url(), csv.nrows()); } // Check if there are at least 2 columns if (csv.ncols() < 2) { throw GException::file_function_columns(G_LOAD_NODES, filename.url(), csv.ncols()); } // Setup nodes double last_energy = 0.0; for (int i = 0; i < csv.nrows(); ++i) { // Get log10 of node energy and value. Make sure they are valid. double log10energy; double log10value; if (csv.real(i,0) > 0) { log10energy = std::log10(csv.real(i,0)); } else { throw GException::file_function_value(G_LOAD_NODES, filename.url(), csv.real(i,0), "Energy value must be positive."); } if (csv.real(i,1) > 0) { log10value = std::log10(csv.real(i,1)); } else { throw GException::file_function_value(G_LOAD_NODES, filename.url(), csv.real(i,1), "Intensity value must be positive."); } // Make sure that energies are increasing if (csv.real(i,0) <= last_energy) { throw GException::file_function_value(G_LOAD_NODES, filename.url(), csv.real(i,0), "Energy values must be monotonically increasing."); } // Append log10 of node energy and value m_lin_nodes.append(csv.real(i,0)); m_log_nodes.append(log10energy); m_lin_values.push_back(csv.real(i,1)); m_log_values.push_back(log10value); // Store last energy for monotonically increasing check last_energy = csv.real(i,0); } // endfor: looped over nodes // Set pre-computation cache set_cache(); // Return return; }