Commit f9a30a181bd977aab37f388eae01c77363aa85cb

Authored by Jürgen Knödlseder
1 parent 4f92d5e4

Implement first_unbinned_observation() and next_unbinned_observation() methods (#1828)

The ctobservation::first_unbinned_observation() and ctobservation::next_unbinned_observation() methods implement an unbinned CTA observation iterator. Using this iterator avoids code duplication and generates a uniform interface for tools to loop over CTA events lists.
ChangeLog
... ... @@ -3,6 +3,7 @@
3 3 * Version 1.2.0 released
4 4 ========================
5 5  
  6 + Rename ctskymap::map() to ctskymap::skymap() (#1828)
6 7 Introduce ctobservation and ctlikelihood base classes (#1828)
7 8 Remove ctselect::time_reference() method
8 9 Add ctool and cscript pars() methods (#1838)
... ...
... ... @@ -30,6 +30,9 @@ observation container. The class implements the following methods:
30 30 - obs() Returns reference to observation container
31 31 - first_unbinned_observation() First unbinned CTA observation in container
32 32 - next_unbinned_observation() Next unbinned CTA observation in container
  33 +The following ctools derive from the class:
  34 +- ctbin
  35 +- ctskymap
33 36  
34 37 The ctlikelihood base class that derives from the ctobservation base class
35 38 was introduced to provide a common base class for all ctools that perform
... ... @@ -92,6 +95,9 @@ ctskymap - CTA sky mapping
92 95 The clear() method now calls GApplication::clear() to conserve the properties
93 96 of the tool (#1835).
94 97  
  98 +The ctskymap::map() method has been renamed to ctskymap::skymap() to avoid a
  99 +name conflict with Python (#1828).
  100 +
95 101  
96 102 ctmodel - CTA counts cube modelling
97 103 -----------------------------------
... ...
pyext/ctbin.i
... ... @@ -34,7 +34,7 @@
34 34 *
35 35 * @brief Event binning tool
36 36 ***************************************************************************/
37   -class ctbin : public ctool {
  37 +class ctbin : public ctobservation {
38 38 public:
39 39 // Constructors and destructors
40 40 ctbin(void);
... ... @@ -48,7 +48,6 @@ public:
48 48 void run(void);
49 49 void save(void);
50 50 void publish(const std::string& name = "");
51   - const GObservations& obs(void) const;
52 51 const GCTAEventCube& cube(void) const;
53 52 };
54 53  
... ...
pyext/ctool.i
... ... @@ -150,7 +150,7 @@ public:
150 150 GObservations get_observations(const bool& get_response = true);
151 151 GSkyDir get_mean_pointing(const GObservations& obs);
152 152 size_t get_current_rss(void);
153   - std::string get_obs_header(const GObservation* obs);
  153 + std::string get_obs_header(const GObservation* obs) const;
154 154 GEnergies insert_energy_boundaries(const GEnergies& energies,
155 155 const GCTAObservation& obs);
156 156 std::vector<bool> cube_layer_usage(const GEbounds& cube_ebounds,
... ...
pyext/ctskymap.i
... ... @@ -34,7 +34,7 @@
34 34 *
35 35 * @brief Sky mapping tool
36 36 ***************************************************************************/
37   -class ctskymap : public ctool {
  37 +class ctskymap : public ctobservation {
38 38 public:
39 39 // Constructors and destructors
40 40 ctskymap(void);
... ... @@ -48,7 +48,7 @@ public:
48 48 void run(void);
49 49 void save(void);
50 50 void publish(const std::string& name = "");
51   - const GSkyMap& map(void) const;
  51 + const GSkyMap& skymap(void) const;
52 52 };
53 53  
54 54  
... ...
src/ctbin/ctbin.cpp
... ... @@ -53,9 +53,9 @@
53 53 /***********************************************************************//**
54 54 * @brief Void constructor
55 55 *
56   - * Constructs an empty ctbin tool.
  56 + * Constructs an empty event binning tool.
57 57 ***************************************************************************/
58   -ctbin::ctbin(void) : ctool(CTBIN_NAME, CTBIN_VERSION)
  58 +ctbin::ctbin(void) : ctobservation(CTBIN_NAME, CTBIN_VERSION)
59 59 {
60 60 // Initialise members
61 61 init_members();
... ... @@ -70,16 +70,14 @@ ctbin::ctbin(void) : ctool(CTBIN_NAME, CTBIN_VERSION)
70 70 *
71 71 * param[in] obs Observation container.
72 72 *
73   - * Constructs ctbin tool from an observation container.
  73 + * Constructs event binning tool from an observation container.
74 74 ***************************************************************************/
75   -ctbin::ctbin(const GObservations& obs) : ctool(CTBIN_NAME, CTBIN_VERSION)
  75 +ctbin::ctbin(const GObservations& obs) :
  76 + ctobservation(CTBIN_NAME, CTBIN_VERSION, obs)
76 77 {
77 78 // Initialise members
78 79 init_members();
79 80  
80   - // Set observations
81   - m_obs = obs;
82   -
83 81 // Return
84 82 return;
85 83 }
... ... @@ -92,11 +90,11 @@ ctbin::ctbin(const GObservations&amp; obs) : ctool(CTBIN_NAME, CTBIN_VERSION)
92 90 * @param[in] argc Number of arguments in command line.
93 91 * @param[in] argv Array of command line arguments.
94 92 *
95   - * Constructs ctbin tool using command line arguments for user parameter
96   - * setting.
  93 + * Constructs event binning tool using command line arguments for user
  94 + * parameter setting.
97 95 ***************************************************************************/
98 96 ctbin::ctbin(int argc, char *argv[]) :
99   - ctool(CTBIN_NAME, CTBIN_VERSION, argc, argv)
  97 + ctobservation(CTBIN_NAME, CTBIN_VERSION, argc, argv)
100 98 {
101 99 // Initialise members
102 100 init_members();
... ... @@ -109,11 +107,11 @@ ctbin::ctbin(int argc, char *argv[]) :
109 107 /***********************************************************************//**
110 108 * @brief Copy constructor
111 109 *
112   - * @param[in] app Application.
  110 + * @param[in] app Event binning tool.
113 111 *
114   - * Constructs ctbin tool from another ctbin instance.
  112 + * Constructs event binning tool from another event binning tool.
115 113 ***************************************************************************/
116   -ctbin::ctbin(const ctbin& app) : ctool(app)
  114 +ctbin::ctbin(const ctbin& app) : ctobservation(app)
117 115 {
118 116 // Initialise members
119 117 init_members();
... ... @@ -129,7 +127,7 @@ ctbin::ctbin(const ctbin&amp; app) : ctool(app)
129 127 /***********************************************************************//**
130 128 * @brief Destructor
131 129 *
132   - * Destructs ctbin tool.
  130 + * Destructs event binning tool.
133 131 ***************************************************************************/
134 132 ctbin::~ctbin(void)
135 133 {
... ... @@ -150,10 +148,10 @@ ctbin::~ctbin(void)
150 148 /***********************************************************************//**
151 149 * @brief Assignment operator
152 150 *
153   - * @param[in] app ctbin tool.
154   - * @return ctbin tool.
  151 + * @param[in] app Event binning tool.
  152 + * @return Event binning tool.
155 153 *
156   - * Assigns ctbin tool.
  154 + * Assigns event binning tool.
157 155 ***************************************************************************/
158 156 ctbin& ctbin::operator=(const ctbin& app)
159 157 {
... ... @@ -161,7 +159,7 @@ ctbin&amp; ctbin::operator=(const ctbin&amp; app)
161 159 if (this != &app) {
162 160  
163 161 // Copy base class members
164   - this->ctool::operator=(app);
  162 + this->ctobservation::operator=(app);
165 163  
166 164 // Free members
167 165 free_members();
... ... @@ -186,21 +184,23 @@ ctbin&amp; ctbin::operator=(const ctbin&amp; app)
186 184 ==========================================================================*/
187 185  
188 186 /***********************************************************************//**
189   - * @brief Clear ctbin tool
  187 + * @brief Clear event binning tool
190 188 *
191   - * Clears ctbin tool.
  189 + * Clears event binning tool.
192 190 ***************************************************************************/
193 191 void ctbin::clear(void)
194 192 {
195 193 // Free members
196 194 free_members();
197 195 this->ctool::free_members();
  196 + this->ctobservation::free_members();
198 197  
199 198 // Clear base class (needed to conserve tool name and version)
200 199 this->GApplication::clear();
201 200  
202 201 // Initialise members
203 202 this->ctool::init_members();
  203 + this->ctobservation::init_members();
204 204 init_members();
205 205  
206 206 // Write header into logger
... ... @@ -212,7 +212,7 @@ void ctbin::clear(void)
212 212  
213 213  
214 214 /***********************************************************************//**
215   - * @brief Run the ctbin tool
  215 + * @brief Run the event binning tool
216 216 *
217 217 * Gets the user parameters and loops over all CTA observations in the
218 218 * observation container to bin the events into a single counts cube. All
... ... @@ -235,30 +235,9 @@ void ctbin::run(void)
235 235 // Write header into logger
236 236 log_header1(TERSE, gammalib::number("Bin observation", m_obs.size()));
237 237  
238   - // Loop over all observations in the container
239   - for (int i = 0; i < m_obs.size(); ++i) {
240   -
241   - // Write header for the current observation
242   - log_header3(TERSE, get_obs_header(m_obs[i]));
243   -
244   - // Get CTA observation
245   - GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
246   -
247   - // Skip observation if it's not CTA
248   - if (obs == NULL) {
249   - std::string msg = " Skipping "+m_obs[i]->instrument()+
250   - " observation";
251   - log_string(NORMAL, msg);
252   - continue;
253   - }
254   -
255   - // Skip observation if we have a binned observation
256   - if (obs->eventtype() == "CountsCube") {
257   - std::string msg = " Skipping binned "+obs->instrument()+
258   - " observation";
259   - log_string(NORMAL, msg);
260   - continue;
261   - }
  238 + // Loop over all unbinned CTA observations in the container
  239 + for (GCTAObservation* obs = first_unbinned_observation(); obs != NULL;
  240 + obs = next_unbinned_observation()) {
262 241  
263 242 // Fill the cube
264 243 fill_cube(obs);
... ... @@ -374,7 +353,6 @@ void ctbin::init_members(void)
374 353 m_chatter = static_cast<GChatter>(2);
375 354  
376 355 // Initialise protected members
377   - m_obs.clear();
378 356 m_counts.clear();
379 357 m_weights.clear();
380 358 m_ebounds.clear();
... ... @@ -402,7 +380,6 @@ void ctbin::copy_members(const ctbin&amp; app)
402 380 m_chatter = app.m_chatter;
403 381  
404 382 // Copy protected members
405   - m_obs = app.m_obs;
406 383 m_counts = app.m_counts;
407 384 m_weights = app.m_weights;
408 385 m_ebounds = app.m_ebounds;
... ...
src/ctbin/ctbin.hpp
... ... @@ -28,14 +28,11 @@
28 28 #define CTBIN_HPP
29 29  
30 30 /* __ Includes ___________________________________________________________ */
31   -#include <vector>
32   -#include "GammaLib.hpp"
33   -#include "GCTALib.hpp"
34   -#include "ctool.hpp"
  31 +#include "ctobservation.hpp"
35 32  
36 33 /* __Definitions _________________________________________________________ */
37 34 #define CTBIN_NAME "ctbin"
38   -#define CTBIN_VERSION "1.1.0"
  35 +#define CTBIN_VERSION "1.2.0"
39 36  
40 37  
41 38 /***********************************************************************//**
... ... @@ -63,7 +60,7 @@
63 60 * PSF cubes should be used for response computation. This is however not
64 61 * yet fully implemented.
65 62 ***************************************************************************/
66   -class ctbin : public ctool {
  63 +class ctbin : public ctobservation {
67 64 public:
68 65 // Constructors and destructors
69 66 ctbin(void);
... ... @@ -80,7 +77,6 @@ public:
80 77 void run(void);
81 78 void save(void);
82 79 void publish(const std::string& name = "");
83   - const GObservations& obs(void) const;
84 80 const GCTAEventCube& cube(void) const;
85 81  
86 82 protected:
... ... @@ -100,7 +96,6 @@ protected:
100 96 GChatter m_chatter; //!< Chattiness
101 97  
102 98 // Protected members
103   - GObservations m_obs; //!< Observation container
104 99 GSkyMap m_counts; //!< Event cube counts
105 100 GSkyMap m_weights; //!< Event cube weights
106 101 GEbounds m_ebounds; //!< Energy boundaries
... ... @@ -110,19 +105,6 @@ protected:
110 105 double m_livetime; //!< Total livetime
111 106 };
112 107  
113   -/***********************************************************************//**
114   - * @brief Return observation container
115   - *
116   - * @return Reference to observation container
117   - *
118   - * Returns a reference to an observation container.
119   - ***************************************************************************/
120   -inline
121   -const GObservations& ctbin::obs(void) const
122   -{
123   - return m_obs;
124   -}
125   -
126 108  
127 109 /***********************************************************************//**
128 110 * @brief Return event cube
... ...
src/ctskymap/ctskymap.cpp
... ... @@ -49,8 +49,10 @@
49 49  
50 50 /***********************************************************************//**
51 51 * @brief Void constructor
  52 + *
  53 + * Constructs an empty sky mapping tool.
52 54 ***************************************************************************/
53   -ctskymap::ctskymap(void) : ctool(CTSKYMAP_NAME, CTSKYMAP_VERSION)
  55 +ctskymap::ctskymap(void) : ctobservation(CTSKYMAP_NAME, CTSKYMAP_VERSION)
54 56 {
55 57 // Initialise members
56 58 init_members();
... ... @@ -65,18 +67,14 @@ ctskymap::ctskymap(void) : ctool(CTSKYMAP_NAME, CTSKYMAP_VERSION)
65 67 *
66 68 * param[in] obs Observation container.
67 69 *
68   - * This method creates an instance of the class by copying an existing
69   - * observations container.
  70 + * Constructs sky mapping tool from an observation container.
70 71 ***************************************************************************/
71 72 ctskymap::ctskymap(const GObservations& obs) :
72   - ctool(CTSKYMAP_NAME, CTSKYMAP_VERSION)
  73 + ctobservation(CTSKYMAP_NAME, CTSKYMAP_VERSION, obs)
73 74 {
74 75 // Initialise members
75 76 init_members();
76 77  
77   - // Set observations
78   - m_obs = obs;
79   -
80 78 // Return
81 79 return;
82 80 }
... ... @@ -88,9 +86,12 @@ ctskymap::ctskymap(const GObservations&amp; obs) :
88 86 *
89 87 * @param[in] argc Number of arguments in command line.
90 88 * @param[in] argv Array of command line arguments.
  89 + *
  90 + * Constructs sky mapping tool using command line arguments for user
  91 + * parameter setting.
91 92 ***************************************************************************/
92 93 ctskymap::ctskymap(int argc, char *argv[]) :
93   - ctool(CTSKYMAP_NAME, CTSKYMAP_VERSION, argc, argv)
  94 + ctobservation(CTSKYMAP_NAME, CTSKYMAP_VERSION, argc, argv)
94 95 {
95 96 // Initialise members
96 97 init_members();
... ... @@ -103,9 +104,9 @@ ctskymap::ctskymap(int argc, char *argv[]) :
103 104 /***********************************************************************//**
104 105 * @brief Copy constructor
105 106 *
106   - * @param[in] app Application.
  107 + * @param[in] app Sky mapping tool.
107 108 ***************************************************************************/
108   -ctskymap::ctskymap(const ctskymap& app) : ctool(app)
  109 +ctskymap::ctskymap(const ctskymap& app) : ctobservation(app)
109 110 {
110 111 // Initialise members
111 112 init_members();
... ... @@ -140,8 +141,8 @@ ctskymap::~ctskymap(void)
140 141 /***********************************************************************//**
141 142 * @brief Assignment operator
142 143 *
143   - * @param[in] app Application.
144   - * @return Application.
  144 + * @param[in] app Sky mapping tool.
  145 + * @return Sky mapping tool.
145 146 ***************************************************************************/
146 147 ctskymap& ctskymap::operator=(const ctskymap& app)
147 148 {
... ... @@ -149,7 +150,7 @@ ctskymap&amp; ctskymap::operator=(const ctskymap&amp; app)
149 150 if (this != &app) {
150 151  
151 152 // Copy base class members
152   - this->ctool::operator=(app);
  153 + this->ctobservation::operator=(app);
153 154  
154 155 // Free members
155 156 free_members();
... ... @@ -174,21 +175,23 @@ ctskymap&amp; ctskymap::operator=(const ctskymap&amp; app)
174 175 ==========================================================================*/
175 176  
176 177 /***********************************************************************//**
177   - * @brief Clear ctskymap tool
  178 + * @brief Clear sky mapping tool
178 179 *
179   - * Clears ctskymap tool.
  180 + * Clears sky mapping tool.
180 181 ***************************************************************************/
181 182 void ctskymap::clear(void)
182 183 {
183 184 // Free members
184 185 free_members();
185 186 this->ctool::free_members();
  187 + this->ctobservation::free_members();
186 188  
187 189 // Clear base class (needed to conserve tool name and version)
188 190 this->GApplication::clear();
189 191  
190 192 // Initialise members
191 193 this->ctool::init_members();
  194 + this->ctobservation::init_members();
192 195 init_members();
193 196  
194 197 // Write header into logger
... ... @@ -200,18 +203,14 @@ void ctskymap::clear(void)
200 203  
201 204  
202 205 /***********************************************************************//**
203   - * @brief Creates sky maps from data
  206 + * @brief Run the sky mapping tool
204 207 *
205   - * This method is the main code. It
206   - * (1) reads task parameters from the par file
207   - * (2) initialises the sky maps
208   - * (3) loops over all observations to add its events to the sky map
  208 + * Generates a sky map from event list by looping over all unbinned CTA
  209 + * observation in the observation container and filling all events into
  210 + * a sky map.
209 211 ***************************************************************************/
210 212 void ctskymap::run(void)
211 213 {
212   - // Initialise statistics
213   - int num_obs = 0;
214   -
215 214 // Switch screen logging on in debug mode
216 215 if (logDebug()) {
217 216 log.cout(true);
... ... @@ -226,37 +225,13 @@ void ctskymap::run(void)
226 225 // Write header into logger
227 226 log_header1(TERSE, gammalib::number("Map observation", m_obs.size()));
228 227  
229   - // Loop over all observation in the container
230   - for (int i = 0; i < m_obs.size(); ++i) {
231   -
232   - // Write header for the current observation
233   - log_header3(TERSE, get_obs_header(m_obs[i]));
234   -
235   - // Get CTA observation
236   - GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
237   -
238   - // Skip observation if it's not CTA
239   - if (obs == NULL) {
240   - std::string msg = " Skipping "+m_obs[i]->instrument()+
241   - " observation";
242   - log_string(NORMAL, msg);
243   - continue;
244   - }
245   -
246   - // Skip observation if we have a binned observation
247   - if (obs->eventtype() == "CountsCube") {
248   - std::string msg = " Skipping binned "+obs->instrument()+
249   - " observation";
250   - log_string(NORMAL, msg);
251   - continue;
252   - }
  228 + // Loop over all unbinned CTA observations in the container
  229 + for (GCTAObservation* obs = first_unbinned_observation(); obs != NULL;
  230 + obs = next_unbinned_observation()) {
253 231  
254 232 // Map events into sky map
255 233 map_events(obs);
256 234  
257   - // Increment observation counter
258   - num_obs++;
259   -
260 235 } // endfor: looped over observations
261 236  
262 237 // Optionally publish sky map
... ... @@ -348,7 +323,6 @@ void ctskymap::publish(const std::string&amp; name)
348 323 void ctskymap::init_members(void)
349 324 {
350 325 // Initialise members
351   - m_obs.clear();
352 326 m_skymap.clear();
353 327 m_emin = 0.0;
354 328 m_emax = 0.0;
... ... @@ -368,7 +342,6 @@ void ctskymap::init_members(void)
368 342 void ctskymap::copy_members(const ctskymap& app)
369 343 {
370 344 // Copy attributes
371   - m_obs = app.m_obs;
372 345 m_skymap = app.m_skymap;
373 346 m_emin = app.m_emin;
374 347 m_emax = app.m_emax;
... ...
src/ctskymap/ctskymap.hpp
... ... @@ -28,9 +28,7 @@
28 28 #define CTSKYMAP_HPP
29 29  
30 30 /* __ Includes ___________________________________________________________ */
31   -#include "GammaLib.hpp"
32   -#include "GCTALib.hpp"
33   -#include "ctool.hpp"
  31 +#include "ctobservation.hpp"
34 32  
35 33 /* __Definitions _________________________________________________________ */
36 34 #define CTSKYMAP_NAME "ctskymap"
... ... @@ -44,7 +42,7 @@
44 42 *
45 43 * This class creates a sky map from a CTA event list.
46 44 ***************************************************************************/
47   -class ctskymap : public ctool {
  45 +class ctskymap : public ctobservation {
48 46  
49 47 public:
50 48 // Constructors and destructors
... ... @@ -62,7 +60,7 @@ public:
62 60 void run(void);
63 61 void save(void);
64 62 void publish(const std::string& name = "");
65   - const GSkyMap& map(void) const;
  63 + const GSkyMap& skymap(void) const;
66 64  
67 65 protected:
68 66 // Protected methods
... ... @@ -80,7 +78,6 @@ protected:
80 78 GChatter m_chatter; //!< Chattiness
81 79  
82 80 // Protected members
83   - GObservations m_obs; //!< Observation container
84 81 GSkyMap m_skymap; //!< Sky map
85 82 };
86 83  
... ... @@ -91,7 +88,7 @@ protected:
91 88 * @return Reference to observation container
92 89 ***************************************************************************/
93 90 inline
94   -const GSkyMap& ctskymap::map(void) const
  91 +const GSkyMap& ctskymap::skymap(void) const
95 92 {
96 93 return m_skymap;
97 94 }
... ...
src/support/ctobservation.cpp
... ... @@ -219,9 +219,12 @@ ctobservation&amp; ctobservation::operator=(const ctobservation&amp; app)
219 219 ***************************************************************************/
220 220 void ctobservation::init_members(void)
221 221 {
222   - // Initialise members
  222 + // Initialise protected members
223 223 m_obs.clear();
224 224  
  225 + // Initialise private members
  226 + m_index_unbinned = 0;
  227 +
225 228 // Return
226 229 return;
227 230 }
... ... @@ -234,9 +237,12 @@ void ctobservation::init_members(void)
234 237 ***************************************************************************/
235 238 void ctobservation::copy_members(const ctobservation& app)
236 239 {
237   - // Copy members
  240 + // Copy protected members
238 241 m_obs = app.m_obs;
239 242  
  243 + // Copy private members
  244 + m_index_unbinned = app.m_index_unbinned;
  245 +
240 246 // Return
241 247 return;
242 248 }
... ... @@ -250,3 +256,88 @@ void ctobservation::free_members(void)
250 256 // Return
251 257 return;
252 258 }
  259 +
  260 +
  261 +/***********************************************************************//**
  262 + * @brief Return first unbinned CTA observation (const version)
  263 + *
  264 + * @return Const pointer to first unbinned CTA observation
  265 + *
  266 + * Returns a const pointer to the first unbinned CTA observation in the
  267 + * container. If no CTA observation exists a NULL pointer is returned.
  268 + *
  269 + * The method calls next_unbinned_observation(). See the method for details.
  270 + ***************************************************************************/
  271 +const GCTAObservation* ctobservation::first_unbinned_observation(void) const
  272 +{
  273 + // Initialise index
  274 + m_index_unbinned = 0;
  275 +
  276 + // Get next unbinned CTA observation
  277 + const GCTAObservation* obs = next_unbinned_observation();
  278 +
  279 + // Return first CTA observation
  280 + return obs;
  281 +}
  282 +
  283 +
  284 +/***********************************************************************//**
  285 + * @brief Return next unbinned CTA observation (const version)
  286 + *
  287 + * @return Const pointer to next unbinned CTA observation
  288 + *
  289 + * Returns a const pointer to the next unbinned CTA observation in the
  290 + * container. If no CTA observation exists any more a NULL pointer is
  291 + * returned.
  292 + *
  293 + * The method writes for each encountered observation a level 3 header into
  294 + * the logger. It will also signal when an observation was skipped because
  295 + * it either was not a CTA observation or not an unbinned observation.
  296 + *
  297 + * @todo Logger methods should be declared const to avoid the const casting.
  298 + ***************************************************************************/
  299 +const GCTAObservation* ctobservation::next_unbinned_observation(void) const
  300 +{
  301 + // Initialise pointer on CTA observation
  302 + const GCTAObservation* obs = NULL;
  303 +
  304 + // Loop over all remaining observation in the container
  305 + for (; m_index_unbinned < m_obs.size(); ++m_index_unbinned) {
  306 +
  307 + // Write header for the current observation
  308 + const_cast<ctobservation*>(this)->log_header3(TERSE,
  309 + get_obs_header(m_obs[m_index_unbinned]));
  310 +
  311 + // Case the observation to a CTA observation. This will return a
  312 + // NULL pointer if the observation is not a CTA observation.
  313 + obs = dynamic_cast<const GCTAObservation*>(m_obs[m_index_unbinned]);
  314 +
  315 + // Skip observation if it's not CTA
  316 + if (obs == NULL) {
  317 + std::string msg = " Skipping "+
  318 + m_obs[m_index_unbinned]->instrument()+
  319 + " observation";
  320 + const_cast<ctobservation*>(this)->log_string(NORMAL, msg);
  321 + continue;
  322 + }
  323 +
  324 + // Skip observation if we have a binned observation
  325 + if (obs->eventtype() == "CountsCube") {
  326 + obs = NULL;
  327 + std::string msg = " Skipping binned "+
  328 + m_obs[m_index_unbinned]->instrument()+
  329 + " observation";
  330 + const_cast<ctobservation*>(this)->log_string(NORMAL, msg);
  331 + continue;
  332 + }
  333 +
  334 + // If we come to this point we have an unbinned CTA observation and
  335 + // we can forward the index to the next index and break the loop
  336 + m_index_unbinned++;
  337 + break;
  338 +
  339 + } // endfor: looped over all observation
  340 +
  341 + // Return next CTA observation
  342 + return obs;
  343 +}
... ...
src/support/ctobservation.hpp
... ... @@ -71,8 +71,18 @@ protected:
71 71 void copy_members(const ctobservation& app);
72 72 void free_members(void);
73 73  
  74 + // Iterator methods and members
  75 + GCTAObservation* first_unbinned_observation(void);
  76 + GCTAObservation* next_unbinned_observation(void);
  77 + const GCTAObservation* first_unbinned_observation(void) const;
  78 + const GCTAObservation* next_unbinned_observation(void) const;
  79 +
74 80 // Protected members
75   - GObservations m_obs; //!< Observation container
  81 + GObservations m_obs; //!< Observation container
  82 +
  83 +private:
  84 + // Private members
  85 + mutable int m_index_unbinned; //!< Current index of unbinned observation
76 86 };
77 87  
78 88  
... ... @@ -89,4 +99,44 @@ const GObservations&amp; ctobservation::obs(void) const
89 99 return m_obs;
90 100 }
91 101  
  102 +
  103 +/***********************************************************************//**
  104 + * @brief Return first unbinned CTA observation
  105 + *
  106 + * @return Pointer to first unbinned CTA observation
  107 + *
  108 + * Returns a pointer to the first unbinned CTA observation in the container.
  109 + * If no CTA observation exists a NULL pointer is returned.
  110 + *
  111 + * The method calls next_unbinned_observation(). See the method for details.
  112 + ***************************************************************************/
  113 +inline
  114 +GCTAObservation* ctobservation::first_unbinned_observation(void)
  115 +{
  116 + return (const_cast<GCTAObservation*>
  117 + (static_cast<const ctobservation&>
  118 + (*this).first_unbinned_observation()));
  119 +}
  120 +
  121 +
  122 +/***********************************************************************//**
  123 + * @brief Return next unbinned CTA observation
  124 + *
  125 + * @return Pointer to next unbinned CTA observation
  126 + *
  127 + * Returns a pointer to the next unbinned CTA observation in the container.
  128 + * If no CTA observation exists any more a NULL pointer is returned.
  129 + *
  130 + * The method writes for each encountered observation a level 3 header into
  131 + * the logger. It will also signal when an observation was skipped because
  132 + * it either was not a CTA observation or not an unbinned observation.
  133 + ***************************************************************************/
  134 +inline
  135 +GCTAObservation* ctobservation::next_unbinned_observation(void)
  136 +{
  137 + return (const_cast<GCTAObservation*>
  138 + (static_cast<const ctobservation&>
  139 + (*this).next_unbinned_observation()));
  140 +}
  141 +
92 142 #endif /* CTOBSERVATION_HPP */
... ...
src/support/ctool.cpp
... ... @@ -1559,7 +1559,7 @@ size_t ctool::get_current_rss(void)
1559 1559 * XXX observation "name" (id=YYYYY)
1560 1560 *
1561 1561 ***************************************************************************/
1562   -std::string ctool::get_obs_header(const GObservation* obs)
  1562 +std::string ctool::get_obs_header(const GObservation* obs) const
1563 1563 {
1564 1564 // Initialise header string
1565 1565 std::string header = obs->instrument() + " observation";
... ...
src/support/ctool.hpp
... ... @@ -113,7 +113,7 @@ protected:
113 113 GObservations get_observations(const bool& get_response = true);
114 114 GSkyDir get_mean_pointing(const GObservations& obs);
115 115 size_t get_current_rss(void);
116   - std::string get_obs_header(const GObservation* obs);
  116 + std::string get_obs_header(const GObservation* obs) const;
117 117 GEnergies insert_energy_boundaries(const GEnergies& energies,
118 118 const GCTAObservation& obs);
119 119 std::vector<bool> cube_layer_usage(const GEbounds& cube_ebounds,
... ...
test/test_ctskymap.py
... ... @@ -108,7 +108,7 @@ class Test(test):
108 108 skymap = ctools.ctskymap()
109 109  
110 110 # Check that empty ctskymap tool holds a map that has no pixels
111   - self._check_map(skymap.map(), nx=0, ny=0)
  111 + self._check_map(skymap.skymap(), nx=0, ny=0)
112 112  
113 113 # Check that saving does not nothing
114 114 skymap['outmap'] = 'ctskymap_py0.fits'
... ... @@ -148,7 +148,7 @@ class Test(test):
148 148 cpy_skymap = skymap.copy()
149 149  
150 150 # Check sky map of ctskymap copy
151   - self._check_map(cpy_skymap.map())
  151 + self._check_map(cpy_skymap.skymap())
152 152  
153 153 # Execute copy of ctskymap tool again, now with a higher chatter
154 154 # level than before
... ... @@ -169,7 +169,7 @@ class Test(test):
169 169 cpy_skymap.clear()
170 170  
171 171 # Check that cleared ctskymap tool holds a map that has no pixels
172   - self._check_map(cpy_skymap.map(), nx=0, ny=0)
  172 + self._check_map(cpy_skymap.skymap(), nx=0, ny=0)
173 173  
174 174 # Get mixed observation container
175 175 obs = self._obs_mixed()
... ...