ctools 2.1.0.dev
Loading...
Searching...
No Matches
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
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 ***************************************************************************/
72ctbkgcube::ctbkgcube(const GObservations& obs) :
73 ctobservation(CTBKGCUBE_NAME, VERSION, obs)
74{
75 // Initialise 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 ***************************************************************************/
90ctbkgcube::ctbkgcube(int argc, char *argv[]) :
91 ctobservation(CTBKGCUBE_NAME, VERSION, argc, argv)
92{
93 // Initialise 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
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 ***************************************************************************/
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 ***************************************************************************/
402void 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
466 m_background = app.m_background;
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}
Background cube generation tool.
Definition ctbkgcube.hpp:44
ctbkgcube & operator=(const ctbkgcube &app)
Assignment operator.
GCTACubeBackground m_background
Background cube.
Definition ctbkgcube.hpp:80
ctbkgcube(void)
Void constructor.
Definition ctbkgcube.cpp:54
void copy_members(const ctbkgcube &app)
Copy class members.
GChatter m_chatter
Chattiness.
Definition ctbkgcube.hpp:77
virtual ~ctbkgcube(void)
Destructor.
void process(void)
Generate the background cube(s).
GFilename m_outcube
Filename of output cube.
Definition ctbkgcube.hpp:74
void save(void)
Save background cube.
GModels m_bkgmdl
CTA background models.
Definition ctbkgcube.hpp:82
void get_parameters(void)
Get application parameters.
bool m_publish
Publish background cube?
Definition ctbkgcube.hpp:76
void free_members(void)
Delete class members.
GFilename m_outmodel
Filename of output XML model.
Definition ctbkgcube.hpp:75
void init_members(void)
Initialise class members.
GModels m_outmdl
Output models.
Definition ctbkgcube.hpp:83
void clear(void)
Clear ctbkgcube tool.
void publish(const std::string &name="")
Publish background cube.
GCTAEventCube m_cube
Event cube.
Definition ctbkgcube.hpp:81
Base class for observation tools.
void free_members(void)
Delete class members.
ctobservation & operator=(const ctobservation &app)
Assignment operator.
GObservations m_obs
Observation container.
void init_members(void)
Initialise class members.
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
void log_observations(const GChatter &chatter, const GObservations &obs, const std::string &what="Observation")
Log observation container.
Definition ctool.cpp:1251
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
#define G_PROCESS
Definition ctbkgcube.cpp:36
Background cube generation tool definition.
#define CTBKGCUBE_NAME
Definition ctbkgcube.hpp:36