Commit b7f38b1285a61effea561a32c625d2aa998be7f7

Authored by Jürgen Knödlseder
1 parent f0dbd8cf

Use XML support functions in all model classes (#1430)

ChangeLog
... ... @@ -36,6 +36,7 @@
36 36 Add time parameter to GApplicationPar class (#1864)
37 37 Add time string constructor and set method to GTime class (#1864)
38 38 Use GNdarray to store GSkyMap pixels and add smooth() method (#1729)
  39 + Use XML support functions in all model classes (#1430)
39 40 Add GSkyRegionMap class (#1121)
40 41  
41 42  
... ...
... ... @@ -143,6 +143,9 @@ None
143 143 A spectral model constructor was added to GModelSpectralNodes to allow
144 144 conversion of any spectral model into a spectral node model (#2178).
145 145  
  146 +XML support functions are now used in all model classes to simplify the
  147 +code (#1430).
  148 +
146 149  
147 150 9. Numerics module
148 151 ------------------
... ...
doc/source/admin/release_history/1.5.rst
... ... @@ -70,6 +70,8 @@ Improvements
70 70 Add time string constructor and set method to ``GTime`` class
71 71 * [`1729 <https://cta-redmine.irap.omp.eu/issues/1729>`_] -
72 72 Use ``GNdarray`` to store ``GSkyMap`` pixels and add ``GSkyMap::smooth()`` method
  73 +* [`1430 <https://cta-redmine.irap.omp.eu/issues/1430>`_] -
  74 + Use XML support functions in all model classes
73 75 * [`1121 <https://cta-redmine.irap.omp.eu/issues/1121>`_] -
74 76 Add ``GSkyRegionMap`` class
75 77  
... ...
src/model/GModelSpatialDiffuseConst.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialDiffuseConst.cpp - Spatial isotropic model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -422,7 +422,7 @@ double GModelSpatialDiffuseConst::mc_norm(const GSkyDir&amp; dir,
422 422 void GModelSpatialDiffuseConst::read(const GXmlElement& xml)
423 423 {
424 424 // Get value parameter
425   - const GXmlElement* par = gammalib::xml_get_par(G_READ, xml, "Value");
  425 + const GXmlElement* par = gammalib::xml_get_par(G_READ, xml, m_value.name());
426 426  
427 427 // Read value parameter
428 428 m_value.read(*par);
... ... @@ -462,7 +462,7 @@ void GModelSpatialDiffuseConst::write(GXmlElement&amp; xml) const
462 462 }
463 463  
464 464 // Get or create Value parameter
465   - GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "Value");
  465 + GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_value.name());
466 466  
467 467 // Write parameter
468 468 m_value.write(*par);
... ...
src/model/GModelSpatialDiffuseCube.cpp
... ... @@ -641,7 +641,6 @@ void GModelSpatialDiffuseCube::write(GXmlElement&amp; xml) const
641 641 }
642 642  
643 643 // Set filename
644   - //xml.attribute("file", m_filename);
645 644 xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename));
646 645  
647 646 // Return
... ...
src/model/GModelSpatialDiffuseMap.cpp
... ... @@ -608,7 +608,6 @@ void GModelSpatialDiffuseMap::write(GXmlElement&amp; xml) const
608 608 }
609 609  
610 610 // Set sky map file name
611   - //xml.attribute("file", m_filename);
612 611 xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename));
613 612  
614 613 // If XML element has 0 nodes then append parameter node. The name
... ...
src/model/GModelSpatialElliptical.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialElliptical.cpp - Abstract elliptical spatial model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2013-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -218,74 +218,48 @@ double GModelSpatialElliptical::eval(const GPhoton&amp; photon,
218 218 ***************************************************************************/
219 219 void GModelSpatialElliptical::read(const GXmlElement& xml)
220 220 {
221   - // Determine number of parameter nodes in XML element
222   - int npars = xml.elements("parameter");
  221 + // Read RA/DEC parameters
  222 + if (gammalib::xml_has_par(xml, "RA") && gammalib::xml_has_par(xml, "DEC")) {
  223 +
  224 + // Get parameters
  225 + const GXmlElement* ra = gammalib::xml_get_par(G_READ, xml, "RA");
  226 + const GXmlElement* dec = gammalib::xml_get_par(G_READ, xml, "DEC");
  227 +
  228 + // Read parameters
  229 + m_ra.read(*ra);
  230 + m_dec.read(*dec);
223 231  
224   - // Verify that XML element has at least 3 parameters
225   - if (xml.elements() < 3 || npars < 3) {
226   - throw GException::model_invalid_parnum(G_READ, xml,
227   - "Elliptical model requires at least 3 parameters.");
228 232 }
229 233  
230   - // Extract model parameters
231   - bool has_glon = false;
232   - bool has_glat = false;
233   - int npar[3] = {0, 0, 0};
234   - for (int i = 0; i < npars; ++i) {
235   -
236   - // Get parameter element
237   - const GXmlElement* par = xml.element("parameter", i);
238   -
239   - // Handle RA/GLON
240   - if (par->attribute("name") == "RA") {
241   - m_ra.read(*par);
242   - npar[0]++;
243   - }
244   - else if (par->attribute("name") == "GLON") {
245   - m_ra.read(*par);
246   - npar[0]++;
247   - has_glon = true;
248   - }
249   -
250   - // Handle DEC/GLAT
251   - else if (par->attribute("name") == "DEC") {
252   - m_dec.read(*par);
253   - npar[1]++;
254   - }
255   - else if (par->attribute("name") == "GLAT") {
256   - m_dec.read(*par);
257   - npar[1]++;
258   - has_glat = true;
259   - }
260   -
261   - // Handle PA
262   - else if (par->attribute("name") == "PA") {
263   - m_posangle.read(*par);
264   - npar[2]++;
265   - }
266   -
267   - } // endfor: looped over all parameters
268   -
269   - // Check if we have to convert GLON/GLAT into RA/DEC
270   - if (has_glon && has_glat) {
  234 + // ... otherwise read GLON/GLAT parameters
  235 + else {
  236 +
  237 + // Get parameters
  238 + const GXmlElement* glon = gammalib::xml_get_par(G_READ, xml, "GLON");
  239 + const GXmlElement* glat = gammalib::xml_get_par(G_READ, xml, "GLAT");
  240 +
  241 + // Read parameters
  242 + m_ra.read(*glon);
  243 + m_dec.read(*glat);
  244 +
  245 + // Convert into RA/DEC
271 246 GSkyDir dir;
272 247 dir.lb_deg(ra(), dec()),
273 248 m_ra.value(dir.ra_deg());
274 249 m_dec.value(dir.dec_deg());
  250 +
  251 + // Set names to RA/DEC
275 252 m_ra.name("RA");
276 253 m_dec.name("DEC");
277   - }
278   - else if (has_glon || has_glat) {
279   - throw GException::model_invalid_parnames(G_READ, xml,
280   - "Require either \"RA\"/\"DEC\" or \"GLON\"/\"GLAT\".");
281   - }
282 254  
283   - // Verify that all parameters were found
284   - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1) {
285   - throw GException::model_invalid_parnames(G_READ, xml,
286   - "Require \"RA\"/\"DEC\", \"GLON\"/\"GLAT\" and \"PA\" parameters.");
287 255 }
288 256  
  257 + // Get other parameters
  258 + const GXmlElement* pa = gammalib::xml_get_par(G_READ, xml, m_posangle.name());
  259 +
  260 + // Read other parameters
  261 + m_posangle.read(*pa);
  262 +
289 263 // Return
290 264 return;
291 265 }
... ... @@ -329,54 +303,15 @@ void GModelSpatialElliptical::write(GXmlElement&amp; xml) const
329 303 "Elliptical model is not of type \""+type()+"\".");
330 304 }
331 305  
332   - // If XML element has 0 nodes then append 3 parameter nodes
333   - if (xml.elements() == 0) {
334   - xml.append(GXmlElement("parameter name=\"RA\""));
335   - xml.append(GXmlElement("parameter name=\"DEC\""));
336   - xml.append(GXmlElement("parameter name=\"PA\""));
337   - }
338   -
339   - // Determine number of parameter nodes in XML element
340   - int npars = xml.elements("parameter");
  306 + // Get or create parameters
  307 + GXmlElement* ra = gammalib::xml_need_par(G_WRITE, xml, m_ra.name());
  308 + GXmlElement* dec = gammalib::xml_need_par(G_WRITE, xml, m_dec.name());
  309 + GXmlElement* pa = gammalib::xml_need_par(G_WRITE, xml, m_posangle.name());
341 310  
342   - // Verify that XML element has at least 3 parameters
343   - if (xml.elements() < 3 || npars < 3) {
344   - throw GException::model_invalid_parnum(G_WRITE, xml,
345   - "Elliptical source model requires at least 3 parameters.");
346   - }
347   -
348   - // Set or update model parameter attributes
349   - int npar[3] = {0, 0, 0};
350   - for (int i = 0; i < npars; ++i) {
351   -
352   - // Get parameter element
353   - GXmlElement* par = xml.element("parameter", i);
354   -
355   - // Handle RA
356   - if (par->attribute("name") == "RA") {
357   - npar[0]++;
358   - m_ra.write(*par);
359   - }
360   -
361   - // Handle DEC
362   - else if (par->attribute("name") == "DEC") {
363   - npar[1]++;
364   - m_dec.write(*par);
365   - }
366   -
367   - // Handle PA
368   - else if (par->attribute("name") == "PA") {
369   - npar[2]++;
370   - m_posangle.write(*par);
371   - }
372   -
373   - } // endfor: looped over all parameters
374   -
375   - // Check of all required parameters are present
376   - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1) {
377   - throw GException::model_invalid_parnames(G_WRITE, xml,
378   - "Require \"RA\", \"DEC\" and \"PA\" parameters.");
379   - }
  311 + // Write parameters
  312 + m_ra.write(*ra);
  313 + m_dec.write(*dec);
  314 + m_posangle.write(*pa);
