/***********************************************************************//**
 * @brief Exposure cube constructor
 *
 * @param[in] wcs     World Coordinate System.
 * @param[in] coords  Coordinate System (CEL or GAL).
 * @param[in] x       X coordinate of sky map centre (deg).
 * @param[in] y       Y coordinate of sky map centre (deg).
 * @param[in] dx      Pixel size in x direction at centre (deg/pixel).
 * @param[in] dy      Pixel size in y direction at centre (deg/pixel).
 * @param[in] nx      Number of pixels in x direction.
 * @param[in] ny      Number of pixels in y direction.
 * @param[in] ebounds Energy boundaries.
 *
 * Constructs an exposure cube by specifying the sky map grid and the energy
 * boundaries.
 ***************************************************************************/
GCTACubeExposure::GCTACubeExposure(const std::string&   wcs,
                                   const std::string&   coords,
                                   const double&        x,
                                   const double&        y,
                                   const double&        dx,
                                   const double&        dy,
                                   const int&           nx,
                                   const int&           ny,
                                   const GEbounds&      ebounds)
{
    // Initialise class members
    init_members();

    // Store energy boundaries
    m_ebounds = ebounds;

    // Set GNodeArray used for interpolation
    set_eng_axis();

    // Create sky map
    m_cube = GSkymap(wcs, coords, x, y, dx, dy, nx, ny, m_ebounds.size());

    // Return
    return;
}
Exemple #2
0
/***********************************************************************//**
 * @brief Setup observation container
 *
 * @exception GException::no_cube
 *            No event cube found in CTA observation.
 *
 * This method sets up the observation container for processing. There are
 * two cases:
 *
 * If there are no observations in the actual observation container, the
 * method will check in "infile" parameter. If this parameter is "NONE" or
 * empty, the task parameters will be used to construct a model map.
 * Otherwise, the method first tries to interpret the "infile" parameter as
 * a counts map, and attemps loading of the file in an event cube. If this
 * fails, the method tries to interpret the "infile" parameter as an
 * observation definition XML file. If this also fails, an exception will
 * be thrown.
 *
 * If observations exist already in the observation container, the method
 * will simply keep them.
 *
 * Test if all CTA observations contain counts maps.
 *
 * Finally, if no models exist so far in the observation container, the
 * models will be loaded from the model XML file.
 ***************************************************************************/
void ctmodel::setup_obs(void)
{
    // If there are no observations in the container then try to build some
    if (m_obs.size() == 0) {

        // If no input filename has been specified, then create a model map
        // from the task parameters
        if ((m_infile == "NONE") || (gammalib::strip_whitespace(m_infile) == "")) {

            // Set pointing direction
            GCTAPointing pnt;
            GSkyDir      skydir;
            skydir.radec_deg(m_ra, m_dec);
            pnt.dir(skydir);

            // Setup energy range covered by model
            GEnergy  emin(m_emin, "TeV");
            GEnergy  emax(m_emax, "TeV");
            GEbounds ebds(m_enumbins, emin, emax);

            // Setup time interval covered by model
            GGti  gti;
            GTime tmin(m_tmin);
            GTime tmax(m_tmax);
            gti.append(tmin, tmax);

            // Setup skymap
            GSkymap map = GSkymap(m_proj, m_coordsys,
                                  m_xref, m_yref, -m_binsz, m_binsz,
                                  m_nxpix, m_nypix, m_enumbins);

            // Create model cube from sky map
            GCTAEventCube cube(map, ebds, gti);

            // Allocate CTA observation
            GCTAObservation obs;

            // Set CTA observation attributes
            obs.pointing(pnt);
            obs.ontime(gti.ontime());
            obs.livetime(gti.ontime()*m_deadc);
            obs.deadc(m_deadc);

            // Set event cube in observation
            obs.events(cube);

            // Append CTA observation to container
            m_obs.append(obs);

            // Signal that no XML file should be used for storage
            m_use_xml = false;

        } // endif: created model map from task parameters

        // ... otherwise try to load information from the file
        else {

            // First try to open the file as a counts map
            try {

                // Allocate CTA observation
                GCTAObservation obs;

                // Load counts map in CTA observation
                obs.load_binned(m_infile);

                // Append CTA observation to container
                m_obs.append(obs);

                // Signal that no XML file should be used for storage
                m_use_xml = false;

            }

            // ... otherwise try to open as XML file
            catch (GException::fits_open_error &e) {

                // Load observations from XML file. This will throw
                // an exception if it fails.
                m_obs.load(m_infile);

                // Signal that XML file should be used for storage
                m_use_xml = true;

            }

        } // endelse: loaded information from input file

    } // endif: there was no observation in the container

    // If there are no models associated with the observations then
    // load now the model definition from the XML file
    if (m_obs.models().size() == 0) {
        m_obs.models(GModels(m_srcmdl));
    }

    // Check if all CTA observations contain an event cube and setup response
    // for all observations
    for (int i = 0; i < m_obs.size(); ++i) {

        // Is this observation a CTA observation?
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);

        // Yes ...
        if (obs != NULL) {

            // Throw an exception if this observation does not contain
            // an event cube
            if (dynamic_cast<const GCTAEventCube*>(obs->events()) == NULL) {
                throw GException::no_cube(G_SETUP_OBS);
            }

            // Set response if it isn't set already
            if (obs->response().aeff() == NULL) {

                // Set calibration database. If specified parameter is a
                // directory then use this as the pathname to the calibration
                // database. Otherwise interpret this as the instrument name,
                // the mission being "cta"
                GCaldb caldb;
                if (gammalib::dir_exists(m_caldb)) {
                    caldb.rootdir(m_caldb);
                }
                else {
                    caldb.open("cta", m_caldb);
                }

                // Set reponse
                obs->response(m_irf, caldb);

            } // endif: observation already has a response

        } // endif: observation was a CTA observation

    } // endfor: looped over all observations

    // Return
    return;
}
Exemple #3
0
/***********************************************************************//**
 * @brief Bin events into a counts map
 *
 * @param[in] obs CTA observation.
 *
 * @exception GException::no_list
 *            No event list found in observation.
 * @exception GCTAException::no_pointing
 *            No valid CTA pointing found.
 *
 * This method bins the events found in a CTA events list into a counts map
 * and replaces the event list by the counts map in the observation. The
 * energy boundaries of the counts map are also stored in the observation's
 * energy boundary member.
 *
 * If the reference values for the map centre (m_xref, m_yref) are 9999.0,
 * the pointing direction of the observation is taken as the map centre.
 * Otherwise, the specified reference value is used.
 ***************************************************************************/
