ctools 2.1.0.dev
Loading...
Searching...
No Matches
ctprob.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * ctprob - Computes event probability for a given model *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2017-2022 by Leonardo Di Venere *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file ctprob.cpp
23 * @brief Event probability computation tool implementation
24 * @author Leonardo Di Venere
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cstdlib>
32#include "ctprob.hpp"
33#include "GTools.hpp"
34
35/* __ Method name definitions ____________________________________________ */
36#define G_EVALUATE_PROB "ctprob::evaluate_probability(GCTAObservation*)"
37
38/* __ Debug definitions __________________________________________________ */
39
40/* __ Coding definitions _________________________________________________ */
41
42
43/*==========================================================================
44 = =
45 = Constructors/destructors =
46 = =
47 ==========================================================================*/
48
49/***********************************************************************//**
50 * @brief Void constructor
51 ***************************************************************************/
53{
54 // Initialise members
56
57 // Return
58 return;
59}
60
61
62/***********************************************************************//**
63 * @brief Observations constructor
64 *
65 * param[in] obs Observation container.
66 *
67 * Creates an instance of the class that is initialised using the information
68 * provided in an observation container.
69 ***************************************************************************/
70ctprob::ctprob(const GObservations& obs) :
71 ctobservation(CTPROB_NAME, VERSION, obs)
72{
73 // Initialise members
75
76 // Return
77 return;
78}
79
80
81
82
83/***********************************************************************//**
84 * @brief Command line constructor
85 *
86 * @param[in] argc Number of arguments in command line.
87 * @param[in] argv Array of command line arguments.
88 ***************************************************************************/
89ctprob::ctprob(int argc, char *argv[]) :
90 ctobservation(CTPROB_NAME, VERSION, argc, argv)
91{
92 // Initialise members
94
95 // Return
96 return;
97}
98
99
100/***********************************************************************//**
101 * @brief Copy constructor
102 *
103 * @param[in] app Application.
104 ***************************************************************************/
106{
107 // Initialise members
108 init_members();
109
110 // Copy members
111 copy_members(app);
112
113 // Return
114 return;
115}
116
117
118/***********************************************************************//**
119 * @brief Destructor
120 ***************************************************************************/
122{
123 // Free members
124 free_members();
125
126 // Return
127 return;
128}
129
130
131/*==========================================================================
132 = =
133 = Operators =
134 = =
135 ==========================================================================*/
136
137/***********************************************************************//**
138 * @brief Assignment operator
139 *
140 * @param[in] app Application.
141 * @return Application.
142 ***************************************************************************/
144{
145 // Execute only if object is not identical
146 if (this != &app) {
147
148 // Copy base class members
149 this->ctobservation::operator=(app);
150
151 // Free members
152 free_members();
153
154 // Initialise members
155 init_members();
156
157 // Copy members
158 copy_members(app);
159
160 } // endif: object was not identical
161
162 // Return this object
163 return *this;
164}
165
166
167/*==========================================================================
168 = =
169 = Public methods =
170 = =
171 ==========================================================================*/
172
173/***********************************************************************//**
174 * @brief Clear ctprob tool
175 *
176 * Clears ctprob tool.
177 ***************************************************************************/
179{
180 // Free members
181 free_members();
183 this->ctool::free_members();
184
185 // Clear base class (needed to conserve tool name and version)
186 this->GApplication::clear();
187
188 // Initialise members
189 this->ctool::init_members();
191 init_members();
192
193 // Write header into logger
194 log_header();
195
196 // Return
197 return;
198}
199
200
201/***********************************************************************//**
202 * @brief Process the ctprob tool
203 *
204 * This method reads in the application parameters and loops over all
205 * unbinned observations to compute the probability for each event that it
206 * comes from one of the model components.
207 ***************************************************************************/
209{
210 // Get parameters
212
213 // Set energy dispersion flags of all CTA observations and save old
214 // values in save_edisp vector
215 std::vector<bool> save_edisp = set_edisp(m_obs, m_apply_edisp);
216
217 // Write input observation container into logger
218 log_observations(NORMAL, m_obs, "Input observation");
219
220 // Write header into logger
221 log_header1(TERSE, "Compute event probabilities");
222
223 // Initialise counters
224 int n_observations = 0;
225
226 // Loop over all unbinned CTA observations in the container
227 for (GCTAObservation* obs = first_unbinned_observation(); obs != NULL;
229
230 // Increment counter
231 n_observations++;
232
233 // Evaluate event probabilities
235
236 } // endfor: looped over observations
237
238 // If more than a single observation has been handled then make sure that
239 // an XML file will be used for storage
240 if (n_observations > 1) {
241 m_use_xml = true;
242 }
243
244 // Write observation(s) into logger
245 log_observations(NORMAL, m_obs, "Output observation");
246
247 // Restore energy dispersion flags of all CTA observations
248 restore_edisp(m_obs, save_edisp);
249
250 // Optionally publish event list(s)
251 if ((*this)["publish"].boolean()) {
252 publish();
253 }
254
255 // Return
256 return;
257}
258
259
260/***********************************************************************//**
261 * @brief Save the selected event list(s)
262 *
263 * This method saves the selected event list(s) into FITS file(s). There are
264 * two modes, depending on the m_use_xml flag.
265 *
266 * If m_use_xml is true, all selected event list(s) will be saved into FITS
267 * files, where the output filenames are constructued from the input
268 * filenames by prepending the m_prefix string to name. Any path information
269 * will be stripped form the input name, hence event files will be written
270 * into the local working directory (unless some path information is present
271 * in the prefix). In addition, an XML file will be created that gathers
272 * the filename information for the selected event list(s). If an XML file
273 * was present on input, all metadata information will be copied from this
274 * input file.
275 *
276 * If m_use_xml is false, the selected event list will be saved into a FITS
277 * file.
278 ***************************************************************************/
279void ctprob::save(void)
280{
281 // Write header into logger
282 log_header1(TERSE, gammalib::number("Save event list", m_obs.size()));
283
284 // Case A: Save event file(s) and XML metadata information
285 if (m_use_xml) {
287 }
288
289 // Case B: Save event file as FITS file
290 else {
292 }
293
294 // Return
295 return;
296}
297
298
299/***********************************************************************//**
300 * @brief Publish event lists
301 *
302 * @param[in] name Event list name.
303 ***************************************************************************/
304void ctprob::publish(const std::string& name)
305{
306 // Write header into logger
307 log_header1(TERSE, gammalib::number("Publish event list", m_obs.size()));
308
309 // Loop over all observation in the container
310 for (int i = 0; i < m_obs.size(); ++i) {
311
312 // Get CTA observation
313 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
314
315 // Handle only CTA observations
316 if (obs != NULL) {
317
318 // Continue only if there is an event list
319 if (obs->events()->size() != 0) {
320
321 // Set default name if user name is empty
322 std::string user_name(name);
323 if (user_name.empty()) {
324 user_name = CTPROB_NAME;
325 }
326
327 // If there are several event lists then add an index
328 if (m_use_xml) {
329 user_name += gammalib::str(i);
330 }
331
332 // Write event list name into logger
333 log_value(NORMAL, "Event list name", user_name);
334
335 // Write events into in-memory FITS file
336 GFits fits;
337 obs->write(fits);
338
339 // Publish
340 fits.publish(gammalib::extname_cta_events, user_name);
341
342 } // endif: there were events
343
344 } // endif: observation was a CTA observation
345
346 } // endfor: looped over observations
347
348 // Return
349 return;
350}
351
352
353/*==========================================================================
354 = =
355 = Private methods =
356 = =
357 ==========================================================================*/
358
359/***********************************************************************//**
360 * @brief Initialise class members
361 ***************************************************************************/
363{
364 // Initialise parameters
365 m_apply_edisp = false;
366 m_publish = false;
367 m_chatter = static_cast<GChatter>(2);
368
369 // Return
370 return;
371}
372
373
374/***********************************************************************//**
375 * @brief Copy class members
376 *
377 * @param[in] app Application.
378 ***************************************************************************/
380{
381 // Copy parameters
382 m_apply_edisp = app.m_apply_edisp;
383 m_publish = app.m_publish;
384 m_chatter = app.m_chatter;
385
386 // Return
387 return;
388}
389
390
391/***********************************************************************//**
392 * @brief Delete class members
393 ***************************************************************************/
395{
396 // Return
397 return;
398}
399
400
401/***********************************************************************//**
402 * @brief Get application parameters
403 *
404 * Get all application parameters by either querying the parameters or by
405 * retrieving the parameters for the parameter file.
406 ***************************************************************************/
408{
409 // Setup observations from "inobs" parameter. Request response
410 // information, accept event lists but do not accept counts cubes.
411 setup_observations(m_obs, true, true, false);
412
413 // Read model definition file if required
414 if (m_obs.models().size() == 0) {
415
416 // Get model filename
417 std::string inmodel = (*this)["inmodel"].filename();
418
419 // Load models from file
420 m_obs.models(inmodel);
421
422 } // endif: there were no models
423
424 // Get energy dispersion flag parameters
425 m_apply_edisp = (*this)["edisp"].boolean();
426
427 // Get remaining parameters
428 m_publish = (*this)["publish"].boolean();
429 m_chatter = static_cast<GChatter>((*this)["chatter"].integer());
430
431 // If needed later, query output filename and prefix now
432 if (read_ahead()) {
433 (*this)["outobs"].query();
434 (*this)["prefix"].query();
435 }
436
437 // Write parameters into logger
438 log_parameters(TERSE);
439
440 // Return
441 return;
442}
443
444
445/***********************************************************************//**
446 * @brief Evaluate probability for events
447 *
448 * @param[in,out] obs CTA observation.
449 *
450 * @exception GException::invalid_value
451 * Observation does not contain an event list.
452 *
453 * Computes for all events the probability that an event arises from a
454 * specific model component. The computation is done by by evaluating the
455 * differential event probability for a given model and normalizing these
456 * probabilities so that the sum of the probabilities for all model
457 * components is unity for each event.
458 *
459 * The method appends for each model component a single precision column to
460 * the event list that contains the event probabilities. The name of the
461 * column is build from the model name prefixed with `PROB_`.
462 ***************************************************************************/
463void ctprob::evaluate_probability(GCTAObservation* obs)
464{
465 // Write header into logger
466 log_header3(NORMAL, "Evaluate events probabilities");
467
468 // Make sure that the observation holds a CTA event list. If this
469 // is not the case then throw an exception.
470 GCTAEventList* events = dynamic_cast<GCTAEventList*>(const_cast<GEvents*>
471 (obs->events()));
472 if (events == NULL) {
473 std::string msg = "CTA Observation does not contain an event list. An "
474 "event list is needed to compute the event "
475 "probabilities.";
476 throw GException::invalid_value(G_EVALUATE_PROB, msg);
477 }
478
479 // Continue only if there are model components
480 int nmodels = m_obs.models().size();
481 if (nmodels > 0) {
482
483 // Allocate single precision FITS table columns for all model components
484 std::vector<GFitsTableFloatCol*> columns;
485 for (int k = 0; k < nmodels; ++k) {
486 const std::string colname = "PROB_" + m_obs.models()[k] ->name();
487 GFitsTableFloatCol* col =
488 new GFitsTableFloatCol(colname, events->size());
489 columns.push_back(col);
490 }
491
492 // Loop over all events in the event list
493 for (int i = 0; i < events->size(); ++i) {
494
495 // Initialise total probability
496 double total = 0.0;
497
498 // Get point to event
499 const GEvent* event = (*events)[i];
500
501 // Initialise probability vector
502 std::vector<double> probabilities(nmodels, 0.0);
503
504 // Loop over models
505 for (int k = 0; k < nmodels; ++k) {
506 double value = m_obs.models()[k]->eval(*event, *obs);
507 probabilities[k] = value;
508 total += value;
509 }
510
511 // Normalize probabilities to unity
512 if (total > 0.0) {
513 for (int k = 0; k < nmodels; ++k) {
514 probabilities[k] /= total;
515 }
516 }
517
518 // Store probabilities in FITS columns
519 for (int k = 0; k < nmodels; ++k) {
520 (*(columns[k]))(i) = probabilities[k];
521 }
522
523 } // endfor: looped over all events
524
525 // Append columns to event list
526 for (int k = 0; k < nmodels; ++k) {
527 events->append_column(*columns[k]);
528 }
529
530 } // endif: there were model components
531
532 // Return
533 return;
534}
Base class for observation tools.
void free_members(void)
Delete class members.
ctobservation & operator=(const ctobservation &app)
Assignment operator.
GCTAObservation * next_unbinned_observation(void)
Return next unbinned CTA observation.
GObservations m_obs
Observation container.
GCTAObservation * first_unbinned_observation(void)
Return first unbinned CTA observation.
void save_events_fits(void)
Save event list in FITS format.
const GObservations & obs(void) const
Return observation container.
void save_events_xml(void)
Save event list(s) in XML format.
void init_members(void)
Initialise class members.
bool m_use_xml
Use XML file instead of FITS file for observations.
Definition ctool.hpp:162
void restore_edisp(GObservations &obs, const std::vector< bool > &edisp) const
Restore energy dispersion flags of CTA observations.
Definition ctool.cpp:1689
void free_members(void)
Delete class members.
Definition ctool.cpp:357
void log_observations(const GChatter &chatter, const GObservations &obs, const std::string &what="Observation")
Log observation container.
Definition ctool.cpp:1251
std::vector< bool > set_edisp(GObservations &obs, const bool &edisp) const
Set energy dispersion to CTA observations.
Definition ctool.cpp:1649
const bool & read_ahead(void) const
Signal whether parameters should be read ahead.
Definition ctool.hpp:177
void log_parameters(const GChatter &chatter)
Log application parameters.
Definition ctool.cpp:1208
void init_members(void)
Initialise class members.
Definition ctool.cpp:321
void setup_observations(GObservations &obs, const bool &response=true, const bool &list=true, const bool &cube=true)
Setup observation container.
Definition ctool.cpp:431
Event probability computation tool.
Definition ctprob.hpp:46
void copy_members(const ctprob &app)
Copy class members.
Definition ctprob.cpp:379
void init_members(void)
Initialise class members.
Definition ctprob.cpp:362
bool m_apply_edisp
Apply energy dispersion?
Definition ctprob.hpp:74
GChatter m_chatter
Chattiness.
Definition ctprob.hpp:76
void evaluate_probability(GCTAObservation *obs)
Evaluate probability for events.
Definition ctprob.cpp:463
void publish(const std::string &name="")
Publish event lists.
Definition ctprob.cpp:304
ctprob(void)
Void constructor.
Definition ctprob.cpp:52
void clear(void)
Clear ctprob tool.
Definition ctprob.cpp:178
ctprob & operator=(const ctprob &app)
Assignment operator.
Definition ctprob.cpp:143
void save(void)
Save the selected event list(s)
Definition ctprob.cpp:279
virtual ~ctprob(void)
Destructor.
Definition ctprob.cpp:121
void process(void)
Process the ctprob tool.
Definition ctprob.cpp:208
void free_members(void)
Delete class members.
Definition ctprob.cpp:394
bool m_publish
Publish event list?
Definition ctprob.hpp:75
void get_parameters(void)
Get application parameters.
Definition ctprob.cpp:407
#define G_EVALUATE_PROB
Definition ctprob.cpp:36
Event probability computation tool interface definition.
#define CTPROB_NAME
Definition ctprob.hpp:38