380 315  
381 316 // Return
382 317 return;
... ...
src/model/GModelSpatialEllipticalDisk.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialEllipticalDisk.cpp - Elliptical disk source model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2016 by Michael Mayer *
  4 + * copyright (C) 2013-2018 by Michael Mayer *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -471,41 +471,13 @@ void GModelSpatialEllipticalDisk::read(const GXmlElement&amp; xml)
471 471 // Read disk location
472 472 GModelSpatialElliptical::read(xml);
473 473  
474   - // Extract model parameters
475   - int npar[2] = {0, 0};
476   - for (int i = 0; i < npars; ++i) {
477   -
478   - // Get parameter element
479   - const GXmlElement* par = xml.element("parameter", i);
480   -
481   - // Handle semiminor radius
482   - if (par->attribute("name") == "MinorRadius") {
483   -
484   - // Read parameter
485   - m_semiminor.read(*par);
486   -
487   - // Increment parameter counter
488   - npar[0]++;
489   - }
490   -
491   - // Handle semimajor radius
492   - else if (par->attribute("name") == "MajorRadius") {
  474 + // Get parameters
  475 + const GXmlElement* minor = gammalib::xml_get_par(G_READ, xml, m_semiminor.name());
  476 + const GXmlElement* major = gammalib::xml_get_par(G_READ, xml, m_semimajor.name());
493 477  
494   - // Read parameter
495   - m_semimajor.read(*par);
496   -
497   - // Increment parameter counter
498   - npar[1]++;
499   - }
500   -
501   - } // endfor: looped over all parameters
502   -
503   - // Verify that all parameters were found
504   - if (npar[0] != 1 || npar[1] != 1) {
505   - throw GException::model_invalid_parnames(G_READ, xml,
506   - "Elliptical disk model requires \"MinorRadius\" and"
507   - " \"MajorRadius\" parameters.");
508   - }
  478 + // Read parameters
  479 + m_semiminor.read(*minor);
  480 + m_semimajor.read(*major);
509 481  
510 482 // Return
511 483 return;
... ... @@ -539,57 +511,13 @@ void GModelSpatialEllipticalDisk::write(GXmlElement&amp; xml) const
539 511 // Write disk location
540 512 GModelSpatialElliptical::write(xml);
541 513  
542   - // If XML element has 3 nodes (which should be the location and PA nodes)
543   - // then append 2 parameter nodes
544   - if (xml.elements() == 3) {
545   - xml.append(GXmlElement("parameter name=\"MinorRadius\""));
546   - xml.append(GXmlElement("parameter name=\"MajorRadius\""));
547   - }
548   -
549   - // Determine number of parameter nodes in XML element
550   - int npars = xml.elements("parameter");
  514 + // Get or create parameters
  515 + GXmlElement* minor = gammalib::xml_need_par(G_WRITE, xml, m_semiminor.name());
  516 + GXmlElement* major = gammalib::xml_need_par(G_WRITE, xml, m_semimajor.name());
