Example #1
0
/***********************************************************************//**
 * @brief Read GTIs from HDU.
 *
 * @param[in] hdu GTI table.
 *
 * Reads the Good Time Intervals from the GTI extension. Since the Fermi
 * LAT Science Tools do not set corrently the time reference for source
 * maps, the method automatically adds this missing information so that
 * the time reference is set correctly. The time reference that is assumed
 * for Fermi LAT is
 *
 *      MJDREFI 51910
 *      MJDREFF 0.00074287037037037
 * 
 ***************************************************************************/
void GLATEventCube::read_gti(const GFitsTable& hdu)
{
    // Work on a local copy of the HDU to make the kluge work
    GFitsTable* hdu_local = hdu.clone();

    // Kluge: modify HDU table in case that the MJDREF header keyword is
    // blank. This happens for Fermi LAT source maps since the Science
    // Tools do not properly write out the time reference. We hard-code
    // here the Fermi LAT time reference to circumvent the problem.
    if (hdu.has_card("MJDREF")) {
        if (gammalib::strip_whitespace(hdu.string("MJDREF")).empty()) {
            hdu_local->header().remove("MJDREF");
            hdu_local->card("MJDREFI", 51910,
                            "Integer part of MJD reference");
            hdu_local->card("MJDREFF", 0.00074287037037037,
                            "Fractional part of MJD reference");
        }
    }

    // Read Good Time Intervals
    m_gti.read(*hdu_local);

    // Set time
    set_times();

    // Return
    return;
}
Example #2
0
/***********************************************************************//**
 * @brief Read Pulse Height Analyzer spectrum
 *
 * @param[in] table FITS table.
 *
 * @exception GException::invalid_value
 *            Mismatch between PHA file and energy boundaries.
 *
 * Reads the Pulse Height Analyzer spectrum from a FITS table. The channel
 * values are expected in the `COUNTS` column of the table. All other
 * columns are ignored.
 *
 * See
 * https://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/spectra/ogip_92_007/node5.html
 * for details about the Pulse Height Analyzer spectrum format.
 ***************************************************************************/
void GPha::read(const GFitsTable& table)
{
    // Clear spectrum
    clear();

    // Get data column
    const GFitsTableCol* col_data = table["COUNTS"];

    // Extract number of channels in FITS file
    int length = col_data->length();

    // Check whether column length is consistent with energy boundaries
    if (m_ebounds.size() > 0) {
        if (m_ebounds.size() != length) {
            std::string msg = "Mismatch between the "+gammalib::str(length)+
                              " channels in the PHA file and the "+
                              gammalib::str(m_ebounds.size())+" energy "
                              "boundaries. Please correct either the energy "
                              "boundaris or the PHA file.";
            throw GException::invalid_value(G_READ, msg);
        }
    }

    // Initialize spectrum
    m_counts.assign(length, 0.0);

    // Copy data
    for (int i = 0; i < length; ++i) {
        m_counts[i] = col_data->real(i);
    }

    // Read keywords
    m_exposure = (table.has_card("EXPOSURE")) ? table.real("EXPOSURE") : 0.0;

    // Return
    return;
}
Example #3
0
/***********************************************************************//**
 * @brief Read spectrum from FITS file
 *
 * @param[in] table FITS table.
 *
 * @exception GMWLException::bad_file_format
 *            Table has invalid format
 *
 * Read spectrum from FITS table. The table is expected to be in one of the
 * three following formats:
 * 2 columns: energy, flux
 * 3 columns: energy, flux, e_flux
 * 4 columns or more:  energy, e_energy, flux, e_flux, ...
 *
 * @todo Investigate whether we can exploit UCDs for identifying the correct
 * columns or for determining the units.
 ***************************************************************************/
void GMWLSpectrum::read_fits(const GFitsTable& table)
{
    // Reset spectrum
    m_data.clear();

    // Initialise column pointers columns
    const GFitsTableCol* c_energy     = NULL;
    const GFitsTableCol* c_energy_err = NULL;
    const GFitsTableCol* c_flux       = NULL;
    const GFitsTableCol* c_flux_err   = NULL;

    // Extract column pointers
    if (table.ncols() == 2) {
        c_energy = table[0];
        c_flux   = table[1];
    }
    else if (table.ncols() == 3) {
        c_energy   = table[0];
        c_flux     = table[1];
        c_flux_err = table[2];
    }
    else if (table.ncols() > 3) {
        c_energy     = table[0];
        c_energy_err = table[1];
        c_flux       = table[2];
        c_flux_err   = table[3];
    }
    else {
        throw GMWLException::bad_file_format(G_READ_FITS,
                             "At least 2 columns are expected is table \""+
                              table.extname()+"\".");
    }

    // Read spectral points and add to spectrum
    for (int i = 0; i < table.nrows(); ++i) {
        GMWLDatum datum;
        if (c_energy     != NULL) {
            datum.m_eng = conv_energy(c_energy->real(i), c_energy->unit());
        }
        if (c_energy_err != NULL) {
            datum.m_eng_err = conv_energy(c_energy_err->real(i), c_energy->unit());
        }
        if (c_flux       != NULL) {
            datum.m_flux = conv_flux(datum.m_eng, c_flux->real(i), c_flux->unit());
        }
        if (c_flux_err   != NULL) {
            datum.m_flux_err = conv_flux(datum.m_eng, c_flux_err->real(i), c_flux_err->unit());
        }
        m_data.push_back(datum);
    }

    // Get telescope name
    if (table.has_card("TELESCOP")) {
        m_telescope = table.string("TELESCOP");
    }
    else {
        m_telescope = "unknown";
    }

    // Get instrument name
    if (table.has_card("INSTRUME")) {
        m_instrument = table.string("INSTRUME");
    }
    else {
        m_instrument = "unknown";
    }

    // Set energy boundaries
    set_ebounds();

    // Return
    return;
}
Example #4
0
/***********************************************************************//**
 * @brief Read LAT events from FITS table.
 *
 * @param[in] table Event table.
 *
 * Read the LAT events from the event table.
 ***************************************************************************/
