示例#1
0
/***********************************************************************//**
 * @brief Read exposure cube from FITS object
 *
 * @param[in] fits FITS object.
 *
 * Read the exposure cube from a FITS object.
 ***************************************************************************/
void GCTACubeExposure::read(const GFits& fits)
{
    // Clear object
    clear();

    // Get HDUs
    const GFitsImage& hdu_expcube = *fits.image("Primary");
    const GFitsTable& hdu_ebounds = *fits.table("EBOUNDS");
    const GFitsTable& hdu_gti     = *fits.table("GTI");

    // Read cube
    m_cube.read(hdu_expcube);

    // Read cube attributes
    read_attributes(hdu_expcube);

    // Read energy boundaries
    m_ebounds.read(hdu_ebounds);

    // Read GTIs
    m_gti.read(hdu_gti);

    // Set energy node array
    set_eng_axis();

    // Return
    return;
}
示例#2
0
/***********************************************************************//**
 * @brief Write CTA event cube into FITS file.
 *
 * @param[in] fits FITS file.
 *
 * Writes CTA event cube into a FITS file. The following HDUs will be written
 *
 *      COUNTS - Counts cube
 *      WEIGHTS - Weights for each counts cube bin
 *      EBOUNDS - Energy boundaries
 *      GTI - Good Time Intervals
 *
 * The counts cube will be written as a double precision sky map. The
 * weighing cube contains the weight for each counts cube, computed as the
 * fraction of the event bin that has been selected in filling the counts
 * cube. This allows to account for proper stacking of observations with
 * different energy thresholds, or different regions of interest. The energy
 * boundaries for all counts cube layers are also written, as well as the
 * Good Time Intervals that have been used in generating the counts cube.
 ***************************************************************************/
void GCTAEventCube::write(GFits& fits) const
{
    // Remove HDUs if they exist already
    if (fits.contains("GTI")) {
        fits.remove("GTI");
    }
    if (fits.contains("EBOUNDS")) {
        fits.remove("EBOUNDS");
    }
    if (fits.contains("WEIGHTS")) {
        fits.remove("WEIGHTS");
    }
    if (fits.contains("COUNTS")) {
        fits.remove("COUNTS");
    }
    if (fits.contains("Primary")) {
        fits.remove("Primary");
    }

    // Write counts cube
    m_map.write(fits, "COUNTS");

    // Write cube weighting
    m_weights.write(fits, "WEIGHTS");

    // Write energy boundaries
    ebounds().write(fits);

    // Write Good Time intervals
    gti().write(fits);

    // Return
    return;
}
示例#3
0
/***********************************************************************//**
 * @brief Read spectrum from FITS file
 *
 * @param[in] fits FITS file.
 * @param[in] extno Extension number of spectrum.
 *
 * @exception GMWLException::file_open_error
 *            No table found in file.
 *
 * Read the spectrum from a FITS table found in the specified extension.
 * In no extension number if specified (or if extno=0) then the spectrum
 * is loaded from the first table extension that is found in the file.
 ***************************************************************************/
void GMWLSpectrum::read(const GFits& fits, const int& extno)
{
    // Clear object
    clear();

    // Initialise extension number
    int extension = extno;

    // If the extension number is 0 then load first FITS table in file.
    if (extension == 0) {
        for (int i = 0; i < fits.size(); ++i) {
            if (fits.at(i)->exttype() == GFitsHDU::HT_ASCII_TABLE ||
                fits.at(i)->exttype() == GFitsHDU::HT_BIN_TABLE) {
                extension = i;
                break;
            }
        }
    }

    // If we found no table then throw an exception
    if (extension == 0) {
        throw GMWLException::file_open_error(G_READ, fits.filename().url(),
                                             "No table found in file.");
    }

    // Get table pointer
    const GFitsTable& table = *fits.table(extension);

    // Read spectrum from table
    read_fits(table);

    // Return
    return;
}
示例#4
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;
}
示例#5
0
/***********************************************************************//**
 * @brief Save CTA event cube into FITS file
 *
 * @param[in] filename FITS filename.
 * @param[in] clobber Overwrite existing FITS file (default=false).
 *
 * Save the CTA event cube into FITS file.
 ***************************************************************************/
void GCTAEventCube::save(const std::string& filename, bool clobber) const
{
    // Create empty FITS file
    GFits fits;

    // Write event cube
    write(fits);
    
    // Save FITS file
    fits.saveto(filename, clobber);

    // Return
    return;
}
示例#6
0
/***********************************************************************//**
 * @brief Save LAT event cube into FITS file
 *
 * @param[in] filename FITS file name.
 * @param[in] clobber Overwrite existing FITS file? (default: false)
 *
 * Save the LAT event cube into FITS file.
 ***************************************************************************/
