Exemplo n.º 1
0
/***********************************************************************//**
 * @brief Return spatially integrated sky model
 *
 * @param[in] obsEng Measured photon energy.
 * @param[in] obsTime Measured photon arrival time.
 * @param[in] obs Observation.
 *
 * @exception GException::no_response
 *            No valid instrument response function defined.
 *
 * Computes
 * \f[N"_{\rm pred} = \int_{\rm ROI}
 *    S(\vec{p}, E, t) PSF(\vec{p'}, E', t' | \vec{d}, \vec{p}, E, t) \,
 *    {\rm d}\vec{p'}\f]
 * where
 * \f$S(\vec{p}, E, t)\f$ is the source model,
 * \f$PSF(\vec{p'}, E', t' | \vec{d}, \vec{p}, E, t)\f$ is the point
 * spread function,
 * \f$\vec{p'}\f$ is the measured photon direction,
 * \f$E'\f$ is the measured photon energy,
 * \f$t'\f$ is the measured photon arrival time,
 * \f$\vec{p}\f$ is the true photon arrival direction,
 * \f$E\f$ is the true photon energy,
 * \f$t\f$ is the true photon arrival time, and
 * \f$d\f$ is the instrument pointing.
 *
 * \f${\rm ROI}\f$ is the region of interest that is stored in the
 * GObservation::m_roi member. The integration over the ROI is performed
 * by the GResponse::npred() method.
 *
 * @todo The actual method is only correct if no energy and time dispersion
 *       exists. For the moment we set srcEng=obsEng and srcTime=obsTime.
 *       Formally, Equation (2) of the instrument document has to be
 *       computed, which is an integration over source energy, time
 *       and arrival direction. For the moment, only the integration over
 *       arrival direction is performed by GResponse::npred().
 ***************************************************************************/
double GModelSky::npred(const GEnergy& obsEng, const GTime& obsTime,
                        const GObservation& obs) const
{
    // Initialise result
    double npred = 0.0;

    // Continue only if model is valid)
    if (valid_model()) {

        // Get response function
        GResponse* rsp = obs.response();
        if (rsp == NULL) {
            throw GException::no_response(G_NPRED);
        }

        // Here we make the simplifying approximations
        // srcEng=obsEng and srcTime=obsTime. To be fully correct we should
        // integrate over true energy and true time here ... at least true
        // time if we want to consider energy dispersion ...
        GEnergy srcEng  = obsEng;
        GTime   srcTime = obsTime;

        // Set source
        GSource source(this->name(), *m_spatial, srcEng, srcTime);

        // Compute response components
        double npred_spatial  = rsp->npred(source, obs);
        double npred_spectral = spectral()->eval(srcEng);
        double npred_temporal = temporal()->eval(srcTime);

        // Compute response
        npred = npred_spatial * npred_spectral * npred_temporal;

        // Compile option: Check for NaN/Inf
#if defined(G_NAN_CHECK)
        if (isnotanumber(npred) || isinfinite(npred)) {
            std::cout << "*** ERROR: GModelSky::npred:";
            std::cout << " NaN/Inf encountered";
            std::cout << " (npred=" << npred;
            std::cout << ", npred_spatial=" << npred_spatial;
            std::cout << ", npred_spectral=" << npred_spectral;
            std::cout << ", npred_temporal=" << npred_temporal;
            std::cout << ", srcEng=" << srcEng;
            std::cout << ", srcTime=" << srcTime;
            std::cout << ")" << std::endl;
        }
#endif

    } // endif: model was valid

    // Return npred
    return npred;
}
Exemplo n.º 2
0
/***********************************************************************//**
 * @brief Perform integration over spectral component
 *
 * @param[in] event Observed event.
 * @param[in] srcTime True photon arrival time.
 * @param[in] obs Observation.
 * @param[in] grad Evaluate gradients.
 *
 * @exception GException::no_response
 *            Observation has no valid instrument response
 * @exception GException::feature_not_implemented
 *            Energy integration not yet implemented
 *
 * This method integrates the source model over the spectral component. If
 * the response function has no energy dispersion then no spectral
 * integration is needed and the observed photon energy is identical to the
 * true photon energy.
 *
 * @todo Needs implementation of spectral integration to handle energy
 *       dispersion.
 ***************************************************************************/