551 517  
552   - // Verify that XML element has exactly 5 parameters
553   - if (xml.elements() != 5 || npars != 5) {
554   - throw GException::model_invalid_parnum(G_WRITE, xml,
555   - "Elliptical Disk model requires exactly 5 parameters.");
556   - }
557   -
558   - // Set or update model parameter attributes
559   - int npar[2] = {0, 0};
560   - for (int i = 0; i < npars; ++i) {
561   -
562   - // Get parameter element
563   - GXmlElement* par = xml.element("parameter", i);
564   -
565   - // Handle semiminor radius
566   - if (par->attribute("name") == "MinorRadius") {
567   -
568   - // Write parameter
569   - m_semiminor.write(*par);
570   -
571   - // Increment parameter counter
572   - npar[0]++;
573   - }
574   -
575   - // Handle semimajor radius
576   - else if (par->attribute("name") == "MajorRadius") {
577   -
578   - // Write parameter
579   - m_semimajor.write(*par);
580   -
581   - // Increment parameter counter
582   - npar[1]++;
583   - }
584   -
585   - } // endfor: looped over all parameters
586   -
587   - // Check of all required parameters are present
588   - if (npar[0] != 1 || npar[1] != 1) {
589   - throw GException::model_invalid_parnames(G_WRITE, xml,
590   - "Elliptical disk model requires \"MinorRadius\" and"
591   - " \"MajorRadius\" parameters.");
592   - }
  518 + // Write parameters
  519 + m_semiminor.write(*minor);
  520 + m_semimajor.write(*major);
593 521  
594 522 // Return
595 523 return;
... ...
src/model/GModelSpatialEllipticalGauss.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialEllipticalGauss.cpp - Elliptical gauss source model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2015-2016 by Michael Mayer *
  4 + * copyright (C) 2015-2018 by Michael Mayer *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -541,41 +541,13 @@ void GModelSpatialEllipticalGauss::read(const GXmlElement&amp; xml)
541 541 // Read gauss location
542 542 GModelSpatialElliptical::read(xml);
543 543  
544   - // Extract model parameters
545   - int npar[2] = {0, 0};
546   - for (int i = 0; i < npars; ++i) {
547   -
548   - // Get parameter element
549   - const GXmlElement* par = xml.element("parameter", i);
550   -
551   - // Handle semiminor radius
552   - if (par->attribute("name") == "MinorRadius") {
553   -
554   - // Read parameter
555   - m_semiminor.read(*par);
556   -
557   - // Increment parameter counter
558   - npar[0]++;
559   - }
560   -
561   - // Handle semimajor radius
562   - else if (par->attribute("name") == "MajorRadius") {
  544 + // Get parameters
  545 + const GXmlElement* minor = gammalib::xml_get_par(G_READ, xml, m_semiminor.name());
  546 + const GXmlElement* major = gammalib::xml_get_par(G_READ, xml, m_semimajor.name());
563 547  
564   - // Read parameter
565   - m_semimajor.read(*par);
566   -
567   - // Increment parameter counter
568   - npar[1]++;
569   - }
570   -
571   - } // endfor: looped over all parameters
572   -
573   - // Verify that all parameters were found
574   - if (npar[0] != 1 || npar[1] != 1) {
575   - throw GException::model_invalid_parnames(G_READ, xml,
576   - "Elliptical disk model requires \"MinorRadius\" and"
577   - " \"MajorRadius\" parameters.");
578   - }
  548 + // Read parameters
  549 + m_semiminor.read(*minor);
  550 + m_semimajor.read(*major);
579 551  
580 552 // Return
581 553 return;
... ... @@ -609,57 +581,13 @@ void GModelSpatialEllipticalGauss::write(GXmlElement&amp; xml) const
609 581 // Write disk location
610 582 GModelSpatialElliptical::write(xml);
611 583  
612   - // If XML element has 3 nodes (which should be the location and PA nodes)
613   - // then append 2 parameter nodes
614   - if (xml.elements() == 3) {
615   - xml.append(GXmlElement("parameter name=\"MinorRadius\""));
616   - xml.append(GXmlElement("parameter name=\"MajorRadius\""));
617   - }
618   -
619   - // Determine number of parameter nodes in XML element
620   - int npars = xml.elements("parameter");
621   -
622   - // Verify that XML element has exactly 5 parameters
623   - if (xml.elements() != 5 || npars != 5) {
624   - throw GException::model_invalid_parnum(G_WRITE, xml,
625   - "Elliptical gauss model requires exactly 5 parameters.");
626   - }
627   -
628   - // Set or update model parameter attributes
629   - int npar[2] = {0, 0};
630   - for (int i = 0; i < npars; ++i) {
631   -
632   - // Get parameter element
633   - GXmlElement* par = xml.element("parameter", i);
634   -
635   - // Handle semiminor radius
636   - if (par->attribute("name") == "MinorRadius") {
637   -
638   - // Write parameter
639   - m_semiminor.write(*par);
640   -
641   - // Increment parameter counter
642   - npar[0]++;
643   - }
644   -
645   - // Handle semimajor radius
646   - else if (par->attribute("name") == "MajorRadius") {
  584 + // Get or create parameters
  585 + GXmlElement* minor = gammalib::xml_need_par(G_WRITE, xml, m_semiminor.name());
  586 + GXmlElement* major = gammalib::xml_need_par(G_WRITE, xml, m_semimajor.name());
647 587  
648   - // Write parameter
649   - m_semimajor.write(*par);
650   -
651   - // Increment parameter counter
652   - npar[1]++;
653   - }
654   -
655   - } // endfor: looped over all parameters
656   -
657   - // Check of all required parameters are present
658   - if (npar[0] != 1 || npar[1] != 1) {
659   - throw GException::model_invalid_parnames(G_WRITE, xml,
660   - "Elliptical gauss model requires \"MinorRadius\" and"
661   - " \"MajorRadius\" parameters.");
662   - }
  588 + // Write parameters
  589 + m_semiminor.write(*minor);
  590 + m_semimajor.write(*major);