void GLATEventCube::save(const GFilename& filename,
                         const bool&      clobber) const
{
    // Create empty FITS file
    GFits fits;

    // Write event cube into FITS file
    write(fits);
    
    // Save FITS file
    fits.saveto(filename, clobber);

    // Return
    return;
}
示例#7
0
文件: GGti.cpp 项目: TarekHC/gammalib
/***********************************************************************//**
 * @brief Save Good Time Intervals intervals to FITS file
 *
 * @param[in] filename FITS filename.
 * @param[in] clobber Overwrite any existing GTI extension?
 * @param[in] extname GTI extension name (defaults to "GTI")
 *
 * Saves Good Time Intervals into extension @p extname of a FITS file. If the
 * file does not exist it is created. If the file exists the GTI is appended
 * as extension. If another GTI exists already it is overwritten if
 * @p clobber=true.
 ***************************************************************************/
void GGti::save(const std::string& filename, const bool& clobber,
                const std::string& extname) const
{
    // Allocate FITS file
    GFits file;

    // Write GTI to FITS file
    write(file, extname);

    // Save to file
    file.saveto(filename, clobber);

    // Return
    return;
}
示例#8
0
/***********************************************************************//**
 * @brief Write energy boundaries into FITS object
 *
 * @param[in] file FITS file.
 * @param[in] extname Energy boundary extension name (defaults to "EBOUNDS")
 * @param[in] unit Energy units (defaults to "keV")
 *
 * Writes the energy boundaries into a FITS object. The @p unit parameter
 * specifies in which unit the energies are written. By default, the energy
 * units are keV.
 *
 * @todo Write header keywords.
 ***************************************************************************/
void GEbounds::write(GFits&             file,
                     const std::string& extname,
                     const std::string& unit) const
{
    // Create energy boundary columns
    GFitsTableDoubleCol cemin = GFitsTableDoubleCol("E_MIN", m_num);
    GFitsTableDoubleCol cemax = GFitsTableDoubleCol("E_MAX", m_num);

    // Fill energy boundary columns
    for (int i = 0; i < m_num; ++i) {
        cemin(i) = m_min[i](unit);
        cemax(i) = m_max[i](unit);
    }

    // Set energy units
    cemin.unit(unit);
    cemax.unit(unit);

    // Create binary table
    GFitsBinTable* table = new GFitsBinTable(m_num);
    table->append(cemin);
    table->append(cemax);
    table->extname(extname);

    // Write to FITS file
    file.append(*table);

    // Free table
    delete table;

    // Return
    return;
}
示例#9
0
文件: GGti.cpp 项目: TarekHC/gammalib
/***********************************************************************//**
 * @brief Write Good Time Intervals and time reference into FITS object
 *
 * @param[in] file FITS file.
 * @param[in] extname GTI extension name (defaults to "GTI")
 *
 * Saves Good Time Intervals and time reference into a FITS object. If the
 * file does not exist it is created. If the file exists the GTI is appended
 * as extension. If another GTI exists already it is overwritten if
 * @p clobber=true.
 *
 * @todo Implement clobber method for overwriting of existing GTIs.
 ***************************************************************************/
void GGti::write(GFits& file, const std::string& extname) const
{
    // Create GTI columns
    GFitsTableDoubleCol cstart = GFitsTableDoubleCol("START", m_num);
    GFitsTableDoubleCol cstop  = GFitsTableDoubleCol("STOP", m_num);

    // Fill GTI columns in specified time reference
    for (int i = 0; i < m_num; ++i) {
        cstart(i) = m_start[i].convert(m_reference);
        cstop(i)  = m_stop[i].convert(m_reference);
    }

    // Create GTI table
    GFitsBinTable* table = new GFitsBinTable(m_num);
    table->append(cstart);
    table->append(cstop);
    table->extname(extname);

    // Write time reference
    m_reference.write(*table);

    // Write to FITS file
    file.append(*table);

    // Free table
    delete table;

    // Return
    return;
}
示例#10
0
/***********************************************************************//**
 * @brief Save exposure cube into FITS file
 *
 * @param[in] filename Exposure cube FITS file name.
 * @param[in] clobber Overwrite existing file? (true=yes)
 *
 * Save the exposure cube into a FITS file.
 *
 * @todo Implement method
 ***************************************************************************/
void GCTACubeExposure::save(const std::string& filename, const bool& clobber) const
{
    // Create empty FITS file
    GFits fits;

    // Write exposure cube
    write(fits);

    // Save FITS file
    fits.saveto(filename, clobber);

    // Store filename
    m_filename = filename;

    // Return
    return;
}
示例#11
0
/***********************************************************************//**
 * @brief Save energy boundaries into FITS file
 *
 * @param[in] filename FITS filename.
 * @param[in] clobber Overwrite any existing file  (defaults to false)?
 * @param[in] extname Energy boundary extension name (defaults to "EBOUNDS").
 * @param[in] unit Energy units (defaults to "keV")
 *
 * Saves the energy boundaries into extension @p extname of a FITS file.
 ***************************************************************************/
