GammaLib 2.2.0.dev
Loading...
Searching...
No Matches
GCOSObservation.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCOSObservation.cpp - COSI observation class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2026 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 GCOSObservation.cpp
23 * @brief COSI 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 "GCOSObservation.hpp"
35
36/* __ Globals ____________________________________________________________ */
38const GObservationRegistry g_obs_cos_registry(&g_obs_cos_seed);
39
40/* __ Method name definitions ____________________________________________ */
41#define G_RESPONSE "GCOSObservation::response(GResponse&)"
42#define G_READ "GCOSObservation::read(GXmlElement&)"
43#define G_WRITE "GCOSObservation::write(GXmlElement&)"
44#define G_LOAD "GCOSObservation::load(std::vector<GFilename>&, GFilename&, "\
45 "GFilename&)"
46
47/* __ Macros _____________________________________________________________ */
48
49/* __ Coding definitions _________________________________________________ */
50
51/* __ Debug definitions __________________________________________________ */
52
53
54/*==========================================================================
55 = =
56 = Constructors/destructors =
57 = =
58 ==========================================================================*/
59
60/***********************************************************************//**
61 * @brief Void constructor
62 *
63 * Creates an empty COSI observation.
64 ***************************************************************************/
66{
67 // Initialise members
69
70 // Return
71 return;
72}
73
74
75/***********************************************************************//**
76 * @brief XML constructor
77 *
78 * @param[in] xml XML element.
79 *
80 * Constructs a COSI observation from the information that is found in an
81 * XML element. See the read() method for more information.
82 ***************************************************************************/
84{
85 // Initialise members
87
88 // Read XML
89 read(xml);
90
91 // Return
92 return;
93}
94
95
96/***********************************************************************//**
97 * @brief Load constructor
98 *
99 * @param[in] eventname Event list FITS file name.
100 * @param[in] spacename Space craft file name.
101 * @param[in] rspname Response file name.
102 *
103 * Creates an unbinned COSI observation by loading an event list, a space
104 * craft file and a response file.
105 ***************************************************************************/
107 const GFilename& spacename,
108 const GFilename& rspname) : GObservation()
109{
110 // Initialise members
111 init_members();
112
113 // Load observation
114 load(eventname, spacename, rspname);
115
116 // Return
117 return;
118}
119
120
121/***********************************************************************//**
122 * @brief Load constructor
123 *
124 * @param[in] eventnames Vector of event list FITS file names.
125 * @param[in] spacename Space craft file name.
126 * @param[in] rspname Response file name.
127 *
128 * Creates an unbinned COSI observation by loading event lists, a space
129 * craft file and a response file. Multiple event lists are appended to
130 * each other and events are sorted by increasing time.
131 ***************************************************************************/
132GCOSObservation::GCOSObservation(const std::vector<GFilename>& eventnames,
133 const GFilename& spacename,
134 const GFilename& rspname) : GObservation()
135{
136 // Initialise members
137 init_members();
138
139 // Load observation
140 load(eventnames, spacename, rspname);
141
142 // Return
143 return;
144}
145
146
147/***********************************************************************//**
148 * @brief Copy constructor
149 *
150 * @param[in] obs COSI observation.
151 *
152 * Creates COSI observation by copying from an existing COSI
153 * observation.
154 ***************************************************************************/
156{
157 // Initialise members
158 init_members();
159
160 // Copy members
161 copy_members(obs);
162
163 // Return
164 return;
165}
166
167
168/***********************************************************************//**
169 * @brief Destructor
170 ***************************************************************************/
172{
173 // Free members
174 free_members();
175
176 // Return
177 return;
178}
179
180
181/*==========================================================================
182 = =
183 = Operators =
184 = =
185 ==========================================================================*/
186
187/***********************************************************************//**
188 * @brief Assignment operator
189 *
190 * @param[in] obs COSI observation.
191 * @return COSI observation.
192 *
193 * Assign COSI observation to this object. The assignment performs
194 * a deep copy of all information, hence the original object from which the
195 * assignment was made can be destroyed after this operation without any loss
196 * of information.
197 ***************************************************************************/
199{
200 // Execute only if object is not identical
201 if (this != &obs) {
202
203 // Copy base class members
204 this->GObservation::operator=(obs);
205
206 // Free members
207 free_members();
208
209 // Initialise members
210 init_members();
211
212 // Copy members
213 copy_members(obs);
214
215 } // endif: object was not identical
216
217 // Return this object
218 return *this;
219}
220
221
222/*==========================================================================
223 = =
224 = Public methods =
225 = =
226 ==========================================================================*/
227
228/***********************************************************************//**
229 * @brief Clear COSI observation
230 *
231 * Clears COSI observation by resetting all class members to an
232 * initial state. Any information that was present before will be lost.
233 ***************************************************************************/
235{
236 // Free members
237 free_members();
239
240 // Initialise members
242 init_members();
243
244 // Return
245 return;
246}
247
248
249/***********************************************************************//**
250 * @brief Clone COSI observation
251 *
252 * @return Pointer to deep copy of COSI observation.
253 ***************************************************************************/
255{
256 return new GCOSObservation(*this);
257}
258
259
260/***********************************************************************//**
261 * @brief Set COSI response function
262 *
263 * @param[in] rsp COSI response function.
264 *
265 * @exception GException::invalid_argument
266 * Specified response is not a COSI response.
267 *
268 * Sets the response function for the observation.
269 ***************************************************************************/
271{
272 // Get pointer on COSI response
273 const GCOSResponse* cosrsp = dynamic_cast<const GCOSResponse*>(&rsp);
274 if (cosrsp == NULL) {
275 std::string cls = std::string(typeid(&rsp).name());
276 std::string msg = "Response of type \""+cls+"\" is "
277 "not a COSI response. Please specify a "
278 "COSI response as argument.";
280 }
281
282 // Clone response function
283 m_response = *cosrsp;
284
285 // Return
286 return;
287}
288
289
290/***********************************************************************//**
291 * @brief Read COSI observation from XML element
292 *
293 * @param[in] xml XML element.
294 *
295 * Reads information for a COSI observation from an XML element. The
296 * method supports both an unbinned and a binned observation.
297 *
298 * For an unbinned observation the XML format is
299 *
300 * <observation name="Crab" id="00001" instrument="COS">
301 * <parameter name="EventList" file="cosi_event_list.fits"/>
302 * <parameter name="SpaceCraftFile" file="cosi_orientation.ori"/>
303 * <parameter name="Response" file="cosi_response.h5"/>
304 * </observation>
305 *
306 * The method supports the presence of multiple "EventList" entries which
307 * will load all specified event lists and merge them into a single event
308 * list. The events will be ordered by increasing time.
309 *
310 * For a binned observation the XML format is
311 *
312 * <observation name="Crab" id="00001" instrument="COS">
313 * </observation>
314 *
315 ***************************************************************************/
317{
318 // Clear observation
319 clear();
320
321 // If the XML elements has an "EventList" attribute we have an unbinned
322 // observation
323 if (gammalib::xml_has_par(xml, "EventList")) {
324
325 // Get event list file names
326 std::vector<GFilename> eventnames;
327 for (int i = 0; i < xml.elements("parameter"); ++i) {
328 const GXmlElement* element = xml.element("parameter", i);
329 if (element->attribute("name") == "EventList") {
330 std::string eventname = element->attribute("file");
331 eventname = gammalib::xml_file_expand(xml, eventname);
332 eventnames.push_back(GFilename(eventname));
333 }
334 }
335
336 // Get space craft and response file names
337 std::string spacename = gammalib::xml_get_attr(G_READ, xml, "SpaceCraftFile", "file");
338 std::string rspname = gammalib::xml_get_attr(G_READ, xml, "Response", "file");
339
340 // Expand names
341 spacename = gammalib::xml_file_expand(xml, spacename);
342 rspname = gammalib::xml_file_expand(xml, rspname);
343
344 // Load observation
345 load(eventnames, spacename, rspname);
346
347 } // endif: unbinned observation
348
349 // ... otherwise we have a binned observation
350 else {
351
352 } // endelse: binned observation
353
354 // Extract attributes
355 m_name = xml.attribute("name");
356 m_id = xml.attribute("id");
357 m_instrument = xml.attribute("instrument");
358
359 // Return
360 return;
361}
362
363
364/***********************************************************************//**
365 * @brief Write COSI observation into XML element
366 *
367 * @param[in] xml XML element.
368 *
369 * Writes information for a COSI observation into an XML element. The
370 * method supports both an unbinned and a binned observation.
371 *
372 * For an unbinned observation the XML format is
373 *
374 * <observation name="Crab" id="00001" instrument="COS">
375 * <parameter name="EventList" file="cosi_event_list.fits"/>
376 * <parameter name="SpaceCraftFile" file="cosi_orientation.ori"/>
377 * <parameter name="Response" file="cosi_response.h5"/>
378 * </observation>
379 *
380 * If multiple event lists were read by the read() method, the method will
381 * write back the file names of all the event lists.
382 *
383 * For a binned observation the XML format is
384 *
385 * <observation name="Crab" id="00001" instrument="COS">
386 * </observation>
387 *
388 ***************************************************************************/
390{
391 // Allocate XML element pointer
392 GXmlElement* par;
393
394 // Handle unbinned observation
395 if (is_unbinned()) {
396
397 // Set event list parameters
398 for (int i = 0; i < m_eventnames.size(); ++i) {
399 par = static_cast<GXmlElement*>(xml.append(GXmlElement("parameter name=\"EventList\"")));
400 par->attribute("file", gammalib::xml_file_reduce(xml, m_eventnames[i]));
401 }
402
403 // Set space craft parameter
404 par = gammalib::xml_need_par(G_WRITE, xml, "SpaceCraftFile");
406
407 // Set response parameter
408 par = gammalib::xml_need_par(G_WRITE, xml, "Response");
410
411 } // endif: observation was unbinned
412
413 // ... otherwise handle a binned observation
414 else if (is_binned()) {
415
416 } // endif: observation was binned
417
418 // Return
419 return;
420}
421
422
423/***********************************************************************//**
424 * @brief Load data for an unbinned observation
425 *
426 * @param[in] eventname Event list FITS file name.
427 * @param[in] spacename Space craft file name.
428 * @param[in] rspname Response file name.
429 *
430 * Loads the event list, space craft file and the response for an unbinned
431 * observation.
432 ***************************************************************************/
433void GCOSObservation::load(const GFilename& eventname,
434 const GFilename& spacename,
435 const GFilename& rspname)
436{
437 // Clear object
438 clear();
439
440 // Setup event list vector with single element
441 std::vector<GFilename> eventnames;
442 eventnames.push_back(eventname);
443
444 // Load data
445 load(eventnames, spacename, rspname);
446
447 // Return
448 return;
449}
450
451
452/***********************************************************************//**
453 * @brief Load data for an unbinned observation
454 *
455 * @param[in] eventnames Vector of event list FITS file names.
456 * @param[in] spacename Space craft file name.
457 * @param[in] rspname Response file name.
458 *
459 * @exception GException::invalid_argument
460 * Empty event list name vector provided.
461 *
462 * Loads the event lists, space craft file and the response for an unbinned
463 * observation. Multiple event lists are appended to each other and events
464 * are sorted by increasing time.
465 *
466 * The method uses the Good Time Intervals provided in the space craft file
467 * and attaches them to the event list. The method also sets the m_ontime,
468 * m_livetime and m_deadc members from the information provided by the
469 * space craft file.
470 *
471 * The specified file names are stored in the m_eventnames, m_spacename and
472 * m_rspname class members which are used when writing the observation
473 * information into an XML element.
474 ***************************************************************************/
475void GCOSObservation::load(const std::vector<GFilename>& eventnames,
476 const GFilename& spacename,
477 const GFilename& rspname)
478{
479 // Clear object
480 clear();
481
482 // Check that at least one event list is provided
483 if (eventnames.size() == 0) {
484 std::string msg = "The eventnames vector is empty but the method "
485 "needs at least one event list name. Please "
486 "specify at least one event list name.";
488 }
489
490 // Load all event lists
491 for (int i = 0; i < eventnames.size(); ++i) {
492
493 // If this is the first event list then allocate event list
494 if (i == 0) {
495 m_events = new GCOSEventList(eventnames[0]);
496 }
497
498 // ... otherwise extend existing event list
499 else {
500 GCOSEventList events(eventnames[i]);
501 static_cast<GCOSEventList*>(m_events)->extend(events);
502 }
503
504 } // endfor: looped over event lists
505
506 // Sort events by increasing time
507 static_cast<GCOSEventList*>(m_events)->sort();
508
509 // Load space craft file
510 m_spacecraft.load(spacename);
511
512 // Load response
513 m_response.load(rspname);
514
515 // Set event list Good Time Intervals from the space craft file Good
516 // Time Intervals
518
519 // Set observation attributes
523
524 // Store filenames
525 m_eventnames = eventnames;
526 m_spacename = spacename;
527 m_rspname = rspname;
528
529 // Return
530 return;
531}
532
533
534/***********************************************************************//**
535 * @brief Print observation information
536 *
537 * @param[in] chatter Chattiness.
538 * @return String containing COSI observation information.
539 ***************************************************************************/
540std::string GCOSObservation::print(const GChatter& chatter) const
541{
542 // Initialise result string
543 std::string result;
544
545 // Continue only if chatter is not silent
546 if (chatter != SILENT) {
547
548 // Append header
549 result.append("=== GCOSObservation ===");
550
551 // Append standard information for observation
552 result.append("\n"+gammalib::parformat("Name")+name());
553 result.append("\n"+gammalib::parformat("Identifier")+id());
554 result.append("\n"+gammalib::parformat("Instrument")+instrument());
555 result.append("\n"+gammalib::parformat("Statistic")+statistic());
556 result.append("\n"+gammalib::parformat("Ontime"));
557 result.append(gammalib::str(ontime())+" sec");
558 result.append("\n"+gammalib::parformat("Livetime"));
559 result.append(gammalib::str(livetime())+" sec");
560 result.append("\n"+gammalib::parformat("Deadtime correction"));
561 result.append(gammalib::str(m_deadc));
562
563 // Append events
564 if (m_events != NULL) {
565 result.append("\n"+m_events->print(gammalib::reduce(chatter)));
566 }
567 else {
568 result.append("\n"+gammalib::parformat("Events")+"undefined");
569 }
570
571 } // endif: chatter was not silent
572
573 // Return result
574 return result;
575}
576
577
578/*==========================================================================
579 = =
580 = Private methods =
581 = =
582 ==========================================================================*/
583
584/***********************************************************************//**
585 * @brief Initialise class members
586 ***************************************************************************/
588{
589 // Initialise members
590 m_instrument = "COS";
593 m_ontime = 0.0;
594 m_livetime = 0.0;
595 m_deadc = 0.0;
596
597 // Initialise members for unbinned observation
598 m_eventnames.clear();
601
602 // Return
603 return;
604}
605
606
607/***********************************************************************//**
608 * @brief Copy class members
609 *
610 * @param[in] obs COSI observation.
611 ***************************************************************************/
613{
614 // Copy members
618 m_ontime = obs.m_ontime;
620 m_deadc = obs.m_deadc;
621
622 // Copy members for unbinned observation
625 m_rspname = obs.m_rspname;
626
627 // Return
628 return;
629}
630
631
632/***********************************************************************//**
633 * @brief Delete class members
634 ***************************************************************************/
636{
637 // Return
638 return;
639}
#define G_WRITE
#define G_READ
#define G_RESPONSE
const GCOSObservation g_obs_cos_seed
COSI observation class definition.
Exception handler interface definition.
#define G_LOAD
Observation registry class definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
COSI event list class.
COSI observation class.
GFilename m_rspname
Response filename.
virtual void write(GXmlElement &xml) const
Write COSI observation into XML element.
bool is_binned(void) const
Check whether observation is binned.
void copy_members(const GCOSObservation &obs)
Copy class members.
virtual double ontime(void) const
Return ontime.
void free_members(void)
Delete class members.
virtual ~GCOSObservation(void)
Destructor.
GCOSObservation(void)
Void constructor.
virtual double livetime(void) const
Return livetime.
bool is_unbinned(void) const
Check whether observation is unbinned.
void load(const GFilename &eventname, const GFilename &spacename, const GFilename &rspname)
Load data for an unbinned observation.
double m_ontime
Ontime (sec)
virtual const GCOSResponse * response(void) const
Return pointer to response function.
double m_deadc
Deadtime correction.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print observation information.
GFilename m_spacename
Space craft filename.
std::string m_instrument
Instrument name.
virtual std::string instrument(void) const
Return instrument.
virtual GCOSObservation * clone(void) const
Clone COSI observation.
virtual GCOSObservation & operator=(const GCOSObservation &obs)
Assignment operator.
GCOSResponse m_response
Response functions.
double m_livetime
Livetime (sec)
GCOSSpaceCraft m_spacecraft
Space craft information.
virtual void clear(void)
Clear COSI observation.
void init_members(void)
Initialise class members.
virtual void read(const GXmlElement &xml)
Read COSI observation from XML element.
std::vector< GFilename > m_eventnames
Event list filenames.
COSI instrument response function class.
virtual void clear(void)
Clear instance.
void load(const GFilename &filename)
const GGti & gti(void) const
Return Good Time Intervals.
void clear(void)
Clear space craft.
const double & deadc(void) const
Return deadtime correction factor.
const double & ontime(void) const
Return ontime in seconds.
void load(const GFilename &filename)
Load COSI space craft file.
const double & livetime(void) const
Return livetime in seconds.
void gti(const GGti &gti)
Set Good Time Intervals.
Definition GEvents.cpp:154
virtual std::string print(const GChatter &chatter=NORMAL) const =0
Print content of object.
Filename class.
Definition GFilename.hpp:62
void clear(void)
Clear file name.
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.
std::string m_name
Observation name.
std::string m_id
Observation identifier.
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:1136
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508
std::string xml_get_attr(const std::string &origin, const GXmlElement &xml, const std::string &name, const std::string &attribute)
Return attribute value for a given parameter in XML element.
Definition GTools.cpp:1789
GXmlElement * xml_need_par(const std::string &origin, GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition GTools.cpp:1688
GFilename xml_file_reduce(const GXmlElement &xml, const std::string &filename)
Reduce file name provided for writing as XML attribute.
Definition GTools.cpp:1997
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition GTypemaps.hpp:65
bool xml_has_par(const GXmlElement &xml, const std::string &name)
Checks if parameter with given name in XML element exists.
Definition GTools.cpp:1647
GFilename xml_file_expand(const GXmlElement &xml, const std::string &filename)
Expand file name provided as XML attribute for loading.
Definition GTools.cpp:1940