GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GSPIModelDataSpace.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GSPIModelDataSpace.cpp - INTEGRAL/SPI data space model *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2020-2022 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 GSPIModelDataSpace.cpp
23  * @brief INTEGRAL/SPI data space model implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <typeinfo>
32 #include "GException.hpp"
33 #include "GTools.hpp"
34 #include "GTimes.hpp"
35 #include "GModelPar.hpp"
36 #include "GModelRegistry.hpp"
37 #include "GSPIModelDataSpace.hpp"
38 #include "GSPIObservation.hpp"
39 #include "GSPIEventBin.hpp"
40 #include "GSPITools.hpp"
41 
42 /* __ Constants __________________________________________________________ */
43 
44 /* __ Globals ____________________________________________________________ */
46 const GModelRegistry g_spi_data_space_registry(&g_spi_data_space_seed);
47 
48 /* __ Method name definitions ____________________________________________ */
49 #define G_CONSTRUCTOR "GSPIModelDataSpace::GSPIModelDataSpace("\
50  "GSPIObservation&, std::string&, std::string&, int&)"
51 #define G_EVAL "GSPIModelDataSpace::eval(GEvent&, GObservation&, bool&)"
52 #define G_READ "GSPIModelDataSpace::read(GXmlElement&)"
53 #define G_WRITE "GSPIModelDataSpace::write(GXmlElement&)"
54 #define G_SETUP_MODEL "GSPIModelDataSpace::setup_model(Observation&)"
55 #define G_GET_DATE_TIME "GSPIModelDataSpace::get_date_time(std::string&)"
56 
57 /* __ Macros _____________________________________________________________ */
58 
59 /* __ Coding definitions _________________________________________________ */
60 
61 /* __ Debug definitions __________________________________________________ */
62 //#define G_DUMP_MC //!< Dump MC information
63 //#define G_DEBUG_SETUP_MODEL //!< Debug setup model method
64 //#define G_DEBUG_SETUP_MODEL_MAP //!< Debug setup of parameter map
65 
66 
67 /*==========================================================================
68  = =
69  = Constructors/destructors =
70  = =
71  ==========================================================================*/
72 
73 /***********************************************************************//**
74  * @brief Void constructor
75  *
76  * Constructs an empty INTEGRAL/SPI data space model.
77  ***************************************************************************/
79 {
80  // Initialise members
81  init_members();
82 
83  // Return
84  return;
85 }
86 
87 
88 /***********************************************************************//**
89  * @brief Model and method constructor
90  *
91  * @param[in] obs INTEGRAL/SPI observation.
92  * @param[in] name Model name.
93  * @param[in] method Fit method.
94  * @param[in] index Model index.
95  *
96  * @exception GException::out_of_range
97  * Model index out of range.
98  *
99  * Constructs an INTEGRAL/SPI data space model by setting the fit method
100  * and the model index.
101  *
102  * The constructor uses the INTEGRAL/SPI observation to setup the model
103  * parameters and the mapping of parameters to the data space.
104  ***************************************************************************/
106  const std::string& name,
107  const std::string& method,
108  const int& index) :
109  GModelData()
110 {
111  // Initialise members
112  init_members();
113 
114  // Set members
115  m_name = name;
116  m_method = method;
117  m_index = index;
118 
119  // Setup model
120  setup_model(obs);
121 
122  // Check whether the index is valid. We can only do this if the
123  // observation contains an event cube
124  GSPIEventCube* cube = dynamic_cast<GSPIEventCube*>(m_obs->events());
125  if (cube != NULL) {
126  int num_models = cube->models();
127  if (index < 0 || index >= num_models) {
128  throw GException::out_of_range(G_CONSTRUCTOR, "Invalid model index",
129  index, num_models);
130  }
131  }
132 
133  // Return
134  return;
135 }
136 
137 
138 /***********************************************************************//**
139  * @brief XML constructor
140  *
141  * @param[in] xml XML element.
142  *
143  * Constructs an INTEGRAL/SPI data space model from the information that is
144  * found in an XML element. Please refer to the read() method to learn more
145  * about the information that is expected in the XML element.
146  ***************************************************************************/
148  GModelData(xml)
149 {
150  // Initialise members
151  init_members();
152 
153  // Read XML
154  read(xml);
155 
156  // Return
157  return;
158 }
159 
160 
161 /***********************************************************************//**
162  * @brief Copy constructor
163  *
164  * @param[in] model INTEGRAL/SPI data space model.
165  *
166  * Constructs an INTEGRAL/SPI data space model by copying information from an
167  * existing model. Note that the copy is a deep copy, so the original object
168  * can be destroyed after the copy without any loss of information.
169  ***************************************************************************/
171  GModelData(model)
172 {
173  // Initialise private members for clean destruction
174  init_members();
175 
176  // Copy members
177  copy_members(model);
178 
179  // Return
180  return;
181 }
182 
183 
184 /***********************************************************************//**
185  * @brief Destructor
186  *
187  * Destroys an INTEGRAL/SPI data space model.
188  ***************************************************************************/
190 {
191  // Free members
192  free_members();
193 
194  // Return
195  return;
196 }
197 
198 
199 /*==========================================================================
200  = =
201  = Operators =
202  = =
203  ==========================================================================*/
204 
205 /***********************************************************************//**
206  * @brief Assignment operator
207  *
208  * @param[in] model INTEGRAL/SPI data space model.
209  * @return INTEGRAL/SPI data space model
210  *
211  * Assigns the information from an INTEGRAL/SPI data space model to the
212  * class instance. Note that a deep copy of the information is performed, so
213  * the @p model instance can be destroyed after the assignment without any
214  * loss of information.
215  ***************************************************************************/
217 {
218  // Execute only if object is not identical
219  if (this != &model) {
220 
221  // Copy base class members
222  this->GModelData::operator=(model);
223 
224  // Free members
225  free_members();
226 
227  // Initialise members
228  init_members();
229 
230  // Copy members
231  copy_members(model);
232 
233  } // endif: object was not identical
234 
235  // Return
236  return *this;
237 }
238 
239 
240 /*==========================================================================
241  = =
242  = Public methods =
243  = =
244  ==========================================================================*/
245 
246 /***********************************************************************//**
247  * @brief Clear instance
248  *
249  * Resets the object to a clean initial state. All information that resided
250  * in the object will be lost.
251  ***************************************************************************/
253 {
254  // Free class members (base and derived classes, derived class first)
255  free_members();
256  this->GModelData::free_members();
257  this->GModel::free_members();
258 
259  // Initialise members
260  this->GModel::init_members();
261  this->GModelData::init_members();
262  init_members();
263 
264  // Return
265  return;
266 }
267 
268 
269 /***********************************************************************//**
270  * @brief Clone instance
271  *
272  * @return Pointer to deep copy of INTEGRAL/SPI data space model.
273  *
274  * Clone an INTEGRAL/SPI data space model. Cloning performs a deep copy of
275  * the information, so the original object can be destroyed after cloning
276  * without any loss of information.
277  ***************************************************************************/
279 {
280  return new GSPIModelDataSpace(*this);
281 }
282 
283 
284 /***********************************************************************//**
285  * @brief Evaluate function
286  *
287  * @param[in] event Observed event.
288  * @param[in] obs Observation.
289  * @param[in] gradients Compute gradients?
290  * @return Model value.
291  *
292  * @exception GException::invalid_argument
293  * Observation is not an INTEGRAL/SPI observation.
294  * Event is not an INTEGRAL/SPI event bin.
295  *
296  * Evaluates the value of the INTEGRAL/SPI data space model for a given
297  * event and a given observation.
298  ***************************************************************************/
299 double GSPIModelDataSpace::eval(const GEvent& event,
300  const GObservation& obs,
301  const bool& gradients) const
302 {
303  // Reset parameter indices
304  m_has_eval_inx = false;
305  m_eval_inx.clear();
306 
307  // Extract INTEGRAL/SPI event bin
308  const GSPIEventBin* bin = dynamic_cast<const GSPIEventBin*>(&event);
309  if (bin == NULL) {
310  std::string cls = std::string(typeid(&event).name());
311  std::string msg = "Event of type \""+cls+"\" is not an INTEGRAL/SPI "
312  "event bin. Please specify an INTEGRAL/SPI event "
313  "bin as argument.";
315  }
316 
317  // Setup model
318  setup_model(obs);
319 
320  // Initialise value
321  double value = 0.0;
322 
323  // Continue only if model was initialised
324  if (m_index >= 0 && m_parameters.size() > 0) {
325 
326  // Get bin size
327  double size = bin->size();
328 
329  // Continue only if bin size is positive
330  if (size > 0.0) {
331 
332  // Get bin index in data space
333  int index = bin->index();
334 
335  // Get parameter index
336  int ipar = m_map[index];
337 
338  // Get relevant model parameter
339  const GModelPar* par = &(m_parameters[ipar]);
340 
341  // Get model value divided by size (note that the size will be
342  // multiplied-in later, hence here we need the model value divided
343  // by size)
344  value = bin->model(m_index) / size;
345 
346  // Get model scale factor
347  double scale = par->value();
348 
349  // Optionally compute gradients
350  if (gradients) {
351 
352  // Compute partial derivative
353  double grad = (par->is_free()) ? value * par->scale() : 0.0;
354 
355  // Set gradient
356  par->factor_gradient(grad);
357 
358  // Signal that gradient for this parameter was set
359  m_has_eval_inx = true;
360  m_eval_inx.push_back(ipar);
361 
362  } // endif: gradient computation was requested
363 
364  // Compute scaled model value
365  value *= scale;
366 
367  // Compile option: Check for NaN/Inf
368  #if defined(G_NAN_CHECK)
369  if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
370  std::cout << "*** ERROR: GSPIModelDataSpace::eval";
371  std::cout << "(index=" << index << "):";
372  std::cout << " NaN/Inf encountered";
373  std::cout << " (value=" << value;
374  std::cout << ", scale=" << scale;
375  std::cout << ")" << std::endl;
376  }
377  #endif
378 
379  } // endif: binsize was positive
380 
381  } // endif: model was initialised
382 
383  // Return
384  return value;
385 }
386 
387 
388 /***********************************************************************//**
389  * @brief Return spatially integrated data model
390  *
391  * @param[in] obsEng Measured event energy.
392  * @param[in] obsTime Measured event time.
393  * @param[in] obs Observation.
394  *
395  * Spatially integrates the data model for a given measured event energy and
396  * event time.
397  *
398  * @todo Implement method.
399  ***************************************************************************/
400 double GSPIModelDataSpace::npred(const GEnergy& obsEng,
401  const GTime& obsTime,
402  const GObservation& obs) const
403 {
404  // Initialise result
405  double npred = 0.0;
406 
407  // Return
408  return npred;
409 }
410 
411 
412 /***********************************************************************//**
413  * @brief Return simulated list of events
414  *
415  * @param[in] obs Observation.
416  * @param[in] ran Random number generator.
417  *
418  * Draws a sample of events from the INTEGRAL/SPI data space model using a
419  * Monte Carlo simulation.
420  *
421  * @todo Implement method.
422  ***************************************************************************/
424  GRan& ran) const
425 {
426  // Initialise new event cube
427  GSPIEventCube* cube = new GSPIEventCube;
428 
429  // Return
430  return cube;
431 }
432 
433 
434 /***********************************************************************//**
435  * @brief Read model from XML element
436  *
437  * @param[in] xml XML element.
438  *
439  * Read the INTEGRAL/SPI data space model from an XML element.
440  *
441  * The model is composed of a list of scale parameters. The following XML
442  * file format is expected:
443  *
444  * <source name="Background" type="DataSpace" method="orbit,dete" index="0" instrument="SPI">
445  * <parameter name="REV0019_DETID00" .../>
446  * <parameter name="REV0019_DETID01" .../>
447  * ...
448  * </source>
449  ***************************************************************************/
451 {
452  // Clear instance
453  clear();
454 
455  // Set model method and index
456  m_method = xml.attribute("method");
457  m_index = gammalib::toint(xml.attribute("index"));
458 
459  // Get number of parameters from XML file
460  int npars = xml.elements("parameter");
461 
462  // Loop over all parameters
463  for (int i = 0; i < npars; ++i) {
464 
465  // Allocate parameter
466  GModelPar parameter;
467 
468  // Get XML element
469  const GXmlElement* par = xml.element("parameter", i);
470 
471  // Read parameter from XML element
472  parameter.read(*par);
473 
474  // Push parameter on list
475  m_parameters.push_back(parameter);
476 
477  } // endfor: looped over parameters
478 
479  // Read model attributes
480  read_attributes(xml);
481 
482  // Set pointers
483  set_pointers();
484 
485  // Return
486  return;
487 }
488 
489 
490 /***********************************************************************//**
491  * @brief Write model into XML element
492  *
493  * @param[in] xml XML element.
494  *
495  * @exception GException::invalid_value
496  * Existing XML element is not of required type
497  * Invalid number of model parameters or nodes found in XML element.
498  *
499  * Write the INTEGRAL/SPI data space model into an XML element.
500  *
501  * The model is composed of a list of scale parameters. The following XML
502  * file structure will be written:
503  *
504  * <source name="Background" type="DataSpace" method="orbit,dete" index="0" instrument="SPI">
505  * <parameter name="REV0019_DETID00" .../>
506  * <parameter name="REV0019_DETID01" .../>
507  * ...
508  * </source>
509  ***************************************************************************/
511 {
512  // Initialise pointer on source
513  GXmlElement* src = NULL;
514 
515  // Search corresponding source
516  int n = xml.elements("source");
517  for (int k = 0; k < n; ++k) {
518  GXmlElement* element = xml.element("source", k);
519  if (element->attribute("name") == name()) {
520  src = element;
521  break;
522  }
523  }
524 
525  // If no source with corresponding name was found then append one.
526  // Set also the type and the instrument.
527  if (src == NULL) {
528  src = xml.append("source");
529  src->attribute("name", name());
530  src->attribute("type", type());
531  if (instruments().length() > 0) {
532  src->attribute("instrument", instruments());
533  }
534  }
535 
536  // Verify model type
537  if (src->attribute("type") != type()) {
538  std::string msg = "Invalid model type \""+src->attribute("type")+"\" "
539  "found in XML file. Model type \""+type()+"\" "
540  "expected.";
542  }
543 
544  // Determine number of parameters
545  int npars = m_parameters.size();
546 
547  // If XML element has 0 parameters then append parameters
548  if (src->elements() == 0) {
549  for (int i = 0; i < npars; ++i) {
550  src->append(GXmlElement("parameter"));
551  }
552  }
553 
554  // Verify that XML element has the required number of nodes
555  if (src->elements() != npars || src->elements("parameter") != npars) {
556  std::string msg = "Invalid number of parameters "+
557  gammalib::str(src->elements("parameter"))+
558  " found in XML file, but model requires exactly "+
559  gammalib::str(npars)+" parameters.";
561  }
562 
563  // Loop over all parameters
564  for (int i = 0; i < npars; ++i) {
565 
566  // Get XML element
567  GXmlElement* par = src->element("parameter", i);
568 
569  // Write parameter into XML element
570  m_parameters[i].write(*par);
571 
572  } // endfor: looped over parameters
573 
574  // Write model attributes
575  write_attributes(*src);
576 
577  // Write method and index
578  src->attribute("method", m_method);
579  src->attribute("index", gammalib::str(m_index));
580 
581  // Return
582  return;
583 }
584 
585 
586 /***********************************************************************//**
587  * @brief Print model information
588  *
589  * @param[in] chatter Chattiness.
590  * @return String containing model information.
591  ***************************************************************************/
592 std::string GSPIModelDataSpace::print(const GChatter& chatter) const
593 {
594  // Initialise result string
595  std::string result;
596 
597  // Continue only if chatter is not silent
598  if (chatter != SILENT) {
599 
600  // Append header
601  result.append("=== GSPIModelDataSpace ===");
602 
603  // Append attributes
604  result.append("\n"+print_attributes());
605 
606  // Append parameter summary
607  result.append("\n"+gammalib::parformat("Method"));
608  result.append(m_method);
609  result.append("\n"+gammalib::parformat("Number of parameters"));
610  result.append(gammalib::str(size()));
611  for (int i = 0; i < size(); ++i) {
612  result.append("\n"+m_pars[i]->print(chatter));
613  }
614 
615  } // endif: chatter was not silent
616 
617  // Return result
618  return result;
619 }
620 
621 
622 /*==========================================================================
623  = =
624  = Private methods =
625  = =
626  ==========================================================================*/
627 
628 /***********************************************************************//**
629  * @brief Initialise class members
630  ***************************************************************************/
632 {
633  // Initialise base class members
634  m_instruments.clear();
635  m_instruments.push_back("SPI");
636 
637  // Initialise members
638  m_obs = NULL;
639  m_method.clear();
640  m_index = -1;
641  m_map_size = 0;
642  m_map = NULL;
643  m_parameters.clear();
644 
645  // Return
646  return;
647 }
648 
649 
650 /***********************************************************************//**
651  * @brief Copy class members
652  *
653  * @param[in] model Model.
654  ***************************************************************************/
656 {
657  // Copy members
658  m_obs = model.m_obs; // Copy pointer
659  m_method = model.m_method;
660  m_index = model.m_index;
661  m_map_size = model.m_map_size;
662  m_parameters = model.m_parameters;
663 
664  // Copy parameter map
665  if (m_map_size > 0) {
666  m_map = new int[m_map_size];
667  for (int i = 0; i < m_map_size; ++i) {
668  m_map[i] = model.m_map[i];
669  }
670  }
671 
672  // Set parameter pointers
673  set_pointers();
674 
675  // Return
676  return;
677 }
678 
679 
680 /***********************************************************************//**
681  * @brief Delete class members
682  ***************************************************************************/
684 {
685  // Delete memory
686  if (m_map != NULL) delete [] m_map;
687 
688  // Set pointers to free
689  m_map = NULL;
690 
691  // Return
692  return;
693 }
694 
695 
696 /***********************************************************************//**
697  * @brief Set pointers
698  *
699  * Set pointers to all model parameters. The pointers are stored in a vector
700  * that is member of the GModel base class.
701  ***************************************************************************/
703 {
704  // Clear parameter pointer(s)
705  m_pars.clear();
706 
707  // Get number of parameters
708  int npars = m_parameters.size();
709 
710  // Set pointers for all parameters
711  for (int i = 0; i < npars; ++i) {
712  m_pars.push_back(&(m_parameters[i]));
713  }
714 
715  // Return
716  return;
717 }
718 
719 
720 /***********************************************************************//**
721  * @brief Setup model
722  *
723  * @param[in] obs Observation.
724  *
725  * Setup the model for a given observation.
726  ***************************************************************************/
728 {
729  // Continue only if observation pointer differs
730  if (&obs != m_obs) {
731 
732  // Debug: signal that pointer differs
733  #if defined(G_DEBUG_SETUP_MODEL)
734  std::cout << "GSPIModelDataSpace::setup_model: ";
735  std::cout << "observation pointer differs";
736  std::cout << std::endl;
737  #endif
738 
739  // Extract INTEGRAL/SPI observation
740  const GSPIObservation* spi_obs = dynamic_cast<const GSPIObservation*>(&obs);
741  if (spi_obs == NULL) {
742  std::string cls = std::string(typeid(&obs).name());
743  std::string msg = "Observation of type \""+cls+"\" is not an "
744  "INTEGRAL/SPI observation. Please specify an "
745  "INTEGRAL/SPI observation as argument.";
747  }
748 
749  // Store observation pointer
750  m_obs = const_cast<GSPIObservation*>(spi_obs);
751 
752  // Extract INTEGRAL/SPI event cube. Continue only if the cube is
753  // valid
754  GSPIEventCube* cube = dynamic_cast<GSPIEventCube*>(m_obs->events());
755  if (cube != NULL) {
756 
757  // Continue only if the model index is valid
758  if (m_index >= 0 && m_index < cube->models()) {
759 
760  // Continue only if there is a method
761  if (!m_method.empty()) {
762  const_cast<GSPIModelDataSpace*>(this)->setup_pars(cube);
763  }
764 
765  // Debug: signal that index is not valid
766  #if defined(G_DEBUG_SETUP_MODEL)
767  else {
768  std::cout << "GSPIModelDataSpace::setup_model: ";
769  std::cout << "no method defined.";
770  std::cout << std::endl;
771  }
772  #endif
773 
774  } // endif: model index was valid
775 
776  // Debug: signal that index is not valid
777  #if defined(G_DEBUG_SETUP_MODEL)
778  else {
779  std::cout << "GSPIModelDataSpace::setup_model: ";
780  std::cout << "model index " << m_index << " is not in valid ";
781  std::cout << "range.";
782  std::cout << std::endl;
783  }
784  #endif
785 
786  } // endif: cube was valid
787 
788  // Debug: signal that event cube was invalid
789  #if defined(G_DEBUG_SETUP_MODEL)
790  else {
791  std::cout << "GSPIModelDataSpace::setup_model: ";
792  std::cout << "no valid event cube found in observation";
793  std::cout << std::endl;
794  }
795  #endif
796 
797  } // endif: observation pointer differed
798 
799  // Return
800  return;
801 }
802 
803 
804 /***********************************************************************//**
805  * @brief Setup parameters
806  *
807  * @param[in] cube INTEGRAL/SPI event cube
808  *
809  * Setup the parameters for a given model.
810  *
811  * We assume that the model index is within the valid range of possible
812  * indices and that a method was specified.
813  ***************************************************************************/
815 {
816  // Free parameter map
817  free_members();
818 
819  // Get cube dimensions
820  int n_pt = cube->naxis(0);
821  int n_det = cube->naxis(1);
822  int n_eng = cube->naxis(2);
823 
824  // Initialise index vectors for all three dimensions
825  std::vector<int> pt_indices(n_pt, 0);
826  std::vector<int> det_indices(n_det, 0);
827  std::vector<int> eng_indices(n_eng, 0);
828 
829  // Initialise name vectors for all three dimensions
830  std::vector<std::string> pt_names;
831  std::vector<std::string> det_names;
832  std::vector<std::string> eng_names;
833 
834  // Determine pointing indices
835  setup_pointing_indices(cube, &pt_indices, &pt_names);
836 
837  // Determine detector indices
838  setup_detector_indices(cube, &det_indices, &det_names);
839 
840  // Determine energy indices
841  setup_energy_indices(cube, &eng_indices, &eng_names);
842 
843  // Determine number of parameters in each dimension. The number of
844  // parameters is given by the last index in the vector + 1. The check
845  // for a non-zero index vector size if just for security, if the event
846  // cube is set it should always be positive, yet for an empty event cube
847  // it may be zero, and in this case the method will just do nothing.
848  int npt = (pt_indices.size() > 0) ? pt_indices[pt_indices.size()-1] + 1 : 0;
849  int ndet = (det_indices.size() > 0) ? det_indices[det_indices.size()-1] + 1 : 0;
850  int neng = (eng_indices.size() > 0) ? eng_indices[eng_indices.size()-1] + 1 : 0;
851  int npars = npt * ndet * neng;
852 
853  // Debug: print number of parameters in each dimension
854  #if defined(G_DEBUG_SETUP_MODEL)
855  std::cout << "GSPIModelDataSpace::setup_pars: ";
856  std::cout << "determined pointing, detector and energy indices:" << std::endl;
857  std::cout << "- npt = " << npt << std::endl;
858  std::cout << "- ndet = " << ndet << std::endl;
859  std::cout << "- neng = " << neng << std::endl;
860  std::cout << "- npars = " << npars << std::endl;
861  #endif
862 
863  // Continue only if there are parameters in the model
864  if (npars > 0) {
865 
866  // Allocate parameters vector
867  std::vector<GModelPar> parameters;
868  parameters.reserve(npars);
869 
870  // Allocate parameters. Energy parameter indices vary the most fastest
871  // followed by detector parameter indices, follwed by pointing parameter
872  // indices.
873  for (int ipt = 0; ipt < npt; ++ipt) {
874  for (int idet = 0; idet < ndet; ++idet) {
875  for (int ieng = 0; ieng < neng; ++ieng) {
876 
877  // Build parameter name
878  std::string par_name;
879  if (m_name.empty()) {
880  par_name = "Scale";
881  }
882  else {
883  par_name = m_name;
884  }
885  if (eng_names.size() > 0) {
886  par_name += " " + eng_names[ieng];
887  }
888  if (det_names.size() > 0) {
889  par_name += " " + det_names[idet];
890  }
891  if (pt_names.size() > 0) {
892  par_name += " " + pt_names[ipt];
893  }
894 
895  // If parameter name exists already in this class instance
896  // (because they were read using the read() method) then
897  // recover the parameter and push it into the vector of
898  // parameters
899  bool has_par = false;
900  for (int i = 0; i < m_parameters.size(); ++i) {
901  if (m_parameters[i].name() == par_name) {
902  parameters.push_back(m_parameters[i]);
903  has_par = true;
904  #if defined(G_DEBUG_SETUP_MODEL)
905  std::cout << "GSPIModelDataSpace::setup_pars: ";
906  std::cout << "copy old parameter \"";
907  std::cout << m_parameters[i].name() << "\"" << std::endl;
908  #endif
909  break;
910  }
911  }
912 
913  // ... otherwise allocate new model parameter
914  if (!has_par) {
915  GModelPar par;
916  par.clear();
917  par.name(par_name);
918  par.free();
919  par.value(1.0);
920  par.scale(1.0);
921  par.gradient(0.0);
922  par.has_grad(true);
923  parameters.push_back(par);
924  #if defined(G_DEBUG_SETUP_MODEL)
925  std::cout << "GSPIModelDataSpace::setup_pars: ";
926  std::cout << "allocate new parameter \"";
927  std::cout << par_name << "\"" << std::endl;
928  #endif
929  }
930 
931  } // endfor: looped over energy parameters
932  } // endfor: looped over detector parameters
933  } // endfor: looped over pointing parameters
934 
935  // Allocate parameter map
936  m_map_size = n_pt * n_det * n_eng;
937  if (m_map_size > 0) {
938  m_map = new int[m_map_size];
939  }
940 
941  // Debug: print size of parameter map in each dimension
942  #if defined(G_DEBUG_SETUP_MODEL)
943  std::cout << "GSPIModelDataSpace::setup_pars: ";
944  std::cout << "allocated parameter map:" << std::endl;
945  std::cout << "- n_pt = " << n_pt << std::endl;
946  std::cout << "- n_det = " << n_det << std::endl;
947  std::cout << "- n_eng = " << n_eng << std::endl;
948  std::cout << "- m_map_size = " << m_map_size << std::endl;
949  #endif
950 
951  // Compute parameter map
952  for (int i_pt = 0; i_pt < n_pt; ++i_pt) {
953  for (int i_det = 0; i_det < n_det; ++i_det) {
954  for (int i_eng = 0; i_eng < n_eng; ++i_eng) {
955 
956  // Compute parameter index, respecting the scheme defined
957  // earlier: energy parameter indices vary the most fastest,
958  // followed by detector parameter indices, followed by
959  // pointing parameter indices
960  int index = pt_indices[i_pt] * ndet * neng +
961  det_indices[i_det] * neng +
962  eng_indices[i_eng];
963 
964  // Compute map index (same as in GSPIEventCube::read_dsp)
965  int i_map = (i_pt * n_det + i_det) * n_eng + i_eng;
966 
967  // Set map value
968  m_map[i_map] = index;
969 
970  // Debug: print mapping
971  #if defined(G_DEBUG_SETUP_MODEL_MAP)
972  std::cout << "- [" << i_pt << "," << i_det << "," << i_eng << "]";
973  std::cout << " = " << index << std::endl;
974  #endif
975 
976  } // endfor: looped over energies
977  } // endfor: looped over detectors
978  } // endfor: looped over pointings
979 
980  // Replace model parameters
981  m_parameters = parameters;
982 
983  // Set pointers
984  set_pointers();
985 
986  } // endif: the model has parameters
987 
988  // Return
989  return;
990 }
991 
992 
993 /***********************************************************************//**
994  * @brief Setup pointing indices
995  *
996  * @param[in] cube Event cube.
997  * @param[in,out] indices Vector of pointing indices.
998  * @param[in,out] names Vector of pointing names.
999  *
1000  * Setup vectors of pointing indices and pointing names. The length of the
1001  * vectors correspond to the number of pointings in the observation.
1002  ***************************************************************************/
1004  std::vector<int>* indices,
1005  std::vector<std::string>* names)
1006 {
1007  // Convert method to lower case
1008  std::string method = gammalib::tolower(m_method);
1009 
1010  // Search for "point"
1011  if (gammalib::contains(method, "point")) {
1012  setup_point(cube, indices, names);
1013  }
1014 
1015  // Search for "orbit"
1016  else if (gammalib::contains(method, "orbit")) {
1017  setup_orbit(cube, indices, names);
1018  }
1019 
1020  // Search for "date"
1021  else if (gammalib::contains(method, "date")) {
1022  double time = get_date_time(method);
1023  setup_date(cube, indices, names, time);
1024  }
1025 
1026  // Handle "gedfail"
1027  if (gammalib::contains(method, "gedfail")) {
1028  add_gedfail(cube, indices, names);
1029  }
1030 
1031  // Handle "gedanneal"
1032  if (gammalib::contains(method, "gedanneal")) {
1033  add_gedanneal(cube, indices, names);
1034  }
1035 
1036  // Return
1037  return;
1038 }
1039 
1040 
1041 /***********************************************************************//**
1042  * @brief Setup detector indices
1043  *
1044  * @param[in] cube Event cube.
1045  * @param[in,out] indices Vector of detector indices.
1046  * @param[in,out] names Vector of detector names.
1047  *
1048  * Setup vectors of detector indices and detector names. The length of the
1049  * vectors correspond to the number of detectors in the observation.
1050  ***************************************************************************/
1052  std::vector<int>* indices,
1053  std::vector<std::string>* names)
1054 {
1055  // Convert method to lower case
1056  std::string method = gammalib::tolower(m_method);
1057 
1058  // Search for "dete"
1059  if (gammalib::contains(method, "dete")) {
1060  setup_dete(cube, indices, names);
1061  }
1062 
1063  // Search for "evtclass"
1064  else if (gammalib::contains(method, "evtclass")) {
1065  setup_evtclass(cube, indices, names);
1066  }
1067 
1068  // Return
1069  return;
1070 }
1071 
1072 
1073 /***********************************************************************//**
1074  * @brief Setup energy indices
1075  *
1076  * @param[in] cube Event cube.
1077  * @param[in,out] indices Vector of energy indices.
1078  * @param[in,out] names Vector of energy names.
1079  *
1080  * Setup vectors of energy indices and energy names. The length of the
1081  * vectors correspond to the number of energies in the observation.
1082  ***************************************************************************/
1084  std::vector<int>* indices,
1085  std::vector<std::string>* names)
1086 {
1087  // Convert method to lower case
1088  std::string method = gammalib::tolower(m_method);
1089 
1090  // Search for "ebin"
1091  if (gammalib::contains(method, "ebin")) {
1092  setup_ebin(cube, indices, names);
1093  }
1094 
1095  // Return
1096  return;
1097 }
1098 
1099 
1100 /***********************************************************************//**
1101  * @brief Setup pointing indices and names for "point" method
1102  *
1103  * @param[in] cube Event cube.
1104  * @param[in,out] indices Vector of pointing indices.
1105  * @param[in,out] names Vector of pointing names.
1106  *
1107  * Setup vectors of pointing indices and names for "point" method.
1108  ***************************************************************************/
1110  std::vector<int>* indices,
1111  std::vector<std::string>* names)
1112 {
1113  // Get number of detectors
1114  int npt = indices->size();
1115 
1116  // Setup index vector
1117  for (int ipt = 0; ipt < npt; ++ipt) {
1118  (*indices)[ipt] = ipt;
1119  names->push_back("P" + gammalib::str(ipt, "%6.6d"));
1120  }
1121 
1122  // Return
1123  return;
1124 }
1125 
1126 
1127 /***********************************************************************//**
1128  * @brief Setup pointing indices and names for "orbit" method
1129  *
1130  * @param[in] cube Event cube.
1131  * @param[in,out] indices Vector of pointing indices.
1132  * @param[in,out] names Vector of pointing names.
1133  *
1134  * Setup vectors of pointing indices and names for "orbit" method.
1135  ***************************************************************************/
1137  std::vector<int>* indices,
1138  std::vector<std::string>* names)
1139 {
1140  // Allocate orbit strings
1141  std::vector<std::string> orbits;
1142 
1143  // Get number of pointings
1144  int npt = indices->size();
1145 
1146  // Loop over all pointings
1147  for (int ipt = 0; ipt < npt; ++ipt) {
1148 
1149  // Initialise index
1150  int index = -1;
1151 
1152  // Get orbit
1153  std::string orbit = cube->ptid(ipt).substr(0,4);
1154 
1155  // If orbit is in orbits then store the location of the string
1156  // in the vector as parameter index.
1157  for (int i = 0; i < orbits.size(); ++i) {
1158  if (orbit == orbits[i]) {
1159  index = i;
1160  break;
1161  }
1162  }
1163 
1164  // If orbit is not yet in vector then
1165  if (index == -1) {
1166  index = orbits.size();
1167  orbits.push_back(orbit);
1168  names->push_back("O" + orbit);
1169  }
1170 
1171  // Store index
1172  (*indices)[ipt] = index;
1173 
1174  } // endfor: looped over pointings
1175 
1176  // Return
1177  return;
1178 }
1179 
1180 
1181 /***********************************************************************//**
1182  * @brief Setup pointing indices and names for "date" method
1183  *
1184  * @param[in] cube Event cube.
1185  * @param[in,out] indices Vector of pointing indices.
1186  * @param[in,out] names Vector of pointing names.
1187  * @param[in] time Time scale in seconds.
1188  *
1189  * Setup vectors of pointing indices and names for "date" method.
1190  ***************************************************************************/
1192  std::vector<int>* indices,
1193  std::vector<std::string>* names,
1194  const double& time)
1195 {
1196  // Compute start time, number of time bins and length of time bin in
1197  // seconds
1198  double tstart = cube->gti().tstart().secs();
1199  double tbin = cube->gti().telapse();
1200  int nbins = int(tbin / time + 0.5);
1201  if (nbins < 1) {
1202  nbins = 1;
1203  }
1204  tbin /= double(nbins);
1205 
1206  // Get number of pointings
1207  int npt = indices->size();
1208 
1209  // Loop over all pointings
1210  for (int ipt = 0; ipt < npt; ++ipt) {
1211 
1212  // Get time of pointing in seconds
1213  double t = 0.5 * (cube->gti().tstart(ipt).secs() +
1214  cube->gti().tstop(ipt).secs());
1215 
1216  // Compute grouping index. Make sure that it is in valid range.
1217  int index = int((t - tstart) / tbin);
1218  if (index < 0) {
1219  index = 0;
1220  }
1221  else if (index >= nbins) {
1222  index = nbins - 1;
1223  }
1224 
1225  // Store index
1226  (*indices)[ipt] = index;
1227 
1228  } // endfor: looped over indices
1229 
1230  // Remove unused indices
1231  for (int index = 0, used_index = 0; index < nbins; ++index) {
1232 
1233  // Replace all indices "index" by "used_index"
1234  int nindex = 0;
1235  for (int ipt = 0; ipt < npt; ++ipt) {
1236  if ((*indices)[ipt] == index) {
1237  (*indices)[ipt] = used_index;
1238  nindex++;
1239  }
1240  }
1241 
1242  // If we found indices to replace then add an index name and
1243  // increase "used_index"
1244  if (nindex > 0) {
1245 
1246  // Add date to names
1247  names->push_back("T" + gammalib::str(used_index, "%6.6d"));
1248 
1249  // Increment used index
1250  used_index++;
1251 
1252  } // endif: index was used
1253 
1254  } // endfor: looped over all pointings
1255 
1256  // Return
1257  return;
1258 }
1259 
1260 
1261 /***********************************************************************//**
1262  * @brief Modify pointing indices and names for "gedfail" method
1263  *
1264  * @param[in] cube Event cube.
1265  * @param[in,out] indices Vector of pointing indices.
1266  * @param[in,out] names Vector of pointing names.
1267  *
1268  * Inserts additional model parameters for each pointing where a detector
1269  * failure occured.
1270  ***************************************************************************/
1272  std::vector<int>* indices,
1273  std::vector<std::string>* names)
1274 {
1275  // Set detector failure times
1277 
1278  // Split pointings for all detector failures
1279  for (int i = 0; i < times.size(); ++i) {
1280  split_pointing_indices(cube, indices, names, times[i], "F");
1281  }
1282 
1283  // Return
1284  return;
1285 }
1286 
1287 
1288 /***********************************************************************//**
1289  * @brief Modify pointing indices and names for "gedanneal" method
1290  *
1291  * @param[in] cube Event cube.
1292  * @param[in,out] indices Vector of pointing indices.
1293  * @param[in,out] names Vector of pointing names.
1294  *
1295  * Inserts additional model parameters for each pointing where a detector
1296  * annealing occured.
1297  ***************************************************************************/
1299  std::vector<int>* indices,
1300  std::vector<std::string>* names)
1301 {
1302  // Set detector annealing start times
1304 
1305  // Split pointings for all detector annealings
1306  for (int i = 0; i < times.size(); ++i) {
1307  split_pointing_indices(cube, indices, names, times[i], "A");
1308  }
1309 
1310  // Return
1311  return;
1312 }
1313 
1314 
1315 /***********************************************************************//**
1316  * @brief Setup detector indices and names for "dete" method
1317  *
1318  * @param[in] cube Event cube.
1319  * @param[in,out] indices Vector of detector indices.
1320  * @param[in,out] names Vector of detector names.
1321  *
1322  * Setup vectors of detector indices and names for "dete" method.
1323  ***************************************************************************/
1325  std::vector<int>* indices,
1326  std::vector<std::string>* names)
1327 {
1328  // Get number of detectors
1329  int ndet = indices->size();
1330 
1331  // Setup index vector
1332  for (int idet = 0; idet < ndet; ++idet) {
1333  (*indices)[idet] = idet;
1334  names->push_back("D" + gammalib::str(idet, "%3.3d"));
1335  }
1336 
1337  // Return
1338  return;
1339 }
1340 
1341 
1342 /***********************************************************************//**
1343  * @brief Setup detector indices and names for "evtclass" method
1344  *
1345  * @param[in] cube Event cube.
1346  * @param[in,out] indices Vector of detector indices.
1347  * @param[in,out] names Vector of detector names.
1348  *
1349  * Setup vectors of detector indices and names for "evtclass" method.
1350  ***************************************************************************/
1352  std::vector<int>* indices,
1353  std::vector<std::string>* names)
1354 {
1355  // Get number of detectors
1356  int ndet = indices->size();
1357 
1358  // Flag which event classes occur in the actual dataset
1359  for (int idet = 0; idet < ndet; ++idet) {
1360 
1361  // Get detector ID for first pointing
1362  int detid = cube->dir(0, idet).detid();
1363 
1364  // Set the corresponding event class flag
1365  if (detid >=0 && detid < 19) {
1366  (*indices)[idet] = 0; // SE
1367  }
1368  else if (detid >= 19 && detid < 61) {
1369  (*indices)[idet] = 1; // ME2
1370  }
1371  else if (detid >= 61 && detid < 85) {
1372  (*indices)[idet] = 2; // ME3
1373  }
1374  else if (detid >= 85 && detid < 104) {
1375  (*indices)[idet] = 3; // PEE
1376  }
1377  else if (detid >= 104 && detid < 123) {
1378  (*indices)[idet] = 4; // PES
1379  }
1380  else if (detid >= 123 && detid < 142) {
1381  (*indices)[idet] = 5; // PEM
1382  }
1383 
1384  } // endfor: looped over all detectors
1385 
1386  // Remove unused indices
1387  for (int index = 0, used_index = 0; index < 6; ++index) {
1388 
1389  // Replace all indices "index" by "used_index"
1390  int nindex = 0;
1391  for (int idet = 0; idet < ndet; ++idet) {
1392  if ((*indices)[idet] == index) {
1393  (*indices)[idet] = used_index;
1394  nindex++;
1395  }
1396  }
1397 
1398  // If we found indices to replace then add an index name and
1399  // increase "used_index"
1400  if (nindex > 0) {
1401 
1402  // Add date to names
1403  names->push_back("C" + gammalib::str(used_index, "%1.1d"));
1404 
1405  // Increment used index
1406  used_index++;
1407 
1408  } // endif: index was used
1409 
1410  } // endfor: looped over all pointings
1411 
1412  // Return
1413  return;
1414 }
1415 
1416 
1417 /***********************************************************************//**
1418  * @brief Setup energy indices and names for "ebin" method
1419  *
1420  * @param[in] cube Event cube.
1421  * @param[in,out] indices Vector of energy indices.
1422  * @param[in,out] names Vector of energy names.
1423  *
1424  * Setup vectors of energy indices and names for "ebin" method.
1425  ***************************************************************************/
1427  std::vector<int>* indices,
1428  std::vector<std::string>* names)
1429 {
1430  // Get number of detectors
1431  int neng = indices->size();
1432 
1433  // Setup index vector
1434  for (int ieng = 0; ieng < neng; ++ieng) {
1435  (*indices)[ieng] = ieng;
1436  names->push_back("E" + gammalib::str(ieng, "%3.3d"));
1437  }
1438 
1439  // Return
1440  return;
1441 }
1442 
1443 
1444 /***********************************************************************//**
1445  * @brief Get time scale from method string
1446  *
1447  * @param[in] method Method string.
1448  * @return Time scale (seconds).
1449  *
1450  * Get the time scale for the "DATE" method from the method string. The
1451  * following time units are supported: min, hour, day, week, month or year.
1452  ***************************************************************************/
1453 double GSPIModelDataSpace::get_date_time(const std::string& method) const
1454 {
1455  // Get position of "date" method in string
1456  size_t start = method.find("date") + 4;
1457 
1458  // Get scale of time
1459  double scale = 0.0;
1460  size_t stop = std::string::npos;
1461  if ((stop = method.find("min", start)) != std::string::npos) {
1462  scale = 60.0;
1463  }
1464  else if ((stop = method.find("hour", start)) != std::string::npos) {
1465  scale = 3600.0;
1466  }
1467  else if ((stop = method.find("day", start)) != std::string::npos) {
1468  scale = 86400.0;
1469  }
1470  else if ((stop = method.find("week", start)) != std::string::npos) {
1471  scale = 604800.0;
1472  }
1473  else if ((stop = method.find("month", start)) != std::string::npos) {
1474  scale = 2628000.0;
1475  }
1476  else if ((stop = method.find("year", start)) != std::string::npos) {
1477  scale = 31536000.0;
1478  }
1479 
1480  // Throw an exception if no time scale was found
1481  if (stop == std::string::npos) {
1482  std::string msg = "Method string \""+method+"\" does not contain "
1483  "time units for \"DATE\" method. Please specify one "
1484  "of the following units: min, hour, day, week, "
1485  "month or year.";
1487  }
1488 
1489  // Get time in seconds
1490  double time = gammalib::todouble(method.substr(start, stop-start)) * scale;
1491 
1492  // Return time
1493  return time;
1494 }
1495 
1496 
1497 /***********************************************************************//**
1498  * @brief Split pointing indices and names at given time
1499  *
1500  * @param[in] cube Event cube.
1501  * @param[in,out] indices Vector of pointing indices.
1502  * @param[in,out] names Vector of pointing names.
1503  * @param[in] time Time of split.
1504  * @param[in] reason Reason for split.
1505  *
1506  * Split the pointing indices at a given time.
1507  ***************************************************************************/
1509  std::vector<int>* indices,
1510  std::vector<std::string>* names,
1511  const GTime& time,
1512  const std::string& reason) const
1513 {
1514  // Get number of pointings
1515  int npt = indices->size();
1516 
1517  // Continue only if there are pointings
1518  if (npt > 0) {
1519 
1520  // Get index of largest pointing group plus one
1521  int igrp_last = 0;
1522  for (int ipt = 0; ipt < npt; ++ipt) {
1523  if ((*indices)[ipt] > igrp_last) {
1524  igrp_last = ipt;
1525  }
1526  }
1527  igrp_last++;
1528 
1529  // Initialise time span of pointing group
1530  int ipt_start = 0;
1531  int ipt_stop = 0;
1532  int igrp_current = (*indices)[ipt_start];
1533  GTime tstart = cube->gti().tstart(ipt_start);
1534  GTime tstop = cube->gti().tstop(ipt_start);
1535 
1536  // Loop over all pointings
1537  for (int ipt = 0; ipt < npt; ++ipt) {
1538 
1539  // If pointing is in same pointing group then update stop
1540  // time
1541  if ((*indices)[ipt] == igrp_current) {
1542  tstop = cube->gti().tstop(ipt);
1543  ipt_stop = ipt;
1544  }
1545 
1546  // If pointing is in different pointing group or the end of
1547  // the pointings has been reached then check whether specified
1548  // time is comprised in the time interval of the pointing
1549  // group. If this is the case and attempt is made to split
1550  // the pointing group into two.
1551  if (((*indices)[ipt] != igrp_current) || (ipt == npt-1)) {
1552 
1553  // If time is comprised within pointing group then split
1554  // pointing group
1555  if ((time > tstart) && (time < tstop)) {
1556 
1557  // Assign a new pointing group index to all pointings
1558  // that have a start time not earlier than the
1559  // specified time
1560  int nnew = 0;
1561  for (int kpt = ipt_start; kpt <= ipt_stop; ++kpt) {
1562  if (cube->gti().tstart(kpt) > time) {
1563  (*indices)[kpt] = igrp_last;
1564  nnew++;
1565  }
1566  }
1567 
1568  // If a new pointing group was assigned then add a
1569  // name to the vector and increment the new pointing
1570  // group index
1571  if (nnew > 0) {
1572  igrp_last++;
1573  names->push_back((*names)[igrp_current]+"-"+reason);
1574  }
1575 
1576  } // endif: pointing group splitted
1577 
1578  // Update time span of next pointing group
1579  ipt_start = ipt;
1580  ipt_stop = ipt;
1581  igrp_current = (*indices)[ipt];
1582  tstart = cube->gti().tstart(ipt);
1583  tstop = cube->gti().tstop(ipt);
1584 
1585  } // endif: next pointing group or end encountered
1586 
1587  } // endfor: looped over pointings
1588 
1589  } // endif: there were pointings
1590 
1591  // Return
1592  return;
1593 }
void setup_orbit(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup pointing indices and names for &quot;orbit&quot; method.
GTimes spi_gedfail_times(void)
Return times of detector failures.
Definition: GSPITools.cpp:301
bool contains(const std::string &str, const std::string &substring)
Checks if a substring is in a string.
Definition: GTools.cpp:1342
int * m_map
Parameter map.
void free_members(void)
Delete class members.
Definition: GModel.cpp:672
int m_map_size
Size of parameter map.
const double & factor_gradient(void) const
Return parameter factor gradient.
void split_pointing_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names, const GTime &time, const std::string &reason) const
Split pointing indices and names at given time.
int size(void) const
Return number of times.
Definition: GTimes.hpp:100
const std::string & name(void) const
Return parameter name.
void setup_pointing_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup pointing indices.
std::string print_attributes(void) const
Print model attributes.
Definition: GModel.cpp:770
Interface definition for the model registry class.
double gradient(void) const
Return parameter gradient.
const GSPIInstDir & dir(const int &ipt, const int &idet) const
Return instrument direction.
#define G_EVAL
virtual GSPIModelDataSpace * clone(void) const
Clone instance.
void setup_point(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup pointing indices and names for &quot;point&quot; method.
std::vector< GModelPar > m_parameters
Model parameters.
Abstract interface for the event classes.
Definition: GEvent.hpp:71
XML element node class.
Definition: GXmlElement.hpp:48
void gti(const GGti &gti)
Set Good Time Intervals.
Definition: GEvents.cpp:154
void free_members(void)
Delete class members.
Definition: GModelData.cpp:300
void setup_energy_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup energy indices.
Random number generator class.
Definition: GRan.hpp:44
bool m_has_eval_inx
Definition: GModel.hpp:186
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition: GXmlNode.cpp:586
Time class.
Definition: GTime.hpp:55
Time container class definition.
Gammalib tools definition.
std::string m_method
Fitting method.
#define G_CONSTRUCTOR
void detid(const int &detid)
Set detector identifier.
const int & index(void) const
Return event bin index.
void add_gedanneal(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Modify pointing indices and names for &quot;gedanneal&quot; method.
GTimes spi_annealing_start_times(void)
Return start time of annealing operations.
Definition: GSPITools.cpp:248
virtual GSPIEventCube * mc(const GObservation &obs, GRan &ran) const
Return simulated list of events.
bool is_free(void) const
Signal if parameter is free.
bool has_par(const std::string &name) const
Checks if parameter name exists.
Definition: GModel.cpp:284
virtual void write(GXmlElement &xml) const
Write model into XML element.
virtual double size(void) const
Return size of event bin.
Time container class.
Definition: GTimes.hpp:45
virtual void read(const GXmlElement &xml)
Read model from XML element.
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
Model parameter class interface definition.
int models(void) const
Return number of models.
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
GSPIObservation * m_obs
SPI observation.
void init_members(void)
Initialise class members.
Definition: GModel.cpp:622
INTEGRAL/SPI event bin container class.
void add_gedfail(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Modify pointing indices and names for &quot;gedfail&quot; method.
Model parameter class.
Definition: GModelPar.hpp:87
std::vector< std::string > m_instruments
Instruments to which model applies.
Definition: GModel.hpp:175
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
INTEGRAL/SPI data space model interface definition.
#define G_SETUP_MODEL
const GXmlAttribute * attribute(const int &index) const
Return attribute.
INTEGRAL/SPI data space model.
const std::string & name(void) const
Return parameter name.
Definition: GModel.hpp:261
void free(void)
Free a parameter.
virtual GSPIModelDataSpace & operator=(const GSPIModelDataSpace &model)
Assignment operator.
#define G_GET_DATE_TIME
virtual std::string type(void) const
Return model type.
void clear(void)
Clear parameter.
GSPIModelDataSpace(void)
Void constructor.
Abstract data model class.
Definition: GModelData.hpp:55
virtual GModelData & operator=(const GModelData &model)
Assignment operator.
Definition: GModelData.cpp:125
std::string instruments(void) const
Returns instruments to which model applies.
Definition: GModel.cpp:310
double get_date_time(const std::string &method) const
Get time scale from method string.
GChatter
Definition: GTypemaps.hpp:33
virtual double npred(const GEnergy &obsEng, const GTime &obsTime, const GObservation &obs) const
Return spatially integrated data model.
void copy_members(const GSPIModelDataSpace &model)
Copy class members.
Abstract observation base class.
void free_members(void)
Delete class members.
GModelPar & scale(const int &index)
Returns reference to scale parameter by index.
Definition: GModel.cpp:369
#define G_WRITE
void write_attributes(GXmlElement &xml) const
Write model attributes.
Definition: GModel.cpp:723
void init_members(void)
Initialise class members.
INTEGRAL/SPI observation class.
void setup_model(const GObservation &obs) const
Setup model.
int m_index
Index of model in event bins.
const std::string & ptid(const int &ipt) const
Return pointing identifier.
const GSPIModelDataSpace g_spi_data_space_seed
virtual ~GSPIModelDataSpace(void)
Destructor.
void setup_ebin(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup energy indices and names for &quot;ebin&quot; method.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition: GXmlNode.cpp:640
std::string m_name
Model name.
Definition: GModel.hpp:174
INTEGRAL/SPI observation class definition.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Definition: GModelPar.cpp:229
double value(void) const
Return parameter value.
virtual double eval(const GEvent &event, const GObservation &obs, const bool &gradients=false) const
Evaluate function.
virtual GEvents * events(void)
Return events.
INTEGRAL/SPI event bin class.
Exception handler interface definition.
std::string tolower(const std::string &s)
Convert string to lower case.
Definition: GTools.cpp:955
std::vector< int > m_eval_inx
Definition: GModel.hpp:188
void read_attributes(const GXmlElement &xml)
Read model attributes.
Definition: GModel.cpp:684
virtual int naxis(const int &axis) const
Return number of bins in axis.
int toint(const std::string &arg)
Convert string into integer value.
Definition: GTools.cpp:821
void setup_date(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names, const double &time)
Setup pointing indices and names for &quot;date&quot; method.
Model registry class definition.
void setup_evtclass(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup detector indices and names for &quot;evtclass&quot; method.
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
const double & model(const int &index) const
Return model value.
INTEGRAL/SPI event bin class definition.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print model information.
void setup_pars(GSPIEventCube *cube)
Setup parameters.
Definition of INTEGRAL/SPI tools.
void setup_dete(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup detector indices and names for &quot;dete&quot; method.
void set_pointers(void)
Set pointers.
void init_members(void)
Initialise class members.
Definition: GModelData.cpp:278
virtual void clear(void)
Clear instance.
double todouble(const std::string &arg)
Convert string into double precision value.
Definition: GTools.cpp:926
Class that handles energies in a unit independent way.
Definition: GEnergy.hpp:48
void setup_detector_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup detector indices.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489