ctools 2.1.0.dev
Loading...
Searching...
No Matches
cttsmap.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * cttsmap - TS map calculation tool *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2014-2022 by Michael Mayer *
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 cttsmap.hpp
23 * @brief TS map calculation tool interface implementation
24 * @author Michael Mayer
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cstdio>
32#include "cttsmap.hpp"
33#include "GTools.hpp"
34
35/* __ Method name definitions ____________________________________________ */
36#define G_GET_PARAMETERS "cttsmap::get_parameters()"
37
38/* __ Debug definitions __________________________________________________ */
39
40/* __ Coding definitions _________________________________________________ */
41
42
43/*==========================================================================
44 = =
45 = Constructors/destructors =
46 = =
47 ==========================================================================*/
48
49/***********************************************************************//**
50 * @brief Void constructor
51 *
52 * Constructs an empty cttsmap tool.
53 ***************************************************************************/
55{
56 // Initialise members
58
59 // Return
60 return;
61}
62
63
64/***********************************************************************//**
65 * @brief Observations constructor
66 *
67 * param[in] obs Observation container.
68 *
69 * Constructs cttsmap tool from an observations container.
70 ***************************************************************************/
71cttsmap::cttsmap(const GObservations& obs) :
72 ctlikelihood(CTTSMAP_NAME, VERSION, obs)
73{
74 // Initialise members
76
77 // Return
78 return;
79}
80
81
82/***********************************************************************//**
83 * @brief Command line constructor
84 *
85 * @param[in] argc Number of arguments in command line.
86 * @param[in] argv Array of command line arguments.
87 *
88 * Constructs an instance of the cttsmap tool that will parse user parameters
89 * that are provided as command line arguments.
90 ***************************************************************************/
91cttsmap::cttsmap(int argc, char *argv[]) :
92 ctlikelihood(CTTSMAP_NAME, VERSION, argc, argv)
93{
94 // Initialise members
96
97 // Return
98 return;
99}
100
101
102/***********************************************************************//**
103 * @brief Copy constructor
104 *
105 * @param[in] app Application.
106 ***************************************************************************/
108{
109 // Initialise members
110 init_members();
111
112 // Copy members
113 copy_members(app);
114
115 // Return
116 return;
117}
118
119
120/***********************************************************************//**
121 * @brief Destructor
122 ***************************************************************************/
124{
125 // Free members
126 free_members();
127
128 // Return
129 return;
130}
131
132
133/*==========================================================================
134 = =
135 = Operators =
136 = =
137 ==========================================================================*/
138
139/***********************************************************************//**
140 * @brief Assignment operator
141 *
142 * @param[in] app Application.
143 * @return Application.
144 ***************************************************************************/
146{
147 // Execute only if object is not identical
148 if (this != &app) {
149
150 // Copy base class members
151 this->ctlikelihood::operator=(app);
152
153 // Free members
154 free_members();
155
156 // Initialise members
157 init_members();
158
159 // Copy members
160 copy_members(app);
161
162 } // endif: object was not identical
163
164 // Return this object
165 return *this;
166}
167
168
169/*==========================================================================
170 = =
171 = Public methods =
172 = =
173 ==========================================================================*/
174
175/***********************************************************************//**
176 * @brief Clear instance
177 ***************************************************************************/
179{
180 // Free members
181 free_members();
184 this->ctool::free_members();
185
186 // Clear base class (needed to conserve tool name and version)
187 this->GApplication::clear();
188
189 // Initialise members
190 this->ctool::init_members();
193 init_members();
194
195 // Return
196 return;
197}
198
199
200/***********************************************************************//**
201 * @brief Computes the TS maps
202 *
203 * This method moves a source along a grid of coordinates and refits the
204 * given models including this additional source. The fit parameters of the
205 * source and its TS values are filled into respective position in the map.
206 ***************************************************************************/
208{
209 // Get task parameters
211
212 // Set energy dispersion flags of all CTA observations and save old
213 // values in save_edisp vector
214 std::vector<bool> save_edisp = set_edisp(m_obs, m_apply_edisp);
215
216 // Write input observation container into logger
217 log_observations(NORMAL, m_obs, "Input observation");
218
219 // Write header
220 log_header1(TERSE, "Initialise TS map");
221
222 // Get bins to be computed
223 // To split the computation on several jobs,
224 // the user is able to provide a subset of bins
225 // which should be computed
226 int binmin = (m_binmin == -1) ? 0 : m_binmin;
227 int binmax = (m_binmax == -1) ? m_tsmap.npix() : m_binmax;
228
229 // Set optimizer logger
230 if (logExplicit()) {
231 static_cast<GOptimizerLM*>(&m_opt)->logger(&log);
232 }
233 else {
234 static_cast<GOptimizerLM*>(&m_opt)->logger(NULL);
235 }
236
237 // Store initial models
238 GModels models_orig = m_obs.models();
239
240 // Get model instance for further computations
241 GModels models = m_obs.models();
242
243 // Remove test source
244 models.remove(m_srcname);
245
246 // Fix spatial parameters if requested
247 if ((*this)["fix_spat"].boolean()) {
248
249 // Loop over all models
250 for (int i = 0; i < models.size(); ++i) {
251
252 // Continue only if model is skymodel
253 GModelSky* sky= dynamic_cast<GModelSky*>(models[i]);
254 if (sky != NULL) {
255
256 // Fix all spatial parameters
257 GModelSpatial* spatial = sky->spatial();
258 for (int j = 0; j < spatial->size(); j++) {
259 (*spatial)[j].fix();
260 }
261
262 } // endif: there was a sky model
263
264 } // endfor: looped over models
265
266 } // endif: spatial parameter should be fixed
267
268 // Get likelihood of null hypothesis if not given before
269 if (m_logL0 == 0.0) {
270
271 // Write header
272 log_header1(TERSE, "Compute NULL Hypothesis for TS computation");
273
274 // Compute likelihood without the test source
275 m_obs.models(models);
276 m_obs.optimize(m_opt);
277 m_logL0 = -(m_opt.value());
278
279 // Write input model container into logger
280 log_models(VERBOSE, m_obs.models(), "Fitted model");
281
282 // If requested, update model for TS map computation
283 if ((*this)["use_h0_fit"].boolean()) {
284 models = m_obs.models();
285 }
286
287 }
288
289 // Write header
290 log_header1(TERSE, "Generate TS map");
291
292 // Loop over grid positions
293 for (int i = binmin; i < binmax; ++i) {
294
295 // Get the coordinate of current bin
296 GSkyDir bincentre = m_tsmap.inx2dir(i);
297
298 // Header for verbose logging
299 log_header2(EXPLICIT, "Computing TS for bin number "+gammalib::str(i)+
300 " at "+bincentre.print());
301
302 // Add test source at current bin position
303 (*m_testsource)["RA"].value(bincentre.ra_deg());
304 (*m_testsource)["DEC"].value(bincentre.dec_deg());
305 models.append(*m_testsource);
306
307 // Assign models to observations
308 m_obs.models(models);
309
310 // Make sure that no values are cached for test source
311 m_obs.remove_response_cache(m_srcname);
312
313 // Optimize observation container
314 m_obs.optimize(m_opt);
315
316 // Compute errors if necessary
317 if (m_errors) {
318 m_obs.errors(m_opt);
319 }
320
321 // Get status of optimization
322 int status = m_opt.status();
323
324 // Retrieve the Likelihood value
325 double logL1 = -(m_opt.value());
326
327 // Compute TS value
328 double ts = 2.0 * (logL1 - m_logL0);
329
330 // Log information
331 if (logExplicit()) {
332 log_value(EXPLICIT, "TS value", ts);
333 }
334 else if (logNormal()) {
335 log_value(NORMAL, "TS value (bin "+gammalib::str(i)+")",
336 gammalib::str(ts)+" ("+bincentre.print()+")");
337 }
338
339 // Get test source model instance
340 GModels best_fit_model = m_obs.models();
341 GModel* testsource = best_fit_model[m_srcname];
342
343 // Assign values to the maps
344 m_tsmap(i) = ts;
345
346 // Extract fitted test source parameters
347 for (int j = 0; j < m_mapnames.size(); ++j) {
348
349 // If map name start with "e_" then set the parameter error ...
350 if (m_mapnames[j].substr(0,2) == "e_") {
351
352 // Get parameter name by removing the error prefix
353 std::string parname = m_mapnames[j].substr(2, m_mapnames[j].size());
354
355 // Get parameter error
356 m_maps[j](i) = (*testsource)[parname].error();
357
358 }
359
360 // ... otherwise set the parameter value
361 else {
362 m_maps[j](i) = (*testsource)[m_mapnames[j]].value();
363 }
364
365 } // endfor: looped over all maps
366
367 // Set Fit status of the bin
368 m_statusmap(i) = status;
369
370 // Remove model from container
371 models.remove(m_srcname);
372
373 } // endfor: looped over grid positions
374
375 // Bring models to initial state
376 m_obs.models(models_orig);
377
378 // Restore energy dispersion flags of all CTA observations
379 restore_edisp(m_obs, save_edisp);
380
381 // Optionally publish TS map
382 if (m_publish) {
383 publish();
384 }
385
386 // Return
387 return;
388}
389
390
391/***********************************************************************//**
392 * @brief Save maps
393 *
394 * This method saves the TS map and additional maps into a FITS file.
395 ***************************************************************************/
397{
398 // Write header
399 log_header1(TERSE, "Save TS map");
400
401 // Save only if filename is valid and TS map is not empty
402 if ((*this)["outmap"].is_valid() && !m_tsmap.is_empty()) {
403
404 // Get TS map filename
405 m_outmap = (*this)["outmap"].filename();
406
407 // Create fits file
408 GFits fits;
409
410 // Write the sky maps to the FITS file
411 m_tsmap.write(fits);
412 for (int i = 0; i < m_mapnames.size(); i++) {
413 m_maps[i].write(fits);
414 }
415
416 // Set extension name for all maps
417 for (int i = 0; i < m_mapnames.size(); i++) {
418 fits[i+1]->extname(m_mapnames[i]);
419 }
420
421 // Write Fit status map
422 m_statusmap.write(fits);
423 fits[fits.size()-1]->extname("STATUS MAP");
424
425 // Stamp FITS file
426 stamp(fits);
427
428 // Save FITS file
429 fits.saveto(m_outmap, clobber());
430
431 } // endif: TS map filename was valid
432
433 // Write into logger what has been done
434 std::string fname = (m_outmap.is_empty()) ? "NONE" : m_outmap.url();
435 if (m_tsmap.is_empty()) {
436 fname.append(" (TS map is empty, no file created)");
437 }
438 log_value(NORMAL, "TS map file", fname);
439
440 // Return
441 return;
442}
443
444
445/***********************************************************************//**
446 * @brief Publish TS map
447 *
448 * @param[in] name TS map name.
449 ***************************************************************************/
450void cttsmap::publish(const std::string& name)
451{
452 // Write header into logger
453 log_header1(TERSE, "Publish TS map");
454
455 // Set default name is user name is empty
456 std::string user_name(name);
457 if (user_name.empty()) {
458 user_name = CTTSMAP_NAME;
459 }
460
461 // Write TS map name into logger
462 log_value(NORMAL, "TS map name", user_name);
463
464 // Publish TS map
465 m_tsmap.publish(user_name);
466
467 // Return
468 return;
469}
470
471
472/*==========================================================================
473 = =
474 = Private methods =
475 = =
476 ==========================================================================*/
477
478/***********************************************************************//**
479 * @brief Initialise class members
480 ***************************************************************************/
482{
483 // Initialise members
484 m_srcname.clear();
485 m_outmap.clear();
486 m_apply_edisp = false;
487 m_publish = false;
488 m_errors = false;
489
490 // Initialise protected members
491 m_binmin = -1;
492 m_binmax = -1;
493 m_logL0 = 0.0;
494 m_tsmap.clear();
495 m_statusmap.clear();
496 m_mapnames.clear();
497 m_maps.clear();
498 m_testsource = NULL;
499
500 // Return
501 return;
502}
503
504
505/***********************************************************************//**
506 * @brief Copy class members
507 *
508 * @param[in] app Application.
509 ***************************************************************************/
511{
512 // Copy attributes
513 m_srcname = app.m_srcname;
514 m_outmap = app.m_outmap;
515 m_apply_edisp = app.m_apply_edisp;
516 m_publish = app.m_publish;
517 m_errors = app.m_errors;
518
519 // Copy protected members
520 m_binmin = app.m_binmin;
521 m_binmax = app.m_binmax;
522 m_logL0 = app.m_logL0;
523 m_tsmap = app.m_tsmap;
524 m_statusmap = app.m_statusmap;
525 m_mapnames = app.m_mapnames;
526 m_maps = app.m_maps;
527
528 // Clone protected members
529 m_testsource = (app.m_testsource != NULL) ? app.m_testsource->clone()
530 : NULL;
531
532 // Return
533 return;
534}
535
536
537/***********************************************************************//**
538 * @brief Delete class members
539 ***************************************************************************/
541{
542 // Free test source
543 if (m_testsource != NULL) {
544 delete m_testsource;
545 m_testsource = NULL;
546 }
547
548 // Return
549 return;
550}
551
552
553/***********************************************************************//**
554 * @brief Get application parameters
555 *
556 * @exception GException::invalid_value
557 * Test source has no RA/DEC parameters.
558 *
559 * Get all task parameters from parameter file.
560 ***************************************************************************/
562{
563 // Setup observations from "inobs" parameter
565
566 // Set observation statistic
567 set_obs_statistic(gammalib::toupper((*this)["statistic"].string()));
568
569 // Setup models from "inmodel" parameter
570 setup_models(m_obs, (*this)["srcname"].string());
571
572 // Get name of test source
573 m_srcname = (*this)["srcname"].string();
574
575 // Get model and store it as protected member. Note that the clone
576 // method will never return a NULL pointer, hence we do not need
577 // to check the pointer.
578 m_testsource = m_obs.models()[m_srcname]->clone();
579
580 // Check if model has RA and DEC parameters which are necessary to
581 // continue
582 if (!m_testsource->has_par("RA") || !m_testsource->has_par("DEC")) {
583 std::string msg = "Source \""+m_srcname+"\" has no \"RA\" and "
584 "\"DEC\" parameters. Only sources with \"RA\" "
585 "and \"DEC\" parameters can be used as test "
586 "sources.";
587 throw GException::invalid_value(G_GET_PARAMETERS, msg);
588 }
589
590 // Fix the spatial parameters of the test source
591 (*m_testsource)["RA"].fix();
592 (*m_testsource)["DEC"].fix();
593
594 // Create sky map based on task parameters
595 GSkyMap map = create_map(m_obs);
596
597 // Check if errors should be computed
598 m_errors = (*this)["errors"].boolean();
599
600 // Initialise maps from user parameters
601 init_maps(map);
602
603 // Read energy dispersion flag
604 m_apply_edisp = (*this)["edisp"].boolean();
605
606 // Get optional splitting parameters
607 m_binmin = (*this)["binmin"].integer();
608 m_binmax = (*this)["binmax"].integer();
609 m_logL0 = (*this)["logL0"].real();
610 m_publish = (*this)["publish"].boolean();
611
612 // Query other parameters
613 (*this)["fix_spat"].boolean();
614
615 // If needed later, query output filename now
616 if (read_ahead()) {
617 (*this)["outmap"].query();
618 }
619
620 // Write parameters into logger
621 log_parameters(TERSE);
622
623 // Return
624 return;
625}
626
627
628/***********************************************************************//**
629 * @brief Initialise skymaps
630 *
631 * Initialises skymaps that will contain map information.
632 ***************************************************************************/
633void cttsmap::init_maps(const GSkyMap& map)
634{
635 // Initialise map information
636 m_tsmap.clear();
637
638 // Create skymap
639 m_tsmap = GSkyMap(map);
640
641 // Initialise map information
642 m_statusmap.clear();
643
644 // Create status map and progress map
645 m_statusmap = GSkyMap(map);
646
647 // Set status map to invalid value -1 to signal that bin wasn't computed yet
648 m_statusmap = -1.0;
649
650 // Loop over all model parameters
651 for (int i = 0; i < m_testsource->size(); i++) {
652
653 // Skip fixed parameters
654 if ((*m_testsource)[i].is_fixed()) {
655 continue;
656 }
657
658 // Add sky map for free parameters. Note that push_back will
659 // create a copy.
660 m_maps.push_back(map);
661
662 // Store parameter name
663 m_mapnames.push_back((*m_testsource)[i].name());
664
665 // Add parameter errors if requested
666 if (m_errors) {
667
668 // Add sky map for fit error of the free parameter
669 m_maps.push_back(map);
670
671 // Store name of parameter error
672 m_mapnames.push_back("e_" + (*m_testsource)[i].name());
673
674 } // endif: error calculation was requested
675
676 } // endfor: looped over all model parameters
677
678 // Return
679 return;
680}
Base class for likelihood tools.
GOptimizerLM m_opt
Optimizer.
ctlikelihood & operator=(const ctlikelihood &app)
Assignment operator.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
GObservations m_obs
Observation container.
void init_members(void)
Initialise class members.
void set_obs_statistic(const std::string &statistic)
Set fit statistic for CTA observations.
void restore_edisp(GObservations &obs, const std::vector< bool > &edisp) const
Restore energy dispersion flags of CTA observations.
Definition ctool.cpp:1689
void setup_models(GObservations &obs, const std::string &name="")
Setup model container.
Definition ctool.cpp:545
void free_members(void)
Delete class members.
Definition ctool.cpp:357
GSkyMap create_map(const GObservations &obs)
Create a skymap from user parameters.
Definition ctool.cpp:937
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
void log_models(const GChatter &chatter, const GModels &models, const std::string &what="Model")
Log model container.
Definition ctool.cpp:1285
TS map calculation tool.
Definition cttsmap.hpp:55
std::string m_srcname
Name of source which is moved around.
Definition cttsmap.hpp:84
int m_binmax
Map bin number where map computation should end.
Definition cttsmap.hpp:92
cttsmap & operator=(const cttsmap &app)
Assignment operator.
Definition cttsmap.cpp:145
void save(void)
Save maps.
Definition cttsmap.cpp:396
void free_members(void)
Delete class members.
Definition cttsmap.cpp:540
void clear(void)
Clear instance.
Definition cttsmap.cpp:178
GSkyMap m_statusmap
Map of optimizer fit status.
Definition cttsmap.hpp:97
bool m_errors
Compute and store parameter errors?
Definition cttsmap.hpp:88
void copy_members(const cttsmap &app)
Copy class members.
Definition cttsmap.cpp:510
int m_binmin
Map bin number from which computation should start.
Definition cttsmap.hpp:91
std::vector< std::string > m_mapnames
Names of free parameters.
Definition cttsmap.hpp:98
bool m_apply_edisp
Apply energy dispersion?
Definition cttsmap.hpp:86
GSkyMap m_tsmap
TS map.
Definition cttsmap.hpp:96
void init_members(void)
Initialise class members.
Definition cttsmap.cpp:481
bool m_publish
Publish TS map?
Definition cttsmap.hpp:87
cttsmap(void)
Void constructor.
Definition cttsmap.cpp:54
double m_logL0
Likelihood value of null hypothesis.
Definition cttsmap.hpp:93
std::vector< GSkyMap > m_maps
Sky maps for each free parameter.
Definition cttsmap.hpp:99
void publish(const std::string &name="")
Publish TS map.
Definition cttsmap.cpp:450
GFilename m_outmap
Output TS map file name.
Definition cttsmap.hpp:85
virtual ~cttsmap(void)
Destructor.
Definition cttsmap.cpp:123
GModel * m_testsource
Pointer to test source for TS computation.
Definition cttsmap.hpp:100
void init_maps(const GSkyMap &map)
Initialise skymaps.
Definition cttsmap.cpp:633
void get_parameters(void)
Get application parameters.
Definition cttsmap.cpp:561
void process(void)
Computes the TS maps.
Definition cttsmap.cpp:207
#define G_GET_PARAMETERS
Definition ctbin.cpp:42
TS map calculation tool interface implementation.
#define CTTSMAP_NAME
Definition cttsmap.hpp:34