Ejemplo n.º 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;
}
Ejemplo n.º 2
0
/***********************************************************************//**
 * @brief Read effective area from FITS table
 *
 * @param[in] hdu FITS table.
 *
 * @exception GLATException::inconsistent_response
 *            Inconsistent response table encountered
 *
 * The effective area is converted into units of cm2.
 ***************************************************************************/
void GLATAeff::read_aeff(const GFitsTable& hdu)
{
    // Clear array
    m_aeff.clear();

    // Get energy and cos theta bins in response table
    m_aeff_bins.read(hdu);

    // Set minimum cos(theta)
    m_min_ctheta = m_aeff_bins.costheta_lo(0);

    // Continue only if there are effective area bins
    int size = m_aeff_bins.size();
    if (size > 0) {

        // Allocate arrays
        m_aeff.reserve(size);

        // Get pointer to effective area column
        const GFitsTableCol* ptr = hdu["EFFAREA"];

        // Check consistency of effective area table
        int num = ptr->number();
        if (num != size) {
            throw GLATException::inconsistent_response(G_READ_AEFF, num, size);
        }

        // Copy data and convert from m2 into cm2
        for (int i = 0; i < size; ++i) {
            m_aeff.push_back(ptr->real(0,i) * 1.0e4);
        }

    } // endif: there were effective area bins

    // Set detector section using the DETNAM keyword in the HDU
    std::string detnam = gammalib::strip_whitespace(hdu.string("DETNAM"));
    m_front            = (detnam == "FRONT");
    m_back             = (detnam == "BACK");

    // Return
    return;
}
Ejemplo n.º 3
0
/***********************************************************************//**
 * @brief Load livetime cube from FITS file
 *
 * @param[in] table FITS table.
 ***************************************************************************/
void GLATLtCubeMap::read(const GFitsTable& table)
{
    // Clear object
    clear();

    // Load skymap
    m_map.read(table);

    // Set costheta binning scheme
    std::string scheme =
        gammalib::strip_whitespace(gammalib::toupper(table.string("THETABIN")));
    m_sqrt_bin = (scheme == "SQRT(1-COSTHETA)");

    // Read attributes
    m_num_ctheta = table.integer("NBRBINS");
    m_num_phi    = table.integer("PHIBINS");
    m_min_ctheta = table.real("COSMIN");

    // Return
    return;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}