GammaLib 2.0.0
Loading...
Searching...
No Matches
GModels.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GModels.cpp - Model container class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2009-2021 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 GModels.cpp
23 * @brief Model container class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GTools.hpp"
32#include "GException.hpp"
33#include "GFilename.hpp"
34#include "GModels.hpp"
35#include "GModel.hpp"
36#include "GModelRegistry.hpp"
37#include "GObservation.hpp"
38#include "GVector.hpp"
39#include "GMatrixSparse.hpp"
40#include "GXml.hpp"
41#include "GXmlElement.hpp"
42#include "GOptimizerPars.hpp"
43
44/* __ Method name definitions ____________________________________________ */
45#define G_ACCESS "GModels::operator[](std::string&)"
46#define G_AT "GModels::at(int&)"
47#define G_SET1 "GModels::set(int&, GModel&)"
48#define G_SET2 "GModels::set(std::string&, GModel&)"
49#define G_APPEND "GModels::append(GModel&)"
50#define G_INSERT1 "GModels::insert(int&, GModel&)"
51#define G_INSERT2 "GModels::insert(std::string&, GModel&)"
52#define G_REMOVE1 "GModels::remove(int&)"
53#define G_REMOVE2 "GModels::remove(std::string&)"
54#define G_EXTEND "GModels::extend(GModels&)"
55#define G_READ "GModels::read(GXml&)"
56
57/* __ Macros _____________________________________________________________ */
58
59/* __ Coding definitions _________________________________________________ */
60
61/* __ Debug definitions __________________________________________________ */
62
63
64/*==========================================================================
65 = =
66 = Constructors/destructors =
67 = =
68 ==========================================================================*/
69
70/***********************************************************************//**
71 * @brief Void constructor
72 ***************************************************************************/
74{
75 // Initialise members
77
78 // Return
79 return;
80}
81
82
83/***********************************************************************//**
84 * @brief Copy constructor
85 *
86 * @param[in] models Model container.
87 ***************************************************************************/
89{
90 // Initialise members
92
93 // Copy members
94 copy_members(models);
95
96 // Return
97 return;
98}
99
100
101/***********************************************************************//**
102 * @brief Load constructor
103 *
104 * @param[in] filename XML filename.
105 *
106 * Constructs model container from an XML file. See the read() method for
107 * more information about the expected structure of the XML file.
108 ***************************************************************************/
110{
111 // Initialise members
112 init_members();
113
114 // Load XML file
115 load(filename);
116
117 // Return
118 return;
119}
120
121
122/***********************************************************************//**
123 * @brief Destructor
124 ***************************************************************************/
126{
127 // Free members
128 free_members();
129
130 // Return
131 return;
132}
133
134
135/*==========================================================================
136 = =
137 = Operators =
138 = =
139 ==========================================================================*/
140
141/***********************************************************************//**
142 * @brief Assignment operator
143 *
144 * @param[in] models Model container.
145 * @return Model container.
146 ***************************************************************************/
148{
149 // Execute only if object is not identical
150 if (this != &models) {
151
152 // Free members
153 free_members();
154
155 // Initialise members
156 init_members();
157
158 // Copy members
159 copy_members(models);
160
161 } // endif: object was not identical
162
163 // Return
164 return *this;
165}
166
167
168/***********************************************************************//**
169 * @brief Return pointer to model
170 *
171 * @param[in] name Model name.
172 *
173 * @exception GException::invalid_argument
174 * Model with specified name not found in container.
175 *
176 * Returns a pointer to the model with the specified @p name.
177 ***************************************************************************/
178GModel* GModels::operator[](const std::string& name)
179{
180 // Get model index
181 int index = get_index(name);
182
183 // Throw exception if model name was not found
184 if (index == -1) {
185 std::string msg = "Model \""+name+"\" not found in model container. "
186 "Please specify the name of an available model.";
188 }
189
190 // Return pointer
191 return m_models[index];
192}
193
194
195/***********************************************************************//**
196 * @brief Return pointer to model (const version)
197 *
198 * @param[in] name Model name.
199 *
200 * @exception GException::invalid_argument
201 * Model with specified name not found in container.
202 *
203 * Returns a const pointer to the model with the specified @p name.
204 ***************************************************************************/
205const GModel* GModels::operator[](const std::string& name) const
206{
207 // Get model index
208 int index = get_index(name);
209
210 // Throw exception if model name was not found
211 if (index == -1) {
212 std::string msg = "Model \""+name+"\" not found in model container. "
213 "Please specify the name of an available model.";
215 }
216
217 // Return pointer
218 return m_models[index];
219}
220
221
222/*==========================================================================
223 = =
224 = Public methods =
225 = =
226 ==========================================================================*/
227
228/***********************************************************************//**
229 * @brief Clear object
230 *
231 * Removes all models from the container.
232 ***************************************************************************/
234{
235 // Free class members (base and derived classes, derived class first)
236 free_members();
237
238 // Initialise members
239 init_members();
240
241 // Return
242 return;
243}
244
245
246/***********************************************************************//**
247 * @brief Clone instance
248 *
249 * @return Pointer to deep copy of model container
250 *
251 * Makes a deep copy of the model container instance.
252 ***************************************************************************/
254{
255 return new GModels(*this);
256}
257
258
259/***********************************************************************//**
260 * @brief Return pointer to model
261 *
262 * @param[in] index Model index [0,...,size()-1].
263 *
264 * @exception GException::out_of_range
265 * Model index is out of range.
266 *
267 * Returns a pointer to the model with the specified @p index.
268 ***************************************************************************/
269GModel* GModels::at(const int& index)
270{
271 // Compile option: raise an exception if index is out of range
272 #if defined(G_RANGE_CHECK)
273 if (index < 0 || index >= size()) {
274 throw GException::out_of_range(G_AT, "Model index", index, size());
275 }
276 #endif
277
278 // Return pointer
279 return m_models[index];
280}
281
282
283/***********************************************************************//**
284 * @brief Return pointer to model (const version)
285 *
286 * @param[in] index Model index [0,...,size()-1].
287 *
288 * @exception GException::out_of_range
289 * Model index is out of range.
290 *
291 * Returns a const pointer to the model with the specified @p index.
292 ***************************************************************************/
293const GModel* GModels::at(const int& index) const
294{
295 // Compile option: raise an exception if index is out of range
296 #if defined(G_RANGE_CHECK)
297 if (index < 0 || index >= size()) {
298 throw GException::out_of_range(G_AT, "Model index", index, size());
299 }
300 #endif
301
302 // Return pointer
303 return m_models[index];
304}
305
306
307/***********************************************************************//**
308 * @brief Set model in container
309 *
310 * @param[in] index Model index [0,...,size()[.
311 * @param[in] model Model.
312 * @return Pointer to deep copy of model.
313 *
314 * @exception GException::out_of_range
315 * Model index is out of range.
316 * @exception GException::invalid_value
317 * Name of model exists already in container.
318 *
319 * Set model in the container. A deep copy of the model will be made.
320 ***************************************************************************/
321GModel* GModels::set(const int& index, const GModel& model)
322{
323 // Compile option: raise exception if index is out of range
324 #if defined(G_RANGE_CHECK)
325 if (index < 0 || index >= size()) {
326 throw GException::out_of_range(G_SET1, "Model index", index, size());
327 }
328 #endif
329
330 // Check if a model with specified name does not yet exist
331 int inx = get_index(model.name());
332 if (inx != -1 && inx != index) {
333 std::string msg =
334 "Attempt to set model with name \""+model.name()+"\" in model "
335 "container at index "+gammalib::str(index)+", but a model with "
336 "the same name exists already at index "+gammalib::str(inx)+
337 " in the container. Every model in the model container needs a "
338 "unique name.";
340 }
341
342 // Free existing model only if it differs from current model. This
343 // prevents unintential deallocation of the argument
344 if ((m_models[index] != NULL) && (m_models[index] != &model)) {
345 delete m_models[index];
346 }
347
348 // Assign new model by cloning
349 m_models[index] = model.clone();
350
351 // Return pointer to model
352 return m_models[index];
353}
354
355
356/***********************************************************************//**
357 * @brief Set model in container
358 *
359 * @param[in] name Model name.
360 * @param[in] model Model pointer.
361 * @return Pointer to deep copy of model.
362 *
363 * @exception GException::invalid_argument
364 * Model with specified name not found in container.
365 * @exception GException::invalid_value
366 * Name of model exists already in container.
367 *
368 * Set model in the container. A deep copy of the model will be made.
369 ***************************************************************************/
370GModel* GModels::set(const std::string& name, const GModel& model)
371{
372 // Get parameter index
373 int index = get_index(name);
374
375 // Throw exception if parameter name was not found
376 if (index == -1) {
377 std::string msg = "Model \""+name+"\" not found in model container. "
378 "Please specify the name of an available model.";
380 }
381
382 // Check if a model with specified name does not yet exist
383 int inx = get_index(model.name());
384 if (inx != -1 && inx != index) {
385 std::string msg =
386 "Attempt to set model with name \""+model.name()+"\" in model"
387 " container at index "+gammalib::str(index)+", but a model with"
388 " the same name exists already at index "+gammalib::str(inx)+
389 " in the container.\n"
390 "Every model in the model container needs a unique name.";
392 }
393
394 // Free existing model only if it differs from current model. This
395 // prevents unintential deallocation of the argument
396 if ((m_models[index] != NULL) && (m_models[index] != &model)) {
397 delete m_models[index];
398 }
399
400 // Assign new model by cloning
401 m_models[index] = model.clone();
402
403 // Return pointer to model
404 return m_models[index];
405}
406
407
408/***********************************************************************//**
409 * @brief Append model to container
410 *
411 * @param[in] model Model.
412 * @return Pointer to deep copy of model.
413 *
414 * @exception GException::invalid_value
415 * Name of model exists already in container.
416 *
417 * Appends model to the container by making a deep copy of the model and
418 * storing its pointer.
419 ***************************************************************************/
421{
422 // Check if a model with specified name does not yet exist
423 int inx = get_index(model.name());
424 if (inx != -1) {
425 std::string msg =
426 "Attempt to append model with name \""+model.name()+"\" to model"
427 " container, but a model with the same name exists already at"
428 " index "+gammalib::str(inx)+" in the container."
429 " Every model in the model container needs a unique name.";
431 }
432
433 // Create deep copy of model
434 GModel* ptr = model.clone();
435
436 // Append deep copy of model
437 m_models.push_back(ptr);
438
439 // Return pointer to model
440 return ptr;
441}
442
443
444/***********************************************************************//**
445 * @brief Insert model into container
446 *
447 * @param[in] index Model index [0,...,size()[.
448 * @param[in] model Model.
449 * @return Pointer to deep copy of model.
450 *
451 * @exception GException::out_of_range
452 * Model index is out of range.
453 * @exception GException::invalid_value
454 * Name of model exists already in container.
455 *
456 * Inserts a @p model into the container before the model with the specified
457 * @p index.
458 ***************************************************************************/
459GModel* GModels::insert(const int& index, const GModel& model)
460{
461 // Compile option: raise exception if index is out of range
462 #if defined(G_RANGE_CHECK)
463 if (is_empty()) {
464 if (index > 0) {
465 throw GException::out_of_range(G_INSERT1, "Model index",
466 index, size());
467 }
468 }
469 else {
470 if (index < 0 || index >= size()) {
471 throw GException::out_of_range(G_INSERT1, "Model index",
472 index, size());
473 }
474 }
475 #endif
476
477 // Check if a model with specified name does not yet exist
478 int inx = get_index(model.name());
479 if (inx != -1) {
480 std::string msg =
481 "Attempt to insert model with name \""+model.name()+"\" in model"
482 " container before index "+gammalib::str(index)+", but a model"
483 " with the same name exists already at index "+gammalib::str(inx)+
484 " in the container.\n"
485 "Every model in the model container needs a unique name.";
487 }
488
489 // Create deep copy of model
490 GModel* ptr = model.clone();
491
492 // Inserts deep copy of model
493 m_models.insert(m_models.begin()+index, ptr);
494
495 // Return pointer to model
496 return ptr;
497}
498
499
500/***********************************************************************//**
501 * @brief Insert model into container
502 *
503 * @param[in] name Model name.
504 * @param[in] model Model.
505 * @return Pointer to deep copy of model.
506 *
507 * @exception GException::invalid_argument
508 * Model with specified name not found in container.
509 * @exception GException::invalid_value
510 * Name of model exists already in container.
511 *
512 * Inserts a @p model into the container before the model with the specified
513 * @p name.
514 ***************************************************************************/
515GModel* GModels::insert(const std::string& name, const GModel& model)
516{
517 // Get parameter index
518 int index = get_index(name);
519
520 // Throw exception if parameter name was not found
521 if (index == -1) {
522 std::string msg = "Model \""+name+"\" not found in model container. "
523 "Please specify the name of an available model.";
525 }
526
527 // Check if a model with specified name does not yet exist
528 int inx = get_index(model.name());
529 if (inx != -1) {
530 std::string msg =
531 "Attempt to insert model with name \""+model.name()+"\" in model"
532 " container before index "+gammalib::str(index)+", but a model"
533 " with the same name exists already at index "+gammalib::str(inx)+
534 " in the container.\n"
535 "Every model in the model container needs a unique name.";
537 }
538
539 // Create deep copy of model
540 GModel* ptr = model.clone();
541
542 // Inserts deep copy of model
543 m_models.insert(m_models.begin()+index, ptr);
544
545 // Return pointer to model
546 return ptr;
547}
548
549
550/***********************************************************************//**
551 * @brief Remove model from container
552 *
553 * @param[in] index Model index [0,...,size()[.
554 *
555 * @exception GException::out_of_range
556 * Model index is out of range.
557 *
558 * Remove model of specified @p index from container.
559 ***************************************************************************/
560void GModels::remove(const int& index)
561{
562 // Compile option: raise exception if index is out of range
563 #if defined(G_RANGE_CHECK)
564 if (index < 0 || index >= size()) {
565 throw GException::out_of_range(G_REMOVE1, "Model index",
566 index, size());
567 }
568 #endif
569
570 // Delete model
571 delete m_models[index];
572
573 // Erase model component from container
574 m_models.erase(m_models.begin() + index);
575
576 // Return
577 return;
578}
579
580
581/***********************************************************************//**
582 * @brief Remove model from container
583 *
584 * @param[in] name Model name.
585 *
586 * @exception GException::invalid_argument
587 * Model with specified name not found in container.
588 *
589 * Remove model of specified @p name from container.
590 ***************************************************************************/
591void GModels::remove(const std::string& name)
592{
593 // Get parameter index
594 int index = get_index(name);
595
596 // Throw exception if parameter name was not found
597 if (index == -1) {
598 std::string msg = "Model \""+name+"\" not found in model container. "
599 "Please specify the name of an available model.";
601 }
602
603 // Delete model
604 delete m_models[index];
605
606 // Erase model component from container
607 m_models.erase(m_models.begin() + index);
608
609 // Return
610 return;
611}
612
613
614/***********************************************************************//**
615 * @brief Append model container
616 *
617 * @param[in] models Model container.
618 *
619 * Append model container to the container.
620 ***************************************************************************/
621void GModels::extend(const GModels& models)
622{
623 // Do nothing if model container is empty
624 if (!models.is_empty()) {
625
626 // Get size. Note that we extract the size first to avoid an
627 // endless loop that arises when a container is appended to
628 // itself.
629 int num = models.size();
630
631 // Reserve enough space
632 reserve(size() + num);
633
634 // Loop over all model components and append pointers to deep copies
635 for (int i = 0; i < num; ++i) {
636
637 // Check if model name does not yet exist
638 int inx = get_index(models[i]->name());
639 if (inx != -1) {
640 std::string msg =
641 "Attempt to append model with name \""+models[i]->name()+
642 "\" to model container, but a model with the same name"
643 " exists already at index "+gammalib::str(inx)+" in the"
644 " container.\n"
645 "Every model in the model container needs a unique name.";
647 }
648
649 // Append model to container
650 m_models.push_back(models[i]->clone());
651
652 } // endfor: looped over all models
653
654 } // endif: model container was not empty
655
656 // Return
657 return;
658}
659
660
661/***********************************************************************//**
662 * @brief Signals if model name exists
663 *
664 * @param[in] name Model name.
665 * @return True if model with specified @p name exists.
666 *
667 * Searches all model names for a match with the specified @p name. If the
668 * specified name has been found, true is returned.
669 ***************************************************************************/
670bool GModels::contains(const std::string& name) const
671{
672 // Get model index
673 int index = get_index(name);
674
675 // Return
676 return (index != -1);
677}
678
679
680/***********************************************************************//**
681 * @brief Load models from XML file
682 *
683 * @param[in] filename XML filename.
684 *
685 * Loads all models from an XML file. See the read() method for more
686 * information about the expected structure of the XML file.
687 ***************************************************************************/
688void GModels::load(const GFilename& filename)
689{
690 // Clear any existing models
691 clear();
692
693 // Load XML document
694 GXml xml(filename.url());
695
696 // Read models from XML document
697 read(xml);
698
699 // Return
700 return;
701}
702
703
704/***********************************************************************//**
705 * @brief Save models into XML file
706 *
707 * @param[in] filename XML filename.
708 *
709 * Saves all models in the container into an XML file.
710 ***************************************************************************/
711void GModels::save(const GFilename& filename) const
712{
713 // Declare empty XML document
714 GXml xml;
715
716 // Append source library element
717 GXmlNode* lib =
718 xml.append(GXmlElement("source_library title=\"source library\""));
719
720 // Write all sources into library.
721 for (int i = 0; i < size(); ++i) {
722
723 // Allocate XML element
724 GXmlElement source;
725
726 // Write model into XML element
727 m_models[i]->write(source);
728
729 // Append source to source library. Since write appends only a
730 // single source we can just access the first element in the
731 // source node.
732 lib->append(*source.element(0));
733
734 } // endfor: looped over sources
735
736 // Write models into XML file
737 //write(xml);
738
739 // Save XML document
740 xml.save(filename);
741
742 // Return
743 return;
744}
745
746
747/***********************************************************************//**
748 * @brief Read models from XML document
749 *
750 * @param[in] xml XML document.
751 *
752 * @exception GException::invalid_value
753 * Invalid model type encountered.
754 *
755 * Read models from the first source library found in the XML document. The
756 * XML document is expected to have the following structure
757 *
758 * <source_library title="source library">
759 * <source name="Source1" type="PointSource">
760 * ...
761 * </source>
762 * <source name="Source2" type="DiffuseSource">
763 * ...
764 * </source>
765 * </source_library>
766 *
767 * Each @p source tag will be interpreted as a model component.
768 *
769 * @todo Sources names are not verified so far for uniqueness. This would be
770 * required to achieve an unambiguous update of parameters in an already
771 * existing XML file when using the write method.
772 ***************************************************************************/
773void GModels::read(const GXml& xml)
774{
775 // Get pointer on source library
776 const GXmlElement* lib = xml.element("source_library", 0);
777
778 // Loop over all sources
779 int n = lib->elements("source");
780 for (int i = 0; i < n; ++i) {
781
782 // Get pointer on source
783 const GXmlElement* src = lib->element("source", i);
784
785 // Get model type
786 std::string type = src->attribute("type");
787
788 // Get model
789 GModelRegistry registry;
790 GModel* ptr = registry.alloc(type);
791
792 // If model if valid then read model from XML file
793 if (ptr != NULL) {
794 ptr->read(*src);
795 }
796
797 // ... otherwise throw an exception
798 else {
799 std::string msg = "Model type \""+type+"\" unknown. The following "
800 "model types are available: "+registry.content()+
801 ". Please specify one of the available model "
802 "types.";
804 }
805
806 // Append model
807 append(*ptr);
808
809 // Free model (appending clones the model)
810 delete ptr;
811
812 } // endfor: looped over all sources
813
814 // Return
815 return;
816}
817
818
819/***********************************************************************//**
820 * @brief Write models into XML document
821 *
822 * @param[in] xml XML document.
823 *
824 * Write models into the first source library that is found in the XML
825 * document. In case that no source library exists, one is added to the
826 * document.
827 ***************************************************************************/
828void GModels::write(GXml& xml) const
829{
830 // If there is no source library then append one
831 if (xml.elements("source_library") == 0) {
832 xml.append(GXmlElement("source_library title=\"source library\""));
833 }
834
835 // Get pointer on source library
836 GXmlElement* lib = xml.element("source_library", 0);
837
838 // Write all sources into library
839 for (int i = 0; i < size(); ++i) {
840 m_models[i]->write(*lib);
841 }
842
843 // Return
844 return;
845}
846
847
848/***********************************************************************//**
849 * @brief Return number of model parameters in container
850 *
851 * @return Number of model parameters in container.
852 ***************************************************************************/
853int GModels::npars(void) const
854{
855 // Initialise number of parameters
856 int npars = 0;
857
858 // Sum of number of parameters in model
859 for (int i = 0; i < size(); ++i) {
860 npars += m_models[i]->size();
861 }
862
863 // Return
864 return npars;
865}
866
867
868/***********************************************************************//**
869 * @brief Return optimizer parameter container
870 *
871 * @return Optimizer parameter container.
872 *
873 * Returns an optimizer parameter container that is built by extracting
874 * all model pointers from the model and attaching them to the parameter
875 * container. The optimizer parameter container will thus contains a flat
876 * array of a model parameters.
877 ***************************************************************************/
879{
880 // Initialise parameter container
882
883 // Attach all parameters
884 for (int i = 0; i < size(); ++i) {
885 GModel* model = m_models[i];
886 int npars = model->size();
887 for (int k = 0; k < npars; ++k) {
888 pars.attach(&((*model)[k]));
889 }
890 }
891
892 // Return
893 return pars;
894}
895
896
897/***********************************************************************//**
898 * @brief Evaluate sum of all models
899 *
900 * @param[in] event Observed event.
901 * @param[in] obs Observation.
902 * @param[in] gradients Compute gradients?
903 * @return Value of models.
904 *
905 * Evaluates the sum of all models for the specified event and observation.
906 * Only valid models are considered in this evaluation.
907 *
908 * If the @p gradients flag is true the method will also set the parameter
909 * gradients of the model parameters.
910 ***************************************************************************/
911double GModels::eval(const GEvent& event,
912 const GObservation& obs,
913 const bool& gradients) const
914{
915 // Initialise model value
916 double value = 0.0;
917
918 // Evaluate function for all models
919 for (int i = 0; i < size(); ++i) {
920 if (m_models[i]->is_valid(obs.instrument(), obs.id())) {
921 value += m_models[i]->eval(event, obs, gradients);
922 }
923 }
924
925 // Return model value
926 return value;
927}
928
929
930/***********************************************************************//**
931 * @brief Evaluate sum vector of all models
932 *
933 * @param[in] obs Observation.
934 * @param[in] gradients Pointer to gradients matrix.
935 * @return Vector of model values.
936 *
937 * Evaluates the sum vector of all models for all events in the observation.
938 * Only valid models are considered in this evaluation.
939 *
940 * If the @p gradients pointer is not NULL the method will fill the
941 * corresponding matrix with the parameter gradients of the model.
942 ***************************************************************************/
944 GMatrixSparse* gradients) const
945{
946 // Get number of events
947 int nevents = obs.events()->size();
948
949 // Initialise model sum
950 GVector values(nevents);
951
952 // Evaluate function for all models
953 for (int i = 0; i < size(); ++i) {
954 if (m_models[i]->is_valid(obs.instrument(), obs.id())) {
955 values += m_models[i]->eval(obs, gradients);
956 }
957 }
958
959 // Return model values
960 return values;
961}
962
963
964/***********************************************************************//**
965 * @brief Print models
966 *
967 * @param[in] chatter Chattiness.
968 * @return String containing model container information.
969 *
970 * Prints all models into a string.
971 ***************************************************************************/
972std::string GModels::print(const GChatter& chatter) const
973{
974 // Initialise result string
975 std::string result;
976
977 // Continue only if chatter is not silent
978 if (chatter != SILENT) {
979
980 // Append header
981 result.append("=== GModels ===");
982
983 // Append information
984 result.append("\n"+gammalib::parformat("Number of models"));
985 result.append(gammalib::str(size()));
986 result.append("\n"+gammalib::parformat("Number of parameters"));
987 result.append(gammalib::str(npars()));
988
989 // Append models
990 for (int i = 0; i < size(); ++i) {
991 result.append("\n"+m_models[i]->print(chatter));
992 }
993
994 } // endif: chatter was not silent
995
996 // Return result
997 return result;
998}
999
1000
1001/*==========================================================================
1002 = =
1003 = Private methods =
1004 = =
1005 ==========================================================================*/
1006
1007/***********************************************************************//**
1008 * @brief Initialise class members
1009 ***************************************************************************/
1011{
1012 // Initialise members
1013 m_models.clear();
1014
1015 // Return
1016 return;
1017}
1018
1019
1020/***********************************************************************//**
1021 * @brief Copy class members
1022 *
1023 * @param[in] models Model container.
1024 *
1025 * Makes a copy of all class members. All models are deep copied, and the
1026 * linear pointer array for parameter access through the GOptimizerPars
1027 * base class is set.
1028 ***************************************************************************/
1030{
1031 // Copy models
1032 m_models.clear();
1033 for (int i = 0; i < models.m_models.size(); ++i) {
1034 m_models.push_back((models.m_models[i]->clone()));
1035 }
1036
1037 // Return
1038 return;
1039}
1040
1041
1042/***********************************************************************//**
1043 * @brief Delete class members
1044 *
1045 * Deallocates all models. The method loops over the model container and
1046 * deallocates the memory that has been allocated before.
1047 ***************************************************************************/
1049{
1050 // Free models
1051 for (int i = 0; i < m_models.size(); ++i) {
1052 delete m_models[i];
1053 m_models[i] = NULL;
1054 }
1055
1056 // Return
1057 return;
1058}
1059
1060
1061/***********************************************************************//**
1062 * @brief Return model index by name
1063 *
1064 * @param[in] name Model name.
1065 * @return Model index (-1 if model name has not been found)
1066 *
1067 * Returns model index based on the specified @p name. If no model with the
1068 * specified @p name is found the method returns -1.
1069 ***************************************************************************/
1070int GModels::get_index(const std::string& name) const
1071{
1072 // Initialise index
1073 int index = -1;
1074
1075 // Search model with specified name
1076 for (int i = 0; i < size(); ++i) {
1077 if (m_models[i]->name() == name) {
1078 index = i;
1079 break;
1080 }
1081 }
1082
1083 // Return index
1084 return index;
1085}
#define G_AT
#define G_REMOVE1
#define G_READ
#define G_INSERT2
#define G_APPEND
#define G_INSERT1
#define G_REMOVE2
#define G_EXTEND
#define G_ACCESS
Exception handler interface definition.
Filename class interface definition.
#define G_SET1
Definition GFits.cpp:57
#define G_SET2
Definition GFits.cpp:58
Sparse matrix class definition.
Model registry class definition.
Abstract model base class interface definition.
Model container class definition.
Abstract observation base class interface definition.
Optimizer parameters base class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Vector class interface definition.
XML element node class interface definition.
XML class interface definition.
Abstract interface for the event classes.
Definition GEvent.hpp:71
virtual int size(void) const =0
Filename class.
Definition GFilename.hpp:62
std::string url(void) const
Return Uniform Resource Locator (URL)
Sparse matrix class interface definition.
Interface definition for the model registry class.
GModel * alloc(const std::string &name) const
Allocate model of given name.
Abstract model class.
Definition GModel.hpp:100
virtual void read(const GXmlElement &xml)=0
int size(void) const
Return number of parameters in model.
Definition GModel.hpp:233
virtual GModel * clone(void) const =0
Clones object.
const std::string & name(void) const
Return parameter name.
Definition GModel.hpp:261
Model container class.
Definition GModels.hpp:152
void save(const GFilename &filename) const
Save models into XML file.
Definition GModels.cpp:711
GModel * insert(const int &index, const GModel &model)
Insert model into container.
Definition GModels.cpp:459
bool contains(const std::string &name) const
Signals if model name exists.
Definition GModels.cpp:670
bool is_empty(void) const
Signals if there are no models in container.
Definition GModels.hpp:273
void free_members(void)
Delete class members.
Definition GModels.cpp:1048
GModel * at(const int &index)
Return pointer to model.
Definition GModels.cpp:269
void clear(void)
Clear object.
Definition GModels.cpp:233
void load(const GFilename &filename)
Load models from XML file.
Definition GModels.cpp:688
GOptimizerPars pars(void) const
Return optimizer parameter container.
Definition GModels.cpp:878
int get_index(const std::string &name) const
Return model index by name.
Definition GModels.cpp:1070
void write(GXml &xml) const
Write models into XML document.
Definition GModels.cpp:828
GModels(void)
Void constructor.
Definition GModels.cpp:73
GModels & operator=(const GModels &models)
Assignment operator.
Definition GModels.cpp:147
int size(void) const
Return number of models in container.
Definition GModels.hpp:259
GModel * set(const int &index, const GModel &model)
Set model in container.
Definition GModels.cpp:321
std::vector< GModel * > m_models
List of models.
Definition GModels.hpp:207
GModels * clone(void) const
Clone instance.
Definition GModels.cpp:253
GModel * operator[](const int &index)
Return pointer to model.
Definition GModels.hpp:231
void read(const GXml &xml)
Read models from XML document.
Definition GModels.cpp:773
int npars(void) const
Return number of model parameters in container.
Definition GModels.cpp:853
void remove(const int &index)
Remove model from container.
Definition GModels.cpp:560
std::string print(const GChatter &chatter=NORMAL) const
Print models.
Definition GModels.cpp:972
double eval(const GEvent &event, const GObservation &obs, const bool &gradients=false) const
Evaluate sum of all models.
Definition GModels.cpp:911
GModel * append(const GModel &model)
Append model to container.
Definition GModels.cpp:420
void init_members(void)
Initialise class members.
Definition GModels.cpp:1010
virtual ~GModels(void)
Destructor.
Definition GModels.cpp:125
void extend(const GModels &models)
Append model container.
Definition GModels.cpp:621
void reserve(const int &num)
Reserves space for models in container.
Definition GModels.hpp:287
void copy_members(const GModels &models)
Copy class members.
Definition GModels.cpp:1029
Abstract observation base class.
virtual GEvents * events(void)
Return events.
virtual std::string instrument(void) const =0
void id(const std::string &id)
Set observation identifier.
Optimizer parameter container class.
void attach(GOptimizerPar *par)
Attach parameter to container.
std::string content(void) const
Return list of names in registry.
Definition GRegistry.cpp:54
Vector class.
Definition GVector.hpp:46
XML element node class.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
Abstract XML node base class.
Definition GXmlNode.hpp:57
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
XML class.
Definition GXml.hpp:172
void save(const GFilename &filename) const
Save XML document into file.
Definition GXml.cpp:581
GXmlElement * element(const int &index)
Return pointer to child element.
Definition GXml.cpp:419
GXmlNode * append(const GXmlNode &node)
Append child node to XML document root.
Definition GXml.cpp:279
int elements(void) const
Return number of child elements in XML document root.
Definition GXml.cpp:384
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489