void ctbin::bin_events(GCTAObservation* obs)
{
    // Continue only if observation pointer is valid
    if (obs != NULL) {

        // Make sure that the observation holds a CTA event list. If this
        // is not the case then throw an exception.
        if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) {
            throw GException::no_list(G_BIN_EVENTS);
        }

        // Setup energy range covered by data
        GEnergy  emin;
        GEnergy  emax;
        GEbounds ebds;
        emin.TeV(m_emin);
        emax.TeV(m_emax);
        ebds.setlog(emin, emax, m_enumbins);

        // Get Good Time intervals
        GGti gti = obs->events()->gti();
        
        // Get map centre
        double xref;
        double yref;
        if (m_xref != 9999.0 && m_yref != 9999.0) {
            xref = m_xref;
            yref = m_yref;
        }
        else {
            
            // Get pointer on CTA pointing
            const GCTAPointing *pnt = obs->pointing();
            if (pnt == NULL) {
                throw GCTAException::no_pointing(G_BIN_EVENTS);
            }
            
            // Set reference point to pointing
            if (toupper(m_coordsys) == "GAL") {
                xref = pnt->dir().l_deg();
                yref = pnt->dir().b_deg();
            }
            else {
                xref = pnt->dir().ra_deg();
                yref = pnt->dir().dec_deg();
            }

        } // endelse: map centre set to pointing

        // Create skymap
        GSkymap map = GSkymap(m_proj, m_coordsys,
                              xref, yref, m_binsz, m_binsz,
                              m_nxpix, m_nypix, m_enumbins);

        // Initialise binning statistics
        int num_outside_map  = 0;
        int num_outside_ebds = 0;
        int num_in_map       = 0;

        // Fill sky map
        GCTAEventList* events = static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events()));
        for (GCTAEventList::iterator event = events->begin(); event != events->end(); ++event) {

            // Determine sky pixel
            GCTAInstDir* inst  = (GCTAInstDir*)&(event->dir());
            GSkyDir      dir   = inst->dir();
            GSkyPixel    pixel = map.dir2xy(dir);

            // Skip if pixel is out of range
            if (pixel.x() < -0.5 || pixel.x() > (m_nxpix-0.5) ||
                pixel.y() < -0.5 || pixel.y() > (m_nypix-0.5)) {
                num_outside_map++;
                continue;
            }

            // Determine energy bin. Skip if we are outside the energy range
            int index = ebds.index(event->energy());
            if (index == -1) {
                num_outside_ebds++;
                continue;
            }

            // Fill event in skymap
            map(pixel, index) += 1.0;
            num_in_map++;

        } // endfor: looped over all events

        // Log binning results
        if (logTerse()) {
            log << std::endl;
            log.header1("Binning");
            log << parformat("Events in list");
            log << obs->events()->size() << std::endl;
            log << parformat("Events in map");
            log << num_in_map << std::endl;
            log << parformat("Events outside map area");
            log << num_outside_map << std::endl;
            log << parformat("Events outside energy bins");
            log << num_outside_ebds << std::endl;
        }

        // Log map
        if (logTerse()) {
            log << std::endl;
            log.header1("Counts map");
            log << map << std::endl;
        }

        // Create events cube from sky map
        GCTAEventCube cube(map, ebds, gti);

        // Replace event list by event cube in observation
        obs->events(&cube);

    } // endif: observation was valid

    // Return
    return;
}