Commit a4cacc7c3d6c403ee92baaf3df221fe0ba7ebbf9

Authored by Jürgen Knödlseder
1 parent eca86928

Support loading and writing of Housekeeping data (#4209)

... ... @@ -37,6 +37,7 @@ The following methods have been added:
37 37 - GCOMObservation::npred()
38 38 - GCOMObservation::drw()
39 39 - GCOMObservation::drwname()
  40 +- GCOMObservation::hkds()
40 41 - GCOMObservation::cachename()
41 42 - GCOMResponse::load_cache()
42 43 - GCOMResponse::save_cache()
... ... @@ -53,6 +54,9 @@ The arguments for the following methods have been changed:
53 54 input; was four filenames before
54 55 - GCOMObservation::load() method now takes 5 filenames on input; was
55 56 four filenames before
  57 +- GCOMObservation::load() method and GCOMObservation::GCOMObservation()
  58 + constructor now takes also a vector for housekeeping file namess on
  59 + input
56 60  
57 61 The return value of the following methods has been changed:
58 62 - none
... ... @@ -174,6 +178,9 @@ None
174 178  
175 179 22. COMPTEL interface
176 180 ---------------------
  181 +Added support to GCOMObservation class for reading and writing of housekeeping
  182 +data (#4209).
  183 +
177 184 Added GCOMHkd and GCOMHkds classes for the handling of housekeeping data
178 185 (#4209).
179 186  
... ...
inst/com/Makefile.am
... ... @@ -43,6 +43,8 @@ sources = src/com_helpers_response_vector.cpp \
43 43 src/GCOMDri.cpp \
44 44 src/GCOMOads.cpp \
45 45 src/GCOMOad.cpp \
  46 + src/GCOMHkds.cpp \
  47 + src/GCOMHkd.cpp \
46 48 src/GCOMBvcs.cpp \
47 49 src/GCOMBvc.cpp \
48 50 src/GCOMTim.cpp \
... ... @@ -70,6 +72,8 @@ pkginclude_HEADERS = include/GCOMTools.hpp \
70 72 include/GCOMDri.hpp \
71 73 include/GCOMOads.hpp \
72 74 include/GCOMOad.hpp \
  75 + include/GCOMHkds.hpp \
  76 + include/GCOMHkd.hpp \
73 77 include/GCOMBvcs.hpp \
74 78 include/GCOMBvc.hpp \
75 79 include/GCOMTim.hpp \
... ...
inst/com/include/GCOMObservation.hpp
... ... @@ -35,6 +35,7 @@
35 35 #include "GCOMResponse.hpp"
36 36 #include "GCOMTim.hpp"
37 37 #include "GCOMOads.hpp"
  38 +#include "GCOMHkds.hpp"
38 39 #include "GCOMBvcs.hpp"
39 40 #include "GCOMDri.hpp"
40 41 #include "GCOMEventList.hpp"
... ... @@ -85,6 +86,7 @@ public:
85 86 GCOMObservation(const GFilename& evpname,
86 87 const GFilename& timname,
87 88 const std::vector<GFilename>& oadnames,
  89 + const std::vector<GFilename>& hkdnames,
88 90 const GFilename& bvcname = "");
89 91 GCOMObservation(const GCOMObservation& obs);
90 92 virtual ~GCOMObservation(void);
... ... @@ -120,6 +122,7 @@ public:
120 122 void load(const GFilename& evpname,
121 123 const GFilename& timname,
122 124 const std::vector<GFilename>& oadnames,
  125 + const std::vector<GFilename>& hkdnames,
123 126 const GFilename& bvcname = "");
124 127 void response(const GCaldb& caldb, const std::string& rspname);
125 128 void response(const GCOMResponse& response);
... ... @@ -139,6 +142,8 @@ public:
139 142 void tim(const GCOMTim& tim);
140 143 const GCOMOads& oads(void) const;
141 144 void oads(const GCOMOads& oads);
  145 + const GCOMHkds& hkds(void) const;
  146 + void hkds(const GCOMHkds& hkds);
142 147 const GCOMBvcs& bvcs(void) const;
143 148 void bvcs(const GCOMBvcs& bvcs);
144 149 const GFilename& drename(void) const;
... ... @@ -232,9 +237,11 @@ protected:
232 237 GFilename m_evpname; //!< EVP filename
233 238 GFilename m_timname; //!< TIM filename
234 239 std::vector<GFilename> m_oadnames; //!< OAD filenames
  240 + std::vector<GFilename> m_hkdnames; //!< HKD filenames
235 241 GFilename m_bvcname; //!< BVC filename
236 242 GCOMTim m_tim; //!< COMPTEL Good Time Intervals
237 243 GCOMOads m_oads; //!< Orbit Aspect Data
  244 + GCOMHkds m_hkds; //!< Housekeeping Data
238 245 GCOMBvcs m_bvcs; //!< Solar System Barycentre Data
239 246 };
240 247  
... ... @@ -527,6 +534,32 @@ void GCOMObservation::oads(const GCOMOads&amp; oads)
527 534  
528 535  
529 536 /***********************************************************************//**
  537 + * @brief Return Housekeeping Data collection
  538 + *
  539 + * @return Housekeeping Data collection
  540 + ***************************************************************************/
  541 +inline
  542 +const GCOMHkds& GCOMObservation::hkds(void) const
  543 +{
  544 + // Return Housekeeping Data collection
  545 + return (m_hkds);
  546 +}
  547 +
  548 +
  549 +/***********************************************************************//**
  550 + * @brief Set Housekeeping Data collection
  551 + *
  552 + * @param[in] hkds Housekeeping Data collection.
  553 + ***************************************************************************/
  554 +inline
  555 +void GCOMObservation::hkds(const GCOMHkds& hkds)
  556 +{
  557 + m_hkds = hkds;
  558 + return;
  559 +}
  560 +
  561 +
  562 +/***********************************************************************//**
530 563 * @brief Return Solar System Barycentre Data
531 564 *
532 565 * @return Solar System Barycentre Data
... ...
inst/com/pyext/GCOMObservation.i
... ... @@ -56,6 +56,7 @@ public:
56 56 GCOMObservation(const GFilename& evpname,
57 57 const GFilename& timname,
58 58 const std::vector<GFilename>& oadnames,
  59 + const std::vector<GFilename>& hkdnames,
59 60 const GFilename& bvcname = "");
60 61 GCOMObservation(const GCOMObservation& obs);
61 62 virtual ~GCOMObservation(void);
... ... @@ -87,6 +88,7 @@ public:
87 88 void load(const GFilename& evpname,
88 89 const GFilename& timname,
89 90 const std::vector<GFilename>& oadnames,
  91 + const std::vector<GFilename>& hkdnames,
90 92 const GFilename& bvcname = "");
91 93 void response(const GCaldb& caldb, const std::string& rspname);
92 94 void response(const GCOMResponse& response);
... ... @@ -106,6 +108,8 @@ public:
106 108 void tim(const GCOMTim& tim);
107 109 const GCOMOads& oads(void) const;
108 110 void oads(const GCOMOads& oads);
  111 + const GCOMHkds& hkds(void) const;
  112 + void hkds(const GCOMHkds& hkds);
109 113 const GCOMBvcs& bvcs(void) const;
110 114 void bvcs(const GCOMBvcs& bvcs);
111 115 const GFilename& drename(void) const;
... ...
inst/com/src/GCOMHkd.cpp
... ... @@ -229,25 +229,40 @@ void GCOMHkd::remove(const int&amp; index)
229 229 *
230 230 * @param[in] hkd Housekeeping Data container.
231 231 *
232   - * Append Housekeeping Data container to existing container.
  232 + * Extend existing Housekeeping Data container with data found in another
  233 + * container by respecting the time ordering of the data.
233 234 ***************************************************************************/
234 235 void GCOMHkd::extend(const GCOMHkd& hkd)
235 236 {
236 237 // Do nothing if Housekeeping Data container is empty
237 238 if (!hkd.is_empty()) {
238 239  
239   - // Get size. Note that we extract the size first to avoid an
240   - // endless loop that arises when a container is appended to
241   - // itself.
  240 + // Get current number of housekeeping data
242 241 int num = hkd.size();
243 242  
244 243 // Reserve enough space
245 244 reserve(size() + num);
246 245  
247   - // Loop over all elements and append them to container
248   - for (int i = 0; i < num; ++i) {
249   - m_times.append(hkd.m_times[i]);
250   - m_values.push_back(hkd.m_values[i]);
  246 + // Find index of where to insert Housekeeping Data
  247 + int index = 0;
  248 + for (; index < size(); ++index) {
  249 + if (hkd.m_times[0] < m_times[index]) {
  250 + break;
  251 + }
  252 + }
  253 +
  254 + // Inserts Housekeeping Data
  255 + if (index < size()) {
  256 + for (int i = 0; i < num; ++i) {
  257 + m_times.insert(index+i, hkd.m_times[i]);
  258 + m_values.insert(m_values.begin()+index+i, hkd.m_values[i]);
  259 + }
  260 + }
  261 + else {
  262 + for (int i = 0; i < num; ++i) {
  263 + m_times.append(hkd.m_times[i]);
  264 + m_values.push_back(hkd.m_values[i]);
  265 + }
251 266 }
252 267  
253 268 } // endif: Housekeeping Data container was not empty
... ...
inst/com/src/GCOMObservation.cpp
... ... @@ -250,24 +250,30 @@ GCOMObservation::GCOMObservation(const GFilename&amp; drename,
250 250 * @param[in] evpname Event list FITS file name.
251 251 * @param[in] timname Good Time Intervals FITS file name.
252 252 * @param[in] oadnames List of Orbit Aspect Data FITS file names.
  253 + * @param[in] hkdnames List of Housekeeping Data FITS file names.
253 254 * @param[in] bvcname Solar System Barycentre Data FITS file name.
254 255 *
255 256 * Creates a COMPTEL unbinned observation by loading the event list, Good
256 257 * Time Interval, Orbit Aspect Data and optionally the Solar System
257   - * Barycentre Data from FITS files. Except of the Solar System Barycentre
258   - * Data all files are mandatory. The Solar System Barycentre Data will only
259   - * be loaded if the file name is not empty.
  258 + * Barycentre Data from FITS files.
  259 + *
  260 + * Except of the Housekeeping Data and the Solar System Barycentre Data all
  261 + * files are mandatory. The Housekeeping Data and the Solar System Barycentre
  262 + * Data will only be loaded if the file names are not empty.
  263 + *
  264 + * See load() method for more information.
260 265 ***************************************************************************/
261 266 GCOMObservation::GCOMObservation(const GFilename& evpname,
262 267 const GFilename& timname,
263 268 const std::vector<GFilename>& oadnames,
  269 + const std::vector<GFilename>& hkdnames,
264 270 const GFilename& bvcname)
265 271 {
266 272 // Initialise members
267 273 init_members();
268 274  
269 275 // Load observation
270   - load(evpname, timname, oadnames, bvcname);
  276 + load(evpname, timname, oadnames, hkdnames, bvcname);
271 277  
272 278 // Return
273 279 return;
... ... @@ -498,6 +504,8 @@ double GCOMObservation::npred(const GModel&amp; model) const
498 504 * <parameter name="TIM" file="m10695_tim.fits"/>
499 505 * <parameter name="OAD" file="m20039_oad.fits"/>
500 506 * <parameter name="OAD" file="m20041_oad.fits"/>
  507 + * <parameter name="HKD" file="m20035_hkd.fits"/>
  508 + * <parameter name="HKD" file="m20037_hkd.fits"/>
501 509 * <parameter name="BVC" file="s10150_bvc.fits"/>
502 510 * ...
503 511 * </observation>
... ... @@ -505,8 +513,8 @@ double GCOMObservation::npred(const GModel&amp; model) const
505 513 * where the observation can contain an arbitrary number of OAD file
506 514 * parameters. The @p file attribute provide either absolute or relative
507 515 * file names. If a file name includes no access path it is assumed that
508   - * the file resides in the same location as the XML file. The BVC file is
509   - * optional and does not need to be specified.
  516 + * the file resides in the same location as the XML file. The HKD and BVC
  517 + * files are optional and do not need to be specified.
510 518 *
511 519 * For a binned observation the XML format is
512 520 *
... ... @@ -552,6 +560,17 @@ void GCOMObservation::read(const GXmlElement&amp; xml)
552 560 }
553 561 }
554 562  
  563 + // Get and expand optional HKD file names
  564 + std::vector<GFilename> hkdnames;
  565 + for (int i = 0; i < xml.elements("parameter"); ++i) {
  566 + const GXmlElement* element = xml.element("parameter", i);
  567 + if (element->attribute("name") == "HKD") {
  568 + std::string hkdname = element->attribute("file");
  569 + hkdname = gammalib::xml_file_expand(xml, hkdname);
  570 + hkdnames.push_back(GFilename(hkdname));
  571 + }
  572 + }
  573 +
555 574 // Get and expand optional BVC file name
556 575 std::string bvcname = "";
557 576 if (gammalib::xml_has_par(xml, "BVC")) {
... ... @@ -560,7 +579,7 @@ void GCOMObservation::read(const GXmlElement&amp; xml)
560 579 }
561 580  
562 581 // Load observation
563   - load(evpname, timname, oadnames, bvcname);
  582 + load(evpname, timname, oadnames, hkdnames, bvcname);
564 583  
565 584 } // endif: unbinned observation
566 585  
... ... @@ -644,6 +663,8 @@ void GCOMObservation::read(const GXmlElement&amp; xml)
644 663 * <parameter name="TIM" file="m10695_tim.fits"/>
645 664 * <parameter name="OAD" file="m20039_oad.fits"/>
646 665 * <parameter name="OAD" file="m20041_oad.fits"/>
  666 + * <parameter name="HKD" file="m20035_hkd.fits"/>
  667 + * <parameter name="HKD" file="m20037_hkd.fits"/>
647 668 * <parameter name="BVC" file="s10150_bvc.fits"/>
648 669 * ...
649 670 * </observation>
... ... @@ -651,9 +672,9 @@ void GCOMObservation::read(const GXmlElement&amp; xml)
651 672 * where the observation can contain an arbitrary number of OAD file
652 673 * parameters. The @p file attribute provide either absolute or relative
653 674 * file names. If a file name includes no access path it is assumed that
654   - * the file resides in the same location as the XML file. The BVC file is
655   - * optional and is only written if BVC information is contained in the
656   - * observation.
  675 + * the file resides in the same location as the XML file. The HKD and BVC
  676 + * files are optional and are only written if HKD and BVC information is
  677 + * contained in the observation.
657 678 *
658 679 * For a binned observation the XML format is
659 680 *
... ... @@ -698,6 +719,12 @@ void GCOMObservation::write(GXmlElement&amp; xml) const
698 719 par->attribute("file", gammalib::xml_file_reduce(xml, m_oadnames[i]));
699 720 }
700 721  
  722 + // Optionally set HKD parameters
  723 + for (int i = 0; i < m_hkdnames.size(); ++i) {
  724 + par = static_cast<GXmlElement*>(xml.append(GXmlElement("parameter name=\"HKD\"")));
  725 + par->attribute("file", gammalib::xml_file_reduce(xml, m_hkdnames[i]));
  726 + }
  727 +
701 728 // Optionally set BVC parameters
702 729 if (!m_bvcs.is_empty()) {
703 730 par = gammalib::xml_need_par(G_WRITE, xml, "BVC");
... ... @@ -814,18 +841,23 @@ void GCOMObservation::load(const GFilename&amp; drename,
814 841 * @param[in] evpname Event list FITS file name.
815 842 * @param[in] timname Good Time Intervals FITS file name.
816 843 * @param[in] oadnames List of Orbit Aspect Data FITS file names.
  844 + * @param[in] hkdnames List of Housekeeping Data FITS file names.
817 845 * @param[in] bvcname Solar System Barycentre Data FITS file name.
818 846 *
819 847 * Loads the event list, Good Time Interval, Orbit Aspect Data and optionally
820   - * the Solar System Barycentre Data for an unbinned observation. Except of
821   - * the Solar System Barycentre Data all files are mandatory. The Solar
822   - * System Barycentre Data will only be loaded if the file name is not empty.
  848 + * Housekeeping data and Solar System Barycentre Data for an unbinned
  849 + * observation.
  850 + *
  851 + * Except of the Housekeeping Data and the Solar System Barycentre Data all
  852 + * files are mandatory. The Housekeeping Data and the Solar System Barycentre
  853 + * Data will only be loaded if the file names are not empty.
823 854 *
824 855 * The method fixes the deadtime correction factor deadc to 0.965.
825 856 ***************************************************************************/
826 857 void GCOMObservation::load(const GFilename& evpname,
827 858 const GFilename& timname,
828 859 const std::vector<GFilename>& oadnames,
  860 + const std::vector<GFilename>& hkdnames,
829 861 const GFilename& bvcname)
830 862 {
831 863 // Clear object
... ... @@ -886,6 +918,22 @@ void GCOMObservation::load(const GFilename&amp; evpname,
886 918 m_oads.extend(oads[i]);
887 919 }
888 920  
  921 + // Optionally load HKD data
  922 + for (int i = 0; i < hkdnames.size(); ++i) {
  923 +
  924 + // Load HKD file
  925 + GCOMHkds hdks(hkdnames[i]);
  926 +
  927 + // Skip file if it is empty
  928 + if (hdks.size() < 1) {
  929 + continue;
  930 + }
  931 +
  932 + // Extend housekeeping data
  933 + m_hkds.extend(hdks);
  934 +
  935 + }
  936 +
889 937 // Optionally load BVC data
890 938 if (bvcname != "") {
891 939 m_bvcs.load(bvcname);
... ... @@ -895,6 +943,7 @@ void GCOMObservation::load(const GFilename&amp; evpname,
895 943 m_evpname = evpname;
896 944 m_timname = timname;
897 945 m_oadnames = oadnames;
  946 + m_hkdnames = hkdnames;
898 947 m_bvcname = bvcname;
899 948  
900 949 // Return
... ... @@ -1077,6 +1126,14 @@ std::string GCOMObservation::print(const GChatter&amp; chatter) const
1077 1126 result.append("\n"+gammalib::parformat("OADs")+"undefined");
1078 1127 }
1079 1128  
  1129 + // Append HKDs (if available)
  1130 + if (!m_hkds.is_empty()) {
  1131 + result.append("\n"+m_hkds.print(gammalib::reduce(chatter)));
  1132 + }
  1133 + else {
  1134 + result.append("\n"+gammalib::parformat("HKDs")+"undefined");
  1135 + }
  1136 +
1080 1137 // Append BVCs (if available)
1081 1138 if (!m_bvcs.is_empty()) {
1082 1139 result.append("\n"+m_bvcs.print(gammalib::reduce(chatter)));
... ... @@ -1130,9 +1187,11 @@ void GCOMObservation::init_members(void)
1130 1187 m_evpname.clear();
1131 1188 m_timname.clear();
1132 1189 m_oadnames.clear();
  1190 + m_hkdnames.clear();
1133 1191 m_bvcname.clear();
1134 1192 m_tim.clear();
1135 1193 m_oads.clear();
  1194 + m_hkds.clear();
1136 1195 m_bvcs.clear();
1137 1196  
1138 1197 // Return
... ... @@ -1174,9 +1233,11 @@ void GCOMObservation::copy_members(const GCOMObservation&amp; obs)
1174 1233 m_evpname = obs.m_evpname;
1175 1234 m_timname = obs.m_timname;
1176 1235 m_oadnames = obs.m_oadnames;
  1236 + m_hkdnames = obs.m_hkdnames;
1177 1237 m_bvcname = obs.m_bvcname;
1178 1238 m_tim = obs.m_tim;
1179 1239 m_oads = obs.m_oads;
  1240 + m_hkds = obs.m_hkds;
1180 1241 m_bvcs = obs.m_bvcs;
1181 1242  
1182 1243 // Return
... ...