Beispiel #1
0
/***********************************************************************//**
 * @brief Save event list into FITS file
 *
 * @param[in] obs Pointer to CTA observation.
 * @param[in] infile Input file name.
 * @param[in] outfile Output file name.
 *
 * Saves an event list into a FITS file and copy all others extensions from
 * the input file to the output file.
 ***************************************************************************/
void ctselect::save_event_list(const GCTAObservation* obs,
                               const std::string&     infile,
                               const std::string&     outfile) const
{
    // Save only if observation is valid
    if (obs != NULL) {

        // Save observation into FITS file
        obs->save(outfile, clobber());

        // Copy all extensions other than EVENTS and GTI from the input to
        // the output event list. The EVENTS and GTI extensions are written
        // by the save method, all others that may eventually be present
        // have to be copied by hand.
        GFits infits(infile);
        GFits outfits(outfile);
        for (int extno = 1; extno < infits.size(); ++extno) {
            GFitsHDU* hdu = infits.hdu(extno);
            if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") {
                outfits.append(*hdu);
            }
        }

        // Close input file
        infits.close();

        // Save file to disk and close it (we need both operations)
        outfits.save(true);
        outfits.close();

    } // endif: observation was valid

    // Return
    return;
}
Beispiel #2
0
/***********************************************************************//**
 * @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;
}
Beispiel #3
0
/***********************************************************************//**
 * @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;
}
Beispiel #4
0
/***********************************************************************//**
 * @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;
}
Beispiel #5
0
/***********************************************************************//**
 * @brief Publish FITS HDU
 *
 * @param[in] hdu FITS HDU
 *
 * Publishes a FITS HDU.           
 ***************************************************************************/
void GVOClient::publish(const GFitsHDU& hdu)
{
    // Signal that client should be disconnected after sending the image
    // to Hub
    bool disconnected = !is_connected();

    // Make sure that the client is connected to a Hub
    if (disconnected) {
        connect();
    }

    // Save FITS HDU into a temporary file
    std::string samp_share = std::tmpnam(NULL);
    GFits fits;
    fits.append(hdu);
    fits.saveto(samp_share, true);

    // Get FITS extension name
    std::string extname = hdu.extname();
    if (extname.empty()) {
        extname = "FITS Image";
    }

    // Compose notification to be passed to the Hub
    std::string hub_command = "";
    hub_command.append("<?xml version=\"1.0\"?>\n");
    hub_command.append("<methodCall>\n");
    hub_command.append("  <methodName>samp.hub.notifyAll</methodName>\n");
    hub_command.append("  <params>\n");
    hub_command.append("    <param><value>image.load.fits</value></param>\n");
    hub_command.append("    <param><value>"+m_secret+"</value></param>\n");
    hub_command.append("    <param><value><struct>\n");
    hub_command.append("      <member><name>samp.params</name><value><struct>\n");
    hub_command.append("        <member><name>name</name><value>"+extname+"</value></member>\n");
    hub_command.append("        <member><name>url</name><value>file://localhost"+samp_share+"</value></member>\n");
    hub_command.append("        <member><name>image-id</name><value>Gammalib Data</value></member>\n");
    hub_command.append("      </struct></value></member>\n");
    hub_command.append("      <member><name>samp.mtype</name><value>image.load.fits</value></member>\n");
    hub_command.append("    </struct></value></param>\n");
    hub_command.append("  </params>\n");
    hub_command.append("</methodCall>\n");

    // Send notification
    execute(hub_command);

    // Disconnect client from Hub
    if (disconnected) {
        disconnect();
    }

    // Return
    return;
}
Beispiel #6
0
/***********************************************************************//**
 * @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;
}
Beispiel #7
0
/***********************************************************************//**
 * @brief Write attributes to exposure extension
 *
 * @param[in] hdu FITS HDU.
 ***************************************************************************/
void GCTACubeExposure::write_attributes(GFitsHDU& hdu) const
{
    // Compute some attributes
    double      tstart   = m_gti.tstart().convert(m_gti.reference());
    double      tstop    = m_gti.tstop().convert(m_gti.reference());
    double      telapse  = m_gti.telapse();
    double      ontime   = m_gti.ontime();
    double      deadc    = (ontime > 0.0 && m_livetime > 0.0) ? 
                           m_livetime / ontime : 1.0;
    std::string utc_obs  = m_gti.tstart().utc();
    std::string utc_end  = m_gti.tstop().utc();
    std::string date_obs = utc_obs.substr(0, 10);
    std::string time_obs = utc_obs.substr(11, 8);
    std::string date_end = utc_end.substr(0, 10);
    std::string time_end = utc_end.substr(11, 8);

    // Set observation information
    hdu.card("CREATOR",  "GammaLib", "Program which created the file");
    hdu.card("TELESCOP", "unknown",  "Telescope");
    hdu.card("OBS_ID",   "unknown",  "Observation identifier");
    hdu.card("DATE_OBS", date_obs,   "Observation start date");
    hdu.card("TIME_OBS", time_obs,   "Observation start time");
    hdu.card("DATE_END", date_end,   "Observation end date");
    hdu.card("TIME_END", time_end,   "Observation end time");

    // Set observation time information
    hdu.card("TSTART",   tstart, "[s] Mission time of start of observation");
    hdu.card("TSTOP",    tstop, "[s] Mission time of end of observation");
    m_gti.reference().write(hdu);
    hdu.card("TELAPSE",  telapse, "[s] Mission elapsed time");
    hdu.card("ONTIME",   ontime, "[s] Total good time including deadtime");
    hdu.card("LIVETIME", m_livetime, "[s] Total livetime");
    hdu.card("DEADC",    deadc, "Deadtime correction factor");
    hdu.card("TIMEDEL",  1.0, "Time resolution");

    // Return
    return;
}
Beispiel #8
0
/***********************************************************************//**
 * @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;
}