/***********************************************************************//** * @brief Generate model map * * @param[in] obs CTA observation pointer. * @param[in] models Model container. * * @exception GException::no_cube * No event cube found in CTA observation. ***************************************************************************/ void ctmodel::model_map(GCTAObservation* obs, const GModels& models) { // Continue only if observation pointer is valid if (obs != NULL) { // Get event cube pointer GCTAEventCube* cube = const_cast<GCTAEventCube*>(dynamic_cast<const GCTAEventCube*>(obs->events())); // Throw an exception if the observation does not hold and event // cube if (cube == NULL) { throw GException::no_cube(G_MODEL_MAP); } // Initialise statistics double sum = 0.0; // Loop over all events in counts map for (int i = 0; i < cube->size(); ++i) { // Get event bin GCTAEventBin* bin = (*cube)[i]; // Compute model value for event bin double model = models.eval(*(const_cast<const GCTAEventBin*>(bin)), *obs) * bin->size(); // Store value bin->counts(model); // Sum all events sum += model; } // Log results if (logTerse()) { log << gammalib::parformat("Model events in cube"); log << sum << std::endl; } } // endif: observation pointer was not valid // Return return; }
/***********************************************************************//** * @brief Fill model into model cube * * @param[in] obs CTA observation. * * Adds the expected number of events for a given observation to the events * that are already found in the model cube. The method also updates the * GTI of the model cube so that cube GTI is a list of the GTIs of all * observations that were used to generate the model cube. ***************************************************************************/ void ctmodel::fill_cube(const GCTAObservation* obs) { // Continue only if observation pointer is valid if (obs != NULL) { // Get GTI and energy boundaries references for observation const GGti& gti = obs->events()->gti(); const GEbounds& obs_ebounds = obs->ebounds(); // Get cube energy boundaries const GEbounds& cube_ebounds = m_cube.ebounds(); // Initialise empty, invalid RoI GCTARoi roi; // Retrieve RoI in case we have an unbinned observation if (obs->eventtype() == "EventList") { roi = obs->roi(); } // Initialise statistics double sum = 0.0; int num_outside_ebds = 0; int num_outside_roi = 0; // Setup cube GTIs for this observation m_cube.gti(obs->events()->gti()); // Loop over all cube bins for (int i = 0; i < m_cube.size(); ++i) { // Get cube bin GCTAEventBin* bin = m_cube[i]; // Skip bin if it is outside the energy range of the observation int index = cube_ebounds.index(bin->energy()); if (index == -1 || !obs_ebounds.contains(cube_ebounds.emin(index)+g_energy_margin, cube_ebounds.emax(index)-g_energy_margin)) { num_outside_ebds++; continue; } // Check if RoI is valid, i.e. check if we have an unbinned // observation if (roi.is_valid()) { // Skip bin if it is outside the RoI of the observation if (!roi.contains(*bin)) { num_outside_roi++; continue; } } // endif: RoI was not valid // Get actual bin value double value = bin->counts(); // Compute model value for cube bin double model = m_obs.models().eval(*bin, *obs) * bin->size(); // Add model to actual value value += model; sum += model; // Store value bin->counts(value); } // endfor: looped over all cube bins // Append GTIs of observation to list of GTIs m_gti.extend(gti); // Update GTIs m_cube.gti(m_gti); // Log results if (logTerse()) { log << gammalib::parformat("Model events in cube"); log << sum << std::endl; log << gammalib::parformat("Bins outside energy range"); log << num_outside_ebds << std::endl; log << gammalib::parformat("Bins outside RoI"); log << num_outside_roi << std::endl; } // Log cube if (logExplicit()) { log.header2("Model cube"); log << m_cube << std::endl; } } // endif: observation was valid // Return return; }