GammaLib 2.0.0
Loading...
Searching...
No Matches
GCTAModelSpatialGaussSpectrum.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCTAModelSpatialGaussSpectrum.cpp - Spatial energy dependent Gaussian *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2019 by Juergen Knoedlseder *
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 GCTAModelSpatialGaussSpectrum.cpp
23 * @brief Spatial energy dependent Gaussian interface 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 "GTools.hpp"
33#include "GMath.hpp"
34#include "GCTAInstDir.hpp"
35#include "GEnergy.hpp"
36#include "GTime.hpp"
41
42/* __ Constants __________________________________________________________ */
43
44/* __ Globals ____________________________________________________________ */
46const GCTAModelSpatialRegistry g_cta_spatial_gauss_spec_registry(&g_cta_spatial_gauss_spec_seed);
47
48/* __ Method name definitions ____________________________________________ */
49#define G_READ "GCTAModelSpatialGaussSpectrum::read(GXmlElement&)"
50#define G_WRITE "GCTAModelSpatialGaussSpectrum::write(GXmlElement&)"
51
52/* __ Macros _____________________________________________________________ */
53
54/* __ Coding definitions _________________________________________________ */
55
56/* __ Debug definitions __________________________________________________ */
57
58
59/*==========================================================================
60 = =
61 = Constructors/destructors =
62 = =
63 ==========================================================================*/
64
65/***********************************************************************//**
66 * @brief Void constructor
67 ***************************************************************************/
70{
71 // Initialise members
73
74 // Return
75 return;
76}
77
78
79/***********************************************************************//**
80 * @brief Energy-independent Gaussian constructor
81 *
82 * @param[in] sigma Gaussian width (degrees\f$^2\f$).
83 ***************************************************************************/
86{
87 // Initialise members
89
90 // Assign sigma
91 this->sigma(sigma);
92
93 // Return
94 return;
95}
96
97
98/***********************************************************************//**
99 * @brief Gaussian spectrum constructor
100 *
101 * @param[in] sigma Spectrum defining the energy-deependent Gaussian width
102 * (degrees\f$^2\f$).
103 ***************************************************************************/
106{
107 // Initialise members
108 init_members();
109
110 // Assign sigma spectrum
111 this->sigma(sigma);
112
113 // Return
114 return;
115}
116
117
118/***********************************************************************//**
119 * @brief XML constructor
120 *
121 * @param[in] xml XML element.
122 *
123 * Creates instance of a spatial energy-dependent Gaussian model by
124 * extracting information from an XML element. See
125 * GCTAModelSpatialGaussSpectrum::read() for more information about the
126 * expected structure of the XML element.
127 ***************************************************************************/
130{
131 // Initialise members
132 init_members();
133
134 // Read information from XML element
135 read(xml);
136
137 // Return
138 return;
139}
140
141
142/***********************************************************************//**
143 * @brief Copy constructor
144 *
145 * @param[in] model Energy-dependent Gaussian model.
146 ***************************************************************************/
148 GCTAModelSpatial(model)
149{
150 // Initialise members
151 init_members();
152
153 // Copy members
154 copy_members(model);
155
156 // Return
157 return;
158}
159
160
161/***********************************************************************//**
162 * @brief Destructor
163 ***************************************************************************/
165{
166 // Free members
167 free_members();
168
169 // Return
170 return;
171}
172
173
174/*==========================================================================
175 = =
176 = Operators =
177 = =
178 ==========================================================================*/
179
180/***********************************************************************//**
181 * @brief Assignment operator
182 *
183 * @param[in] model Energy-dependent Gaussian model.
184 ***************************************************************************/
186{
187 // Execute only if object is not identical
188 if (this != &model) {
189
190 // Copy base class members
191 this->GCTAModelSpatial::operator=(model);
192
193 // Free members
194 free_members();
195
196 // Initialise members
197 init_members();
198
199 // Copy members
200 copy_members(model);
201
202 } // endif: object was not identical
203
204 // Return
205 return *this;
206}
207
208
209/*==========================================================================
210 = =
211 = Public methods =
212 = =
213 ==========================================================================*/
214
215/***********************************************************************//**
216 * @brief Clear instance
217 ***************************************************************************/
219{
220 // Free class members (base and derived classes, derived class first)
221 free_members();
223
224 // Initialise members
226 init_members();
227
228 // Return
229 return;
230}
231
232
233/***********************************************************************//**
234 * @brief Clone instance
235 ***************************************************************************/
240
241
242/***********************************************************************//**
243 * @brief Evaluate function
244 *
245 * @param[in] dir Event direction.
246 * @param[in] energy Event energy.
247 * @param[in] time Event time.
248 * @param[in] gradients Compute gradients?
249 * @return Function value
250 *
251 * Evaluates the energy-dependent Gaussian model for a given event direction.
252 * The Gaussian model is defined by
253 *
254 * \f[f(\theta,E) = \exp \left(-\frac{1}{2}
255 * \left( \frac{\theta^2}{\sigma(E)} \right)^2 \right)\f]
256 *
257 * where
258 * \f$\theta\f$ is the offset angle (in degrees), and
259 * \f$\sigma(E)\f$ is the energy-dependent Gaussian width (in degrees\f$^2\f$).
260 *
261 * If the @p gradients flag is true the method will also compute the partial
262 * derivatives of the parameters. The partial derivative of the Gaussian width
263 * is given by
264 *
265 * \f[\frac{df}{d\sigma_v} = f(\theta) \frac{\theta^4}{\sigma^3} \sigma_s\f]
266 *
267 * where
268 * \f$\sigma_v\f$ is the value part,
269 * \f$\sigma_s\f$ is the scaling part, and
270 * \f$\sigma = \sigma_v \sigma_s\f$.
271 *
272 * Note that this method implements a function which is unity for
273 * \f$\theta=0\f$.
274 ***************************************************************************/
276 const GEnergy& energy,
277 const GTime& time,
278 const bool& gradients) const
279{
280 // Initialise value
281 double value = 0.0;
282
283 // Continue only if a sigma spectrum exists
284 if (m_sigma != NULL) {
285
286 // Compute offset angle in degrees
287 double offset = dir.theta() * gammalib::rad2deg;
288
289 // Compute energy dependent sigma value in degrees^2
290 double sigma = m_sigma->eval(energy, time, gradients);
291
292 // Compute Gaussian value
293 double arg = offset * offset / sigma;
294 double arg2 = arg * arg;
295 value = std::exp(-0.5 * arg2);
296
297 // Optionally compute partial derivatives
298 if (gradients) {
299
300 // Compute partial derivatives of the sigma parameter
301 double g_sigma = value * arg2 / sigma;
302
303 // Loop over model parameters
304 for (int i = 0; i < m_sigma->size(); ++i) {
305
306 // Get reference to model parameter
307 GModelPar& par = m_sigma->operator[](i);
308
309 // Scale parameter gradient
310 par.gradient(par.gradient()*g_sigma);
311
312 } // endfor: loop over model parameters
313
314 } // endif: computed partial derivatives
315
316 // Compile option: Check for NaN/Inf
317 #if defined(G_NAN_CHECK)
318 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
319 std::cout << "*** ERROR: GCTAModelSpatialGaussSpectrum::eval";
320 std::cout << "(offset=" << offset << "): NaN/Inf encountered";
321 std::cout << " (value=" << value;
322 std::cout << ", energy=" << energy;
323 std::cout << ", sigma=" << sigma;
324 std::cout << ")" << std::endl;
325 }
326 #endif
327
328 } // endif: sigma spectrum existed
329
330 // Return value
331 return value;
332}
333
334
335/***********************************************************************//**
336 * @brief Read model from XML element
337 *
338 * @param[in] xml XML element.
339 *
340 * Read the energy-dependent Gaussian spatial model information from an XML
341 * element. The XML element needs to be of the following format:
342 *
343 * <spatialModel type="EnergyDependentGaussian">
344 * <sigma type="...">
345 * ...
346 * </sigma>
347 * </spatialModel>
348 *
349 * where any spectral model type can be provided for the @a sigma tag.
350 ***************************************************************************/
352{
353 // Clear model
354 clear();
355
356 // Get pointers on sigma model components
357 const GXmlElement* sigma = xml.element("sigma", 0);
358
359 // Get sigma model
360 GModelSpectralRegistry registry;
361 m_sigma = registry.alloc(*sigma);
362
363 // Set pointers
364 set_pointers();
365
366 // Return
367 return;
368}
369
370
371/***********************************************************************//**
372 * @brief Write model into XML element
373 *
374 * @param[in] xml XML element.
375 *
376 * @exception GException::invalid_value
377 * Spatial model is not of valid type.
378 *
379 * Write the energy-dependent Gaussian spatial model information into an XML
380 * element. The XML element will be of the following format:
381 *
382 * <spatialModel type="EnergyDependentGaussian">
383 * <sigma type="...">
384 * ...
385 * </sigma>
386 * </spatialModel>
387 *
388 * where the spectral sigma model will be written into the @a sigma tag.
389 ***************************************************************************/
391{
392 // Set model type
393 if (xml.attribute("type") == "") {
394 xml.attribute("type", type());
395 }
396
397 // Verify model type
398 if (xml.attribute("type") != type()) {
399 std::string msg = "Spatial model \""+xml.attribute("type")+
400 "\" is not of type \""+type()+"\".";
402 }
403
404 // Write sigma spectrum if it exists
405 if (m_sigma != NULL) {
406
407 // Create new sigma spectrum node
408 xml.append(GXmlElement("sigma"));
409
410 // Get new sigma spectrum node
411 GXmlElement* sigma = xml.element("sigma", xml.elements("sigma")-1);
412
413 // Write sigma spectrum
415
416 } // endif: sigma spectrum was not NULL
417
418 // Return
419 return;
420}
421
422
423/***********************************************************************//**
424 * @brief Set sigma spectrum from value
425 *
426 * @param[in] sigma Constant sigma value.
427 ***************************************************************************/
429{
430 // Clear sigma spectrum
431 clear();
432
433 // Set constant spectrum
435
436 // Set parameter pointers
437 set_pointers();
438
439 // Return
440 return;
441}
442
443
444/***********************************************************************//**
445 * @brief Set sigma spectrum
446 *
447 * @param[in] sigma Sigma spectrum.
448 ***************************************************************************/
450{
451 // Clear sigma spectrum
452 clear();
453
454 // Set spectrum
455 m_sigma = sigma.clone();
456
457 // Set parameter pointers
458 set_pointers();
459
460 // Return
461 return;
462}
463
464
465/***********************************************************************//**
466 * @brief Print point source information
467 *
468 * @param[in] chatter Chattiness.
469 * @return String containing point source information.
470 ***************************************************************************/
471std::string GCTAModelSpatialGaussSpectrum::print(const GChatter& chatter) const
472{
473 // Initialise result string
474 std::string result;
475
476 // Continue only if chatter is not silent
477 if (chatter != SILENT) {
478
479 // Append header
480 result.append("=== GCTAModelSpatialGaussSpectrum ===");
481
482 // Determine number of sigma parameters
483 int n_sigma = (m_sigma != NULL) ? m_sigma->size() : 0;
484
485 // Append sigma spectrum type
486 result.append("\n"+gammalib::parformat("Sigma spectrum"));
487 if (n_sigma > 0) {
488 result.append("\""+m_sigma->type()+"\"");
489 }
490
491 // Append sigma spectrum parameters
492 for (int i = 0; i < n_sigma; ++i) {
493 result.append("\n"+(m_sigma)[i].print());
494 }
495
496 } // endif: chatter was not silent
497
498 // Return result
499 return result;
500}
501
502
503/*==========================================================================
504 = =
505 = Private methods =
506 = =
507 ==========================================================================*/
508
509/***********************************************************************//**
510 * @brief Initialise class members
511 ***************************************************************************/
513{
514 // Initialise sigma spectrum pointer
515 m_sigma = NULL;
516
517 // Clear parameter pointer(s)
518 m_pars.clear();
519
520 // Return
521 return;
522}
523
524
525/***********************************************************************//**
526 * @brief Copy class members
527 *
528 * @param[in] model Energy-dependent Gaussian model.
529 ***************************************************************************/
531{
532 // Clone sigma spectrum
533 if (model.m_sigma != NULL) {
534 m_sigma = model.m_sigma->clone();
535 }
536
537 // Set parameter pointers
538 set_pointers();
539
540 // Return
541 return;
542}
543
544
545/***********************************************************************//**
546 * @brief Delete class members
547 ***************************************************************************/
549{
550 // Delete sigma spectrum
551 if (m_sigma != NULL) delete m_sigma;
552
553 // Signal free pointer
554 m_sigma = NULL;
555
556 // Return
557 return;
558}
559
560
561/***********************************************************************//**
562 * @brief Set pointers
563 *
564 * Set pointers to all model parameters. The pointers are stored in a vector
565 * that is member of the GModelData base class.
566 ***************************************************************************/
568{
569 // Clear parameters
570 m_pars.clear();
571
572 // Determine number of sigma parameters
573 int n_sigma = (m_sigma != NULL) ? m_sigma->size() : 0;
574
575 // Gather sigma parameters if there are some
576 if (n_sigma > 0) {
577 for (int i = 0; i < n_sigma; ++i) {
578 m_pars.push_back(&((*m_sigma)[i]));
579 }
580 }
581
582 // Return
583 return;
584}
#define G_WRITE
CTA instrument direction class interface definition.
const GCTAModelSpatialGaussSpectrum g_cta_spatial_gauss_spec_seed
Spatial energy dependent Gaussian interface definition.
Spatial model registry class definition.
Energy value class definition.
Mathematical function definitions.
Constant spectral model class interface definition.
Spectral model registry class definition.
Time class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
CTA instrument direction class.
double theta(void) const
Return offset angle (in radians)
Spatial energy dependent Gaussian model class.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print point source information.
void free_members(void)
Delete class members.
virtual ~GCTAModelSpatialGaussSpectrum(void)
Destructor.
virtual void write(GXmlElement &xml) const
Write model into XML element.
virtual GCTAModelSpatialGaussSpectrum & operator=(const GCTAModelSpatialGaussSpectrum &model)
Assignment operator.
void copy_members(const GCTAModelSpatialGaussSpectrum &model)
Copy class members.
virtual void read(const GXmlElement &xml)
Read model from XML element.
virtual double eval(const GCTAInstDir &dir, const GEnergy &energy, const GTime &time, const bool &gradients=false) const
Evaluate function.
virtual GCTAModelSpatialGaussSpectrum * clone(void) const
Clone instance.
virtual std::string type(void) const
Return model type.
void init_members(void)
Initialise class members.
virtual void clear(void)
Clear instance.
const GModelSpectral * sigma(void) const
Return pointer to sigma spectrum.
Interface definition for the spatial model registry class.
Abstract spatial model class.
void init_members(void)
Initialise class members.
std::vector< GModelPar * > m_pars
Parameter pointers.
virtual GCTAModelSpatial & operator=(const GCTAModelSpatial &model)
Assignment operator.
void free_members(void)
Delete class members.
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
Model parameter class.
Definition GModelPar.hpp:87
Constant spectral model class.
Interface definition for the spectral model registry class.
GModelSpectral * alloc(const GXmlElement &xml) const
Allocate spectral model that is found in XML element.
Abstract spectral model base class.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const =0
virtual GModelSpectral * clone(void) const =0
Clones object.
virtual void write(GXmlElement &xml) const =0
virtual std::string type(void) const =0
int size(void) const
Return number of parameters.
double gradient(void) const
Return parameter gradient.
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
const double rad2deg
Definition GMath.hpp:44