GammaLib 2.0.0
Loading...
Searching...
No Matches
GCTAModelSkyCube.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCTAModelSkyCube.cpp - CTA sky cube model class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2020 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 GCTAModelSkyCube.cpp
23 * @brief CTA sky cube model class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GTools.hpp"
32#include "GModelRegistry.hpp"
36#include "GObservation.hpp"
37#include "GCTAModelSkyCube.hpp"
38#include "GCTASupport.hpp"
39
40/* __ Globals ____________________________________________________________ */
42const GModelRegistry g_cta_inst_sky_registry(&g_cta_inst_sky_seed);
43
44/* __ Method name definitions ____________________________________________ */
45#define G_EVAL "GCTAModelSkyCube::eval(GEvent&, GObservation&, bool&)"
46#define G_NPRED "GCTAModelSkyCube::npred(GEnergy&, GTime&, GObservation&)"
47#define G_MC "GCTAModelSkyCube::mc(GObservation&, GRan&)"
48#define G_READ_XML_SPATIAL "GCTAModelSkyCube::read_xml_spatial(GXmlElement&)"
49#define G_WRITE_XML_SPATIAL "GCTAModelSkyCube::write_xml_spatial("\
50 "GXmlElement&)"
51#define G_XML_SPECTRAL "GCTAModelSkyCube::xml_spectral(GXmlElement&)"
52#define G_XML_TEMPORAL "GCTAModelSkyCube::xml_temporal(GXmlElement&)"
53
54/* __ Macros _____________________________________________________________ */
55
56/* __ Coding definitions _________________________________________________ */
57#define G_USE_NPRED_CACHE
58
59/* __ Debug definitions __________________________________________________ */
60//#define G_DEBUG_NPRED
61
62/* __ Constants __________________________________________________________ */
63
64
65/*==========================================================================
66 = =
67 = Constructors/destructors =
68 = =
69 ==========================================================================*/
70
71/***********************************************************************//**
72 * @brief Void constructor
73 ***************************************************************************/
75{
76 // Initialise class members
78
79 // Return
80 return;
81}
82
83
84/***********************************************************************//**
85 * @brief XML constructor
86 *
87 * @param[in] xml XML element.
88 *
89 * Constructs a CTA sky cube model from the information provided by an
90 * XML element (see GCTAModelSkyCube::read method).
91 ***************************************************************************/
93{
94 // Initialise members
96
97 // Read XML
98 read(xml);
99
100 // Set parameter pointers
101 set_pointers();
102
103 // Return
104 return;
105}
106
107
108/***********************************************************************//**
109 * @brief Construct from filename and spectral component
110 *
111 * @param[in] filename Cube file name.
112 * @param[in] spectral Spectral model component.
113 *
114 * Constructs a CTA sky cube model from a cube @p filename and a @p spectral
115 * model component. The temporal component is assumed to be constant.
116 ***************************************************************************/
118 const GModelSpectral& spectral) :
119 GModelData()
120{
121 // Initialise members
122 init_members();
123
124 // Allocate temporal constant model
126
127 // Load filename
128 load(filename);
129
130 // Clone model components
133
134 // Set parameter pointers
135 set_pointers();
136
137 // Return
138 return;
139}
140
141
142/***********************************************************************//**
143 * @brief Construct from model components
144 *
145 * @param[in] filename Cube file name.
146 * @param[in] spectral Spectral model component.
147 * @param[in] temporal Temporal model component.
148 *
149 * Constructs a CTA sky cube model from a cube @p filename, a @p spectral
150 * model component and a @p temporal component.
151 ***************************************************************************/
153 const GModelSpectral& spectral,
154 const GModelTemporal& temporal) :
155 GModelData()
156{
157 // Initialise members
158 init_members();
159
160 // Load filename
161 load(filename);
162
163 // Clone model components
166
167 // Set parameter pointers
168 set_pointers();
169
170 // Return
171 return;
172}
173
174
175/***********************************************************************//**
176 * @brief Copy constructor
177 *
178 * @param[in] sky CTA sky cube model.
179 ***************************************************************************/
181 GModelData(sky)
182{
183 // Initialise class members
184 init_members();
185
186 // Copy members
187 copy_members(sky);
188
189 // Return
190 return;
191}
192
193
194/***********************************************************************//**
195 * @brief Destructor
196 ***************************************************************************/
198{
199 // Free members
200 free_members();
201
202 // Return
203 return;
204}
205
206
207/*==========================================================================
208 = =
209 = Operators =
210 = =
211 ==========================================================================*/
212
213/***********************************************************************//**
214 * @brief Assignment operator
215 *
216 * @param[in] sky CTA sky cube model.
217 * @return CTA sky cube model.
218 ***************************************************************************/
220{
221 // Execute only if object is not identical
222 if (this != &sky) {
223
224 // Copy base class members
225 this->GModelData::operator=(sky);
226
227 // Free members
228 free_members();
229
230 // Initialise private members
231 init_members();
232
233 // Copy members
234 copy_members(sky);
235
236 } // endif: object was not identical
237
238 // Return this object
239 return *this;
240}
241
242
243/*==========================================================================
244 = =
245 = Public methods =
246 = =
247 ==========================================================================*/
248
249/***********************************************************************//**
250 * @brief Clear CTA sky cube model
251 *
252 * This method properly resets the CTA sky cube model to an initial state.
253 ***************************************************************************/
255{
256 // Free class members (base and derived classes, derived class first)
257 free_members();
259
260 // Initialise members
262 init_members();
263
264 // Return
265 return;
266}
267
268
269/***********************************************************************//**
270 * @brief Clone CTA sky cube model
271 *
272 * @return Pointer to deep copy of CTA sky cube model.
273 ***************************************************************************/
275{
276 return new GCTAModelSkyCube(*this);
277}
278
279
280/***********************************************************************//**
281 * @brief Load sky cube
282 *
283 * @param[in] filename Sky cube filename.
284 *
285 * Load the sky cube from the primary image extension.
286 ***************************************************************************/
288{
289 // Clear object
290 clear();
291
292 // Put into OpenMP criticial zone
293 #pragma omp critical(GCTAModelSkyCube_load)
294 {
295 // Open FITS file
296 GFits fits(filename);
297
298 // Get HDUs
299 const GFitsImage& hdu_skycube = *fits.image("Primary");
300 const GFitsTable& hdu_ebounds = *fits.table(gammalib::extname_ebounds);
301
302 // Read sky cube
303 m_cube.read(hdu_skycube);
304
305 // Read energy boundaries
306 m_ebounds.read(hdu_ebounds);
307
308 // Set energy node array
309 for (int i = 0; i < m_ebounds.size(); ++i) {
311 }
312
313 // Close FITS file
314 fits.close();
315
316 } // end of OpenMP critical zone
317
318 // Store filename
320
321 // Return
322 return;
323}
324
325
326/***********************************************************************//**
327 * @brief Set spectral model component
328 *
329 * @param[in] spectral Pointer to spectral model component.
330 *
331 * Sets the spectral model component of the model.
332 ***************************************************************************/
334{
335 // Free spectral model component only if it differs from current
336 // component. This prevents unintential deallocation of the argument
337 if ((m_spectral != NULL) && (m_spectral != spectral)) {
338 delete m_spectral;
339 }
340
341 // Clone spectral model component if it exists, otherwise set pointer
342 // to NULL
343 m_spectral = (spectral != NULL) ? spectral->clone() : NULL;
344
345 // Set parameter pointers
346 set_pointers();
347
348 // Return
349 return;
350}
351
352
353/***********************************************************************//**
354 * @brief Set temporal model component
355 *
356 * @param[in] temporal Pointer to temporal model component.
357 *
358 * Sets the temporal model component of the model.
359 ***************************************************************************/
361{
362 // Free temporal model component only if it differs from current
363 // component. This prevents unintential deallocation of the argument
364 if ((m_temporal != NULL) && (m_temporal != temporal)) {
365 delete m_temporal;
366 }
367
368 // Clone temporal model component if it exists, otherwise set pointer
369 // to NULL
370 m_temporal = (temporal != NULL) ? temporal->clone() : NULL;
371
372 // Set parameter pointers
373 set_pointers();
374
375 // Return
376 return;
377}
378
379
380/***********************************************************************//**
381 * @brief Return event rate in units of events MeV\f$^{-1}\f$
382 * s\f$^{-1}\f$ sr\f$^{-1}\f$
383 *
384 * @param[in] event Observed event.
385 * @param[in] obs Observation.
386 * @param[in] gradients Compute gradients?
387 * @return Event rate (events MeV\f$^{-1}\f$ s\f$^{-1}\f$ sr\f$^{-1}\f$).
388 *
389 * Evaluates the sky cube model. The method returns a measured rate, defined
390 * as the number of counts per MeV, steradian and ontime.
391 *
392 * If the @p gradients flag is true the method will also set the parameter
393 * gradients of the model parameters.
394 ***************************************************************************/
395double GCTAModelSkyCube::eval(const GEvent& event,
396 const GObservation& obs,
397 const bool& gradients) const
398{
399 // Set indices and weighting factors for energy interpolation
401 int inx_left = m_elogmeans.inx_left();
402 int inx_right = m_elogmeans.inx_right();
403 double wgt_left = m_elogmeans.wgt_left();
404 double wgt_right = m_elogmeans.wgt_right();
405
406 // Get reference on CTA instrument direction from event
407 const GCTAInstDir& dir = gammalib::cta_dir(G_EVAL, event);
408
409 // Initialise non-normalised spatial component
410 double spat_raw = 0.0;
411
412 // If left weight is close to 1, use left node
413 if (std::abs(wgt_left-1.0) < 1.0e-6) {
414 spat_raw = m_cube(dir.dir(), inx_left);
415 }
416
417 // ... otherwise, if right weight is close to 1, use right node
418 else if (std::abs(wgt_right-1.0) < 1.0e-6) {
419 spat_raw = m_cube(dir.dir(), inx_right);
420 }
421
422 // ... otherwise perform interpolation
423 else {
424 double spat_left = m_cube(dir.dir(), inx_left);
425 double spat_right = m_cube(dir.dir(), inx_right);
426 if (spat_left > 0.0 && spat_right > 0.0) {
427 spat_raw = std::exp(wgt_left * std::log(spat_left) +
428 wgt_right * std::log(spat_right));
429 }
430 }
431
432 // Multiply-in normalisation
433 double spat = spat_raw * m_norm.value();
434
435 // Make sure that spatial component does not become negative
436 if (spat < 0.0) {
437 spat = 0.0;
438 }
439
440 // Divide spatial model value by event size
441 if (event.size() != 0.0) {
442 spat /= event.size();
443 }
444 else {
445 spat = 0.0;
446 }
447
448 // Evaluate spectral and temporal components
449 double spec = (spectral() != NULL)
450 ? spectral()->eval(event.energy(), event.time(), gradients)
451 : 1.0;
452 double temp = (temporal() != NULL)
453 ? temporal()->eval(event.time(), gradients) : 1.0;
454
455 // Compute value
456 double value = spat * spec * temp;
457
458 // If gradients were requested then multiply factors to spectral and
459 // temporal gradients
460 if (gradients) {
461
462 // Multiply factors to spatial gradient
463 if (m_norm.is_free()) {
464 double fact = spec * temp;
465 double g_norm = spat_raw * m_norm.scale();
466 m_norm.factor_gradient(g_norm * fact);
467 }
468
469 // Multiply factors to spectral gradients
470 if (spectral() != NULL) {
471 double fact = spat * temp;
472 if (fact != 1.0) {
473 for (int i = 0; i < spectral()->size(); ++i)
474 (*spectral())[i].factor_gradient((*spectral())[i].factor_gradient() * fact);
475 }
476 }
477
478 // Multiply factors to temporal gradients
479 if (temporal() != NULL) {
480 double fact = spat * spec;
481 if (fact != 1.0) {
482 for (int i = 0; i < temporal()->size(); ++i)
483 (*temporal())[i].factor_gradient((*temporal())[i].factor_gradient() * fact);
484 }
485 }
486
487 } // endif: gradients were requested
488
489 // Return value
490 return value;
491}
492
493
494/***********************************************************************//**
495 * @brief Return spatially integrated event rate in units of
496 * events MeV\f$^{-1}\f$ s\f$^{-1}\f$
497 *
498 * @param[in] obsEng Measured event energy.
499 * @param[in] obsTime Measured event time.
500 * @param[in] obs Observation.
501 * @return Spatially integrated event rate
502 * (events MeV\f$^{-1}\f$ s\f$^{-1}\f$)
503 *
504 * Spatially integrates the sky cube model for a given measured event energy
505 * and event time.
506 ***************************************************************************/
507double GCTAModelSkyCube::npred(const GEnergy& obsEng,
508 const GTime& obsTime,
509 const GObservation& obs) const
510{
511 // Initialise result
512 double npred = 0.0;
513 bool has_npred = false;
514
515 // Build unique identifier
516 std::string id = obs.instrument() + ":" + obs.id();
517
518 // Check if Npred value is already in cache
519 #if defined(G_USE_NPRED_CACHE)
520 if (!m_npred_names.empty()) {
521
522 // Search for unique identifier, and if found, recover Npred value
523 // and break
524 for (int i = 0; i < m_npred_names.size(); ++i) {
525 if (m_npred_names[i] == id && m_npred_energies[i] == obsEng) {
527 has_npred = true;
528 #if defined(G_DEBUG_NPRED)
529 std::cout << "GCTAModelSkyCube::npred:";
530 std::cout << " cache=" << i;
531 std::cout << " npred=" << npred << std::endl;
532 #endif
533 break;
534 }
535 }
536
537 } // endif: there were values in the Npred cache
538 #endif
539
540 // Continue only if no Npred cache value has been found
541 if (!has_npred) {
542
543 // Evaluate only if model is valid
544 if (valid_model()) {
545
546 // Set indices and weighting factors for energy interpolation
548 int inx_left = m_elogmeans.inx_left();
549 int inx_right = m_elogmeans.inx_right();
550 double wgt_left = m_elogmeans.wgt_left();
551 double wgt_right = m_elogmeans.wgt_right();
552
553 // Loop over all map pixels
554 for (int i = 0; i < m_cube.npix(); ++i) {
555
556 // Get bin value
557 double value = wgt_left * m_cube(i, inx_left) +
558 wgt_right * m_cube(i, inx_right);
559
560 // Sum bin contents
561 npred += value * m_cube.solidangle(i);
562
563 }
564
565 // Store result in Npred cache
566 #if defined(G_USE_NPRED_CACHE)
567 m_npred_names.push_back(id);
568 m_npred_energies.push_back(obsEng);
569 m_npred_times.push_back(obsTime);
570 m_npred_values.push_back(npred);
571 #endif
572
573 // Debug: Check for NaN
574 #if defined(G_NAN_CHECK)
576 std::string origin = "GCTAModelSkyCube::npred";
577 std::string message = " NaN/Inf encountered (npred=" +
578 gammalib::str(npred) + ")";
579 gammalib::warning(origin, message);
580 }
581 #endif
582
583 } // endif: model was valid
584
585 } // endif: Npred computation required
586
587 // Multiply in normalisation value
588 npred *= m_norm.value();
589
590 // Multiply in spectral and temporal components
591 npred *= spectral()->eval(obsEng, obsTime);
592 npred *= temporal()->eval(obsTime);
593
594 // Return Npred
595 return npred;
596}
597
598
599/***********************************************************************//**
600 * @brief Return simulated list of events
601 *
602 * @param[in] obs Observation.
603 * @param[in] ran Random number generator.
604 * @return Pointer to list of simulated events (needs to be de-allocated by
605 * client)
606 *
607 * @exception GException::feature_not_implemented
608 * Class does not support the generation of event lists.
609 *
610 * The simulation of an event list from a sky cube model is not implemented,
611 * hence the method will always throw an exception.
612 ***************************************************************************/
614{
615 // Feature not yet implemented
617 "MC computation not implemented for binned analysis.");
618
619 // Return NULL pointer
620 return NULL;
621
622}
623
624
625/***********************************************************************//**
626 * @brief Read CTA sky cube model from XML element
627 *
628 * @param[in] xml XML element.
629 *
630 * Set up CTA sky cube model from the information provided by an XML element.
631 * The XML element is expected to have the following structure
632 *
633 * <source name="CTA sky cube" type="CTASkyCube" instrument="CTA">
634 * <spatialModel type="ModelCube" file="model_cube.fits">
635 * <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="0"/>
636 * </spatialModel>
637 * <spectrum type="...">
638 * ...
639 * </spectrum>
640 * </source>
641 *
642 * Optionally, a temporal model may be provided using the following
643 * syntax
644 *
645 * <source name="CTA sky cube" type="CTASkyCube" instrument="CTA">
646 * <spatialModel type="ModelCube" file="model_cube.fits">
647 * <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="0"/>
648 * </spatialModel>
649 * <spectrum type="...">
650 * ...
651 * </spectrum>
652 * <temporal type="...">
653 * ...
654 * </temporal>
655 * </source>
656 *
657 * If no temporal component is found a constant model is assumed.
658 ***************************************************************************/
660{
661 // Clear model
662 clear();
663
664 // Get pointers on spatial and spectral components
665 const GXmlElement* spat = xml.element("spatialModel", 0);
666 const GXmlElement* spec = xml.element("spectrum", 0);
667
668 // Set spatial and spectral models
669 read_xml_spatial(*spat);
670 m_spectral = xml_spectral(*spec);
671
672 // Handle optional temporal model
673 if (xml.elements("temporal")) {
674 const GXmlElement* temporal = xml.element("temporal", 0);
676 }
677 else {
678 GModelTemporalConst constant;
679 m_temporal = constant.clone();
680 }
681
682 // Read model attributes
683 read_attributes(xml);
684
685 // Set parameter pointers
686 set_pointers();
687
688 // Return
689 return;
690}
691
692
693/***********************************************************************//**
694 * @brief Write CTA cube background model into XML element
695 *
696 * @param[in] xml XML element.
697 *
698 * Write CTA cube background model information into an XML element.
699 * The XML element will have the following structure
700 *
701 * <source name="CTA sky cube" type="CTASkyCube" instrument="CTA">
702 * <spatialModel type="ModelCube" file="model_cube.fits">
703 * <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="0"/>
704 * </spatialModel>
705 * <spectrum type="...">
706 * ...
707 * </spectrum>
708 * </source>
709 *
710 * If the model contains a non-constant temporal model, the temporal
711 * component will also be written following the syntax
712 *
713 * <source name="CTA sky cube" type="CTASkyCube" instrument="CTA">
714 * <spatialModel type="ModelCube" file="model_cube.fits">
715 * <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="0"/>
716 * </spatialModel>
717 * <spectrum type="...">
718 * ...
719 * </spectrum>
720 * <temporal type="...">
721 * ...
722 * </temporal>
723 * </source>
724 *
725 * If no temporal component is found a constant model is assumed.
726 ***************************************************************************/
728{
729 // Initialise pointer on source
730 GXmlElement* src = NULL;
731
732 // Search corresponding source
733 int n = xml.elements("source");
734 for (int k = 0; k < n; ++k) {
735 GXmlElement* element = xml.element("source", k);
736 if (element->attribute("name") == name()) {
737 src = element;
738 break;
739 }
740 }
741
742 // If we have a temporal model that is either not a constant, or a
743 // constant with a normalization value that differs from 1.0 then
744 // write the temporal component into the XML element. This logic
745 // assures compatibility with the Fermi/LAT format as this format
746 // does not handle temporal components.
747 bool write_temporal = ((m_temporal != NULL) &&
748 (m_temporal->type() != "Constant" ||
749 (*m_temporal)[0].value() != 1.0));
750
751 // If no source with corresponding name was found then append one
752 if (src == NULL) {
753 src = xml.append("source");
754 src->append(GXmlElement("spatialModel"));
755 src->append(GXmlElement("spectrum"));
756 if (write_temporal) {
757 src->append(GXmlElement("temporal"));
758 }
759 }
760
761 // Write spatial model
762 GXmlElement* spat = src->element("spatialModel", 0);
763 write_xml_spatial(*spat);
764
765 // Write spectral model
766 if (spectral() != NULL) {
767 GXmlElement* spec = src->element("spectrum", 0);
768 spectral()->write(*spec);
769 }
770
771 // Optionally write temporal model
772 if (write_temporal) {
773 if (dynamic_cast<GModelTemporalConst*>(temporal()) == NULL) {
774 GXmlElement* temp = src->element("temporal", 0);
775 temporal()->write(*temp);
776 }
777 }
778
779 // Write model attributes
780 write_attributes(*src);
781
782 // Return
783 return;
784}
785
786
787/***********************************************************************//**
788 * @brief Print CTA cube background model information
789 *
790 * @param[in] chatter Chattiness.
791 * @return String containing CTA cube background model information.
792 ***************************************************************************/
793std::string GCTAModelSkyCube::print(const GChatter& chatter) const
794{
795 // Initialise result string
796 std::string result;
797
798 // Continue only if chatter is not silent
799 if (chatter != SILENT) {
800
801 // Append header
802 result.append("=== GCTAModelSkyCube ===");
803
804 // Determine number of parameters per type
805 int n_spectral = (spectral() != NULL) ? spectral()->size() : 0;
806 int n_temporal = (temporal() != NULL) ? temporal()->size() : 0;
807
808 // Append attributes
809 result.append("\n"+print_attributes());
810
811 // Append model type
812 result.append("\n"+gammalib::parformat("Model type"));
813 if (n_spectral > 0) {
814 result.append("\""+spectral()->type()+"\"");
815 if (n_temporal > 0) {
816 result.append(" * ");
817 }
818 }
819 if (n_temporal > 0) {
820 result.append("\""+temporal()->type()+"\"");
821 }
822
823 // Append parameters
824 result.append("\n"+gammalib::parformat("Number of parameters") +
826 result.append("\n"+gammalib::parformat("Number of spectral par's") +
827 gammalib::str(n_spectral));
828 for (int i = 0; i < n_spectral; ++i) {
829 result.append("\n"+(*spectral())[i].print());
830 }
831 result.append("\n"+gammalib::parformat("Number of temporal par's") +
832 gammalib::str(n_temporal));
833 for (int i = 0; i < n_temporal; ++i) {
834 result.append("\n"+(*temporal())[i].print());
835 }
836
837 } // endif: chatter was not silent
838
839 // Return result
840 return result;
841}
842
843
844/*==========================================================================
845 = =
846 = Private methods =
847 = =
848 ==========================================================================*/
849
850/***********************************************************************//**
851 * @brief Initialise class members
852 ***************************************************************************/
854{
855 // Initialise Value
856 m_norm.clear();
857 m_norm.name("Normalization");
858 m_norm.value(1.0);
859 m_norm.scale(1.0);
860 m_norm.range(0.001, 1000.0);
861 m_norm.gradient(0.0);
862 m_norm.fix();
863 m_norm.has_grad(true);
864
865 // Set parameter pointer(s)
866 m_pars.clear();
867 m_pars.push_back(&m_norm);
868
869 // Initialise members
871 m_cube.clear();
874 m_spectral = NULL;
875 m_temporal = NULL;
876
877 // Initialise Npred cache
878 m_npred_names.clear();
879 m_npred_energies.clear();
880 m_npred_times.clear();
881 m_npred_values.clear();
882
883 // Return
884 return;
885}
886
887
888/***********************************************************************//**
889 * @brief Copy class members
890 *
891 * @param[in] sky CTA sky cube model.
892 ***************************************************************************/
894{
895 // Copy members
897 m_cube = sky.m_cube;
898 m_ebounds = sky.m_ebounds;
900 m_norm = sky.m_norm;
901
902 // Copy cache
907
908 // Clone spectral and temporal model components
909 m_spectral = (sky.m_spectral != NULL) ? sky.m_spectral->clone() : NULL;
910 m_temporal = (sky.m_temporal != NULL) ? sky.m_temporal->clone() : NULL;
911
912 // Set parameter pointers
913 set_pointers();
914
915 // Return
916 return;
917}
918
919
920/***********************************************************************//**
921 * @brief Delete class members
922 ***************************************************************************/
924{
925 // Free memory
926 if (m_spectral != NULL) delete m_spectral;
927 if (m_temporal != NULL) delete m_temporal;
928
929 // Signal free pointers
930 m_spectral = NULL;
931 m_temporal = NULL;
932
933 // Return
934 return;
935}
936
937
938/***********************************************************************//**
939 * @brief Set pointers
940 *
941 * Set pointers to all model parameters. The pointers are stored in a vector
942 * that is member of the GModelData base class.
943 ***************************************************************************/
945{
946 // Clear parameters
947 m_pars.clear();
948
949 // Push normalisation parameter on stack
950 m_pars.push_back(&m_norm);
951
952 // Determine the number of parameters
953 int n_spectral = (spectral() != NULL) ? spectral()->size() : 0;
954 int n_temporal = (temporal() != NULL) ? temporal()->size() : 0;
955 int n_pars = n_spectral + n_temporal;
956
957 // Continue only if there are parameters
958 if (n_pars > 0) {
959
960 // Gather spectral parameters
961 for (int i = 0; i < n_spectral; ++i) {
962 m_pars.push_back(&((*spectral())[i]));
963 }
964
965 // Gather temporal parameters
966 for (int i = 0; i < n_temporal; ++i) {
967 m_pars.push_back(&((*temporal())[i]));
968 }
969
970 }
971
972 // Return
973 return;
974}
975
976
977/***********************************************************************//**
978 * @brief Verifies if model has all components
979 *
980 * Returns 'true' if models has a spectral and a temporal component.
981 * Otherwise returns 'false'.
982 ***************************************************************************/
984{
985 // Set result
986 bool result = ((spectral() != NULL) && (temporal() != NULL));
987
988 // Return result
989 return result;
990}
991
992
993/***********************************************************************//**
994 * @brief Read spatial model from XML element
995 *
996 * @param[in] xml XML element.
997 *
998 * @exception GException::invalid_value
999 * Invalid XML format encountered.
1000 *
1001 * Read sky cube information from the spatial XML element. The expected
1002 * format of the XML element is
1003 *
1004 * <spatialModel type="ModelCube" file="model_cube.fits">
1005 * <parameter name="Normalization" ../>
1006 * </spatialModel>
1007 ***************************************************************************/
1009{
1010 // Verify model type
1011 if (xml.attribute("type") != "ModelCube") {
1012 std::string msg = "Spatial model type \""+xml.attribute("type")+
1013 "\" is not of type \"ModelCube\". Please verify "
1014 "the XML format.";
1016 }
1017
1018 // Get filename
1020
1021 // Get XML parameter
1023 m_norm.name());
1024
1025 // Read parameter
1026 m_norm.read(*norm);
1027
1028 // Load sky cube
1029 load(filename);
1030
1031 // Return
1032 return;
1033}
1034
1035
1036/***********************************************************************//**
1037 * @brief Write spatial model into XML element
1038 *
1039 * @param[in] xml XML element.
1040 *
1041 * @exception GException::invalid_value
1042 * Invalid XML format encountered.
1043 *
1044 * Write sky cube information into the spatial XML element. The format of
1045 * the XML element is
1046 *
1047 * <spatialModel type="ModelCube" file="model_cube.fits">
1048 * <parameter name="Normalization" ../>
1049 * </spatialModel>
1050 ***************************************************************************/
1052{
1053 // Set model type
1054 if (xml.attribute("type") == "") {
1055 xml.attribute("type", "ModelCube");
1056 }
1057
1058 // Verify model type
1059 if (xml.attribute("type") != "ModelCube") {
1060 std::string msg = "Spatial model type \""+xml.attribute("type")+
1061 "\" is not of type \"ModelCube\". Please verify "
1062 "the XML format.";
1064 }
1065
1066 // Set filename
1068
1069 // Get XML parameter
1071 m_norm.name());
1072
1073 // Write parameter
1074 m_norm.write(*norm);
1075
1076 // Return
1077 return;
1078}
1079
1080
1081/***********************************************************************//**
1082 * @brief Return pointer to spectral model from XML element
1083 *
1084 * @param[in] spectral XML element.
1085 * @return Pointer to spectral model.
1086 *
1087 * Returns pointer to spectral model that is defined in an XML element.
1088 ***************************************************************************/
1090{
1091 // Get spectral model
1092 GModelSpectralRegistry registry;
1093 GModelSpectral* ptr = registry.alloc(spectral);
1094
1095 // Return pointer
1096 return ptr;
1097}
1098
1099
1100/***********************************************************************//**
1101 * @brief Return pointer to temporal model from XML element
1102 *
1103 * @param[in] temporal XML element.
1104 * @return Pointer to temporal model.
1105 *
1106 * Returns pointer to temporal model that is defined in an XML element.
1107 ***************************************************************************/
1109{
1110 // Get temporal model
1111 GModelTemporalRegistry registry;
1112 GModelTemporal* ptr = registry.alloc(temporal);
1113
1114 // Return pointer
1115 return ptr;
1116}
const GCTAModelSkyCube g_cta_inst_sky_seed
#define G_READ_XML_SPATIAL
#define G_WRITE_XML_SPATIAL
CTA sky cube model class interface definition.
Definition of support function used by CTA classes.
#define G_EVAL
Model registry class definition.
Spectral model registry class definition.
Constant temporal model class interface definition.
Temporal model registry class definition.
Abstract observation base class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
double norm(const GVector &vector)
Computes vector norm.
Definition GVector.cpp:864
CTA event list class.
CTA instrument direction class.
void dir(const GSkyDir &dir)
Set sky direction.
CTA sky cube model class.
void init_members(void)
Initialise class members.
GModelSpectral * spectral(void) const
Return spectral model component.
std::vector< GTime > m_npred_times
Model time.
bool valid_model(void) const
Verifies if model has all components.
GNodeArray m_elogmeans
Mean log10(TeV) energies for the sky cube.
std::vector< GEnergy > m_npred_energies
Model energy.
void copy_members(const GCTAModelSkyCube &bgd)
Copy class members.
GModelTemporal * m_temporal
Temporal model.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print CTA cube background model information.
virtual void read(const GXmlElement &xml)
Read CTA sky cube model from XML element.
GModelTemporal * temporal(void) const
Return temporal model component.
void write_xml_spatial(GXmlElement &xml) const
Write spatial model into XML element.
virtual ~GCTAModelSkyCube(void)
Destructor.
virtual void write(GXmlElement &xml) const
Write CTA cube background model into XML element.
GFilename m_filename
Filename.
const GFilename & filename(void) const
Return filename.
GModelTemporal * xml_temporal(const GXmlElement &temporal) const
Return pointer to temporal model from XML element.
GModelSpectral * xml_spectral(const GXmlElement &spectral) const
Return pointer to spectral model from XML element.
GEbounds m_ebounds
Energy boundaries of sky cube.
virtual GCTAEventList * mc(const GObservation &obs, GRan &ran) const
Return simulated list of events.
GSkyMap m_cube
Sky cube.
void free_members(void)
Delete class members.
virtual GCTAModelSkyCube & operator=(const GCTAModelSkyCube &model)
Assignment operator.
void read_xml_spatial(const GXmlElement &xml)
Read spatial model from XML element.
std::vector< std::string > m_npred_names
Model names.
virtual void clear(void)
Clear CTA sky cube model.
virtual GCTAModelSkyCube * clone(void) const
Clone CTA sky cube model.
GModelSpectral * m_spectral
Spectral model.
GModelPar m_norm
Normalisation parameter.
void load(const GFilename &filename)
Load sky cube.
GCTAModelSkyCube(void)
Void constructor.
std::vector< double > m_npred_values
Model values.
virtual double eval(const GEvent &event, const GObservation &obs, const bool &gradients=false) const
Return event rate in units of events MeV s sr .
void set_pointers(void)
Set pointers.
virtual double npred(const GEnergy &obsEng, const GTime &obsTime, const GObservation &obs) const
Return spatially integrated event rate in units of events MeV s .
void read(const GFitsTable &table)
Read energy boundaries from FITS table.
Definition GEbounds.cpp:761
int size(void) const
Return number of energy boundaries.
Definition GEbounds.hpp:163
void clear(void)
Clear energy boundaries.
Definition GEbounds.cpp:268
GEnergy elogmean(const int &index) const
Returns logarithmic mean energy for a given energy interval.
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
double log10TeV(void) const
Return log10 of energy in TeV.
Definition GEnergy.cpp:457
Abstract interface for the event classes.
Definition GEvent.hpp:71
virtual const GEnergy & energy(void) const =0
virtual double size(void) const =0
virtual const GTime & time(void) const =0
Filename class.
Definition GFilename.hpp:62
void clear(void)
Clear file name.
Abstract FITS image base class.
Abstract interface for FITS table.
FITS file class.
Definition GFits.hpp:63
GFitsImage * image(const int &extno)
Get pointer to image HDU.
Definition GFits.cpp:368
void close(void)
Close FITS file.
Definition GFits.cpp:1342
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition GFits.cpp:482
Abstract data model class.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
virtual GModelData & operator=(const GModelData &model)
Assignment operator.
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Interface definition for the model registry 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.
Constant temporal model class.
virtual GModelTemporalConst * clone(void) const
Clone constant temporal model.
Interface definition for the temporal model registry class.
GModelTemporal * alloc(const GXmlElement &xml) const
Allocate temporal model that is found in XML element.
Abstract temporal model base class.
virtual GModelTemporal * clone(void) const =0
Clones object.
virtual double eval(const GTime &srcTime, const bool &gradients=false) const =0
int size(void) const
Return number of parameters.
virtual std::string type(void) const =0
virtual void write(GXmlElement &xml) const =0
std::vector< GModelPar * > m_pars
Pointers to all model parameters.
Definition GModel.hpp:178
void write_attributes(GXmlElement &xml) const
Write model attributes.
Definition GModel.cpp:723
std::string print_attributes(void) const
Print model attributes.
Definition GModel.cpp:770
int size(void) const
Return number of parameters in model.
Definition GModel.hpp:233
void read_attributes(const GXmlElement &xml)
Read model attributes.
Definition GModel.cpp:684
const std::string & name(void) const
Return parameter name.
Definition GModel.hpp:261
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
const int & inx_right(void) const
Returns right node index.
const int & inx_left(void) const
Returns left node index.
const double & wgt_right(void) const
Returns right node weight.
const double & wgt_left(void) const
Returns left node weight.
void clear(void)
Clear node array.
void append(const double &node)
Append one node to array.
Abstract observation base class.
virtual std::string instrument(void) const =0
void id(const std::string &id)
Set observation identifier.
bool is_free(void) const
Signal if parameter is free.
const double & scale(void) const
Return parameter scale.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
void range(const double &min, const double &max)
Set minimum and maximum parameter boundaries.
const double & factor_gradient(void) const
Return parameter factor gradient.
void fix(void)
Fix a parameter.
double gradient(void) const
Return parameter gradient.
void clear(void)
Clear parameter.
double value(void) const
Return parameter value.
const std::string & name(void) const
Return parameter name.
Random number generator class.
Definition GRan.hpp:44
double solidangle(const int &index) const
Returns solid angle of pixel.
Definition GSkyMap.cpp:1858
void clear(void)
Clear instance.
Definition GSkyMap.cpp:1100
void read(const GFitsHDU &hdu)
Read skymap from FITS HDU.
Definition GSkyMap.cpp:2664
const int & npix(void) const
Returns number of pixels.
Definition GSkyMap.hpp:345
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 std::string extname_ebounds
Definition GEbounds.hpp:44
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
const GXmlElement * xml_get_par(const std::string &origin, const GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition GTools.cpp:1689
const GCTAInstDir & cta_dir(const std::string &origin, const GEvent &event)
Retrieve CTA instrument direction from generic event.
GXmlElement * xml_need_par(const std::string &origin, GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition GTools.cpp:1637
GFilename xml_file_reduce(const GXmlElement &xml, const std::string &filename)
Reduce file name provided for writing as XML attribute.
Definition GTools.cpp:1946
void warning(const std::string &origin, const std::string &message)
Emits warning.
Definition GTools.cpp:1386
GFilename xml_file_expand(const GXmlElement &xml, const std::string &filename)
Expand file name provided as XML attribute for loading.
Definition GTools.cpp:1889