void GEbounds::save(const std::string& filename,
                    const bool&        clobber,
                    const std::string& extname,
                    const std::string& unit) const
{
    // Allocate FITS file
    GFits file;

    // Write energy boundaries to FITS file
    write(file, extname, unit);

    // Save to file
    file.saveto(filename, clobber);

    // Return
    return;
}
示例#12
0
/***********************************************************************//**
 * @brief Save PSF table into FITS file
 *
 * @param[in] filename PSF table FITS file name.
 * @param[in] clobber Overwrite existing file? (true=yes)
 *
 * Save the PSF table into a FITS file.
 ***************************************************************************/
void GCTAPsf2D::save(const std::string& filename, const bool& clobber) const
{
    // Create binary table
    GFitsBinTable table;
    table.extname("POINT SPREAD FUNCTION");

    // Write the PSF table
    write(table);

    // Create FITS file, append table, and write into the file
    GFits fits;
    fits.append(table);
    fits.saveto(filename, clobber);

    // Return
    return;
}
示例#13
0
/***********************************************************************//**
 * @brief Read LAT events from FITS file.
 *
 * @param[in] file FITS file.
 *
 * This method read the LAT event list from a FITS file.
 *
 * The method clears the object before loading, thus any events residing in
 * the object before loading will be lost.
 ***************************************************************************/
void GLATEventList::read(const GFits& file)
{
    // Clear object
    clear();

    // Get HDU (pointer is always valid)
    const GFitsTable& hdu = *file.table("EVENTS");

    // Read event data
    read_events(hdu);

    // Read data selection keywords
    read_ds_keys(hdu);

    // If we have a GTI extension, then read Good Time Intervals from that
    // extension
    if (file.contains("GTI")) {
        const GFitsTable& gti = *file.table("GTI");
        m_gti.read(gti);
    }

    // ... otherwise build GTI from TSTART and TSTOP
    else {

        // Read start and stop time
        double tstart = hdu.real("TSTART");
        double tstop  = hdu.real("TSTOP");

        // Create time reference from header information
        GTimeReference timeref(hdu);
        
        // Set start and stop time
        GTime start(tstart);
        GTime stop(tstop);

        // Append start and stop time as single time interval to GTI
        m_gti.append(start, stop);

        // Set GTI time reference
        m_gti.reference(timeref);

    } // endelse: GTI built from TSTART and TSTOP

    // Return
    return;
}
示例#14
0
/***********************************************************************//**
 * @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;
}
示例#15
0
/***********************************************************************//**
 * @brief Load energy boundaries from FITS file
 *
 * @param[in] filename FITS filename.
 * @param[in] extname FITS extension name (defaults to "EBOUNDS").
 *
 * Loads the energy boundaries from FITS file.
 ***************************************************************************/
void GEbounds::load(const std::string& filename, const std::string& extname)
{
    // Allocate FITS file
    GFits file;

    // Open FITS file
    file.open(filename);

    // Get energy boundary table
    const GFitsTable& table = *file.table(extname);

    // Read energy boundaries from table
    read(table);

    // Close FITS file
    file.close();

    // Return
    return;
}
示例#16
0
文件: GGti.cpp 项目: TarekHC/gammalib
/***********************************************************************//**
 * @brief Load Good Time Intervals from FITS file
 *
 * @param[in] filename FITS filename.
 * @param[in] extname GTI extension name (defaults to "GTI")
 *
 * Loads the Good Time Intervals from FITS file.
 ***************************************************************************/
void GGti::load(const std::string& filename, const std::string& extname)
{
    // Allocate FITS file
    GFits file;

    // Open FITS file
    file.open(filename);

    // Get GTI table
    const GFitsTable& table = *file.table(extname);

    // Read GTI from table
    read(table);

    // Close FITS file
    file.close();

    // Return
    return;
}
示例#17
0
/***********************************************************************//**
 * @brief Read effective area from FITS file
 *
 * @param[in] fits FITS file.
 *
 * Reads the effective area and efficiency parameter information form the
 * FITS file. The effective area is read from the extension EFFECTIVE AREA,
 * the efficiency parameter information from the extension EFFICIENCY_PARAMS.
 * If the latter extension does not exist, no efficiency parameters will be
 * loaded.
 *
 * @todo Implement reading of Phi-dependence information.
 ***************************************************************************/
