GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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"
35 #include "GModelTemporalConst.hpp"
36 #include "GObservation.hpp"
37 #include "GCTAModelSkyCube.hpp"
38 #include "GCTASupport.hpp"
39 
40 /* __ Globals ____________________________________________________________ */
42 const 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
77  init_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
95  init_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
131  m_spectral = spectral.clone();
132  m_temporal = temporal.clone();
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
164  m_spectral = spectral.clone();
165  m_temporal = temporal.clone();
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();
258  this->GModelData::free_members();
259 
260  // Initialise members
261  this->GModelData::init_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  ***************************************************************************/
287 void GCTAModelSkyCube::load(const GFilename& filename)
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  ***************************************************************************/
395 double 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  ***************************************************************************/
507 double 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) {
526  npred = m_npred_values[i];
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
547  m_elogmeans.set_value(obsEng.log10TeV());
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)
575  if (gammalib::is_notanumber(npred) || gammalib::is_infinite(npred)) {
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);
675  m_temporal = xml_temporal(*temporal);
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  ***************************************************************************/
793 std::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") +
825  gammalib::str(size()));
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
870  m_filename.clear();
871  m_cube.clear();
872  m_ebounds.clear();
873  m_elogmeans.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
896  m_filename = sky.m_filename;
897  m_cube = sky.m_cube;
898  m_ebounds = sky.m_ebounds;
899  m_elogmeans = sky.m_elogmeans;
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
1067  xml.attribute("file", gammalib::xml_file_reduce(xml, m_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 }
virtual std::string type(void) const
Return data model type.
virtual void write(GXmlElement &xml) const =0
GModelTemporal * m_temporal
Temporal model.
Constant temporal model class interface definition.
#define G_EVAL
virtual GCTAEventList * mc(const GObservation &obs, GRan &ran) const
Return simulated list of events.
Abstract FITS image base class.
Definition: GFitsImage.hpp:43
void init_members(void)
Initialise class members.
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition: GFits.cpp:482
const double & factor_gradient(void) const
Return parameter factor gradient.
double norm(const GVector &vector)
Computes vector norm.
Definition: GVector.cpp:864
const GCTAInstDir & cta_dir(const std::string &origin, const GEvent &event)
Retrieve CTA instrument direction from generic event.
CTA sky cube model class interface definition.
const std::string & name(void) const
Return parameter name.
std::string print_attributes(void) const
Print model attributes.
Definition: GModel.cpp:770
void warning(const std::string &origin, const std::string &message)
Emits warning.
Definition: GTools.cpp:1386
Abstract spectral model base class.
Interface definition for the model registry class.
virtual std::string instrument(void) const =0
double gradient(void) const
Return parameter gradient.
Abstract temporal model base class.
int size(void) const
Return number of parameters.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
Definition: GVector.cpp:1253
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
Definition: GModelPar.cpp:351
int size(void) const
Return number of energy boundaries.
Definition: GEbounds.hpp:163
const GFilename & filename(void) const
Return filename.
GModelSpectral * m_spectral
Spectral model.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const =0
Abstract interface for the event classes.
Definition: GEvent.hpp:71
void load(const GFilename &filename)
Load sky cube.
CTA event list class.
XML element node class.
Definition: GXmlElement.hpp:48
const double & wgt_left(void) const
Returns left node weight.
Definition: GNodeArray.hpp:264
virtual ~GCTAModelSkyCube(void)
Destructor.
void free_members(void)
Delete class members.
Definition: GModelData.cpp:300
virtual double size(void) const =0
Spectral model registry class definition.
void clear(void)
Clear node array.
Definition: GNodeArray.cpp:235
virtual void write(GXmlElement &xml) const =0
double log10TeV(void) const
Return log10 of energy in TeV.
Definition: GEnergy.cpp:457
Random number generator class.
Definition: GRan.hpp:44
#define G_WRITE_XML_SPATIAL
void read(const GFitsTable &table)
Read energy boundaries from FITS table.
Definition: GEbounds.cpp:761
GSkyMap m_cube
Sky cube.
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition: GXmlNode.cpp:586
Time class.
Definition: GTime.hpp:55
Gammalib tools definition.
FITS file class.
Definition: GFits.hpp:63
virtual GModelTemporalConst * clone(void) const
Clone constant temporal model.
void set_pointers(void)
Set pointers.
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
Definition: GNodeArray.cpp:587
virtual const GTime & time(void) const =0
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 read(const GFitsHDU &hdu)
Read skymap from FITS HDU.
Definition: GSkyMap.cpp:2664
void dir(const GSkyDir &dir)
Set sky direction.
bool is_free(void) const
Signal if parameter is free.
CTA sky cube model class.
void id(const std::string &id)
Set observation identifier.
GCTAModelSkyCube(void)
Void constructor.
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition: GTools.hpp:201
std::vector< GModelPar * > m_pars
Pointers to all model parameters.
Definition: GModel.hpp:178
int size(void) const
Return number of parameters in model.
Definition: GModel.hpp:233
const double & scale(void) const
Return parameter scale.
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition: GTools.hpp:184
virtual GCTAModelSkyCube * clone(void) const
Clone CTA sky cube model.
Definition of support function used by CTA classes.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
virtual void write(GXmlElement &xml) const
Write CTA cube background model into XML element.
virtual void clear(void)
Clear CTA sky cube model.
const double & wgt_right(void) const
Returns right node weight.
Definition: GNodeArray.hpp:279
const GXmlAttribute * attribute(const int &index) const
Return attribute.
const std::string & name(void) const
Return parameter name.
Definition: GModel.hpp:261
Filename class.
Definition: GFilename.hpp:62
GModelTemporal * xml_temporal(const GXmlElement &temporal) const
Return pointer to temporal model from XML element.
void fix(void)
Fix a parameter.
int size(void) const
Return number of parameters.
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
GModelTemporal * alloc(const GXmlElement &xml) const
Allocate temporal model that is found in XML element.
virtual const GEnergy & energy(void) const =0
GVector log(const GVector &vector)
Computes natural logarithm of vector elements.
Definition: GVector.cpp:1274
const std::string extname_ebounds
Definition: GEbounds.hpp:44
void clear(void)
Clear parameter.
Abstract data model class.
Definition: GModelData.hpp:55
GModelSpectral * alloc(const GXmlElement &xml) const
Allocate spectral model that is found in XML element.
Abstract interface for FITS table.
Definition: GFitsTable.hpp:44
virtual GModelData & operator=(const GModelData &model)
Assignment operator.
Definition: GModelData.cpp:125
GEbounds m_ebounds
Energy boundaries of sky cube.
GChatter
Definition: GTypemaps.hpp:33
GModelPar m_norm
Normalisation parameter.
GEnergy elogmean(const int &index) const
Returns logarithmic mean energy for a given energy interval.
Definition: GEbounds.cpp:1126
const int & inx_left(void) const
Returns left node index.
Definition: GNodeArray.hpp:235
bool valid_model(void) const
Verifies if model has all components.
std::vector< double > m_npred_values
Model values.
void clear(void)
Clear instance.
Definition: GSkyMap.cpp:1100
virtual double eval(const GTime &srcTime, const bool &gradients=false) const =0
Abstract observation base class.
void clear(void)
Clear energy boundaries.
Definition: GEbounds.cpp:268
Abstract observation base class interface definition.
Interface definition for the spectral model registry class.
const int & inx_right(void) const
Returns right node index.
Definition: GNodeArray.hpp:249
Interface definition for the temporal model registry class.
void write_attributes(GXmlElement &xml) const
Write model attributes.
Definition: GModel.cpp:723
virtual GModelSpectral * clone(void) const =0
Clones object.
void read_xml_spatial(const GXmlElement &xml)
Read spatial model from XML element.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print CTA cube background model information.
std::vector< std::string > m_npred_names
Model names.
virtual void read(const GXmlElement &xml)
Read CTA sky cube model from XML element.
GFitsImage * image(const int &extno)
Get pointer to image HDU.
Definition: GFits.cpp:368
virtual std::string type(void) const =0
GFilename m_filename
Filename.
void free_members(void)
Delete class members.
void write_xml_spatial(GXmlElement &xml) const
Write spatial model into XML element.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition: GXmlNode.cpp:640
void clear(void)
Clear file name.
Definition: GFilename.cpp:188
Temporal model registry class definition.
void range(const double &min, const double &max)
Set minimum and maximum parameter boundaries.
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 read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Definition: GModelPar.cpp:229
double value(void) const
Return parameter value.
GNodeArray m_elogmeans
Mean log10(TeV) energies for the sky cube.
GModelSpectral * spectral(void) const
Return spectral model component.
void copy_members(const GCTAModelSkyCube &bgd)
Copy class members.
GModelSpectral * xml_spectral(const GXmlElement &spectral) const
Return pointer to spectral model from XML element.
GVector exp(const GVector &vector)
Computes exponential of vector elements.
Definition: GVector.cpp:1232
virtual GModelTemporal * clone(void) const =0
Clones object.
void read_attributes(const GXmlElement &xml)
Read model attributes.
Definition: GModel.cpp:684
CTA instrument direction class.
Definition: GCTAInstDir.hpp:63
#define G_READ_XML_SPATIAL
std::vector< GTime > m_npred_times
Model time.
GModelTemporal * temporal(void) const
Return temporal model component.
Model registry class definition.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition: GXmlNode.cpp:287
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
void append(const double &node)
Append one node to array.
Definition: GNodeArray.cpp:351
const int & npix(void) const
Returns number of pixels.
Definition: GSkyMap.hpp:347
void close(void)
Close FITS file.
Definition: GFits.cpp:1342
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
virtual GCTAModelSkyCube & operator=(const GCTAModelSkyCube &model)
Assignment operator.
void init_members(void)
Initialise class members.
Definition: GModelData.cpp:278
std::vector< GEnergy > m_npred_energies
Model energy.
Constant temporal model class.
const GCTAModelSkyCube g_cta_inst_sky_seed
Class that handles energies in a unit independent way.
Definition: GEnergy.hpp:48
#define G_MC
GFilename xml_file_expand(const GXmlElement &xml, const std::string &filename)
Expand file name provided as XML attribute for loading.
Definition: GTools.cpp:1889
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489
virtual double npred(const GEnergy &obsEng, const GTime &obsTime, const GObservation &obs) const
Return spatially integrated event rate in units of events MeV s .