GammaLib 2.0.0
Loading...
Searching...
No Matches
GCTAModelSpatialMultiplicative.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCTAModelSpatialMultiplicative.cpp - Multiplicative spatial model class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2018 by Jurgen Knodlseder *
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 GCTAModelSpatialMultiplicative.cpp
23 * @brief Multiplicative spatial model class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cmath>
32#include "GException.hpp"
33#include "GTools.hpp"
34#include "GMath.hpp"
35#include "GRan.hpp"
36#include "GEnergy.hpp"
37#include "GTime.hpp"
38#include "GXmlElement.hpp"
39#include "GCTAObservation.hpp"
40#include "GCTAInstDir.hpp"
41#include "GCTARoi.hpp"
44
45/* __ Constants __________________________________________________________ */
46
47/* __ Globals ____________________________________________________________ */
49const GCTAModelSpatialRegistry g_cta_spatial_multi_registry(&g_cta_spatial_multi_seed);
50
51/* __ Method name definitions ____________________________________________ */
52#define G_READ "GCTAModelSpatialMultiplicative::read(GXmlElement&)"
53#define G_WRITE "GCTAModelSpatialMultiplicative::write(GXmlElement&)"
54#define G_COMPONENT_INDEX "GCTAModelSpatialMultiplicative::component(int&)"
55#define G_COMPONENT_NAME "GCTAModelSpatialMultiplicative::component"\
56 "(std::string&)"
57#define G_APPEND "GCTAModelSpatialMultiplicative::append(GCTAModelSpatial&, "\
58 "std::string&)"
59
60/* __ Macros _____________________________________________________________ */
61
62/* __ Coding definitions _________________________________________________ */
63
64/* __ Debug definitions __________________________________________________ */
65
66
67/*==========================================================================
68 = =
69 = Constructors/destructors =
70 = =
71 ==========================================================================*/
72
73/***********************************************************************//**
74 * @brief Void constructor
75 ***************************************************************************/
78{
79 // Initialise members
81
82 // Return
83 return;
84}
85
86
87/***********************************************************************//**
88 * @brief XML constructor
89 *
90 * @param[in] xml XML element.
91 *
92 * Creates instance of a multiplicative spatial model by extracting
93 * information from an XML element.
94 * See GCTAModelSpatialMultiplicative::read() for more information about the
95 * expected structure of the XML element.
96 ***************************************************************************/
99{
100 // Initialise members
101 init_members();
102
103 // Read information from XML element
104 read(xml);
105
106 // Return
107 return;
108}
109
110
111/***********************************************************************//**
112 * @brief Copy constructor
113 *
114 * @param[in] model Spatial model.
115 ***************************************************************************/
118{
119 // Initialise members
120 init_members();
121
122 // Copy members
123 copy_members(model);
124
125 // Return
126 return;
127}
128
129
130/***********************************************************************//**
131 * @brief Destructor
132 ***************************************************************************/
134{
135 // Free members
136 free_members();
137
138 // Return
139 return;
140}
141
142
143/*==========================================================================
144 = =
145 = Operators =
146 = =
147 ==========================================================================*/
148
149/***********************************************************************//**
150 * @brief Assignment operator
151 *
152 * @param[in] model Spatial model.
153 ***************************************************************************/
155{
156 // Execute only if object is not identical
157 if (this != &model) {
158
159 // Copy base class members
160 this->GCTAModelSpatial::operator=(model);
161
162 // Free members
163 free_members();
164
165 // Initialise members
166 init_members();
167
168 // Copy members
169 copy_members(model);
170
171 } // endif: object was not identical
172
173 // Return
174 return *this;
175}
176
177
178/*==========================================================================
179 = =
180 = Public methods =
181 = =
182 ==========================================================================*/
183
184/***********************************************************************//**
185 * @brief Clear instance
186 ***************************************************************************/
188{
189 // Free class members (base and derived classes, derived class first)
190 free_members();
192
193 // Initialise members
195 init_members();
196
197 // Return
198 return;
199}
200
201
202/***********************************************************************//**
203 * @brief Clone instance
204 ***************************************************************************/
209
210
211/***********************************************************************//**
212 * @brief Evaluate function (in units of sr^-1)
213 *
214 * @param[in] dir Event direction.
215 * @param[in] energy Event energy.
216 * @param[in] time Event time.
217 * @param[in] gradients Compute gradients?
218 * @return Model value
219 *
220 * Evaluate spatial model for a given event direction.
221 ***************************************************************************/
223 const GEnergy& energy,
224 const GTime& time,
225 const bool& gradients) const
226{
227 // Initialise result
228 double value = 0.0;
229
230 // Check for available spatial components
231 if (m_spatial.size() > 0) {
232
233 // Initialise vector of values
234 std::vector<double> values(m_spatial.size(), 0.0);
235
236 // Compute values of components and function value
237 for (int i = 0; i < m_spatial.size(); ++i) {
238 values[i] = m_spatial[i]->eval(dir, energy, time, gradients);
239 if (i == 0) {
240 value = values[0];
241 }
242 else {
243 value *= values[i];
244 }
245 }
246
247 // Modify gradients if requested
248 if (gradients) {
249
250 // Loop over model components
251 for (int i = 0; i < m_spatial.size(); ++i) {
252
253 // Initialise scaling factor
254 double factor = 1.0;
255
256 // Loop over other model components and compute factor
257 for (int j = 0; j < m_spatial.size(); ++j) {
258 if (i != j) {
259 factor *= values[j];
260 }
261 }
262
263 // Loop over model parameters
264 for (int ipar = 0; ipar < m_spatial[i]->size(); ++ipar) {
265
266 // Get reference to model parameter
267 GModelPar& par = m_spatial[i]->operator[](ipar);
268
269 // Scale parameter gradient
270 par.gradient(par.gradient()*factor);
271
272 } // endfor: loop over model parameters
273
274 } // endfor: loop over models
275
276 } //endif: compute gradients
277
278 } // endif: there were spatial components
279
280 // Compile option: Check for NaN/Inf
281 #if defined(G_NAN_CHECK)
282 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
283 std::cout << "*** ERROR: GCTAModelSpatialMultiplicative::eval";
284 std::cout << "(dir=" << dir.print();
285 std::cout << ", energy=" << energy;
286 std::cout << ", time=" << time << "):";
287 std::cout << " NaN/Inf encountered";
288 std::cout << " (value=" << value;
289 std::cout << ")" << std::endl;
290 }
291 #endif
292
293 // Return value
294 return value;
295}
296
297
298/***********************************************************************//**
299 * @brief Return maximum function value for Monte Carlo simulations
300 *
301 * @param[in] obs CTA Observation.
302 * @return Maximum function value for Monte Carlo simulations.
303 ***************************************************************************/
305{
306 // Initialise maximum value
307 double value = 1.0;
308
309 // Compute maximum value from components
310 for (int i = 0; i < m_spatial.size(); ++i) {
311 value *= m_spatial[i]->mc_max_value(obs);
312 }
313
314 // Return maximum value
315 return value;
316}
317
318
319/***********************************************************************//**
320 * @brief Read model from XML element
321 *
322 * @param[in] xml XML element.
323 *
324 * Reads the spatial information from an XML element.
325 ***************************************************************************/
327{
328 // Get number of spatial components
329 int n_spatials = xml.elements("spatialModel");
330
331 // Loop over spatial elements
332 for (int i = 0; i < n_spatials; ++i) {
333
334 // Get spatial XML element
335 const GXmlElement* spatial = xml.element("spatialModel", i);
336
337 // Allocate a spatial registry object
339
340 // Read spatial model
341 GCTAModelSpatial* ptr = registry.alloc(*spatial);
342
343 // Get component attribute from XML file
344 std::string component_name = spatial->attribute("component");
345
346 // Append spatial component to container
347 append(*ptr, component_name);
348
349 // Free spatial model
350 delete ptr;
351
352 } // endfor: loop over components
353
354 // Return
355 return;
356}
357
358
359/***********************************************************************//**
360 * @brief Write model into XML element
361 *
362 * @param[in] xml XML element.
363 *
364 * Writes the spatial information into an XML element.
365 ***************************************************************************/
367{
368 // Check model type
370
371 // Loop over model components
372 for (int i = 0; i < m_spatial.size(); i++) {
373
374 // Write spatial model
375 if (m_spatial[i] != NULL) {
376
377 // Create new spectrum node
378 xml.append(GXmlElement("spatialModel"));
379
380 // Get new spatial node
381 GXmlElement* spatial = xml.element("spatialModel",
382 xml.elements("spatialModel")-1);
383
384 // Create temporary copy of the spatial model. This is a kluge to
385 // write out the original parameters.
386 GCTAModelSpatial* cpy = m_spatial[i]->clone();
387
388 // Loop over parameters of model
389 for (int j = 0; j < cpy->size(); ++j) {
390
391 // Get model parameter and name
392 GModelPar& par = (*cpy)[j];
393 std::string parname = par.name();
394
395 // Check if name contains colon
396 if (gammalib::contains(parname, ":")) {
397
398 // Split at the colon
399 std::vector<std::string> splits = gammalib::split(parname, ":");
400
401 // Use second part of the string to recover original
402 // parameter name
403 par.name(splits[1]);
404 }
405
406 } // endfor: loop over parameters
407
408 // Write spatial component
409 cpy->write(*spatial);
410
411 // Add component name if previously available
412 if (m_components[i] != gammalib::str(i+1)) {
413 spatial->attribute("component", m_components[i]);
414 }
415
416 // Remove temporary copy
417 delete cpy;
418
419 } // endif: spatial model was not NULL
420
421 } // endfor: loop over model components
422
423 // Return
424 return;
425}
426
427
428/***********************************************************************//**
429 * @brief Append spatial component
430 *
431 * @param[in] spatial Spatial model component.
432 * @param[in] name Name of spatial component (can be empty).
433 *
434 * @exception GException::invalid_value
435 * Invalid component name specified
436 *
437 * Appends a spatial component to the multiplicative model
438 ***************************************************************************/
440 const std::string& name)
441{
442 // Append model container
443 m_spatial.push_back(spatial.clone());
444
445 // Get index of latest model
446 int index = m_spatial.size()-1;
447
448 // Use model index as component name if component name is empty
449 std::string component_name = !name.empty() ? name
450 : gammalib::str(m_spatial.size());
451
452 // Check if component name is unique, throw exception if not
453 if (gammalib::contains(m_components, component_name)) {
454 std::string msg = "Attempt to append component with name \""+
455 component_name+"\" to multiplicative spatial model "
456 "container, but a component with the same name exists "
457 "already. Every component in the container needs a "
458 "unique name. On default the system will increment "
459 "an integer if no component name is provided.";
461 }
462
463 // Add component name (for now simple number)
464 m_components.push_back(component_name);
465
466 // Get number of spatial parameters from model
467 int npars = m_spatial[index]->size();
468
469 // Loop over model parameters
470 for (int ipar = 0; ipar < npars; ++ipar) {
471
472 // Get model parameter
473 GModelPar* par = &(m_spatial[index]->operator[](ipar));
474
475 // Prepend component name to parameter name
476 par->name(component_name+":"+par->name());
477
478 // Append model parameter with new name to internal container
479 m_pars.push_back(par);
480
481 } // endfor: loop over model parameters
482
483 // Return
484 return;
485}
486
487
488/***********************************************************************//**
489 * @brief Return spatial model component by index
490 *
491 * @param[in] index Index of spectral component.
492 * @return Pointer to spatial model.
493 *
494 * @exception GException::out_of_range
495 * Model index out of valid range
496 *
497 * Returns a component of the multiplicative spatial model by @p index.
498 ***************************************************************************/
500{
501 // Check if index is in validity range
502 if (index >= m_spatial.size() || index < 0) {
503 throw GException::out_of_range(G_COMPONENT_INDEX, "Component Index",
504 index, m_spatial.size());
505 }
506
507 // Return spatial component
508 return m_spatial[index];
509}
510
511
512/***********************************************************************//**
513 * @brief Return spatial model component by name
514 *
515 * @param[in] name Name of spatial component.
516 * @return Pointer to spatial model.
517 *
518 * @exception GException::invalid_argument
519 * Spatial component not found
520 *
521 * Returns a component of the multiplicative spatial model by @p name.
522 ***************************************************************************/
524{
525 // Check if model name is found
526 int index = -1;
527 for (int i = 0; i < m_components.size(); ++i) {
528 if (m_components[i] == name) {
529 index = i;
530 break;
531 }
532 }
533
534 // Check if component name was found
535 if (index == -1) {
536 std::string msg = "Model component \""+name+"\" not found in "
537 "multiplicative spatial model.";
539 }
540
541 // Return spatial component
542 return m_spatial[index];
543}
544
545
546/***********************************************************************//**
547 * @brief Print multiplicative spatial model information
548 *
549 * @param[in] chatter Chattiness.
550 * @return String containing model information.
551 ***************************************************************************/
552std::string GCTAModelSpatialMultiplicative::print(const GChatter& chatter) const
553{
554 // Initialise result string
555 std::string result;
556
557 // Continue only if chatter is not silent
558 if (chatter != SILENT) {
559
560 // Append header
561 result.append("=== GCTAModelSpatialMultiplicative ===");
562
563 // Append information
564 result.append("\n"+gammalib::parformat("Number of components"));
565 result.append(gammalib::str(components()));
566 result.append("\n"+gammalib::parformat("Number of parameters"));
567 result.append(gammalib::str(size()));
568
569 // Print parameter information
570 for (int i = 0; i < size(); ++i) {
571 result.append("\n"+m_pars[i]->print(chatter));
572 }
573
574 } // endif: chatter was not silent
575
576 // Return result
577 return result;
578}
579
580
581/*==========================================================================
582 = =
583 = Private methods =
584 = =
585 ==========================================================================*/
586
587/***********************************************************************//**
588 * @brief Initialise class members
589 ***************************************************************************/
591{
592 // Initialise model type
593 m_type = "Multiplicative";
594
595 // Clear spatial models
596 m_spatial.clear();
597 m_components.clear();
598
599 // Return
600 return;
601}
602
603
604/***********************************************************************//**
605 * @brief Copy class members
606 *
607 * @param[in] model Spatial background model component.
608 ***************************************************************************/
610{
611 // Copy members
612 m_type = model.m_type;
614
615 // Copy pointer(s) of spatial component
616 m_spatial.clear();
617 for (int i = 0; i < model.components(); ++i) {
618 m_spatial.push_back(model.m_spatial[i]->clone());
619 }
620
621 // Store pointers to spatial parameters
622 m_pars.clear();
623 for (int i = 0; i < model.components(); ++i) {
624
625 // Retrieve spatial model
626 GCTAModelSpatial* spatial = m_spatial[i];
627
628 // Loop over parameters
629 for (int ipar = 0; ipar < spatial->size(); ++ipar) {
630
631 // Get model parameter reference
632 GModelPar& par = spatial->operator[](ipar);
633
634 // Append model parameter pointer to internal container
635 m_pars.push_back(&par);
636 }
637 }
638
639 // Return
640 return;
641}
642
643
644/***********************************************************************//**
645 * @brief Delete class members
646 ***************************************************************************/
648{
649 // Free memory
650 for (int i = 0; i < m_spatial.size(); ++i) {
651
652 // Delete component i
653 if (m_spatial[i] != NULL) delete m_spatial[i];
654
655 // Signal free pointer
656 m_spatial[i] = NULL;
657
658 }
659
660 // Return
661 return;
662}
#define G_WRITE
#define G_APPEND
CTA instrument direction class interface definition.
const GCTAModelSpatialMultiplicative g_cta_spatial_multi_seed
Multiplicative spatial model class interface definition.
Spatial model registry class definition.
CTA observation class interface definition.
CTA region of interest class interface definition.
Energy value class definition.
Exception handler interface definition.
Mathematical function definitions.
#define G_COMPONENT_INDEX
#define G_COMPONENT_NAME
Random number generator class definition.
Time class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
XML element node class interface definition.
CTA instrument direction class.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print instrument direction information.
Multiplicative spatial model class.
virtual GCTAModelSpatialMultiplicative & operator=(const GCTAModelSpatialMultiplicative &model)
Assignment operator.
int components(void) const
Return number of spatial components.
void init_members(void)
Initialise class members.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print multiplicative spatial model information.
void append(const GCTAModelSpatial &spatial, const std::string &name="")
Append spatial component.
virtual void clear(void)
Clear instance.
std::vector< GCTAModelSpatial * > m_spatial
Container of spatial models.
const GCTAModelSpatial * component(const int &index) const
Return spatial model component by index.
void copy_members(const GCTAModelSpatialMultiplicative &model)
Copy class members.
virtual double eval(const GCTAInstDir &dir, const GEnergy &energy, const GTime &time, const bool &gradients=false) const
Evaluate function (in units of sr^-1)
virtual double mc_max_value(const GCTAObservation &obs) const
Return maximum function value for Monte Carlo simulations.
virtual std::string type(void) const
Return model type.
virtual void write(GXmlElement &xml) const
Write model into XML element.
void free_members(void)
Delete class members.
virtual GCTAModelSpatialMultiplicative * clone(void) const
Clone instance.
std::vector< std::string > m_components
Names of components.
virtual void read(const GXmlElement &xml)
Read model from XML element.
Interface definition for the spatial model registry class.
GCTAModelSpatial * alloc(const GXmlElement &xml) const
Allocate spatial model that is found in XML element.
Abstract spatial model class.
void init_members(void)
Initialise class members.
std::vector< GModelPar * > m_pars
Parameter pointers.
int size(void) const
Return number of model parameters.
virtual GCTAModelSpatial & operator=(const GCTAModelSpatial &model)
Assignment operator.
virtual void write(GXmlElement &xml) const =0
void free_members(void)
Delete class members.
virtual GCTAModelSpatial * clone(void) const =0
Clones object.
CTA observation class.
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
Model parameter class.
Definition GModelPar.hpp:87
double gradient(void) const
Return parameter gradient.
const std::string & name(void) const
Return parameter name.
Time class.
Definition GTime.hpp:55
XML element node class.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition GXmlNode.cpp:287
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition GXmlNode.cpp:640
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition GXmlNode.cpp:586
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition GTools.hpp:184
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition GTools.hpp:201
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
bool contains(const std::string &str, const std::string &substring)
Checks if a substring is in a string.
Definition GTools.cpp:1342
std::vector< std::string > split(const std::string &s, const std::string &sep)
Split string.
Definition GTools.cpp:983
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.
Definition GTools.cpp:1819