void GLATAeff::read(const GFits& fits)
{
    // Clear instance
    clear();

    // Get pointer to effective area HDU
    const GFitsTable& hdu_aeff = *fits.table("EFFECTIVE AREA");

    // Read effective area
    read_aeff(hdu_aeff);

    // Read efficiency factors from appropriate HDU. Does nothing if the
    // HDU does not exist.
    if (fits.contains("EFFICIENCY_PARAMS")) {
        const GFitsTable& hdu_eff = *fits.table("EFFICIENCY_PARAMS");
        read_efficiency(hdu_eff);
    }

    // Return
    return;
}
示例#18
0
/***********************************************************************//**
 * @brief Read LAT event cube from FITS file.
 *
 * @param[in] fits FITS file.
 *
 * It is assumed that the counts map resides in the primary extension of the
 * FITS file, the energy boundaries reside in the EBOUNDS extension and the
 * Good Time Intervals reside in the GTI extension.  The method clears the
 * object before loading, thus any events residing in the object before
 * loading will be lost.
 ***************************************************************************/
void GLATEventCube::read(const GFits& fits)
{
    // Clear object
    clear();

    // Get HDUs
    const GFitsImage& hdu_cntmap  = *fits.image("Primary");
    const GFitsTable& hdu_ebounds = *fits.table("EBOUNDS");
    const GFitsTable& hdu_gti     = *fits.table("GTI");

    // Load counts map
    read_cntmap(hdu_cntmap);

    // Load energy boundaries
    read_ebds(hdu_ebounds);

    // Load GTIs
    read_gti(hdu_gti);

    // Load additional source maps
    for (int i = 1; i < fits.size(); ++i) {
        if (fits.at(i)->exttype() == GFitsHDU::HT_IMAGE) {
            const GFitsImage& hdu_srcmap = *fits.image(i);
            read_srcmap(hdu_srcmap);
        }
    }

    // Return
    return;
}
示例#19
0
/***********************************************************************//**
 * @brief Write point spread function into FITS file
 *
 * @param[in] file FITS file.
 *
 * Writes the PSF into the extension "RPSF" of a FITS file. This method
 * does not check if a "RPSF" extension exists so far, it simply adds one
 * each time it is called.
 *
 * Nothing is done if the PSF size is 0.
 *
 * @todo Check if a RPSF extension exists already in FITS file
 ***************************************************************************/
void GLATPsfV3::write(GFits& file) const
{
    // Continue only if there are bins
    int size = m_rpsf_bins.size();
    if (size > 0) {

        // Create new binary table
        GFitsBinTable* hdu_rpsf = new GFitsBinTable;

        // Set table attributes
        hdu_rpsf->extname("RPSF");

        // Write boundaries into table
        m_rpsf_bins.write(hdu_rpsf);

        // Allocate floating point vector columns
        GFitsTableFloatCol col_ncore = GFitsTableFloatCol("NCORE",  1, size);
        GFitsTableFloatCol col_ntail = GFitsTableFloatCol("NTAIL",  1, size);
        GFitsTableFloatCol col_score = GFitsTableFloatCol("SCORE",  1, size);
        GFitsTableFloatCol col_stail = GFitsTableFloatCol("STAIL",  1, size);
        GFitsTableFloatCol col_gcore = GFitsTableFloatCol("GCORE",  1, size);
        GFitsTableFloatCol col_gtail = GFitsTableFloatCol("GTAIL",  1, size);

        // Fill columns
        for (int i = 0; i < size; ++i) {
            col_ncore(0,i) = m_ncore[i];
            col_ntail(0,i) = m_ntail[i];
            col_score(0,i) = m_score[i];
            col_stail(0,i) = m_stail[i];
            col_gcore(0,i) = m_gcore[i];
            col_gtail(0,i) = m_gtail[i];
        }

        // Append columns to table
        hdu_rpsf->append_column(col_ncore);
        hdu_rpsf->append_column(col_ntail);
        hdu_rpsf->append_column(col_score);
        hdu_rpsf->append_column(col_stail);
        hdu_rpsf->append_column(col_gcore);
        hdu_rpsf->append_column(col_gtail);

        // Append HDU to FITS file
        file.append(*hdu_rpsf);

        // Free binary table
        delete hdu_rpsf;

    } // endif: there were data to write

    // Return
    return;
}
示例#20
0
/***********************************************************************//**
 * @brief Read CTA event cube from FITS file
 *
 * @param[in] file FITS file.
 *
 * It is assumed that the counts map resides in the primary extension of the
 * FITS file, the energy boundaries reside in the EBOUNDS extension and the
 * Good Time Intervals reside in the GTI extension.  The method clears the
 * object before loading, thus any events residing in the object before
 * loading will be lost.
 ***************************************************************************/
void GCTAEventCube::read(const GFits& file)
{
    // Clear object
    clear();

    // Get HDUs
    GFitsImage* hdu_cntmap  = file.image("Primary");
    GFitsTable* hdu_ebounds = file.table("EBOUNDS");
    GFitsTable* hdu_gti     = file.table("GTI");

    // Load counts map
    read_cntmap(hdu_cntmap);

    // Load energy boundaries
    read_ebds(hdu_ebounds);

    // Load GTIs
    read_gti(hdu_gti);

    // Return
    return;
}
示例#21
0
/***********************************************************************//**
 * @brief Read spectrum from FITS file
 *
 * @param[in] fits FITS file.
 * @param[in] extname FITS extension name.
 ***************************************************************************/
