GammaLib 2.0.0
Loading...
Searching...
No Matches
GLATObservation.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GLATObservation.cpp - Fermi LAT observation class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2008-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 GLATObservation.cpp
23 * @brief Fermi LAT observation class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <typeinfo>
32#include "GException.hpp"
34#include "GLATObservation.hpp"
35#include "GLATEventList.hpp"
36#include "GLATEventCube.hpp"
37#include "GLATRoi.hpp"
38#include "GFits.hpp"
39#include "GTools.hpp"
40#include "GEnergy.hpp"
41
42/* __ Globals ____________________________________________________________ */
44const GObservationRegistry g_obs_lat_registry(&g_obs_lat_seed);
45
46/* __ Method name definitions ____________________________________________ */
47#define G_RESPONSE "GLATObservation::response(GResponse&)"
48#define G_READ "GLATObservation::read(GXmlElement&)"
49#define G_WRITE "GLATObservation::write(GXmlElement&)"
50
51/* __ Macros _____________________________________________________________ */
52
53/* __ Coding definitions _________________________________________________ */
54
55/* __ Debug definitions __________________________________________________ */
56
57
58/*==========================================================================
59 = =
60 = Constructors/destructors =
61 = =
62 ==========================================================================*/
63
64/***********************************************************************//**
65 * @brief Void constructor
66 ***************************************************************************/
68{
69 // Initialise members
71
72 // Return
73 return;
74}
75
76
77/***********************************************************************//**
78 * @brief XML constructor
79 *
80 * @param[in] xml XML element.
81 *
82 * Constructs a LAT observation from the information that is found in an
83 * XML element.
84 ***************************************************************************/
86{
87 // Initialise members
89
90 // Read XML
91 read(xml);
92
93 // Return
94 return;
95}
96
97
98/***********************************************************************//**
99 * @brief Copy constructor
100 *
101 * @param[in] obs LAT observation.
102 ***************************************************************************/
104{
105 // Initialise members
106 init_members();
107
108 // Copy members
109 copy_members(obs);
110
111 // Return
112 return;
113}
114
115
116/***********************************************************************//**
117 * @brief Destructor
118 ***************************************************************************/
120{
121 // Free members
122 free_members();
123
124 // Return
125 return;
126}
127
128
129/*==========================================================================
130 = =
131 = Operators =
132 = =
133 ==========================================================================*/
134
135/***********************************************************************//**
136 * @brief Assignment operator
137 *
138 * @param[in] obs Fermi/LAT observation.
139 * @return Fermi/LAT observation.
140 ***************************************************************************/
142{
143 // Execute only if object is not identical
144 if (this != &obs) {
145
146 // Copy base class members
147 this->GObservation::operator=(obs);
148
149 // Free members
150 free_members();
151
152 // Initialise members
153 init_members();
154
155 // Copy members
156 copy_members(obs);
157
158 } // endif: object was not identical
159
160 // Return this object
161 return *this;
162}
163
164
165/*==========================================================================
166 = =
167 = Public methods =
168 = =
169 ==========================================================================*/
170
171/***********************************************************************//**
172 * @brief Clear Fermi/LAT observation
173 ***************************************************************************/
175{
176 // Free members
177 free_members();
179
180 // Initialise members
182 init_members();
183
184 // Return
185 return;
186}
187
188
189/***********************************************************************//**
190 * @brief Clone Fermi/LAT observation
191 *
192 * @return Pointer to deep copy of Fermi/LAT observation.
193 ***************************************************************************/
195{
196 return new GLATObservation(*this);
197}
198
199
200/***********************************************************************//**
201 * @brief Set response function
202 *
203 * @param[in] rsp Response function.
204 *
205 * @exception GException::invalid_argument
206 * Response @p rsp in not a LAT response.
207 *
208 * Sets the response function for the observation. The argument has to be of
209 * type GLATResponse, otherwise an exception is thrown.
210 ***************************************************************************/
212{
213 // Get pointer on LAT response
214 const GLATResponse* latrsp = dynamic_cast<const GLATResponse*>(&rsp);
215
216 // If pointer is not valid then throw an exception
217 if (latrsp == NULL) {
218 std::string cls = std::string(typeid(&rsp).name());
219 std::string msg = "Invalid response type \""+cls+"\" specified. "
220 "Please specify a \"GLATResponse\" instance as "
221 "argument.";
223 }
224
225 // Copy response function
226 m_response = *latrsp;
227
228 // Return
229 return;
230}
231
232
233/***********************************************************************//**
234 * @brief Set response function
235 *
236 * @param[in] irfname Name of instrument response function.
237 *
238 * Set the LAT response function using the IRF name and the path to the
239 * calibration database. The IRF name has to be one of
240 *
241 * name (is equivalent to front+back)
242 * name::front
243 * name::back
244 * name::psf(0-3)
245 * name::edisp(0-3)
246 *
247 * where name is the response name (for example "P8R2_SOURCE_V6"). Note that
248 * the name is case sensitive, but the event typ is not case sensitive.
249 ***************************************************************************/
250void GLATObservation::response(const std::string& irfname)
251{
252 // Clear LAT response function
254
255 // Load instrument response function
256 m_response.load(irfname);
257
258 // Return
259 return;
260}
261
262
263/***********************************************************************//**
264 * @brief Read observation from XML element
265 *
266 * @param[in] xml XML element.
267 *
268 * @exception GException::invalid_value
269 * Invalid parameter names found in XML element.
270 *
271 * Reads information for a LAT observation from an XML element. The expected
272 * format of the XML element is
273 *
274 * <observation name="..." id="..." instrument="LAT">
275 * <parameter name="FT1" file="..."/>
276 * <parameter name="FT2" file="..."/>
277 * <parameter name="LiveTimeCube" file="..."/>
278 * <parameter name="IRF" file="..."/>
279 * </observation>
280 *
281 * for an unbinned observation and
282 *
283 * <observation name="..." id="..." instrument="LAT">
284 * <parameter name="CountsMap" file="..."/>
285 * <parameter name="ExposureMap" file="..."/>
286 * <parameter name="LiveTimeCube" file="..."/>
287 * <parameter name="IRF" value="..."/>
288 * </observation>
289 *
290 * for a binned observation.
291 ***************************************************************************/
293{
294 // Clear observation
295 clear();
296
297 // Initialise attributes
298 std::string ft1file = "";
299 std::string ft2file = "";
300 std::string ltfile = "";
301 std::string cntfile = "";
302 std::string expfile = "";
303 std::string irfname = "";
304
305 // Determine number of parameter nodes in XML element
306 int npars = xml.elements("parameter");
307
308 // Verify that XML element has exactly 4 parameters
310
311 // Extract parameters
312 int npar1[] = {0, 0, 0, 0};
313 int npar2[] = {0, 0, 0, 0};
314 for (int i = 0; i < npars; ++i) {
315
316 // Get parameter element
317 const GXmlElement* par = xml.element("parameter", i);
318
319 // Handle Unbinned format
320 if (par->attribute("name") == "FT1") {
321 ft1file = par->attribute("file");
322 npar1[0]++;
323 }
324 else if (par->attribute("name") == "FT2") {
325 ft2file = par->attribute("file");
326 npar1[1]++;
327 }
328
329 // Handle Binned format
330 else if (par->attribute("name") == "CountsMap") {
331 cntfile = par->attribute("file");
332 npar2[0]++;
333 }
334 else if (par->attribute("name") == "ExposureMap") {
335 expfile = par->attribute("file");
336 npar2[1]++;
337 }
338
339 // Handle common parameters
340 else if (par->attribute("name") == "LiveTimeCube") {
341 ltfile = par->attribute("file");
342 npar1[2]++;
343 npar2[2]++;
344 }
345 else if (par->attribute("name") == "IRF") {
346 irfname = par->attribute("value");
347 npar1[3]++;
348 npar2[3]++;
349 }
350
351 } // endfor: looped over all parameters
352
353 // Verify that all parameters were found
354 bool unbin_ok = (npar1[0] == 1 && npar1[1] == 1 && npar1[2] == 1 && npar1[3] == 1);
355 bool bin_ok = (npar2[0] == 1 && npar2[1] == 1 && npar2[2] == 1 && npar2[3] == 1);
356 if (!bin_ok && !unbin_ok) {
357 std::string msg = "Require either \"FT1\", \"FT2\", \"LiveTimeCube\", "
358 "and \"IRF\" or \"CountsMap\", \"ExposureMap\", "
359 "\"LiveTimeCube\", and \"IRF\" parameters. Please "
360 "verify the XML format.";
362 }
363
364 // Load data
365 if (unbin_ok) {
366
367 // Expand file names
368 ft1file = gammalib::xml_file_expand(xml, ft1file);
369 ft2file = gammalib::xml_file_expand(xml, ft2file);
370 ltfile = gammalib::xml_file_expand(xml, ltfile);
371
372 // Load files
373 load_unbinned(ft1file, ft2file, ltfile);
374 }
375 else {
376
377 // Expand file names
378 cntfile = gammalib::xml_file_expand(xml, cntfile);
379 expfile = gammalib::xml_file_expand(xml, expfile);
380 ltfile = gammalib::xml_file_expand(xml, ltfile);
381
382 // Load files
383 load_binned(cntfile, expfile, ltfile);
384 }
385
386 // Set response function
387 response(irfname);
388
389 // Return
390 return;
391}
392
393
394/***********************************************************************//**
395 * @brief Write observation into XML element
396 *
397 * @param[in] xml XML element.
398 *
399 * @exception GException::invalid_value
400 * No events allocated or invalid parameter names found in XML element..
401 * @exception GException::runtime_error
402 * Non-LAT events encountered.
403 *
404 * Writes information for a LAT observation into an XML element. The expected
405 * format of the XML element is
406 *
407 * <observation name="..." id="..." instrument="LAT">
408 * <parameter name="FT1" file="..."/>
409 * <parameter name="FT2" file="..."/>
410 * <parameter name="LiveTimeCube" file="..."/>
411 * <parameter name="IRF" file="..."/>
412 * </observation>
413 *
414 * for an unbinned observation and
415 *
416 * <observation name="..." id="..." instrument="LAT">
417 * <parameter name="CountsMap" file="..."/>
418 * <parameter name="ExposureMap" file="..."/>
419 * <parameter name="LiveTimeCube" file="..."/>
420 * <parameter name="IRF" value="..."/>
421 * </observation>
422 *
423 * for a binned observation.
424 *
425 * @todo We should create a special exception that informs that there is
426 * neither a valid LAT event list nor a valid LAT counts map in this
427 * observations.
428 ***************************************************************************/
430{
431 // Determine if we deal with a binned or unbinned observation
432 const GLATEventList* list = dynamic_cast<const GLATEventList*>(m_events);
433 const GLATEventCube* cube = dynamic_cast<const GLATEventCube*>(m_events);
434 if (list == NULL && cube == NULL) {
435 if (m_events == NULL) {
436 std::string msg = "No events associated with LAT observation. "
437 "Please allocate events before calling the "
438 "method.";
440 }
441 else {
442 std::string cls = std::string(typeid(&m_events).name());
443 std::string msg = "Invalid event type \""+cls+"\" encountered. A "
444 "LAT observation can only contain a LAT event "
445 "list or cube. Please set up LAT observation "
446 "appropriately.";
448 }
449 }
450
451 // Set event list flag
452 bool is_list = (list != NULL);
453
454 // If XML element has 0 nodes then append 4 parameter nodes
455 if (xml.elements() == 0) {
456 if (is_list) {
457 xml.append(GXmlElement("parameter name=\"FT1\""));
458 xml.append(GXmlElement("parameter name=\"FT2\""));
459 xml.append(GXmlElement("parameter name=\"LiveTimeCube\""));
460 xml.append(GXmlElement("parameter name=\"IRF\""));
461 }
462 else {
463 xml.append(GXmlElement("parameter name=\"CountsMap\""));
464 xml.append(GXmlElement("parameter name=\"ExposureMap\""));
465 xml.append(GXmlElement("parameter name=\"LiveTimeCube\""));
466 xml.append(GXmlElement("parameter name=\"IRF\""));
467 }
468 }
469
470 // Verify that XML element has exactly 4 parameters
472
473 // Set or update parameter attributes
474 int npar[] = {0, 0, 0, 0};
475 for (int i = 0; i < 4; ++i) {
476
477 // Get parameter element
478 GXmlElement* par = xml.element("parameter", i);
479
480 // Handle FT1
481 if (par->attribute("name") == "FT1") {
483 npar[0]++;
484 }
485
486 // Handle CountsMap
487 else if (par->attribute("name") == "CountsMap") {
489 npar[0]++;
490 }
491
492 // Handle FT2
493 else if (par->attribute("name") == "FT2") {
495 npar[1]++;
496 }
497
498 // Handle ExposureMap
499 else if (par->attribute("name") == "ExposureMap") {
501 npar[1]++;
502 }
503
504 // Handle LiveTimeCube
505 else if (par->attribute("name") == "LiveTimeCube") {
506 par->attribute("file", gammalib::xml_file_reduce(xml, m_ltfile));
507 npar[2]++;
508 }
509
510 // Handle IRF
511 else if (par->attribute("name") == "IRF") {
512 par->attribute("value", m_response.rspname());
513 npar[3]++;
514 }
515
516 } // endfor: looped over all parameters
517
518 // Verify that all required parameters are present
519 if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) {
520 std::string msg = "Require either \"FT1\", \"FT2\", \"LiveTimeCube\", "
521 "and \"IRF\" or \"CountsMap\", \"ExposureMap\", "
522 "\"LiveTimeCube\", and \"IRF\" parameters. Please "
523 "verify the XML format.";
525 }
526
527 // Return
528 return;
529}
530
531
532/***********************************************************************//**
533 * @brief Print LAT observation information
534 *
535 * @param[in] chatter Chattiness.
536 * @return String containing LAT observation information.
537 ***************************************************************************/
538std::string GLATObservation::print(const GChatter& chatter) const
539{
540 // Initialise result string
541 std::string result;
542
543 // Continue only if chatter is not silent
544 if (chatter != SILENT) {
545
546 // Append header
547 result.append("=== GLATObservation ===");
548
549 // Append information
550 result.append("\n"+gammalib::parformat("Name")+name());
551 result.append("\n"+gammalib::parformat("Identifier")+id());
552 result.append("\n"+gammalib::parformat("Instrument")+instrument());
553 result.append("\n"+gammalib::parformat("Statistic")+statistic());
554 result.append("\n"+gammalib::parformat("Ontime"));
555 result.append(gammalib::str(ontime())+" s");
556 result.append("\n"+gammalib::parformat("Livetime"));
557 result.append(gammalib::str(livetime())+" s");
558
559 // Append detailed information
560 GChatter reduced_chatter = gammalib::reduce(chatter);
561 if (reduced_chatter > SILENT) {
562
563 // Append response
564 result.append("\n"+m_response.print(reduced_chatter));
565
566 // Append livetime cube
567 if (m_ltcube != NULL) {
568 result.append("\n"+m_ltcube->print(reduced_chatter));
569 }
570 else {
571 result.append("\n"+gammalib::parformat("LAT livetime cube"));
572 result.append("undefined");
573 }
574
575 // Append events
576 if (m_events != NULL) {
577 result.append("\n"+m_events->print(reduced_chatter));
578 }
579
580 } // endif: appended detailed information
581
582 } // endif: chatter was not silent
583
584 // Return result
585 return result;
586}
587
588
589/***********************************************************************//**
590 * @brief Load data for unbinned analysis
591 *
592 * @param[in] ft1name FT1 FITS filename.
593 * @param[in] ft2name FT2 FITS filename.
594 * @param[in] ltcube_name Livetime cube FITS filename
595 *
596 * @todo So far nothing is done with the ft2 file and the ltcube file.
597 * Loading of the relevant information needs to be implemented.
598 ***************************************************************************/
599void GLATObservation::load_unbinned(const std::string& ft1name,
600 const std::string& ft2name,
601 const std::string& ltcube_name)
602{
603 // Delete any existing event container (do not call clear() as we do not
604 // want to delete the response function)
605 if (m_events != NULL) delete m_events;
606 m_events = NULL;
607
608 // Allocate event list
610
611 // Assign event list as the observation's event container
613
614 // Open FITS file
615 GFits file(ft1name);
616
617 // Read event list
618 events->read(file);
619
620 // Read observation attributes from EVENTS extension
621 //GFitsHDU* hdu = file.hdu("EVENTS");
622 //read_attributes(hdu);
623
624 // Close FITS file
625 file.close();
626
627 // Optionally allocate and load livetime cube
628 if (ltcube_name.length() > 0) {
629 m_ltcube = new GLATLtCube;
630 m_ltcube->load(ltcube_name);
631 }
632
633 // Store filenames
634 m_ft1file = ft1name;
635 m_ft2file = ft2name;
636 m_ltfile = ltcube_name;
637
638 // Return
639 return;
640}
641
642
643/***********************************************************************//**
644 * @brief Load data for binned analysis
645 *
646 * @param[in] cntmap_name Counts map or Source map FITS filename
647 * @param[in] expmap_name Binned explosure map FITS filename
648 * @param[in] ltcube_name Livetime cube FITS filename
649 *
650 * @todo So far nothing is done with the expmap file.
651 * Approriate loading needs to be implemented.
652 ***************************************************************************/
653void GLATObservation::load_binned(const std::string& cntmap_name,
654 const std::string& expmap_name,
655 const std::string& ltcube_name)
656{
657 // Delete old events and livetime cube. We do not call clear() here
658 // since we want to preserve any existing response function.
659 if (m_events != NULL) delete m_events;
660 if (m_ltcube != NULL) delete m_ltcube;
661 m_events = NULL;
662 m_ltcube = NULL;
663
664 // Allocate event cube
666
667 // Assign event cube as the observation's event container
669
670 // Load event list
671 events->load(cntmap_name);
672
673 // Optionally allocate and load livetime cube
674 if (ltcube_name.length() > 0) {
675 m_ltcube = new GLATLtCube;
676 m_ltcube->load(ltcube_name);
677 }
678
679 // Store filenames
680 m_cntfile = cntmap_name;
681 m_expfile = expmap_name;
682 m_ltfile = ltcube_name;
683
684 // Return
685 return;
686}
687
688
689/*==========================================================================
690 = =
691 = Private methods =
692 = =
693 ==========================================================================*/
694
695/***********************************************************************//**
696 * @brief Initialise class members
697 ***************************************************************************/
699{
700 // Initialise members
701 m_ft1file.clear();
702 m_ft2file.clear();
703 m_ltfile.clear();
704 m_cntfile.clear();
705 m_expfile.clear();
707 m_ltcube = NULL;
708
709 // Return
710 return;
711}
712
713
714/***********************************************************************//**
715 * @brief Copy class members
716 *
717 * @param[in] obs LAT observation.
718 ***************************************************************************/
720{
721 // Copy members
722 m_ft1file = obs.m_ft1file;
723 m_ft2file = obs.m_ft2file;
724 m_ltfile = obs.m_ltfile;
725 m_cntfile = obs.m_cntfile;
726 m_expfile = obs.m_expfile;
728
729 // Clone members
730 if (obs.m_ltcube != NULL) m_ltcube = obs.m_ltcube->clone();
731
732 // Return
733 return;
734}
735
736
737/***********************************************************************//**
738 * @brief Delete class members
739 ***************************************************************************/
741{
742 // Free memory
743 if (m_ltcube != NULL) delete m_ltcube;
744
745 // Mark memory as free
746 m_ltcube = NULL;
747
748 // Return
749 return;
750}
#define G_WRITE
#define G_READ
#define G_RESPONSE
Energy value class definition.
Exception handler interface definition.
FITS file class interface definition.
Fermi/LAT event cube class definition.
Fermi/LAT event list class definition.
const GLATObservation g_obs_lat_seed
Fermi/LAT observation class definition.
Fermi/LAT region of interest class definition.
Observation registry class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
virtual void read(const GFits &file)=0
virtual std::string print(const GChatter &chatter=NORMAL) const =0
Print content of object.
virtual void load(const GFilename &filename)=0
FITS file class.
Definition GFits.hpp:63
void close(void)
Close FITS file.
Definition GFits.cpp:1342
Fermi/LAT event cube class.
Fermi/LAT event list class.
Interface for the Fermi LAT livetime cube.
GLATLtCube * clone(void) const
Clone livetime cube.
std::string print(const GChatter &chatter=NORMAL) const
Print livetime cube information.
void load(const GFilename &filename)
Load livetime cube from FITS file.
Fermi/LAT observation class.
virtual void write(GXmlElement &xml) const
Write observation into XML element.
virtual void read(const GXmlElement &xml)
Read observation from XML element.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print LAT observation information.
void init_members(void)
Initialise class members.
std::string m_expfile
Exposure map filename.
virtual GLATObservation * clone(void) const
Clone Fermi/LAT observation.
void load_unbinned(const std::string &ft1name, const std::string &ft2name, const std::string &ltcube_name)
Load data for unbinned analysis.
std::string m_ltfile
Lifetime cube filename.
GLATObservation(void)
Void constructor.
void free_members(void)
Delete class members.
virtual double livetime(void) const
Return livetime.
void copy_members(const GLATObservation &obs)
Copy class members.
GLATLtCube * m_ltcube
Pointer to livetime cube.
std::string m_ft1file
FT1 filename.
virtual std::string instrument(void) const
Return instrument name.
std::string m_cntfile
Counts map filename.
virtual const GLATResponse * response(void) const
Return Fermi/LAT response function.
virtual void clear(void)
Clear Fermi/LAT observation.
void load_binned(const std::string &cntmap_name, const std::string &expmap_name, const std::string &ltcube_name)
Load data for binned analysis.
virtual double ontime(void) const
Return ontime.
GLATObservation & operator=(const GLATObservation &obs)
Assignment operator.
virtual ~GLATObservation(void)
Destructor.
std::string m_ft2file
FT2 filename.
GLATResponse m_response
Instrument response functions.
Fermi/LAT Response class.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print Fermi-LAT response information.
const std::string & rspname(void) const
Return response name.
virtual void clear(void)
Clear response.
void load(const std::string &rspname)
Load Fermi LAT response from calibration database.
Interface definition for the observation registry class.
Abstract observation base class.
const std::string & statistic(void) const
Return optimizer statistic.
const std::string & name(void) const
Return observation name.
virtual GEvents * events(void)
Return events.
void init_members(void)
Initialise class members.
virtual GObservation & operator=(const GObservation &obs)
Assignment operator.
GEvents * m_events
Pointer to event container.
void free_members(void)
Delete class members.
Abstract instrument response base class.
Definition GResponse.hpp:77
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
GFilename xml_file_reduce(const GXmlElement &xml, const std::string &filename)
Reduce file name provided for writing as XML attribute.
Definition GTools.cpp:1946
void xml_check_parnum(const std::string &origin, const GXmlElement &xml, const int &number)
Checks number of parameters.
Definition GTools.cpp:1777
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition GTypemaps.hpp:65
GFilename xml_file_expand(const GXmlElement &xml, const std::string &filename)
Expand file name provided as XML attribute for loading.
Definition GTools.cpp:1889