663 591  
664 592 // Return
665 593 return;
... ... @@ -669,7 +597,7 @@ void GModelSpatialEllipticalGauss::write(GXmlElement&amp; xml) const
669 597 /***********************************************************************//**
670 598 * @brief Print information
671 599 *
672   - * @param[in] chatter Chattiness (defaults to NORMAL).
  600 + * @param[in] chatter Chattiness.
673 601 * @return String containing model information.
674 602 ***************************************************************************/
675 603 std::string GModelSpatialEllipticalGauss::print(const GChatter& chatter) const
... ...
src/model/GModelSpatialPointSource.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialPointSource.cpp - Spatial point source model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -371,57 +371,40 @@ bool GModelSpatialPointSource::contains(const GSkyDir&amp; dir,
371 371 ***************************************************************************/
372 372 void GModelSpatialPointSource::read(const GXmlElement& xml)
373 373 {
374   - // Verify that XML element has exactly 2 parameters
375   - if (xml.elements() != 2 || xml.elements("parameter") != 2) {
376   - throw GException::model_invalid_parnum(G_READ, xml,
377   - "Point source model requires exactly 2 parameters.");
378   - }
  374 + // Read RA/DEC parameters
  375 + if (gammalib::xml_has_par(xml, "RA") && gammalib::xml_has_par(xml, "DEC")) {
379 376  
380   - // Extract model parameters
381   - bool has_glon = false;
382   - bool has_glat = false;
383   - int npar[] = {0, 0};
384   - for (int i = 0; i < 2; ++i) {
  377 + // Get parameters
  378 + const GXmlElement* ra = gammalib::xml_get_par(G_READ, xml, "RA");
  379 + const GXmlElement* dec = gammalib::xml_get_par(G_READ, xml, "DEC");
385 380  
386   - // Get parameter element
387   - const GXmlElement* par = xml.element("parameter", i);
  381 + // Read parameters
  382 + m_ra.read(*ra);
  383 + m_dec.read(*dec);
388 384  
389   - // Handle RA/GLON
390   - if (par->attribute("name") == "RA") {
391   - m_ra.read(*par);
392   - npar[0]++;
393   - }
394   - else if (par->attribute("name") == "GLON") {
395   - m_ra.read(*par);
396   - npar[0]++;
397   - has_glon = true;
398   - }
  385 + }
399 386  
400   - // Handle DEC/GLAT
401   - else if (par->attribute("name") == "DEC") {
402   - m_dec.read(*par);
403   - npar[1]++;
404   - }
405   - else if (par->attribute("name") == "GLAT") {
406   - m_dec.read(*par);
407   - npar[1]++;
408   - has_glat = true;
409   - }
  387 + // ... otherwise read GLON/GLAT parameters
  388 + else {
  389 +
  390 + // Get parameters
  391 + const GXmlElement* glon = gammalib::xml_get_par(G_READ, xml, "GLON");
  392 + const GXmlElement* glat = gammalib::xml_get_par(G_READ, xml, "GLAT");
410 393  
411   - } // endfor: looped over all parameters
  394 + // Read parameters
  395 + m_ra.read(*glon);
  396 + m_dec.read(*glat);
412 397  
413   - // Check if we have to convert GLON/GLAT into RA/DEC
414   - if (has_glon && has_glat) {
  398 + // Convert into RA/DEC
415 399 GSkyDir dir;
416 400 dir.lb_deg(ra(), dec()),
417 401 m_ra.value(dir.ra_deg());
418 402 m_dec.value(dir.dec_deg());
  403 +
  404 + // Set names to RA/DEC
419 405 m_ra.name("RA");
420 406 m_dec.name("DEC");
421   - }
422   - else if (has_glon || has_glat) {
423   - throw GException::model_invalid_parnames(G_READ, xml,
424   - "Require either RA/DEC or GLON/GLAT.");
  407 +
425 408 }
426 409  
427 410 // Return
... ... @@ -465,35 +448,13 @@ void GModelSpatialPointSource::write(GXmlElement&amp; xml) const
465 448 "Spatial model is not of type \""+type()+"\".");
466 449 }
467 450  
468   - // If XML element has 0 nodes then append 2 parameter nodes
469   - if (xml.elements() == 0) {
470   - xml.append(GXmlElement("parameter name=\"RA\""));
471   - xml.append(GXmlElement("parameter name=\"DEC\""));
472   - }
473   -
474   - // Verify that XML element has exactly 2 parameters
475   - if (xml.elements() != 2 || xml.elements("parameter") != 2) {
476   - throw GException::model_invalid_parnum(G_WRITE, xml,
477   - "Point source model requires exactly 2 parameters.");
478   - }
479   -
480   - // Get pointers on both model parameters
481   - GXmlElement* par1 = xml.element("parameter", 0);
482   - GXmlElement* par2 = xml.element("parameter", 1);
  451 + // Get or create parameters
  452 + GXmlElement* ra = gammalib::xml_need_par(G_WRITE, xml, m_ra.name());
  453 + GXmlElement* dec = gammalib::xml_need_par(G_WRITE, xml, m_dec.name());
483 454  
484   - // Set or update sky direction
485   - if (par1->attribute("name") == "RA" && par2->attribute("name") == "DEC") {
486   - m_ra.write(*par1);
487   - m_dec.write(*par2);
488   - }
489   - else if (par2->attribute("name") == "RA" && par1->attribute("name") == "DEC") {
490   - m_ra.write(*par2);
491   - m_dec.write(*par1);
492   - }
493   - else {
494   - throw GException::model_invalid_parnames(G_WRITE, xml,
495   - "Require RA and DEC parameters.");
496   - }
  455 + // Write parameters
  456 + m_ra.write(*ra);
  457 + m_dec.write(*dec);
497 458  
498 459 // Return
499 460 return;
... ...
src/model/GModelSpatialRadial.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialRadial.cpp - Abstract radial spatial model base class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2011-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2011-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -215,66 +215,40 @@ double GModelSpatialRadial::eval(const GPhoton&amp; photon,
215 215 ***************************************************************************/
216 216 void GModelSpatialRadial::read(const GXmlElement& xml)
217 217 {
218   - // Determine number of parameter nodes in XML element
219   - int npars = xml.elements("parameter");
  218 + // Read RA/DEC parameters
  219 + if (gammalib::xml_has_par(xml, "RA") && gammalib::xml_has_par(xml, "DEC")) {
  220 +
  221 + // Get parameters
  222 + const GXmlElement* ra = gammalib::xml_get_par(G_READ, xml, "RA");
  223 + const GXmlElement* dec = gammalib::xml_get_par(G_READ, xml, "DEC");
  224 +
  225 + // Read parameters
  226 + m_ra.read(*ra);
  227 + m_dec.read(*dec);
220 228  
221   - // Verify that XML element has at least 2 parameters
222   - if (xml.elements() < 2 || npars < 2) {
223   - throw GException::model_invalid_parnum(G_READ, xml,
224   - "Radial model requires at least 2 parameters.");
225 229 }
226 230  
227   - // Extract model parameters
228   - bool has_glon = false;
229   - bool has_glat = false;
230   - int npar[2] = {0, 0};
231   - for (int i = 0; i < npars; ++i) {
232   -
233   - // Get parameter element
234   - const GXmlElement* par = xml.element("parameter", i);
235   -
236   - // Handle RA/GLON
237   - if (par->attribute("name") == "RA") {
238   - m_ra.read(*par);
239   - npar[0]++;
240   - }
241   - else if (par->attribute("name") == "GLON") {
242   - m_ra.read(*par);
243   - npar[0]++;
244   - has_glon = true;
245   - }
246   -
247   - // Handle DEC/GLAT
248   - else if (par->attribute("name") == "DEC") {
249   - m_dec.read(*par);
250   - npar[1]++;
251   - }
252   - else if (par->attribute("name") == "GLAT") {
253   - m_dec.read(*par);
254   - npar[1]++;
255   - has_glat = true;
256   - }
257   -
258   - } // endfor: looped over all parameters
259   -
260   - // Check if we have to convert GLON/GLAT into RA/DEC
261   - if (has_glon && has_glat) {
  231 + // ... otherwise read GLON/GLAT parameters
  232 + else {
  233 +
  234 + // Get parameters
  235 + const GXmlElement* glon = gammalib::xml_get_par(G_READ, xml, "GLON");
  236 + const GXmlElement* glat = gammalib::xml_get_par(G_READ, xml, "GLAT");
  237 +
  238 + // Read parameters
  239 + m_ra.read(*glon);
  240 + m_dec.read(*glat);
  241 +
  242 + // Convert into RA/DEC
262 243 GSkyDir dir;
263 244 dir.lb_deg(ra(), dec()),
264 245 m_ra.value(dir.ra_deg());
265 246 m_dec.value(dir.dec_deg());
  247 +
  248 + // Set names to RA/DEC
266 249 m_ra.name("RA");
267 250 m_dec.name("DEC");
268   - }
269   - else if (has_glon || has_glat) {
270   - throw GException::model_invalid_parnames(G_READ, xml,
271   - "Require either \"RA\"/\"DEC\" or \"GLON\"/\"GLAT\".");
272   - }
273 251  
274   - // Verify that all parameters were found
275   - if (npar[0] != 1 || npar[1] != 1) {
276   - throw GException::model_invalid_parnames(G_READ, xml,
277   - "Require \"RA\"/\"DEC\" and \"GLON\"/\"GLAT\" parameters.");
278 252 }
279 253  
280 254 // Return
... ... @@ -319,47 +293,13 @@ void GModelSpatialRadial::write(GXmlElement&amp; xml) const
319 293 "Radial model is not of type \""+type()+"\".");
320 294 }
321 295  
322   - // If XML element has 0 nodes then append 2 parameter nodes
323   - if (xml.elements() == 0) {
324   - xml.append(GXmlElement("parameter name=\"RA\""));
325   - xml.append(GXmlElement("parameter name=\"DEC\""));
326   - }
327   -
328   - // Determine number of parameter nodes in XML element
329   - int npars = xml.elements("parameter");
330   -
331   - // Verify that XML element has at least 2 parameters
332   - if (xml.elements() < 2 || npars < 2) {
333   - throw GException::model_invalid_parnum(G_WRITE, xml,
334   - "Radial source model requires at least 2 parameters.");
335   - }
336   -
337   - // Set or update model parameter attributes
338   - int npar[2] = {0, 0};
339   - for (int i = 0; i < npars; ++i) {
340   -
341   - // Get parameter element
342   - GXmlElement* par = xml.element("parameter", i);
  296 + // Get or create parameters
  297 + GXmlElement* ra = gammalib::xml_need_par(G_WRITE, xml, m_ra.name());
  298 + GXmlElement* dec = gammalib::xml_need_par(G_WRITE, xml, m_dec.name());
343 299  
344   - // Handle RA
345   - if (par->attribute("name") == "RA") {
346   - npar[0]++;
347   - m_ra.write(*par);
348   - }
349   -
350   - // Handle DEC
351   - else if (par->attribute("name") == "DEC") {
352   - npar[1]++;
353   - m_dec.write(*par);
354   - }
355   -
356   - } // endfor: looped over all parameters
357   -
358   - // Check of all required parameters are present
359   - if (npar[0] != 1 || npar[1] != 1) {
360   - throw GException::model_invalid_parnames(G_WRITE, xml,
361   - "Require \"RA\" and \"DEC\" parameters.");
362   - }
  300 + // Write parameters
  301 + m_ra.write(*ra);
  302 + m_dec.write(*dec);
363 303  
364 304 // Return
365 305 return;
... ...
src/model/GModelSpatialRadialDisk.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialRadialDisk.cpp - Radial disk source model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2011-2016 by Christoph Deil *
  4 + * copyright (C) 2011-2018 by Christoph Deil *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -421,32 +421,11 @@ void GModelSpatialRadialDisk::read(const GXmlElement&amp; xml)
421 421 // Read disk location
422 422 GModelSpatialRadial::read(xml);
423 423  
424   - // Extract model parameters
425   - int npar[1] = {0};
426   - for (int i = 0; i < npars; ++i) {
427   -
428   - // Get parameter element
429   - const GXmlElement* par = xml.element("parameter", i);
430   -
431   - // Handle Radius
432   - if (par->attribute("name") == "Radius") {
433   -
434   - // Read parameter
435   - m_radius.read(*par);
436   -
437   - //TODO: Check parameter
438   -
439   - // Increment parameter counter
440   - npar[0]++;
441   - }
442   -
443   - } // endfor: looped over all parameters
  424 + // Get parameters
  425 + const GXmlElement* radius = gammalib::xml_get_par(G_READ, xml, m_radius.name());
444 426  
445   - // Verify that all parameters were found
446   - if (npar[0] != 1) {
447   - throw GException::model_invalid_parnames(G_READ, xml,
448   - "Require \"Radius\" parameter.");
449   - }
  427 + // Read parameters
  428 + m_radius.read(*radius);
450 429  
451 430 // Return
452 431 return;
... ... @@ -478,41 +457,11 @@ void GModelSpatialRadialDisk::write(GXmlElement&amp; xml) const
478 457 // Write disk location
479 458 GModelSpatialRadial::write(xml);
480 459  
481   - // If XML element has 2 nodes (which should be the location nodes)
482   - // then append 1 parameter node
483   - if (xml.elements() == 2) {
484   - xml.append(GXmlElement("parameter name=\"Radius\""));
485   - }
486   -
487   - // Determine number of parameter nodes in XML element
488   - int npars = xml.elements("parameter");
489   -
490   - // Verify that XML element has exactly 3 parameters
491   - if (xml.elements() != 3 || npars != 3) {
492   - throw GException::model_invalid_parnum(G_WRITE, xml,
493   - "Disk model requires exactly 3 parameters.");
494   - }
495   -
496   - // Set or update model parameter attributes
497   - int npar[1] = {0};
498   - for (int i = 0; i < npars; ++i) {
499   -
500   - // Get parameter element
501   - GXmlElement* par = xml.element("parameter", i);
  460 + // Get or create parameters
  461 + GXmlElement* radius = gammalib::xml_need_par(G_WRITE, xml, m_radius.name());
502 462  
503   - // Handle Radius
504   - if (par->attribute("name") == "Radius") {
505   - m_radius.write(*par);
506   - npar[0]++;
507   - }
508   -
509   - } // endfor: looped over all parameters
510   -
511   - // Check of all required parameters are present
512   - if (npar[0] != 1) {
513   - throw GException::model_invalid_parnames(G_WRITE, xml,
514   - "Require \"Radius\" parameter.");
515   - }
  463 + // Write parameters
  464 + m_radius.write(*radius);
516 465  
517 466 // Return
518 467 return;
... ...
src/model/GModelSpatialRadialGauss.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialRadialGauss.cpp - Radial Gaussian source model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2011-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2011-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -417,32 +417,11 @@ void GModelSpatialRadialGauss::read(const GXmlElement&amp; xml)
417 417 // Read Gaussian location
418 418 GModelSpatialRadial::read(xml);
419 419  
420   - // Extract model parameters
421   - int npar[1] = {0};
422   - for (int i = 0; i < npars; ++i) {
423   -
424   - // Get parameter element
425   - const GXmlElement* par = xml.element("parameter", i);
426   -
427   - // Handle Gaussian width
428   - if (par->attribute("name") == "Sigma") {
429   -
430   - // Read parameter
431   - m_sigma.read(*par);
432   -
433   - //TODO: Check parameter
434   -
435   - // Increment parameter counter
436   - npar[0]++;
437   - }
438   -
439   - } // endfor: looped over all parameters
  420 + // Get parameters
  421 + const GXmlElement* sigma = gammalib::xml_get_par(G_READ, xml, m_sigma.name());
440 422  
441   - // Verify that all parameters were found
442   - if (npar[0] != 1) {
443   - throw GException::model_invalid_parnames(G_READ, xml,
444   - "Require \"Sigma\" parameters.");
445   - }
  423 + // Read parameters
  424 + m_sigma.read(*sigma);
446 425  
447 426 // Return
448 427 return;
... ... @@ -476,41 +455,11 @@ void GModelSpatialRadialGauss::write(GXmlElement&amp; xml) const
476 455 // Write Gaussian location
477 456 GModelSpatialRadial::write(xml);
478 457  
479   - // If XML element has 2 nodes (which should be the location nodes)
480   - // then append 1 parameter node
481   - if (xml.elements() == 2) {
482   - xml.append(GXmlElement("parameter name=\"Sigma\""));
483   - }
  458 + // Get or create parameters
  459 + GXmlElement* sigma = gammalib::xml_need_par(G_WRITE, xml, m_sigma.name());
484 460  
485   - // Determine number of parameter nodes in XML element
486   - int npars = xml.elements("parameter");
487   -
488   - // Verify that XML element has exactly 3 parameters
489   - if (xml.elements() != 3 || npars != 3) {
490   - throw GException::model_invalid_parnum(G_WRITE, xml,
491   - "Point source model requires exactly 3 parameters.");
492   - }
493   -
494   - // Set or update model parameter attributes
495   - int npar[1] = {0};
496   - for (int i = 0; i < npars; ++i) {
497   -
498   - // Get parameter element
499   - GXmlElement* par = xml.element("parameter", i);
500   -
501   - // Handle Sigma
502   - if (par->attribute("name") == "Sigma") {
503   - m_sigma.write(*par);
504   - npar[0]++;
505   - }
506   -
507   - } // endfor: looped over all parameters
508   -
509   - // Check of all required parameters are present
510   - if (npar[0] != 1) {
511   - throw GException::model_invalid_parnames(G_WRITE, xml,
512   - "Require \"Sigma\" parameter.");
513   - }
  461 + // Write parameters
  462 + m_sigma.write(*sigma);
514 463  
515 464 // Return
516 465 return;
... ...
src/model/GModelSpatialRadialProfileGauss.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialRadialProfileGauss.cpp - Gaussian radial profile class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2016-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -265,7 +265,7 @@ void GModelSpatialRadialProfileGauss::read(const GXmlElement&amp; xml)
265 265 GModelSpatialRadial::read(xml);
266 266  
267 267 // Read Sigma parameter
268   - const GXmlElement* par = gammalib::xml_get_par(G_READ, xml, "Sigma");
  268 + const GXmlElement* par = gammalib::xml_get_par(G_READ, xml, m_sigma.name());
269 269 m_sigma.read(*par);
270 270  
271 271 // Return
... ... @@ -293,7 +293,7 @@ void GModelSpatialRadialProfileGauss::write(GXmlElement&amp; xml) const
293 293 GModelSpatialRadial::write(xml);
294 294  
295 295 // Write Sigma parameter
296   - GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "Sigma");
  296 + GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_sigma.name());
297 297 m_sigma.write(*par);
298 298  
299 299 // Return
... ...
src/model/GModelSpatialRadialShell.cpp
1 1 /***************************************************************************
2 2 * GModelSpatialRadialShell.cpp - Radial shell source model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2011-2017 by Christoph Deil *
  4 + * copyright (C) 2011-2018 by Christoph Deil *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -477,47 +477,13 @@ void GModelSpatialRadialShell::read(const GXmlElement&amp; xml)
477 477 // Read shell location
478 478 GModelSpatialRadial::read(xml);
479 479  
480   - // Extract remaining model parameters. Note that we have to loop over
481   - // all parameters to find the remaining 2 parameters that are
482   - // implemented by this class (the location is implemented by the base
483   - // class)
484   - int npar[2] = {0, 0};
485   - for (int i = 0; i < npars; ++i) {
486   -
487   - // Get parameter element
488   - const GXmlElement* par = xml.element("parameter", i);
489   -
490   - // Handle Radius
491   - if (par->attribute("name") == "Radius") {
492   -
493   - // Read parameter
494   - m_radius.read(*par);
495   -
496   - //TODO: Check parameter
497   -
498   - // Increment parameter counter
499   - npar[0]++;
500   - }
501   -
502   - // Handle Width
503   - else if (par->attribute("name") == "Width") {
504   -
505   - // Read parameter
506   - m_width.read(*par);
507   -
508   - //TODO: Check parameter
509   -
510   - // Increment parameter counter
511   - npar[1]++;
512   - }
  480 + // Get parameters
  481 + const GXmlElement* radius = gammalib::xml_get_par(G_READ, xml, m_radius.name());
  482 + const GXmlElement* width = gammalib::xml_get_par(G_READ, xml, m_width.name());
513 483  
514   - } // endfor: looped over all parameters
515   -
516   - // Verify that all parameters were found
517   - if (npar[0] != 1 || npar[1] != 1) {
518   - throw GException::model_invalid_parnames(G_READ, xml,
519   - "Require \"Radius\" and \"Width\" parameters.");
520   - }
  484 + // Read parameters
  485 + m_radius.read(*radius);
  486 + m_width.read(*width);
521 487  
522 488 // Return
523 489 return;
... ... @@ -552,48 +518,13 @@ void GModelSpatialRadialShell::write(GXmlElement&amp; xml) const
552 518 // Write shell location
553 519 GModelSpatialRadial::write(xml);
554 520  
555   - // If XML element has 2 nodes (which should be the location nodes)
556   - // then append 2 parameter nodes
557   - if (xml.elements() == 2) {
558   - xml.append(GXmlElement("parameter name=\"Radius\""));
559   - xml.append(GXmlElement("parameter name=\"Width\""));
560   - }
  521 + // Get or create parameters
  522 + GXmlElement* radius = gammalib::xml_need_par(G_WRITE, xml, m_radius.name());
  523 + GXmlElement* width = gammalib::xml_need_par(G_WRITE, xml, m_width.name());
561 524  
562   - // Determine number of parameter nodes in XML element
563   - int npars = xml.elements("parameter");
564   -
565   - // Verify that XML element has exactly 4 parameters
566   - if (xml.elements() != 4 || npars != 4) {
567   - throw GException::model_invalid_parnum(G_WRITE, xml,
568   - "Shell source model requires exactly 4 parameters.");
569   - }
570   -
571   - // Set or update model parameter attributes
572   - int npar[2] = {0, 0};
573   - for (int i = 0; i < npars; ++i) {
574   -
575   - // Get parameter element
576   - GXmlElement* par = xml.element("parameter", i);
577   -
578   - // Handle Radius
579   - if (par->attribute("name") == "Radius") {
580   - m_radius.write(*par);
581   - npar[0]++;
582   - }
583   -
584   - // Handle Width
585   - else if (par->attribute("name") == "Width") {
586   - m_width.write(*par);
587   - npar[1]++;
588   - }
589   -
590   - } // endfor: looped over all parameters
591   -
592   - // Check of all required parameters are present
593   - if (npar[0] != 1 || npar[1] != 1) {
594   - throw GException::model_invalid_parnames(G_WRITE, xml,
595   - "Require \"Radius\" and \"Width\" parameters.");
596   - }
  525 + // Write parameters
  526 + m_radius.write(*radius);
  527 + m_width.write(*width);
597 528  
598 529 // Return
599 530 return;
... ...
src/model/GModelSpectralFunc.cpp
... ... @@ -579,7 +579,6 @@ void GModelSpectralFunc::read(const GXmlElement&amp; xml)
579 579 }
580 580  
581 581 // Load nodes from file
582   - //load_nodes(xml.attribute("file"));
583 582 load_nodes(gammalib::xml_file_expand(xml, xml.attribute("file")));
584 583  
585 584 // Return
... ... @@ -646,7 +645,6 @@ void GModelSpectralFunc::write(GXmlElement&amp; xml) const
646 645 }
647 646  
648 647 // Set file attribute
649   - //xml.attribute("file", m_filename.url());
650 648 xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename));
651 649  
652 650 // Return
... ...
src/model/GModelSpectralGauss.cpp
... ... @@ -503,48 +503,15 @@ GEnergy GModelSpectralGauss::mc(const GEnergy&amp; emin,
503 503 ***************************************************************************/
504 504 void GModelSpectralGauss::read(const GXmlElement& xml)
505 505 {
506   - // Set number of parameters
507   - const int n_pars = 3;
  506 + // Get parameters
  507 + const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name());
  508 + const GXmlElement* mean = gammalib::xml_get_par(G_READ, xml, m_mean.name());
  509 + const GXmlElement* sigma = gammalib::xml_get_par(G_READ, xml, m_sigma.name());
508 510  
509   - // Verify that XML element has exactly 3 parameters
510   - if (xml.elements() != n_pars || xml.elements("parameter") != n_pars) {
511   - throw GException::model_invalid_parnum(G_READ, xml,
512   - "Gaussian model requires exactly 3 parameters.");
513   - }
514   -
515   - // Extract model parameters
516   - int npar[] = {0, 0, 0};
517   - for (int i = 0; i < n_pars; ++i) {
518   -
519   - // Get parameter element
520   - const GXmlElement* par = xml.element("parameter", i);
521   -
522   - // Handle normalization
523   - if (par->attribute("name") == "Normalization") {
524   - m_norm.read(*par);
525   - npar[0]++;
526   - }
527   -
528   - // Handle mean
529   - else if (par->attribute("name") == "Mean") {
530   - m_mean.read(*par);
531   - npar[1]++;
532   - }
533   -
534   - // Handle sigma
535   - else if (par->attribute("name") == "Sigma") {
536   - m_sigma.read(*par);
537   - npar[2]++;
538   - }
539   -
540   - } // endfor: looped over all parameters
541   -
542   - // Verify that all parameters were found
543   - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1) {
544   - throw GException::model_invalid_parnames(G_READ, xml,
545   - "Require \"Normalization\", \"Mean\", and \"Sigma\""
546   - " parameters.");
547   - }
  511 + // Read parameters
  512 + m_norm.read(*norm);
  513 + m_mean.read(*mean);
  514 + m_sigma.read(*sigma);