void GLATEventList::read_events(const GFitsTable& table)
{
    // Clear existing events
    m_events.clear();

    // Allocate space for keyword name
    char keyword[10];

    // Extract number of events in FT1 file
    int num = table.integer("NAXIS2");

    // If there are events then load them
    if (num > 0) {

        // Reserve data
        m_events.reserve(num);

        // Get column pointers
        const GFitsTableCol* ptr_time    = table["TIME"];
        const GFitsTableCol* ptr_energy  = table["ENERGY"];
        const GFitsTableCol* ptr_ra      = table["RA"];
        const GFitsTableCol* ptr_dec     = table["DEC"];
        const GFitsTableCol* ptr_theta   = table["THETA"];
        const GFitsTableCol* ptr_phi     = table["PHI"];
        const GFitsTableCol* ptr_zenith  = table["ZENITH_ANGLE"];
        const GFitsTableCol* ptr_azimuth = table["EARTH_AZIMUTH_ANGLE"];
        const GFitsTableCol* ptr_eid     = table["EVENT_ID"];
        const GFitsTableCol* ptr_rid     = table["RUN_ID"];
        const GFitsTableCol* ptr_recon   = table["RECON_VERSION"];
        const GFitsTableCol* ptr_calib   = table["CALIB_VERSION"];
        const GFitsTableCol* ptr_class   = table["EVENT_CLASS"];
        const GFitsTableCol* ptr_conv    = table["CONVERSION_TYPE"];
        const GFitsTableCol* ptr_ltime   = table["LIVETIME"];

        // Copy data from columns into GLATEventAtom objects
        GLATEventAtom event;
        for (int i = 0; i < num; ++i) {
            event.m_time.set(ptr_time->real(i), m_gti.reference());
            event.m_energy.MeV(ptr_energy->real(i));
            event.m_dir.dir().radec_deg(ptr_ra->real(i), ptr_dec->real(i));
            event.m_theta               = ptr_theta->real(i);
            event.m_phi                 = ptr_phi->real(i);
            event.m_zenith_angle        = ptr_zenith->real(i);
            event.m_earth_azimuth_angle = ptr_azimuth->real(i);
            event.m_event_id            = ptr_eid->integer(i);
            event.m_run_id              = ptr_rid->integer(i);
            event.m_recon_version       = ptr_recon->integer(i);
            event.m_calib_version[0]    = ptr_calib->integer(i,0);
            event.m_calib_version[1]    = ptr_calib->integer(i,1);
            event.m_calib_version[2]    = ptr_calib->integer(i,2);
            event.m_event_class         = ptr_class->integer(i);
            event.m_conversion_type     = ptr_conv->integer(i);
            event.m_livetime            = ptr_ltime->real(i);
            m_events.push_back(event);
        }

        // Extract number of diffuse response labels
        int num_difrsp = table.integer("NDIFRSP");

        // Allocate diffuse response components
        if (num_difrsp > 0) {

            // Reserve space
            m_difrsp_label.reserve(num_difrsp);

            // Allocate components
            for (int i = 0; i < num; ++i) {
                m_events[i].m_difrsp = new double[num_difrsp];
            }

            // Load diffuse columns
            for (int k = 0; k < num_difrsp; ++k) {

                // Set keyword name
                std::sprintf(keyword, "DIFRSP%d", k);

                // Get DIFRSP label
                if (table.has_card(std::string(keyword))) {
                    m_difrsp_label.push_back(table.string(std::string(keyword)));
                }
                else {
                    m_difrsp_label.push_back("NONE");
                }

                // Get column pointer
                const GFitsTableCol* ptr_dif = table[std::string(keyword)];

                // Copy data from columns into GLATEventAtom objects
                for (int i = 0; i < num; ++i) {
                    m_events[i].m_difrsp[k] = ptr_dif->real(i);
                }

            } // endfor: looped over diffuse columns

        } // endif: diffuse components found

    } // endif: events found

    // Return
    return;
}