ctools  2.0.0
 All Classes Namespaces Files Functions Variables Macros Pages
ctbkgcube.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * ctbkgcube - Background cube generation tool *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2014-2022 by Chia-Chun Lu *
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 ctbkgcube.cpp
23  * @brief Background cube generation tool definition
24  * @author Chia-Chun Lu
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <cstdio>
32 #include "ctbkgcube.hpp"
33 #include "GTools.hpp"
34 
35 /* __ Method name definitions ____________________________________________ */
36 #define G_PROCESS "ctbkgcube::process()"
37 
38 /* __ Debug definitions __________________________________________________ */
39 
40 /* __ Coding definitions _________________________________________________ */
41 
42 /* __ Constants __________________________________________________________ */
43 
44 
45 /*==========================================================================
46  = =
47  = Constructors/destructors =
48  = =
49  ==========================================================================*/
50 
51 /***********************************************************************//**
52  * @brief Void constructor
53  ***************************************************************************/
55 {
56  // Initialise members
57  init_members();
58 
59  // Return
60  return;
61 }
62 
63 
64 /***********************************************************************//**
65  * @brief Observations constructor
66  *
67  * param[in] obs Observation container.
68  *
69  * This method creates an instance of the class by copying an existing
70  * observations container.
71  ***************************************************************************/
72 ctbkgcube::ctbkgcube(const GObservations& obs) :
73  ctobservation(CTBKGCUBE_NAME, VERSION, obs)
74 {
75  // Initialise members
76  init_members();
77 
78  // Return
79  return;
80 }
81 
82 
83 
84 /***********************************************************************//**
85  * @brief Command line constructor
86  *
87  * @param[in] argc Number of arguments in command line.
88  * @param[in] argv Array of command line arguments.
89  ***************************************************************************/
90 ctbkgcube::ctbkgcube(int argc, char *argv[]) :
91  ctobservation(CTBKGCUBE_NAME, VERSION, argc, argv)
92 {
93  // Initialise members
94  init_members();
95 
96  // Return
97  return;
98 }
99 
100 
101 /***********************************************************************//**
102  * @brief Copy constructor
103  *
104  * @param[in] app Application.
105  ***************************************************************************/
107 {
108  // Initialise members
109  init_members();
110 
111  // Copy members
112  copy_members(app);
113 
114  // Return
115  return;
116 }
117 
118 
119 /***********************************************************************//**
120  * @brief Destructor
121  ***************************************************************************/
123 {
124  // Free members
125  free_members();
126 
127  // Return
128  return;
129 }
130 
131 
132 /*==========================================================================
133  = =
134  = Operators =
135  = =
136  ==========================================================================*/
137 
138 /***********************************************************************//**
139  * @brief Assignment operator
140  *
141  * @param[in] app Application.
142  * @return Returns application.
143  ***************************************************************************/
145 {
146  // Execute only if object is not identical
147  if (this != &app) {
148 
149  // Copy base class members
150  this->ctobservation::operator=(app);
151 
152  // Free members
153  free_members();
154 
155  // Initialise members
156  init_members();
157 
158  // Copy members
159  copy_members(app);
160 
161  } // endif: object was not identical
162 
163  // Return this object
164  return *this;
165 }
166 
167 
168 /*==========================================================================
169  = =
170  = Public methods =
171  = =
172  ==========================================================================*/
173 
174 /***********************************************************************//**
175  * @brief Clear ctbkgcube tool
176  *
177  * Clears ctbkgcube tool.
178  ***************************************************************************/
180 {
181  // Free members
182  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();
192  init_members();
193 
194  // Write header into logger
195  log_header();
196 
197  // Return
198  return;
199 }
200 
201 
202 /***********************************************************************//**
203  * @brief Generate the background cube(s).
204  *
205  * This method reads the task parameters from the parfile, sets up the
206  * observation container, loops over all CTA observations in the container
207  * and generates a background cube from the CTA observations.
208  ***************************************************************************/
210 {
211  // Get task parameters
212  get_parameters();
213 
214  // Write input observation container into logger
215  log_observations(NORMAL, m_obs, "Input observation");
216 
217  // Write input model container into logger
218  log_models(NORMAL, m_obs.models(), "Input model");
219 
220  // Write header
221  log_header1(TERSE, "Prepare model");
222 
223  // Copy models from observation container and reset output model
224  // container
225  GModels models_orig = m_obs.models();
226  m_bkgmdl = m_obs.models();
227  m_outmdl.clear();
228 
229  // Initialise instruments string
230  std::string instruments;
231 
232  // Remove all models that are not CTA background models from the
233  // container and put all removed components in the output
234  // container
235  int num = m_bkgmdl.size();
236  for (int i = num-1; i >= 0; --i) {
237 
238  // Flag removal
239  bool remove = true;
240 
241  // If we have a data space model with "GCTA" classname then we
242  // have a CTA background model and we want to keep the model
243  if ((dynamic_cast<GModelData*>(m_bkgmdl[i]) != NULL) &&
244  (m_bkgmdl[i]->classname().substr(0,4) == "GCTA")) {
245 
246  // Signal that model should be kept
247  remove = false;
248 
249  // Collect instrument identifiers
250  if (instruments.length() > 0) {
251  instruments += ",";
252  }
253  instruments += m_bkgmdl[i]->instruments();
254  }
255 
256  // Log model removal or keeping
257  std::string what = (remove) ? "Remove model" : "Keep model";
258  std::string value = m_bkgmdl[i]->name()+" "+m_bkgmdl[i]->type()+"("+
259  m_bkgmdl[i]->instruments()+")";
260  log_value(NORMAL, what, value);
261 
262  // If removal is requested, append model to output container and
263  // remove it from the background model container. We use here the
264  // insert() method to assure that the model order is preserved.
265  if (remove) {
266  m_outmdl.insert(0, *(m_bkgmdl[i]));
267  m_bkgmdl.remove(i);
268  }
269 
270  } // endfor: looped over all background models
271 
272  // If there are no models in the background model container then throw
273  // an exception since we need at least one model to generate a background
274  // cube
275  if (m_bkgmdl.size() == 0) {
276  std::string msg = "No background model found in model container. "
277  "At least one background model is required in the "
278  "model container to generate a background cube.";
279  throw GException::invalid_value(G_PROCESS, msg);
280  }
281 
282  // Write header
283  log_header1(TERSE, "Generate background cube");
284 
285  // Assign background models to container
286  m_obs.models(m_bkgmdl);
287 
288  // Set pointer to logger dependent on chattiness
289  GLog* logger = (logNormal()) ? &log : NULL;
290 
291  // Fill background cube from observations
292  m_background.fill(m_obs, logger);
293 
294  // Un-normalize background cube. We do this since the counts cube weight is
295  // later multiplied when computing the model value for binned analysis.
296  GSkyMap* bkg = const_cast<GSkyMap*>(&m_background.cube());
297  for (int pixel = 0; pixel < m_cube.npix(); ++pixel) {
298  for (int iebin = 0; iebin < m_cube.ebins(); ++iebin) {
299  double weight = m_cube.weights()(pixel, iebin);
300  if (weight > 0.0) {
301  (*bkg)(pixel, iebin) /= weight;
302  }
303  }
304  }
305 
306  // Create a background model for the output background cube and append
307  // that model to the input model in place of the original
308  // background models
309  // TODO: We might think of creating the spectral model via user parameter
310  GModelSpectralPlaw spectral(1.0, 0.0, GEnergy(1.0, "TeV"));
311  spectral["Prefactor"].range(0.01, 100.0);
312  spectral["Index"].range(-5.0, 5.0);
313  GCTAModelCubeBackground model(spectral);
314 
315  // Set model name
316  model.name("BackgroundModel");
317 
318  // Set model instruments
319  //model.instruments(instruments);
320  model.instruments("CTA,HESS,MAGIC,VERITAS,ASTRI"); // Temporary fix for #2140
321 
322  // Append model to output container
323  m_outmdl.append(model);
324 
325  // Write background cube into logger
326  log_string(NORMAL, m_background.print(m_chatter));
327 
328  // Write input model container into logger
329  log_models(NORMAL, m_outmdl, "Output model");
330 
331  // Recover original models
332  m_obs.models(models_orig);
333 
334  // Optionally publish background cube
335  if (m_publish) {
336  publish();
337  }
338 
339  // Return
340  return;
341 }
342 
343 
344 /***********************************************************************//**
345  * @brief Save background cube
346  *
347  * Save the background cube into a FITS file and the output model into an
348  * XML file.
349  ***************************************************************************/
350 void ctbkgcube::save(void)
351 {
352  // Write header
353  log_header1(TERSE, "Save background cube");
354 
355  // Determine whether a model definition file should be written
356  bool write_moddef = (*this)["outmodel"].is_valid();
357 
358  // Save background cube if filename is valid and the background cube is
359  // not empty
360  if ((*this)["outcube"].is_valid() && !m_background.cube().is_empty()) {
361 
362  // Get background cube file name
363  m_outcube = (*this)["outcube"].filename();
364 
365  // Save background cube
366  m_background.save(m_outcube, clobber());
367 
368  // Stamp background cube
369  stamp(m_outcube);
370  }
371 
372  // Save model definition file if requested
373  if (write_moddef) {
374 
375  // Get model file name
376  m_outmodel = (*this)["outmodel"].filename();
377 
378  // Save model
379  m_outmdl.save(m_outmodel.url());
380 
381  }
382 
383  // Write into logger what has been done
384  std::string fname = (m_outcube.is_empty()) ? "NONE" : m_outcube.url();
385  std::string mname = (write_moddef) ? m_outmodel.url() : "NONE";
386  if (m_background.cube().is_empty()) {
387  fname.append(" (cube is empty, no file created)");
388  }
389  log_value(NORMAL, "Background cube file", fname);
390  log_value(NORMAL, "Model definition file", mname);
391 
392  // Return
393  return;
394 }
395 
396 
397 /***********************************************************************//**
398  * @brief Publish background cube
399  *
400  * @param[in] name Background cube name.
401  ***************************************************************************/
402 void ctbkgcube::publish(const std::string& name)
403 {
404  // Write header
405  log_header1(TERSE, "Publish background cube");
406 
407  // Set default name if user name is empty
408  std::string user_name(name);
409  if (user_name.empty()) {
410  user_name = CTBKGCUBE_NAME;
411  }
412 
413  // Log background cube name
414  log_value(NORMAL, "Publish background cube", user_name);
415 
416  // Publish exposure cube
417  m_background.cube().publish(user_name);
418 
419  // Return
420  return;
421 }
422 
423 
424 /*==========================================================================
425  = =
426  = Private methods =
427  = =
428  ==========================================================================*/
429 
430 /***********************************************************************//**
431  * @brief Initialise class members
432  ***************************************************************************/
434 {
435  // Initialise user parameters
436  m_outcube.clear();
437  m_outmodel.clear();
438  m_publish = false;
439  m_chatter = static_cast<GChatter>(2);
440 
441  // Initialise protected members
442  m_background.clear();
443  m_cube.clear();
444  m_bkgmdl.clear();
445  m_outmdl.clear();
446 
447  // Return
448  return;
449 }
450 
451 
452 /***********************************************************************//**
453  * @brief Copy class members
454  *
455  * @param[in] app Application.
456  ***************************************************************************/
458 {
459  // Copy user parameters
460  m_outmodel = app.m_outmodel;
461  m_outcube = app.m_outcube;
462  m_publish = app.m_publish;
463  m_chatter = app.m_chatter;
464 
465  // Copy protected members
467  m_cube = app.m_cube;
468  m_bkgmdl = app.m_bkgmdl;
469  m_outmdl = app.m_outmdl;
470 
471  // Return
472  return;
473 }
474 
475 
476 /***********************************************************************//**
477  * @brief Delete class members
478  ***************************************************************************/
480 {
481  // Return
482  return;
483 }
484 
485 
486 /***********************************************************************//**
487  * @brief Get application parameters
488  *
489  * Get all task parameters from parameter file or (if required) by querying
490  * the user. The parameters are read in the correct order.
491  ***************************************************************************/
493 {
494  // Setup observations from "inobs" parameter. Require response and accept
495  // event lists, but do not accept counts cubes.
496  setup_observations(m_obs, true, true, false);
497 
498  // If no counts cube exists then load one from the "incube" filename
499  if (m_cube.size() == 0) {
500  m_cube = GCTAEventCube((*this)["incube"].filename());
501  }
502 
503  // Define background cube
504  m_background = GCTACubeBackground(m_cube);
505 
506  // Setup models from "inmodel" parameter
508 
509  // Get remaining parameters
510  m_publish = (*this)["publish"].boolean();
511  m_chatter = static_cast<GChatter>((*this)["chatter"].integer());
512 
513  // If needed later, query output filenames now
514  if (read_ahead()) {
515  (*this)["outcube"].query();
516  (*this)["outmodel"].query();
517  }
518 
519  // Write parameters into logger
520  log_parameters(TERSE);
521 
522  // Return
523  return;
524 }
void log_models(const GChatter &chatter, const GModels &models, const std::string &what="Model")
Log model container.
Definition: ctool.cpp:1285
void free_members(void)
Delete class members.
Definition: ctbkgcube.cpp:479
ctbkgcube(void)
Void constructor.
Definition: ctbkgcube.cpp:54
GModels m_outmdl
Output models.
Definition: ctbkgcube.hpp:83
void setup_observations(GObservations &obs, const bool &response=true, const bool &list=true, const bool &cube=true)
Setup observation container.
Definition: ctool.cpp:431
Background cube generation tool.
Definition: ctbkgcube.hpp:44
void setup_models(GObservations &obs, const std::string &name="")
Setup model container.
Definition: ctool.cpp:545
GModels m_bkgmdl
CTA background models.
Definition: ctbkgcube.hpp:82
void init_members(void)
Initialise class members.
Definition: ctool.cpp:321
Background cube generation tool definition.
void clear(void)
Clear ctbkgcube tool.
Definition: ctbkgcube.cpp:179
GCTAEventCube m_cube
Event cube.
Definition: ctbkgcube.hpp:81
void save(void)
Save background cube.
Definition: ctbkgcube.cpp:350
void process(void)
Generate the background cube(s).
Definition: ctbkgcube.cpp:209
void copy_members(const ctbkgcube &app)
Copy class members.
Definition: ctbkgcube.cpp:457
ctbkgcube & operator=(const ctbkgcube &app)
Assignment operator.
Definition: ctbkgcube.cpp:144
#define CTBKGCUBE_NAME
Definition: ctbkgcube.hpp:36
void log_parameters(const GChatter &chatter)
Log application parameters.
Definition: ctool.cpp:1208
GCTACubeBackground m_background
Background cube.
Definition: ctbkgcube.hpp:80
Base class for observation tools.
GChatter m_chatter
Chattiness.
Definition: ctbkgcube.hpp:77
virtual ~ctbkgcube(void)
Destructor.
Definition: ctbkgcube.cpp:122
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
Definition: ctbkgcube.cpp:433
#define G_PROCESS
Definition: ctbkgcube.cpp:36
void free_members(void)
Delete class members.
Definition: ctool.cpp:357
void init_members(void)
Initialise class members.
GFilename m_outcube
Filename of output cube.
Definition: ctbkgcube.hpp:74
void publish(const std::string &name="")
Publish background cube.
Definition: ctbkgcube.cpp:402
ctobservation & operator=(const ctobservation &app)
Assignment operator.
GFilename m_outmodel
Filename of output XML model.
Definition: ctbkgcube.hpp:75
const bool & read_ahead(void) const
Signal whether parameters should be read ahead.
Definition: ctool.hpp:177
void get_parameters(void)
Get application parameters.
Definition: ctbkgcube.cpp:492
void log_observations(const GChatter &chatter, const GObservations &obs, const std::string &what="Observation")
Log observation container.
Definition: ctool.cpp:1251
GObservations m_obs
Observation container.
bool m_publish
Publish background cube?
Definition: ctbkgcube.hpp:76