548 515  
549 516 // Return
550 517 return;
... ... @@ -576,62 +543,24 @@ void GModelSpectralGauss::write(GXmlElement&amp; xml) const
576 543 {
577 544 // Set model type
578 545 if (xml.attribute("type") == "") {
579   - xml.attribute("type", "Gaussian");
  546 + xml.attribute("type", type());
580 547 }
581 548  
582 549 // Verify model type
583   - if (xml.attribute("type") != "Gaussian") {
  550 + if (xml.attribute("type") != type()) {
584 551 throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"),
585   - "Spectral model is not of type \"Gaussian\".");
586   - }
587   -
588   - // If XML element has 0 nodes then append 3 parameter nodes
589   - if (xml.elements() == 0) {
590   - xml.append(GXmlElement("parameter name=\"Normalization\""));
591   - xml.append(GXmlElement("parameter name=\"Mean\""));
592   - xml.append(GXmlElement("parameter name=\"Sigma\""));
593   - }
594   -
595   - // Verify that XML element has exactly 3 parameters
596   - if (xml.elements() != 3 || xml.elements("parameter") != 3) {
597   - throw GException::model_invalid_parnum(G_WRITE, xml,
598   - "Power law model requires exactly 3 parameters.");
  552 + "Spectral model is not of type \""+type()+"\".");
599 553 }
600 554  
601   - // Set or update model parameter attributes
602   - int npar[] = {0, 0, 0};
603   - for (int i = 0; i < 3; ++i) {
604   -
605   - // Get parameter element
606   - GXmlElement* par = xml.element("parameter", i);
  555 + // Get XML parameters
  556 + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name());
  557 + GXmlElement* mean = gammalib::xml_need_par(G_WRITE, xml, m_mean.name());
  558 + GXmlElement* sigma = gammalib::xml_need_par(G_WRITE, xml, m_sigma.name());
