/***********************************************************************//** * @brief Return Good Time Intervals extension name from data sub-space keywords * * @param[in] hdu FITS HDU * @return Good Time Interval extension name * * @exception GException::invalid_value * Invalid Good Time Intervals data sub-space encountered * * Returns the name of the FITS extension that contains the Good Time * Intervals by screening the data sub-space keywords that are present in * the FITS header. The method searches for a DSTYPx keyword named "TIME" * and a corresponding DSVALx keyword named "TABLE", and the extension name * is extracted from the corresponding DSREFx keyword. Note that by * convention the extension name is preceeded by a colon, which is stripped * by this method. ***************************************************************************/ std::string gammalib::read_ds_gti_extname(const GFitsHDU& hdu) { // Initialise extension name std::string extname; // Get number of data sub-space keys (default to 0 if "NDSKEYS" keyword // is not found) int ndskeys = (hdu.has_card("NDSKEYS")) ? hdu.integer("NDSKEYS") : 0; // Loop over all data sub-space keys for (int i = 1; i <= ndskeys; ++i) { // Set data sub-space key strings std::string type_key = "DSTYP"+gammalib::str(i); std::string unit_key = "DSUNI"+gammalib::str(i); std::string value_key = "DSVAL"+gammalib::str(i); std::string ref_key = "DSREF"+gammalib::str(i); // Skip if DSTYPi keyword does not exist, or if it is not "TIME" if (!hdu.has_card(type_key) || hdu.string(type_key) != "TIME") { continue; } // If DSVALi keyword does not exist or if it's value is not // "TABLE" then throw an exception if (!hdu.has_card(value_key)) { std::string msg = "Keyword \""+value_key+"\" missing for data " "sub-space selection of type "+type_key+ "=\"TIME\". Please correct FITS header."; throw GException::invalid_value(G_READ_DS_GTI, msg); } if (hdu.string(value_key) != "TABLE") { std::string msg = "Cannot interpret keyword \""+value_key+"\" " "value \""+hdu.string(value_key)+"\". Only " "the value \"TABLE\" is supported."; throw GException::invalid_value(G_READ_DS_GTI, msg); } // If DSREFi keyword does not exist then throw an exception if (!hdu.has_card(ref_key)) { std::string msg = "Keyword \""+ref_key+"\" missing for data " "sub-space selection of type "+type_key+ "=\"TIME\". Please correct FITS header."; throw GException::invalid_value(G_READ_DS_GTI, msg); } // Get extension name (strip any leading and trailing colons) extname = gammalib::strip_whitespace(gammalib::strip_chars(hdu.string(ref_key), ":")); } // endfor: looped over data sub-space keywords // Return return extname; }
/***********************************************************************//** * @brief Extract ROI from data sub-space keywords * * @param[in] hdu FITS HDU * * @exception GException::invalid_value * Invalid ROI data sub-space encountered * * Reads the ROI data sub-space keywords by searching for a DSTYPx keyword * named "POS(RA,DEC)". The data sub-space information is expected to be in * the format "CIRCLE(267.0208,-24.78,4.5)", where the 3 arguments are Right * Ascension, Declination and radius in units of degrees. No detailed syntax * checking is performed. * * If no ROI information has been found, an GCTARoi object with initial * values will be returned. ***************************************************************************/ GCTARoi gammalib::read_ds_roi(const GFitsHDU& hdu) { // Initialise ROI GCTARoi roi; // Get number of data sub-space keywords (default to 0 if keyword is // not found) int ndskeys = (hdu.has_card("NDSKEYS")) ? hdu.integer("NDSKEYS") : 0; // Loop over all data selection keys for (int i = 1; i <= ndskeys; ++i) { // Set data sub-space key strings std::string type_key = "DSTYP"+gammalib::str(i); //std::string unit_key = "DSUNI"+gammalib::str(i); std::string value_key = "DSVAL"+gammalib::str(i); // Continue only if type_key is found and if this key is POS(RA,DEC) if (hdu.has_card(type_key) && hdu.string(type_key) == "POS(RA,DEC)") { // ... //std::string unit = gammalib::toupper(hdu.string(unit_key)); std::string value = hdu.string(value_key); std::string value_proc = gammalib::strip_chars(value, "CIRCLE("); value_proc = gammalib::strip_chars(value_proc, ")"); std::vector<std::string> args = gammalib::split(value_proc, ","); if (args.size() == 3) { double ra = gammalib::todouble(args[0]); double dec = gammalib::todouble(args[1]); double rad = gammalib::todouble(args[2]); GCTAInstDir dir; dir.dir().radec_deg(ra, dec); roi.centre(dir); roi.radius(rad); } else { std::string msg = "Invalid acceptance cone value \""+value+ "\" encountered in data sub-space " "key \""+value_key+"\"."; throw GException::invalid_value(G_READ_DS_ROI, msg); } } // endif: POS(RA,DEC) type found } // endfor: looped over data sub-space keys // Return roi return roi; }
/***********************************************************************//** * @brief Read exposure attributes * * @param[in] hdu FITS HDU. * * Reads CTA exposure attributes from the HDU. ***************************************************************************/ void GCTACubeExposure::read_attributes(const GFitsHDU& hdu) { // Read mandatory attributes m_livetime = (hdu.has_card("LIVETIME")) ? hdu.real("LIVETIME") : 0.0; // Return return; }
/***********************************************************************//** * @brief Read energy boundary data sub-space keywords * * @param[in] hdu FITS HDU * * @exception GException::invalid_value * Invalid energy data sub-space encountered * * Reads the energy boundary data sub-space keywords by searching for a * DSTYPx keyword named "ENERGY". The data sub-space information is expected * to be in the format "200:50000", where the 2 arguments are the minimum * and maximum energy. The energy unit is given by the keyword DSUNIx, which * supports keV, MeV, GeV and TeV (case independent). No detailed syntax * checking is performed. ***************************************************************************/ GEbounds gammalib::read_ds_ebounds(const GFitsHDU& hdu) { // Initialise energy boundaries GEbounds ebounds; // Get number of data sub-space keywords (default to 0 if keyword is // not found) int ndskeys = (hdu.has_card("NDSKEYS")) ? hdu.integer("NDSKEYS") : 0; // Loop over all data sub-space keys for (int i = 1; i <= ndskeys; ++i) { // Set data sub-space key strings std::string type_key = "DSTYP"+gammalib::str(i); std::string unit_key = "DSUNI"+gammalib::str(i); std::string value_key = "DSVAL"+gammalib::str(i); // Continue only if type_key is found and if this key is ENERGY if (hdu.has_card(type_key) && hdu.string(type_key) == "ENERGY") { // Extract energy boundaries std::string value = hdu.string(value_key); std::string unit = hdu.string(unit_key); std::vector<std::string> values = gammalib::split(value, ":"); if (values.size() == 2) { double emin = gammalib::todouble(values[0]); double emax = gammalib::todouble(values[1]); GEnergy e_min(emin, unit); GEnergy e_max(emax, unit); ebounds.append(e_min, e_max); } else { std::string msg = "Invalid energy value \""+value+ "\" encountered in data selection key \""+ value_key+"\""; throw GException::invalid_value(G_READ_DS_EBOUNDS, msg); } } // endif: ENERGY type_key found } // endfor: looped over data selection keys // Return return ebounds; }
/***********************************************************************//** * @brief Read data selection keywords from FITS HDU. * * @param[in] hdu FITS HDU pointer. * * @todo Declared header card const in to GFitsHDU. * @todo Add check key method to GFitsHDU to avoid unneccesary try/catch * blocks. ***************************************************************************/ void GLATEventList::read_ds_keys(const GFitsHDU& hdu) { // Get number of data selection keys int ds_num = hdu.integer("NDSKEYS"); // Get data selection keys if (ds_num > 0) { // Circumvent const correctness. We need this because the header() // card method is not declared const. This should be corrected. //GFitsHDU* ptr = (GFitsHDU*)&hdu; // Reserve space m_ds_type.reserve(ds_num); m_ds_unit.reserve(ds_num); m_ds_value.reserve(ds_num); m_ds_reference.reserve(ds_num); // Allocate space for the keyword char keyword[10]; // Get columns for (int i = 0; i < ds_num; ++i) { // Get DSTYPnn std::sprintf(keyword, "DSTYP%d", i+1); if (hdu.has_card(std::string(keyword))) { m_ds_type.push_back(hdu.string(std::string(keyword))); } else { m_ds_type.push_back(""); } // Get DSUNInn std::sprintf(keyword, "DSUNI%d", i+1); if (hdu.has_card(std::string(keyword))) { m_ds_unit.push_back(hdu.string(std::string(keyword))); } else { m_ds_unit.push_back(""); } // Get DSVALnn std::sprintf(keyword, "DSVAL%d", i+1); if (hdu.has_card(std::string(keyword))) { m_ds_value.push_back(hdu.string(std::string(keyword))); } else { m_ds_value.push_back(""); } // Get DSREFnn std::sprintf(keyword, "DSREF%d", i+1); if (hdu.has_card(std::string(keyword))) { m_ds_reference.push_back(hdu.string(std::string(keyword))); } else { m_ds_reference.push_back(""); } } // endfor: looped over data selection keys } // endif: there were data selection keys // Return return; }