Пример #1
0
/***********************************************************************//**
 * @brief Get response cube spectrum
 *
 * @return Response cube spectrum.
 *
 * Returns the response cube spectrum.
 ***************************************************************************/
inline
const GModelSpectralNodes& GCTABackgroundPerfTable::spectrum(void) const
{
    if (m_mc_spectrum.nodes() == 0) {
        init_mc_cache();
    }
    return (m_mc_spectrum);
}
Пример #2
0
/***********************************************************************//**
 * @brief Determine sky model flux
 *
 * @param[in] model Sky model.
 * @param[in] emin Minimum energy.
 * @param[in] emax Maximum energy.
 * @param[in] centre Centre of region for photon rate determination.
 * @param[in] radius Radius of region for photon rate determination.
 * @return Model flux (photons/cm2/sec).
 ***************************************************************************/
double ctobssim::get_model_flux(const GModelSky* model,
                                const GEnergy&   emin,
                                const GEnergy&   emax,
                                const GSkyDir&   centre,
                                const double&    radius)
{
    // Initialise de-allocation flag
    bool free_spectral = false;

    // Get pointer to spectral model
    const GModelSpectral* spectral = model->spectral();

    // If the spatial model is a diffuse cube then create a node function
    // spectral model that is the product of the diffuse cube node function
    // and the spectral model evaluated at the energies of the node function
    GModelSpatialDiffuseCube* cube = dynamic_cast<GModelSpatialDiffuseCube*>(model->spatial());
    if (cube != NULL) {

        // Set MC cone
        cube->set_mc_cone(centre, radius);

        // Allocate node function to replace the spectral component
        GModelSpectralNodes* nodes = new GModelSpectralNodes(cube->spectrum());
        for (int i = 0; i < nodes->nodes(); ++i) {
            GEnergy energy    = nodes->energy(i);
            GTime   time;                              // Dummy time
            double  intensity = nodes->intensity(i);
            double  norm      = spectral->eval(energy, time);
            nodes->intensity(i, norm*intensity);
        }

        // Signal that node function needs to be de-allocated later
        free_spectral = true;

        // Set the spectral model pointer to the node function
        spectral = nodes;

    } // endif: spatial model was a diffuse cube
    
    // Compute flux within [emin, emax] in model from spectral
    // component (units: ph/cm2/s)
    double flux = spectral->flux(emin, emax);

    // Free spectral model if required
    if (free_spectral) delete spectral;

    // Return model flux
    return flux;
}
Пример #3
0
/***********************************************************************//**
 * @brief Return simulated list of events
 *
 * @param[in] obs Observation.
 * @param[in] ran Random number generator.
 * @return Pointer to list of simulated events (needs to be de-allocated by
 *         client)
 *
 * @exception GException::invalid_argument
 *            No CTA event list found in observation.
 *
 * Draws a sample of events from the background model using a Monte
 * Carlo simulation. The pointing information, the energy boundaries and the
 * good time interval for the sampling will be extracted from the observation
 * argument that is passed to the method. The method also requires a random
 * number generator of type GRan which is passed by reference, hence the
 * state of the random number generator will be changed by the method.
 *
 * The method also applies a deadtime correction using a Monte Carlo process,
 * taking into account temporal deadtime variations. For this purpose, the
 * method makes use of the time dependent GObservation::deadc method.
 ***************************************************************************/
GCTAEventList* GCTAModelBackground::mc(const GObservation& obs, GRan& ran) const
{
    // Initialise new event list
    GCTAEventList* list = new GCTAEventList;

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

        // Extract event list to access the ROI, energy boundaries and GTIs
        const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs.events());
        if (events == NULL) {
            std::string msg = "No CTA event list found in observation.\n" +
                              obs.print();
            throw GException::invalid_argument(G_MC, msg);
        }

        // Get simulation region
        const GCTARoi&  roi     = events->roi();
        const GEbounds& ebounds = events->ebounds();
        const GGti&     gti     = events->gti();

        // Set simulation region for result event list
        list->roi(roi);
        list->ebounds(ebounds);
        list->gti(gti);

        // Loop over all energy boundaries
        for (int ieng = 0; ieng < ebounds.size(); ++ieng) {

            // Initialise de-allocation flag
            bool free_spectral = false;

            // Set pointer to spectral model
            GModelSpectral* spectral = m_spectral;

            // If the spectral model is a diffuse cube then create a node
            // function spectral model that is the product of the diffuse
            // cube node function and the spectral model evaluated at the
            // energies of the node function
            GModelSpatialDiffuseCube* cube =
                dynamic_cast<GModelSpatialDiffuseCube*>(m_spatial);
            if (cube != NULL) {

			   // Set MC simulation cone based on ROI
			   cube->set_mc_cone(roi.centre().dir(), roi.radius());

			   // Allocate node function to replace the spectral component
			   GModelSpectralNodes* nodes = new GModelSpectralNodes(cube->spectrum());
			   for (int i = 0; i < nodes->nodes(); ++i) {
				   GEnergy energy    = nodes->energy(i);
				   double  intensity = nodes->intensity(i);
				   double  norm      = m_spectral->eval(energy, events->tstart());
				   nodes->intensity(i, norm*intensity);
			   }

			   // Signal that node function needs to be de-allocated later
			   free_spectral = true;

			   // Set the spectral model pointer to the node function
			   spectral = nodes;

            } // endif: spatial model was a diffuse cube

            // Compute the background rate in model within the energy boundaries
            // from spectral component (units: cts/s).
            // Note that the time here is ontime. Deadtime correction will be done
            // later.
            double rate = spectral->flux(ebounds.emin(ieng), ebounds.emax(ieng));

            // Debug option: dump rate
            #if defined(G_DUMP_MC)
            std::cout << "GCTAModelBackground::mc(\"" << name() << "\": ";
            std::cout << "rate=" << rate << " cts/s)" << std::endl;
            #endif

            // Loop over all good time intervals
            for (int itime = 0; itime < gti.size(); ++itime) {

                // Get Monte Carlo event arrival times from temporal model
                GTimes times = m_temporal->mc(rate,
                                              gti.tstart(itime),
                                              gti.tstop(itime),
                                              ran);

                // Get number of events
                int n_events = times.size();

                // Reserve space for events
                if (n_events > 0) {
                    list->reserve(n_events);
                }

                // Loop over events
                for (int i = 0; i < n_events; ++i) {

                    // Apply deadtime correction
                    double deadc = obs.deadc(times[i]);
                    if (deadc < 1.0) {
                        if (ran.uniform() > deadc) {
                            continue;
                        }
                    }

                    // Get Monte Carlo event energy from spectral model
                    GEnergy energy = spectral->mc(ebounds.emin(ieng),
                                                  ebounds.emax(ieng),
                                                  times[i],
                                                  ran);

                    // Get Monte Carlo event direction from spatial model
                    GSkyDir dir = spatial()->mc(energy, times[i], ran);

                    // Allocate event
                    GCTAEventAtom event;

                    // Set event attributes
                    event.dir(GCTAInstDir(dir));
                    event.energy(energy);
                    event.time(times[i]);

                    // Append event to list if it falls in ROI
                    if (events->roi().contains(event)) {
                        list->append(event);
                    }

                } // endfor: looped over all events

            } // endfor: looped over all GTIs

            // Free spectral model if required
            if (free_spectral) delete spectral;

        } // endfor: looped over all energy boundaries

    } // endif: model was valid

    // Return
    return list;
}