void GMWLSpectrum::read(const GFits& fits, const std::string& extname)
{
    // Clear object
    clear();

    // Get table pointer
    const GFitsTable& table = *fits.table(extname);

    // Read spectrum from table
    read_fits(table);

    // Return
    return;
}
示例#22
0
/***********************************************************************//**
 * @brief Write CTA exposure cube into FITS object.
 *
 * @param[in] fits FITS file.
 *
 * Writes the exposure cube image, the energy boundaries and the Good Time
 * Intervals into the FITS object.
 ***************************************************************************/
void GCTACubeExposure::write(GFits& fits) const
{
    // Write cube
    m_cube.write(fits);

    // Get last HDU and write attributes
    GFitsHDU& hdu = *fits[fits.size()-1];
    write_attributes(hdu);

    // Write energy boundaries
    m_ebounds.write(fits);

    // Write GTIs
    m_gti.write(fits);

    // Return
    return;
}
示例#23
0
/***********************************************************************//**
 * @brief Read PSF from FITS file
 *
 * @param[in] fits FITS file pointer.
 *
 * @exception GException::invalid_value
 *            FITS file format differs from expectation.
 *
 * Reads the PSF from the FITS file extension "POINT SPREAD FUNCTION". The data
 * are stored in m_psf which is of type GCTAResponseTable.
 * The energy axis will be set to log10. The offset angle axis and
 * sigma parameter columns will be set to radians.
 ***************************************************************************/
void GCTAPsf2D::read(const GFits& fits)
{
    // Clear response table
    m_psf.clear();

    // Get PSF table
    const GFitsTable& table = *fits.table("POINT SPREAD FUNCTION");

    // Read PSF table
    m_psf.read(table);

    // Check that axis names comply to format
    if (m_psf.axis_lo_name(0) != "ENERG_LO" ||
            m_psf.axis_hi_name(0) != "ENERG_HI") {
        std::string msg = "Point spread function response table does not"
                          " contain \"ENERG_LO\" and \"ENERG_HI\" columns"
                          " as the first axis.";
        throw GException::invalid_value(G_READ, msg);
    }
    if (m_psf.axis_lo_name(1) != "THETA_LO" ||
            m_psf.axis_hi_name(1) != "THETA_HI") {
        std::string msg = "Point spread function response table does not"
                          " contain \"THETA_LO\" and \"THETA_HI\" columns"
                          " as the second axis.";
        throw GException::invalid_value(G_READ, msg);
    }

    // Set energy axis to logarithmic scale
    m_psf.axis_log10(0);

    // Set offset angle axis to radians
    m_psf.axis_radians(1);

    // Convert sigma parameters to radians
    m_psf.scale(1, gammalib::deg2rad);
    m_psf.scale(3, gammalib::deg2rad);
    m_psf.scale(5, gammalib::deg2rad);

    // Return
    return;
}
示例#24
0
/***********************************************************************//**
 * @brief Write PSF scale factors
 *
 * @param[in] file FITS file.
 *
 * Writes the PSF scale factors in the extension "PSF_SCALING_PARAMS". This
 * method appends an extension "PSF_SCALING_PARAMS" to the FITS file,
 * irrespectively of whether the extension exists already or not.
 * The scale facors are written into the column "PSFSCALE".
 *
 * @todo Check if PSF_SCALING_PARAMS exists already in FITS file
 ***************************************************************************/
void GLATPsfBase::write_scale(GFits& file) const
{
    // Create new binary table
    GFitsBinTable* hdu_scale = new GFitsBinTable;

    // Set table attributes
    hdu_scale->extname("PSF_SCALING_PARAMS");

    // Allocate floating point vector column
    GFitsTableFloatCol col_scale = GFitsTableFloatCol("PSFSCALE",  1, 5);

    // Fill columns
    if (front()) {
        col_scale(0,0) = m_scale_par1;
        col_scale(0,1) = m_scale_par2;
        col_scale(0,2) = 0.0;
        col_scale(0,3) = 0.0;
    }
    else {
        col_scale(0,0) = 0.0;
        col_scale(0,1) = 0.0;
        col_scale(0,2) = m_scale_par1;
        col_scale(0,3) = m_scale_par2;
    }
    col_scale(0,4) = m_scale_index;

    // Append column to table
    hdu_scale->append(col_scale);

    // Append HDU to FITS file
    file.append(*hdu_scale);

    // Free binary table
    delete hdu_scale;

    // Return
    return;
}
示例#25
0
/***********************************************************************//**
 * @brief Read CTA event cube from FITS file
 *
 * @param[in] fits FITS file.
 *
 * Read an event cube from a FITS file. The following HDUs will be read
 *
 *      COUNTS - Counts cube (or primary extension if COUNTS does not exist)
 *      WEIGHTS - Weights for each counts cube bin (optional)
 *      EBOUNDS - Energy boundaries
 *      GTI - Good Time Intervals
 *
 * The method clears the event cube before reading, thus any events residing
 * in the event cube will be lost.
 ***************************************************************************/