double GModelSky::spectral(const GEvent& event, const GTime& srcTime,
                           const GObservation& obs, bool grad) const
{
    // Initialise result
    double value = 0.0;

    // Get response function
    GResponse* rsp = obs.response();
    if (rsp == NULL) {
        throw GException::no_response(G_SPECTRAL);
    }

    // Determine if energy integration is needed
    bool integrate = rsp->hasedisp();

    // Case A: Integraion
    if (integrate) {
        throw GException::feature_not_implemented(G_SPECTRAL);
    }

    // Case B: No integration (assume no energy dispersion)
    else {
        value = spatial(event, event.energy(), srcTime, obs, grad);
    }

    // Compile option: Check for NaN/Inf
#if defined(G_NAN_CHECK)
    if (isnotanumber(value) || isinfinite(value)) {
        std::cout << "*** ERROR: GModelSky::spectral:";
        std::cout << " NaN/Inf encountered";
        std::cout << " (value=" << value;
        std::cout << ", event=" << event;
        std::cout << ", srcTime=" << srcTime;
        std::cout << ")" << std::endl;
    }
#endif

    // Return value
    return value;
}
Exemplo n.º 3
0
/***********************************************************************//**
 * @brief Returns spatial model component
 *
 * @param[in] event Observed event.
 * @param[in] srcEng True photon energy.
 * @param[in] srcTime True photon arrival time.
 * @param[in] obs Observation.
 * @param[in] grad Evaluate gradients.
 *
 * @exception GException::no_response
 *            Observation has no valid instrument response
 *
 * This method computes the spatial model component for a given true photon
 * energy and arrival time.
 ***************************************************************************/
double GModelSky::spatial(const GEvent& event,
                          const GEnergy& srcEng, const GTime& srcTime,
                          const GObservation& obs, bool grad) const
{
    // Initialise result
    double value = 0.0;

    // Continue only if the model has a spatial component
    if (m_spatial != NULL) {

        // Get response function
        GResponse* rsp = obs.response();
        if (rsp == NULL) {
            throw GException::no_response(G_SPATIAL);
        }

        // Set source
        GSource source(this->name(), *m_spatial, srcEng, srcTime);

        // Get IRF value. This method returns the spatial component of the
        // source model.
        double irf = rsp->irf(event, source, obs);

        // Case A: evaluate gradients
        if (grad) {

            // Evaluate source model
            double spec = (spectral() != NULL) ? spectral()->eval_gradients(srcEng)  : 1.0;
            double temp = (temporal() != NULL) ? temporal()->eval_gradients(srcTime) : 1.0;

            // Set value
            value = spec * temp * irf;

            // Compile option: Check for NaN/Inf
#if defined(G_NAN_CHECK)
            if (isnotanumber(value) || isinfinite(value)) {
                std::cout << "*** ERROR: GModelSky::spatial:";
                std::cout << " NaN/Inf encountered";
                std::cout << " (value=" << value;
                std::cout << ", spec=" << spec;
                std::cout << ", temp=" << temp;
                std::cout << ", irf=" << irf;
                std::cout << ")" << std::endl;
            }
#endif

            // Multiply factors to spectral gradients
            if (spectral() != NULL) {
                double fact = temp * irf;
                if (fact != 1.0) {
                    for (int i = 0; i < spectral()->size(); ++i) {
                        (*spectral())[i].gradient((*spectral())[i].gradient() * fact);
                    }
                }
            }

            // Multiply factors to temporal gradients
            if (temporal() != NULL) {
                double fact = spec * irf;
                if (fact != 1.0) {
                    for (int i = 0; i < temporal()->size(); ++i) {
                        (*temporal())[i].gradient((*temporal())[i].gradient() * fact);
                    }
                }
            }

        } // endif: gradient evaluation has been requested

        // Case B: evaluate no gradients
        else {

            // Evaluate source model
            double spec = (m_spectral != NULL) ? m_spectral->eval(srcEng) : 1.0;
            double temp = (m_temporal != NULL) ? m_temporal->eval(srcTime) : 1.0;

            // Set value
            value = spec * temp * irf;

            // Compile option: Check for NaN/Inf
#if defined(G_NAN_CHECK)
            if (isnotanumber(value) || isinfinite(value)) {
                std::cout << "*** ERROR: GModelSky::spatial:";
                std::cout << " NaN/Inf encountered";
                std::cout << " (value=" << value;
                std::cout << ", spec=" << spec;
                std::cout << ", temp=" << temp;
                std::cout << ", irf=" << irf;
                std::cout << ")" << std::endl;
            }
#endif

        }

    } // endif: Gamma-ray source model had a spatial component

    // Return value
    return value;
}