607 559  
608   - // Handle normalization
609   - if (par->attribute("name") == "Normalization") {
610   - npar[0]++;
611   - m_norm.write(*par);
612   - }
613   -
614   - // Handle mean
615   - else if (par->attribute("name") == "Mean") {
616   - npar[1]++;
617   - m_mean.write(*par);
618   - }
619   -
620   - // Handle sigma
621   - else if (par->attribute("name") == "Sigma") {
622   - npar[2]++;
623   - m_sigma.write(*par);
624   - }
625   -
626   -
627   - } // endfor: looped over all parameters
628   -
629   - // Check of all required parameters are present
630   - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 ) {
631   - throw GException::model_invalid_parnames(G_WRITE, xml,
632   - "Require \"Normalization\", \"Mean\" and \"Sigma\""
633   - " parameters.");
634   - }
  560 + // Write parameters
  561 + m_norm.write(*norm);
  562 + m_mean.write(*mean);
  563 + m_sigma.write(*sigma);
635 564  
636 565 // Return
637 566 return;
... ...
src/model/GModelSpectralNodes.cpp
1 1 /***************************************************************************
2 2 * GModelSpectralNodes.cpp - Spectral nodes model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2012-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2012-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -645,38 +645,13 @@ void GModelSpectralNodes::read(const GXmlElement&amp; xml)
645 645 // Get node
646 646 const GXmlElement* node = xml.element("node", i);
647 647  
648   - // Verify that node XML element has exactly 2 parameters
649   - if (node->elements() != 2 || node->elements("parameter") != 2) {
650   - throw GException::model_invalid_parnum(G_READ, xml,
651   - "Node requires exactly 2 parameters.");
652   - }
653   -
654   - // Extract node parameters
655   - int npar[] = {0, 0};
656   - for (int k = 0; k < 2; ++k) {
657   -
658   - // Get parameter element
659   - const GXmlElement* par = node->element("parameter", k);
660   -
661   - // Handle energy
662   - if (par->attribute("name") == "Energy") {
663   - energy.read(*par);
664   - npar[0]++;
665   - }
  648 + // Get parameters
  649 + const GXmlElement* epar = gammalib::xml_get_par(G_READ, *node, "Energy");
  650 + const GXmlElement* ipar = gammalib::xml_get_par(G_READ, *node, "Intensity");
666 651  
667   - // Handle intensity
668   - else if (par->attribute("name") == "Intensity") {
669   - intensity.read(*par);
670   - npar[1]++;
671   - }
672   -
673   - } // endfor: looped over parameters
674   -
675   - // Verify that all parameters were found
676   - if (npar[0] != 1 || npar[1] != 1) {
677   - throw GException::model_invalid_parnames(G_READ, xml,
678   - "Require \"Energy\" and \"Intensity\" parameters.");
679   - }
  652 + // Read parameters
  653 + energy.read(*epar);
  654 + intensity.read(*ipar);
680 655  
681 656 // Throw an exception if either energy or intensity is not positive
682 657 if (energy.value() <= 0.0) {
... ...
src/model/GModelTemporalConst.cpp
1 1 /***************************************************************************
2 2 * GModelTemporalConst.cpp - Temporal constant model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2009-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2009-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -326,27 +326,11 @@ GTimes GModelTemporalConst::mc(const double&amp; rate, const GTime&amp; tmin,
326 326 ***************************************************************************/
327 327 void GModelTemporalConst::read(const GXmlElement& xml)
328 328 {
329   - // Verify that XML element has exactly 1 parameter
330   - if (xml.elements() != 1 || xml.elements("parameter") != 1) {
331   - std::string msg = "Constant temporal model requires exactly 1 "
332   - "<parameter> tag but "+
333   - gammalib::str(xml.elements("parameter"))+
334   - " <parameter> tags were found.";
335   - throw GException::invalid_value(G_READ, msg);
336   - }
  329 + // Get parameter pointers
  330 + const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name());