void GCTAEventCube::read(const GFits& fits)
{
    // Clear object
    clear();

    // Set counts cube HDU
    std::string counts_hdu("Primary");
    if (fits.contains("COUNTS")) {
        counts_hdu = "COUNTS";
    }
    
    // Get HDUs
    const GFitsImage& hdu_cntmap  = *fits.image(counts_hdu);
    const GFitsTable& hdu_ebounds = *fits.table("EBOUNDS");
    const GFitsTable& hdu_gti     = *fits.table("GTI");

    // Load counts map
    read_cntmap(hdu_cntmap);

    // Load energy boundaries
    read_ebds(hdu_ebounds);

    // Load GTIs
    read_gti(hdu_gti);

    // If a WEIGHTS HDU exist then load it from the FITS file ...
    if (fits.contains("WEIGHTS")) {

        // Get WEIGHTS HDU
        const GFitsImage& hdu_weights = *fits.image("WEIGHTS");

        // Read HDU
        m_weights.read(hdu_weights);

    }

    // ... otherwise set the weight map to unity
    else {
        m_weights = m_map;
        m_weights = 1.0;
    }

    // Return
    return;
}
示例#26
0
/***********************************************************************//**
 * @brief Write effective area into FITS file
 *
 * @param[in] file FITS file.
 *
 * This method does not write anything if the instance is empty.
 ***************************************************************************/
void GLATAeff::write_aeff(GFits& file) const
{
    // Continue only if there are bins
    int size = m_aeff_bins.size();
    if (size > 0) {

        // Create new binary table
        GFitsBinTable* hdu_aeff = new GFitsBinTable;

        // Set table attributes
        hdu_aeff->extname("EFFECTIVE AREA");

        // Write boundaries into table
        m_aeff_bins.write(*hdu_aeff);

        // Allocate floating point vector columns
        GFitsTableFloatCol col_aeff = GFitsTableFloatCol("EFFAREA",  1, size);

        // Fill columns
        for (int i = 0; i < size; ++i) {
            col_aeff(0,i) = m_aeff[i];
        }

        // Append columns to table
        hdu_aeff->append(col_aeff);

        // Append HDU to FITS file
        file.append(*hdu_aeff);

        // Free binary table
        delete hdu_aeff;

    } // endif: there were data to write

    // Return
    return;
}
示例#27
0
/***********************************************************************//**
 * @brief Write Pulse Height Analyzer spectrum
 *
 * @param[in] fits FITS file.
 *
 * Writes the Pulse Height Analyzer spectrum into `SPECTRUM` and `EBOUNDS`
 * extensions of the FITS file. Extensions with these names will be removed
 * from the FITS file before writing.
 *
 * The columns `CHANNEL`, `COUNTS`, `STAT_ERR`, `SYS_ERR`, `QUALITY`,
 * `GROUPING`, `AREASCAL`, and `BACKSCAL` will be written into the `SPECTRUM`
 * extension, but only the `CHANNEL` and `COUNTS` columns will be filled with
 * values. Note that the channels start from 1 in the Pulse Height Analyzer
 * spectrum.
 *
 * See
 * https://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/spectra/ogip_92_007/node5.html
 * for details about the PHA file format.
 ***************************************************************************/
void GPha::write(GFits& fits) const
{
    // Remove extensions if they exist already
    if (fits.contains("EBOUNDS")) {
        fits.remove("EBOUNDS");
    }
    if (fits.contains("SPECTRUM")) {
        fits.remove("SPECTRUM");
    }

    // Set column length
    int length = size();

    // Continue only if there are bins
    if (length > 0) {

        // Create new binary table
        GFitsBinTable hdu;

        // Allocate floating point vector columns
        GFitsTableShortCol col_chan("CHANNEL",  length);
        GFitsTableFloatCol col_data("COUNTS",   length);
        GFitsTableFloatCol col_stat("STAT_ERR", length);
        GFitsTableFloatCol col_syst("SYS_ERR",  length);
        GFitsTableShortCol col_qual("QUALITY",  length);
        GFitsTableShortCol col_grpg("GROUPING", length);
        GFitsTableFloatCol col_area("AREASCAL", length);
        GFitsTableFloatCol col_back("BACKSCAL", length);

        // Fill columns
        for (int i = 0; i < length; ++i) {
            col_chan(i) = i+1; // Channels start at 1
            col_data(i) = float(m_counts[i]);
        }

        // Set table attributes
        hdu.extname("SPECTRUM");

        // Append columns to table
        hdu.append(col_chan);
        hdu.append(col_data);
        hdu.append(col_stat);
        hdu.append(col_syst);
        hdu.append(col_qual);
        hdu.append(col_grpg);
        hdu.append(col_area);
        hdu.append(col_back);

        // Write keywords
        hdu.card("EXPOSURE", m_exposure, "[s] Deadtime corrected exposure time");

        // Append HDU to FITS file
        fits.append(hdu);

        // Optionally append energy boundaries
        if (m_ebounds.size() > 0) {
            m_ebounds.write(fits);
        }

    } // endif: there were data to write

    // Return
    return;
}
示例#28
0
/***********************************************************************//**
 * @brief Write Auxiliary Response File
 *
 * @param[in] fits FITS file.
 *
 * Writes the Auxiliary Response File into the `SPECRESP` extension of the
 * FITS file. An existing extension with the same name will be removed from
 * the FITS file before writing.
 *
 * The method writes the boundaries of the true energy bins into the
 * `ENERG_LO` and `ENERG_HI` columns, response information will be written
 * into the `SPECRESP` column.
 *
 * See
 * http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/docs/memos/cal_gen_92_002/cal_gen_92_002.html#tth_sEc4
 * for details about the Auxiliary Response File format.
 ***************************************************************************/
