GammaLib 2.0.0
Loading...
Searching...
No Matches
GModelAssociation.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GModelAssociation.cpp - Model association class *
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 GModelAssociation.cpp
23 * @brief Model association class implementation
24 * @author Juergen Knodlseder
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 "GXmlElement.hpp"
34#include "GModelAssociation.hpp"
35
36/* __ Constants __________________________________________________________ */
37
38/* __ Method name definitions ____________________________________________ */
39#define G_VALUE "GModelAssociation::value(std::string&)"
40#define G_ERROR "GModelAssociation::error(std::string&)"
41#define G_PROPERTY "GModelAssociation::property(std::string&, std::string&,"\
42 " std::string&)"
43#define G_GET_PROPERTY_XML "GModelAssociation::get_property_xml("\
44 "GXmlElement&, std::string&)"
45
46/* __ Macros _____________________________________________________________ */
47
48/* __ Coding definitions _________________________________________________ */
49
50/* __ Debug definitions __________________________________________________ */
51
52
53/*==========================================================================
54 = =
55 = Constructors/destructors =
56 = =
57 ==========================================================================*/
58
59/***********************************************************************//**
60 * @brief Void constructor
61 ***************************************************************************/
63{
64 // Initialise private members
66
67 // Return
68 return;
69}
70
71
72/***********************************************************************//**
73 * @brief Association name constructor
74 *
75 * @param[in] name Association name.
76 *
77 * Construct a model association from an association name.
78 ***************************************************************************/
80{
81 // Initialise private members
83
84 // Set association name
85 this->name(name);
86
87 // Return
88 return;
89}
90
91
92/***********************************************************************//**
93 * @brief XML element constructor
94 *
95 * @param[in] xml XML element.
96 *
97 * Construct a model association from an XML element.
98 ***************************************************************************/
100{
101 // Initialise private members
102 init_members();
103
104 // Read model association from XML element
105 read(xml);
106
107 // Return
108 return;
109}
110
111
112/***********************************************************************//**
113 * @brief Copy constructor
114 *
115 * @param[in] association Model association.
116 ***************************************************************************/
118{
119 // Initialise private members
120 init_members();
121
122 // Copy members
123 copy_members(association);
124
125 // Return
126 return;
127}
128
129
130/***********************************************************************//**
131 * @brief Destructor
132 ***************************************************************************/
134{
135 // Free members
136 free_members();
137
138 // Return
139 return;
140}
141
142
143/*==========================================================================
144 = =
145 = Operators =
146 = =
147 ==========================================================================*/
148
149/***********************************************************************//**
150 * @brief Assignment operator
151 *
152 * @param[in] association Model association.
153 * @return Model association.
154 ***************************************************************************/
156{
157 // Execute only if object is not identical
158 if (this != &association) {
159
160 // Free members
161 free_members();
162
163 // Initialise private members for clean destruction
164 init_members();
165
166 // Copy members
167 copy_members(association);
168
169 } // endif: object was not identical
170
171 // Return
172 return *this;
173}
174
175
176/*==========================================================================
177 = =
178 = Public methods =
179 = =
180 ==========================================================================*/
181
182/***********************************************************************//**
183 * @brief Clear model association
184 ***************************************************************************/
186{
187 // Free members
188 free_members();
189
190 // Initialise private members
191 init_members();
192
193 // Return
194 return;
195}
196
197
198/***********************************************************************//**
199 * @brief Clone model association
200 *
201 * @return Pointer to deep copy of model association.
202 ***************************************************************************/
204{
205 // Clone this model association
206 return new GModelAssociation(*this);
207}
208
209
210/***********************************************************************//**
211 * @brief Return property value
212 *
213 * @param[in] name Property name
214 * @return Property value.
215 *
216 * @exception GException::invalid_argument
217 * Property name not found
218 *
219 * Returns the value of the property with the specified @p name.
220 ***************************************************************************/
221const std::string& GModelAssociation::value(const std::string& name) const
222{
223 // Get model index
224 int index = get_index(name);
225
226 // Throw exception if property name was not found
227 if (index == -1) {
228 std::string msg = "Property \""+name+"\" not found in association.";
230 }
231
232 // Return property value
233 return (m_values[index]);
234}
235
236
237/***********************************************************************//**
238 * @brief Return property error
239 *
240 * @param[in] name Property name
241 * @return Property error.
242 *
243 * @exception GException::invalid_argument
244 * Property name not found
245 *
246 * Returns the error of the property with the specified @p name.
247 ***************************************************************************/
248const std::string& GModelAssociation::error(const std::string& name) const
249{
250 // Get model index
251 int index = get_index(name);
252
253 // Throw exception if property name was not found
254 if (index == -1) {
255 std::string msg = "Association property \""+name+"\" not found.";
257 }
258
259 // Return property error
260 return (m_errors[index]);
261}
262
263
264/***********************************************************************//**
265* @brief Set property value and (optionally) error
266*
267* @param[in] name Property name
268* @param[in] value Property value
269* @param[in] error Property error
270*
271* @exception GException::invalid_argument
272* Property with specified @p name exists aleady
273*
274* Sets the value and optionally the error of the property with the
275* specified @p name.
276***************************************************************************/
277void GModelAssociation::property(const std::string& name,
278 const std::string& value,
279 const std::string& error)
280{
281 // Throw an exception if property exists already
282 if (get_index(name) != -1) {
283 std::string msg = "Association property \""+name+"\" exists already.";
285 }
286
287 // Push name, value and error in property lists
288 m_names.push_back(name);
289 m_values.push_back(value);
290 m_errors.push_back(error);
291
292 // Return
293 return;
294}
295
296
297/***********************************************************************//**
298 * @brief Read model association from XML document
299 *
300 * @param[in] xml XML element.
301 *
302 * Read model association from the XML element. The XML element is expected
303 * to have the following structure
304 *
305 * <association name="Crab">
306 * <property name="RA" value="83.6331"/>
307 * <property name="DEC" value="22.0145"/>
308 * <property name="distance" value="0.0123"/>
309 * <property name="probability" value="0.978"/>
310 * </association>
311 *
312 * Properties need to have unique names. If properties with identical names
313 * are encountered, and exception is thrown.
314 ***************************************************************************/
316{
317 // Initialise properties
318 m_names.clear();
319 m_values.clear();
320 m_errors.clear();
321
322 // Set association name
323 name(xml.attribute("name"));
324
325 // Get number of properties
326 int n = xml.elements("property");
327
328 // Loop over all properties
329 for (int i = 0; i < n; ++i) {
330
331 // Get pointer on property
332 const GXmlElement* property = xml.element("property", i);
333
334 // Read name, value and error. If one of the attributes does not
335 // exist an empty string will be returned
336 std::string name = property->attribute("name");
337 std::string value = property->attribute("value");
338 std::string error = property->attribute("error");
339
340 // Set property
341 this->property(name, value, error);
342
343 } // endfor: looped over properties
344
345 // Return
346 return;
347}
348
349
350/***********************************************************************//**
351 * @brief Write model association into XML element
352 *
353 * @param[in] xml XML element.
354 *
355 * Write model association into the XML element. The following structure
356 * will be written
357 *
358 * <association name="Crab">
359 * <property name="RA" value="83.6331"/>
360 * <property name="DEC" value="22.0145"/>
361 * <property name="distance" value="0.0123"/>
362 * <property name="probability" value="0.978"/>
363 * </association>
364 *
365 ***************************************************************************/
367{
368 // Write association name
369 xml.attribute("name", name());
370
371 // Loop over all association properties
372 for (int i = 0; i < size(); ++i) {
373 GXmlElement* property = get_property_xml(xml, m_names[i]);
374 property->attribute("name", m_names[i]);
375 property->attribute("value", m_values[i]);
376 if (!m_errors[i].empty()) {
377 property->attribute("error", m_errors[i]);
378 }
379 }
380
381 // Return
382 return;
383}
384
385
386/***********************************************************************//**
387 * @brief Print model association
388 *
389 * @param[in] chatter Chattiness.
390 * @return String containing model association information.
391 ***************************************************************************/
392std::string GModelAssociation::print(const GChatter& chatter) const
393{
394 // Initialise result string
395 std::string result;
396
397 // Continue only if chatter is not silent
398 if (chatter != SILENT) {
399
400 // Append header
401 result.append("=== GModelAssociation ===");
402
403 // Append association name
404 result.append("\n"+gammalib::parformat("Name")+name());
405
406 // Append association properties
407 result.append("\n"+gammalib::parformat("Number of properties"));
408 result.append(gammalib::str(size()));
409 for (int i = 0; i < size(); ++i) {
410 result.append("\n"+gammalib::parformat(m_names[i])+m_values[i]);
411 if (m_errors[i] != "") {
412 result.append(" +/- "+m_errors[i]);
413 }
414 }
415
416 } // endif: chatter was not silent
417
418 // Return
419 return result;
420}
421
422
423/*==========================================================================
424 = =
425 = Private methods =
426 = =
427 ==========================================================================*/
428
429/***********************************************************************//**
430 * @brief Initialise class members
431 ***************************************************************************/
433{
434 // Initialise members
435 m_name.clear();
436 m_names.clear();
437 m_values.clear();
438 m_errors.clear();
439
440 // Return
441 return;
442}
443
444
445/***********************************************************************//**
446 * @brief Copy class members
447 *
448 * @param[in] association Model association.
449 ***************************************************************************/
451{
452 // Copy members
453 m_name = association.m_name;
454 m_names = association.m_names;
455 m_values = association.m_values;
456 m_errors = association.m_errors;
457
458 // Return
459 return;
460}
461
462
463/***********************************************************************//**
464 * @brief Delete class members
465 ***************************************************************************/
467{
468 // Return
469 return;
470}
471
472
473/***********************************************************************//**
474 * @brief Return property index by name
475 *
476 * @param[in] name Property name.
477 * @return Property index (-1 if not found)
478 *
479 * Returns the index of the property with the specified @p name. If no
480 * property with the specified @p name is found the method returns -1.
481 ***************************************************************************/
482int GModelAssociation::get_index(const std::string& name) const
483{
484 // Initialise index
485 int index = -1;
486
487 // Search property names for the specified name
488 for (int i = 0; i < size(); ++i) {
489 if (m_names[i] == name) {
490 index = i;
491 break;
492 }
493 }
494
495 // Return index
496 return index;
497}
498
499
500/***********************************************************************//**
501 * @brief Return pointer to property with given name in XML element
502 *
503 * @param[in] xml XML element.
504 * @param[in] name Property name.
505 * @return Pointer to property XML element.
506 *
507 * @exception GException::invalid_value
508 * Invalid XML format encountered.
509 *
510 * Returns pointer to property with given @p name in XML element. If the
511 * @p name is not found, a property with the given @p name is added.
512 *
513 * The function checks for multiple occurences of a property and throws an
514 * exception in case that more than one property with a given name is found.
515 ***************************************************************************/
517 const std::string& name) const
518{
519 // Initialize XML element pointer
520 GXmlElement* property = NULL;
521
522 // Number of elements
523 int number = 0;
524
525 // Get number of elements in XML element
526 int n = xml.elements("property");
527
528 // Search for property with given name
529 for (int i = 0; i < n; ++i) {
530 GXmlElement* element = xml.element("property", i);
531 if (element->attribute("name") == name) {
532 property = element;
533 number++;
534 }
535 }
536
537 // Create property if none was found
538 if (number == 0) {
539 property = static_cast<GXmlElement*>(xml.append(GXmlElement("property name=\""+name+"\"")));
540 number++;
541 }
542
543 // Throw case dependent exception
544 if (number < 1) {
545 std::string msg = "Property \""+name+"\" not found in XML element."
546 " Please verify the XML format.";
548 }
549 else if (number > 1) {
550 std::string msg = "Property \""+name+"\" found "+
551 gammalib::str(number)+" times in XML element."
552 " Please verify the XML format.";
554 }
555
556 // Return
557 return property;
558}
Exception handler interface definition.
#define G_GET_PROPERTY_XML
#define G_VALUE
#define G_PROPERTY
#define G_ERROR
Model association class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
XML element node class interface definition.
Model association class.
void free_members(void)
Delete class members.
void copy_members(const GModelAssociation &association)
Copy class members.
const std::string & error(const std::string &name) const
Return property error.
int size(void) const
Return number of association properties.
void write(GXmlElement &xml) const
Write model association into XML element.
GModelAssociation * clone(void) const
Clone model association.
void property(const std::string &name, const std::string &value, const std::string &error="")
Set property value and (optionally) error.
const std::string & name(void) const
Return association name.
std::vector< std::string > m_values
Property values.
std::string print(const GChatter &chatter=NORMAL) const
Print model association.
GModelAssociation(void)
Void constructor.
const std::string & value(const std::string &name) const
Return property value.
int get_index(const std::string &name) const
Return property index by name.
GModelAssociation & operator=(const GModelAssociation &association)
Assignment operator.
std::vector< std::string > m_names
Property names.
void read(const GXmlElement &xml)
Read model association from XML document.
virtual ~GModelAssociation(void)
Destructor.
std::vector< std::string > m_errors
Property errors.
std::string m_name
Association name.
void clear(void)
Clear model association.
GXmlElement * get_property_xml(GXmlElement &xml, const std::string &name) const
Return pointer to property with given name in XML element.
void init_members(void)
Initialise class members.
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
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489