337 331  
338   - // Get parameter element
339   - const GXmlElement* par = xml.element("parameter", 0);
340   -
341   - // Get value
342   - if (par->attribute("name") == "Normalization") {
343   - m_norm.read(*par);
344   - }
345   - else {
346   - std::string msg = "Constant temporal model parameter "
347   - "\"Normalization\" not found in XML element.";
348   - throw GException::invalid_value(G_READ, msg);
349   - }
  332 + // Read parameters
  333 + m_norm.read(*norm);
350 334  
351 335 // Return
352 336 return;
... ... @@ -371,42 +355,20 @@ void GModelTemporalConst::write(GXmlElement&amp; xml) const
371 355 {
372 356 // Set model type
373 357 if (xml.attribute("type") == "") {
374   - xml.attribute("type", "Constant");
  358 + xml.attribute("type", type());
375 359 }
376 360  
377 361 // Verify model type
378   - if (xml.attribute("type") != "Constant") {
379   - std::string msg = "Temporal model of type "+xml.attribute("type")+
380   - " encountered while \"Constant\" was expected.";
381   - throw GException::invalid_value(G_WRITE, msg);
382   - }
383   -
384   - // If XML element has 0 nodes then append parameter node.
385   - if (xml.elements() == 0) {
386   - xml.append(GXmlElement("parameter name=\"Normalization\""));
387   - }
388   -
389   - // Verify that XML element has exactly 1 parameter
390   - if (xml.elements() != 1 || xml.elements("parameter") != 1) {
391   - std::string msg = "Constant temporal model requires exactly 1 "
392   - "<parameter> tag but "+
393   - gammalib::str(xml.elements("parameter"))+
394   - " <parameter> tags were found.";
395   - throw GException::invalid_value(G_WRITE, msg);
  362 + if (xml.attribute("type") != type()) {
  363 + throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"),
  364 + "Temporal model is not of type \""+type()+"\".");
396 365 }
397 366  
398   - // Get parameter element
399   - GXmlElement* par = xml.element("parameter", 0);
  367 + // Get XML parameters
  368 + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name());
400 369  
401   - // Set parameyter
402   - if (par->attribute("name") == "Normalization") {
403   - m_norm.write(*par);
404   - }
405   - else {
406   - std::string msg = "Constant temporal model parameter "
407   - "\"Normalization\" not found in XML element.";
408   - throw GException::invalid_value(G_WRITE, msg);
409   - }
  370 + // Write parameters
  371 + m_norm.write(*norm);
410 372  
411 373 // Return
412 374 return;
... ... @@ -416,7 +378,7 @@ void GModelTemporalConst::write(GXmlElement&amp; xml) const
416 378 /***********************************************************************//**
417 379 * @brief Print constant information
418 380 *
419   - * @param[in] chatter Chattiness (defaults to NORMAL).
  381 + * @param[in] chatter Chattiness.
420 382 * @return String containing model information.
421 383 ***************************************************************************/
422 384 std::string GModelTemporalConst::print(const GChatter& chatter) const
... ...