void GArf::write(GFits& fits) const
{
    // If the FITS object contains already an extension with the same
    // name then remove now this extension
    if (fits.contains("SPECRESP")) {
        fits.remove("SPECRESP");
    }

    // Set column length
    int length = size();

    // Continue only if there are bins
    if (length > 0) {

        // Create new binary table
        GFitsBinTable hdu;

        // Allocate floating point vector columns
        GFitsTableFloatCol energy_lo("ENERG_LO", length);
        GFitsTableFloatCol energy_hi("ENERG_HI", length);
        GFitsTableFloatCol specresp("SPECRESP",  length);

        // Fill columns
        for (int i = 0; i < length; ++i) {
            energy_lo(i) = (float)m_ebounds.emin(i).keV();
            energy_hi(i) = (float)m_ebounds.emax(i).keV();
            specresp(i)  = (float)m_specresp[i];
        }

        // Set column units
        energy_lo.unit("keV");
        energy_hi.unit("keV");
        specresp.unit("cm^2");

        // Set table attributes
        hdu.extname("SPECRESP");

        // Append columns to table
        hdu.append(energy_lo);
        hdu.append(energy_hi);
        hdu.append(specresp);

        // Append any additional columns
        for (int icol = 0; icol < columns(); ++icol) {

            // Allocate floating point vector columns
            GFitsTableFloatCol column(m_colnames[icol], length);

            // Fill columns
            for (int i = 0; i < length; ++i) {
                column(i) = (float)m_coldata[icol][i];
            }

            // Append columns to table
            hdu.append(column);

        } // endfor: looped over all additional columns

        // Append HDU to FITS file
        fits.append(hdu);

    } // endif: there were data to write

    // Return
    return;
}
示例#29
0
/***********************************************************************//**
 * @brief Test GTimeReference
 ***************************************************************************/
void TestGObservation::test_time_reference(void)
{
    // Test void constructor
    test_try("Void constructor");
    try {
        GTimeReference reference;
        test_try_success();
    }
    catch (std::exception &e) {
        test_try_failure(e);
    }

    // Test copy constructor
    test_try("Copy constructor");
    try {
        GTimeReference reference;
        GTimeReference reference2(reference);
        test_try_success();
    }
    catch (std::exception &e) {
        test_try_failure(e);
    }

    // Test reference constructor
    test_try("Reference constructor");
    try {
        GTimeReference reference(55197.0, "s", "TT", "LOCAL");
        test_try_success();
        test_value(reference.mjdref(), 55197.0);
        test_assert(reference.timeunit() == "s",
                    "Time unit was \""+reference.timeunit()+"\", expected \"s\"");
        test_assert(reference.timesys() == "TT",
                    "Time system was \""+reference.timesys()+"\", expected \"TT\"");
        test_assert(reference.timeref() == "LOCAL",
                    "Time reference was \""+reference.timeref()+"\", expected \"LOCAL\"");
    }
    catch (std::exception &e) {
        test_try_failure(e);
    }

    // Test reference constructor
    test_try("Reference constructor (split reference)");
    try {
        GTimeReference reference(55197, 0.000766018518519, "s", "TT", "LOCAL");
        test_try_success();
        test_value(reference.mjdref(), 55197.000766018518519);
        test_assert(reference.timeunit() == "s",
                    "Time unit was \""+reference.timeunit()+"\", expected \"s\"");
        test_assert(reference.timesys() == "TT",
                    "Time system was \""+reference.timesys()+"\", expected \"TT\"");
        test_assert(reference.timeref() == "LOCAL",
                    "Time reference was \""+reference.timeref()+"\", expected \"LOCAL\"");
    }
    catch (std::exception &e) {
        test_try_failure(e);
    }

    // Test FITS file writing
    GTimeReference reference(55197.000766018518519, "s", "TT", "LOCAL");
    GFits          fits;
    GFitsBinTable  table;
    reference.write(table);
    fits.append(table);
    fits.saveto("test_time_reference.fits", true);
    fits.close();

    // Read back from FITS file and check values
    fits.open("test_time_reference.fits");
    const GFitsTable& hdu = *fits.table(1);
    GTimeReference value(hdu);
    fits.close();
    test_value(value.mjdref(),  reference.mjdref());
    test_value(value.mjdrefi(), reference.mjdrefi());
    test_value(value.mjdreff(), reference.mjdreff());
    test_assert(value.timeunit() == reference.timeunit(),
                "Time unit was \""+value.timeunit()+"\", expected "+reference.timeunit()+".");
    test_assert(value.timesys() == reference.timesys(),
                "Time system was \""+value.timesys()+"\", expected "+reference.timesys()+".");
    test_assert(value.timeref() == reference.timeref(),
                "Time reference was \""+value.timeref()+"\", expected "+reference.timeref()+".");

    // Return
    return;
}
示例#30
0
/***********************************************************************//**
 * @brief Load nodes from file
 *
 * @param[in] filename File name.
 *
 * @exception GException::invalid_value
 *            File function FITS file is invalid
 *
 * Load the light curve nodes from a FITS file. The light curve nodes are
 * expected in the first extension of the FITS file, containing two mandatory
 * columns with names "TIME" and "NORM".
 ***************************************************************************/
