GammaLib 2.0.0
Loading...
Searching...
No Matches
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"
38#include "GSPIObservation.hpp"
39#include "GSPIEventBin.hpp"
40#include "GSPITools.hpp"
41
42/* __ Constants __________________________________________________________ */
43
44/* __ Globals ____________________________________________________________ */
46const 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
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();
257 this->GModel::free_members();
258
259 // Initialise members
260 this->GModel::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 ***************************************************************************/
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 ***************************************************************************/
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 ***************************************************************************/
592std::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;
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 ***************************************************************************/
1453double 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}
#define G_WRITE
Exception handler interface definition.
#define G_CONSTRUCTOR
Definition GMatrix.cpp:41
#define G_EVAL
Model parameter class interface definition.
Model registry class definition.
INTEGRAL/SPI event bin class definition.
#define G_SETUP_MODEL
const GSPIModelDataSpace g_spi_data_space_seed
#define G_GET_DATE_TIME
INTEGRAL/SPI data space model interface definition.
INTEGRAL/SPI observation class definition.
Definition of INTEGRAL/SPI tools.
Time container class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
Abstract interface for the event classes.
Definition GEvent.hpp:71
void gti(const GGti &gti)
Set Good Time Intervals.
Definition GEvents.cpp:154
Abstract data model class.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
virtual GModelData & operator=(const GModelData &model)
Assignment operator.
Model parameter class.
Definition GModelPar.hpp:87
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Interface definition for the model registry class.
GModelPar & scale(const int &index)
Returns reference to scale parameter by index.
Definition GModel.cpp:369
std::vector< std::string > m_instruments
Instruments to which model applies.
Definition GModel.hpp:175
std::vector< GModelPar * > m_pars
Pointers to all model parameters.
Definition GModel.hpp:178
void write_attributes(GXmlElement &xml) const
Write model attributes.
Definition GModel.cpp:723
std::string m_name
Model name.
Definition GModel.hpp:174
void free_members(void)
Delete class members.
Definition GModel.cpp:672
void init_members(void)
Initialise class members.
Definition GModel.cpp:622
std::string print_attributes(void) const
Print model attributes.
Definition GModel.cpp:770
std::vector< int > m_eval_inx
Definition GModel.hpp:188
int size(void) const
Return number of parameters in model.
Definition GModel.hpp:233
bool has_par(const std::string &name) const
Checks if parameter name exists.
Definition GModel.cpp:284
std::string instruments(void) const
Returns instruments to which model applies.
Definition GModel.cpp:310
bool m_has_eval_inx
Definition GModel.hpp:186
void read_attributes(const GXmlElement &xml)
Read model attributes.
Definition GModel.cpp:684
const std::string & name(void) const
Return parameter name.
Definition GModel.hpp:261
Abstract observation base class.
virtual GEvents * events(void)
Return events.
bool is_free(void) const
Signal if parameter is free.
void free(void)
Free a parameter.
const double & scale(void) const
Return parameter scale.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
const double & factor_gradient(void) const
Return parameter factor gradient.
double gradient(void) const
Return parameter gradient.
void clear(void)
Clear parameter.
double value(void) const
Return parameter value.
const std::string & name(void) const
Return parameter name.
Random number generator class.
Definition GRan.hpp:44
INTEGRAL/SPI event bin class.
const double & model(const int &index) const
Return model value.
virtual double size(void) const
Return size of event bin.
const int & index(void) const
Return event bin index.
INTEGRAL/SPI event bin container class.
const GSPIInstDir & dir(const int &ipt, const int &idet) const
Return instrument direction.
int models(void) const
Return number of models.
virtual int naxis(const int &axis) const
Return number of bins in axis.
const std::string & ptid(const int &ipt) const
Return pointing identifier.
void detid(const int &detid)
Set detector identifier.
INTEGRAL/SPI data space model.
void setup_evtclass(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup detector indices and names for "evtclass" method.
int * m_map
Parameter map.
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.
double get_date_time(const std::string &method) const
Get time scale from method string.
std::string m_method
Fitting method.
void setup_date(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names, const double &time)
Setup pointing indices and names for "date" method.
void init_members(void)
Initialise class members.
void copy_members(const GSPIModelDataSpace &model)
Copy class members.
void add_gedfail(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Modify pointing indices and names for "gedfail" method.
void setup_model(const GObservation &obs) const
Setup model.
int m_index
Index of model in event bins.
virtual GSPIModelDataSpace & operator=(const GSPIModelDataSpace &model)
Assignment operator.
void setup_detector_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup detector indices.
void setup_energy_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup energy indices.
int m_map_size
Size of parameter map.
virtual GSPIModelDataSpace * clone(void) const
Clone instance.
void add_gedanneal(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Modify pointing indices and names for "gedanneal" method.
void setup_dete(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup detector indices and names for "dete" method.
void free_members(void)
Delete class members.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print model information.
GSPIModelDataSpace(void)
Void constructor.
void setup_pointing_indices(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup pointing indices.
void set_pointers(void)
Set pointers.
virtual double eval(const GEvent &event, const GObservation &obs, const bool &gradients=false) const
Evaluate function.
GSPIObservation * m_obs
SPI observation.
virtual void read(const GXmlElement &xml)
Read model from XML element.
virtual double npred(const GEnergy &obsEng, const GTime &obsTime, const GObservation &obs) const
Return spatially integrated data model.
virtual std::string type(void) const
Return model type.
virtual void clear(void)
Clear instance.
void setup_ebin(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup energy indices and names for "ebin" method.
std::vector< GModelPar > m_parameters
Model parameters.
virtual void write(GXmlElement &xml) const
Write model into XML element.
virtual GSPIEventCube * mc(const GObservation &obs, GRan &ran) const
Return simulated list of events.
void setup_orbit(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup pointing indices and names for "orbit" method.
void setup_point(GSPIEventCube *cube, std::vector< int > *indices, std::vector< std::string > *names)
Setup pointing indices and names for "point" method.
void setup_pars(GSPIEventCube *cube)
Setup parameters.
virtual ~GSPIModelDataSpace(void)
Destructor.
INTEGRAL/SPI observation class.
Time class.
Definition GTime.hpp:55
Time container class.
Definition GTimes.hpp:45
int size(void) const
Return number of times.
Definition GTimes.hpp:100
XML element node class.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition GXmlNode.cpp:287
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition GXmlNode.cpp:640
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition GXmlNode.cpp:586
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition GTools.hpp:184
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition GTools.hpp:201
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
double todouble(const std::string &arg)
Convert string into double precision value.
Definition GTools.cpp:926
std::string tolower(const std::string &s)
Convert string to lower case.
Definition GTools.cpp:955
int toint(const std::string &arg)
Convert string into integer value.
Definition GTools.cpp:821
bool contains(const std::string &str, const std::string &substring)
Checks if a substring is in a string.
Definition GTools.cpp:1342
GTimes spi_annealing_start_times(void)
Return start time of annealing operations.
GTimes spi_gedfail_times(void)
Return times of detector failures.