void GModelTemporalLightCurve::load_nodes(const GFilename& filename)
{
    // Set maximum light curve normalization value, including a small margin
    const double max_norm = 1.0 + 1.0e-8;

    // Clear nodes and values
    m_nodes.clear();
    m_values.clear();

    // Set filename
    m_filename = filename;

    // Load FITS file
    GFits fits = GFits(filename);

    // Extract binary table (so far always load extension 1 as table)
    GFitsTable* table = fits.table(1);

    // Read time reference from binary table
    m_timeref.read(*table);

    // Extract columns
    GFitsTableCol* time_col = (*table)["TIME"];
    GFitsTableCol* norm_col = (*table)["NORM"];

    // Check that there are at least two nodes in table
    if (time_col->nrows() < 2) {
        std::string msg = "\"TIME\" column contains "+
                          gammalib::str(time_col->nrows())+" rows but at "
                          "least two rows are required. Please specify a valid "
                          "temporal file function.";
        throw GException::invalid_value(G_LOAD_NODES, msg);
    }

    // Check that both columns are consistent
    if (time_col->nrows() != norm_col->nrows()) {
        std::string msg = "\"TIME\" and \"NORM\" columns have inconsistent "
                          "number of rows ("+
                          gammalib::str(time_col->nrows())+", "+
                          gammalib::str(norm_col->nrows())+"). Please "
                          "specify a valid temporal file function.";
        throw GException::invalid_value(G_LOAD_NODES, msg);
    }

    // Set number of nodes
    int nodes = time_col->nrows();

    // Check that time values are in ascending order and that no node is
    // larger than 1
    double last_time = -1.0;
    for (int i = 0; i < nodes; ++i) {

        // Check if time has increased
        if (last_time >= 0.0 && time_col->real(i) <= last_time) {
            std::string msg = "Time "+gammalib::str(time_col->real(i))+
                              " in row "+gammalib::str(i+1)+" of \"TIME\" "
                              "column is equal to or smaller than preceeding "
                              "value. Please provide a light curve file with "
                              "monotonically increasing times.";
            throw GException::invalid_value(G_LOAD_NODES, msg);
        }

        // Check if value is smaller than maximum allowed normalisation
        if (norm_col->real(i) > max_norm) {
            std::string msg = "Value "+gammalib::str(norm_col->real(i))+" at "
                              "time "+gammalib::str(time_col->real(i))+" is "
                              "larger than 1. Please provide a light curve file "
                              "with normalizations not exceeding 1.";
            throw GException::invalid_value(G_LOAD_NODES, msg);
        }
        
    } // endfor: looped over nodes

    // Extract nodes
    for (int i = 0; i < nodes; ++i) {
        m_nodes.append(time_col->real(i));
        m_values.push_back(norm_col->real(i));
    }

    // Make sure that no node exceeds 1
    for (int i = 0; i < m_values.size(); ++i) {
        if (m_values[i] > 1.0) {
            m_values[i] = 1.0;
        }
    }

    // Set minimum and maximum times (assumes that times are ordered)
    m_tmin.set(time_col->real(0), m_timeref);
    m_tmax.set(time_col->real(time_col->nrows()-1), m_timeref);

    // Close FITS file
    fits.close();

    // Return
    return;
}