Commit 08dd5785e9cbd8d84b5e100f28cbe4e135ca393e

Authored by Jürgen Knödlseder
1 parent 9590a9c6

Allow to append empty intervals to GGti and add single interval constructor.

ChangeLog
... ... @@ -20,6 +20,8 @@
20 20 Increase precision for diffuse model Npred computation (#1248)
21 21 Implement observation definition reader/writer (#1429)
22 22 Remove etrue flag from CTA background IRF (#1437)
  23 + Allow appending of empty intervals to GEbounds and GGti
  24 + Add single interval constructor to GGti
23 25  
24 26  
25 27 2015-01-07 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
... ...
... ... @@ -75,7 +75,11 @@ None
75 75  
76 76 10. Observation module
77 77 ----------------------
78   -None
  78 +The GEbounds and GGti classes now allow appending of empty intervals (i.e.
  79 +intervals having the same start and end value).
  80 +
  81 +A single time interval constructor has been added to GGti, similar to the
  82 +one that exists for GEbounds.
79 83  
80 84  
81 85 11. Optimization module
... ...
include/GGti.hpp
... ... @@ -59,6 +59,7 @@ public:
59 59 // Constructors and destructors
60 60 GGti(void);
61 61 GGti(const GGti& gti);
  62 + GGti(const GTime& tstart, const GTime& tstop);
62 63 explicit GGti(const GXmlElement& xml);
63 64 explicit GGti(const GTimeReference& ref);
64 65 virtual ~GGti(void);
... ...
pyext/GGti.i
... ... @@ -40,6 +40,7 @@ public:
40 40 // Constructors and destructors
41 41 GGti(void);
42 42 GGti(const GGti& gti);
  43 + GGti(const GTime& tstart, const GTime& tstop);
43 44 explicit GGti(const GXmlElement& xml);
44 45 explicit GGti(const GTimeReference& ref);
45 46 virtual ~GGti(void);
... ...
src/obs/GGti.cpp
... ... @@ -38,11 +38,13 @@
38 38 #include "GXmlElement.hpp"
39 39  
40 40 /* __ Method name definitions ____________________________________________ */
  41 +#define G_REDUCE "GGti::reduce(GTime&, GTime&)"
41 42 #define G_REMOVE "GGti::remove(int&)"
42 43 #define G_READ_XML "GGti::read(GXmlElement&)"
43 44 #define G_WRITE_XML "GGti::write(GXmlElement&)"
44 45 #define G_TSTART "GGti::tstart(int&)"
45 46 #define G_TSTOP "GGti::tstop(int&)"
  47 +#define G_INSERT_GTI "GGti::insert_gti(int&, GTime&, GTime&)"
46 48  
47 49 /* __ Macros _____________________________________________________________ */
48 50  
... ... @@ -109,6 +111,28 @@ GGti::GGti(const GXmlElement&amp; xml)
109 111  
110 112  
111 113 /***********************************************************************//**
  114 + * @brief Single time interval constructor
  115 + *
  116 + * @param[in] tstart Start time of interval.
  117 + * @param[in] tstop Stop time of interval.
  118 + *
  119 + * Constructs Good Time Intervals from a single time interval, given by
  120 + * [p@ tstart, @p tstop].
  121 + ***************************************************************************/
  122 +GGti::GGti(const GTime& tstart, const GTime& tstop)
  123 +{
  124 + // Initialise members
  125 + init_members();
  126 +
  127 + // Append time interval
  128 + append(tstart, tstop);
  129 +
  130 + // Return
  131 + return;
  132 +}
  133 +
  134 +
  135 +/***********************************************************************//**
112 136 * @brief Time reference constructor
113 137 *
114 138 * @param[in] ref Time reference.
... ... @@ -155,7 +179,7 @@ GGti::~GGti(void)
155 179 * @param[in] gti Good Time Intervals.
156 180 * @return Good Time Intervals.
157 181 ***************************************************************************/
158   -GGti& GGti::operator= (const GGti& gti)
  182 +GGti& GGti::operator=(const GGti& gti)
159 183 {
160 184 // Execute only if object is not identical
161 185 if (this != &gti) {
... ... @@ -216,19 +240,11 @@ GGti* GGti::clone(void) const
216 240 * @param[in] tstop Stop time of interval.
217 241 *
218 242 * Appends a Good Time Interval at the end of the container.
219   - *
220   - * The method does nothing if the Good Time Interval is not valid
221   - * (i.e. @p tstart >= @p tstop).
222 243 ***************************************************************************/
223 244 void GGti::append(const GTime& tstart, const GTime& tstop)
224 245 {
225   - // Continue only if time interval is valid
226   - if (tstop > tstart) {
227   -
228   - // Insert GTI at end of list
229   - insert_gti(m_num, tstart, tstop);
230   -
231   - } // endif: Time interval was valid
  246 + // Insert GTI at end of list
  247 + insert_gti(m_num, tstart, tstop);
232 248  
233 249 // Return
234 250 return;
... ... @@ -244,27 +260,19 @@ void GGti::append(const GTime&amp; tstart, const GTime&amp; tstop)
244 260 * Inserts a Good Time Interval into the container after the first interval
245 261 * that has a start time smaller than @p tstart. The method implicitely
246 262 * assumes that the Good Time Intervals are ordered by increasing start time.
247   - *
248   - * The method does nothing if the Good Time Interval is not valid
249   - * (i.e. @p tstart >= @p tstop).
250 263 ***************************************************************************/
251 264 void GGti::insert(const GTime& tstart, const GTime& tstop)
252 265 {
253   - // Continue only if time interval is valid
254   - if (tstop > tstart) {
255   -
256   - // Determine index at which GTI should be inserted
257   - int inx = 0;
258   - for (int i = 0; i < m_num; ++i) {
259   - if (tstart < m_start[i]) {
260   - break;
261   - }
  266 + // Determine index at which GTI should be inserted
  267 + int inx = 0;
  268 + for (int i = 0; i < m_num; ++i) {
  269 + if (tstart < m_start[i]) {
  270 + break;
262 271 }
  272 + }
263 273  
264   - // Insert interval
265   - insert_gti(inx, tstart, tstop);
266   -
267   - } // endif: Time interval was valid
  274 + // Insert interval
  275 + insert_gti(inx, tstart, tstop);
268 276  
269 277 // Return
270 278 return;
... ... @@ -325,30 +333,22 @@ void GGti::merge(void)
325 333 * that has a start time smaller than @p tstart and then merges any
326 334 * overlapping or connecting Good Time Intervals. The method implicitely
327 335 * assumes that the intervals are ordered by increasing start time.
328   - *
329   - * The method does nothing if the Good Time Interval is not valid
330   - * (i.e. @p tstart >= @p tstop).
331 336 ***************************************************************************/
332 337 void GGti::merge(const GTime& tstart, const GTime& tstop)
333 338 {
334   - // Continue only if time interval is valid
335   - if (tstop > tstart) {
336   -
337   - // Determine index at which GTI should be inserted
338   - int inx = 0;
339   - for (int i = 0; i < m_num; ++i) {
340   - if (tstart < m_start[i]) {
341   - break;
342   - }
  339 + // Determine index at which GTI should be inserted
  340 + int inx = 0;
  341 + for (int i = 0; i < m_num; ++i) {
  342 + if (tstart < m_start[i]) {
  343 + break;
343 344 }
  345 + }
344 346  
345   - // Insert GTI
346   - insert_gti(inx, tstart, tstop);
347   -
348   - // Merge any overlapping GTIs
349   - merge();
  347 + // Insert GTI
  348 + insert_gti(inx, tstart, tstop);
350 349  
351   - } // endif: Time interval was valid
  350 + // Merge any overlapping GTIs
  351 + merge();
352 352  
353 353 // Return
354 354 return;
... ... @@ -361,72 +361,75 @@ void GGti::merge(const GTime&amp; tstart, const GTime&amp; tstop)
361 361 * @param[in] tstart Start time of interval.
362 362 * @param[in] tstop Stop time of interval.
363 363 *
  364 + * @exception GException::invalid_argument
  365 + * Start time is later than stop time
  366 + *
364 367 * Reduces the Good Time Intervals to the specified interval. Reducing means
365 368 * that all Good Time Intervals are dropped that fall outside the specified
366 369 * interval [@p tstart, @p tstop], and Good Time Intervals will be limited
367 370 * to >@p tstart and <=@p tstop in case that their boundaries are outside
368 371 * [@p tstart, @p tstop].
369   - *
370   - * The method does nothing if the Good Time Interval is not valid
371   - * (i.e. @p tstart >= @p tstop).
372 372 ***************************************************************************/
373 373 void GGti::reduce(const GTime& tstart, const GTime& tstop)
374 374 {
375   - // Continue only if time interval is valid
376   - if (tstop > tstart) {
  375 + // Throw an exception if time interval is invalid
  376 + if (tstart > tstop) {
  377 + std::string msg = "Invalid time interval specified. Start time "+
  378 + tstart.print(NORMAL)+" can not be later than "
  379 + "stop time "+tstop.print(NORMAL)+".";
  380 + throw GException::invalid_argument(G_REDUCE, msg);
  381 + }
377 382  
378   - // Adjust existing GTIs. This will limit all GTIs to [tstart,tstop].
379   - // All GTIs outside [tstart,tstop] will have start > stop. The number
380   - // of valid GTIs will also be determined.
381   - int num = 0;
382   - for (int i = 0; i < m_num; ++i) {
383   - if (m_start[i] < tstart) {
384   - m_start[i] = tstart;
385   - }
386   - if (m_stop[i] > tstop) {
387   - m_stop[i] = tstop;
388   - }
389   - if (m_start[i] <= m_stop[i]) {
390   - num++;
391   - }
  383 + // Adjust existing GTIs. This will limit all GTIs to [tstart,tstop].
  384 + // All GTIs outside [tstart,tstop] will have start > stop. The number
  385 + // of valid GTIs will also be determined.
  386 + int num = 0;
  387 + for (int i = 0; i < m_num; ++i) {
  388 + if (m_start[i] < tstart) {
  389 + m_start[i] = tstart;
  390 + }
  391 + if (m_stop[i] > tstop) {
  392 + m_stop[i] = tstop;
  393 + }
  394 + if (m_start[i] <= m_stop[i]) {
  395 + num++;
392 396 }
  397 + }
393 398  
394   - // If we still have valid GTIs then allocate memory for them, copy
395   - // over the start and stop times, and update the attributes
396   - if (num > 0) {
  399 + // If we still have valid GTIs then allocate memory for them, copy
  400 + // over the start and stop times, and update the attributes
  401 + if (num > 0) {
397 402  
398   - // Allocate new intervals
399   - GTime* start = new GTime[num];
400   - GTime* stop = new GTime[num];
  403 + // Allocate new intervals
  404 + GTime* start = new GTime[num];
  405 + GTime* stop = new GTime[num];
401 406  
402   - // Copy valid intervals
403   - for (int i = 0; i < m_num; ++i) {
404   - if (m_start[i] <= m_stop[i]) {
405   - start[i] = m_start[i];
406   - stop[i] = m_stop[i];
407   - }
  407 + // Copy valid intervals
  408 + for (int i = 0; i < m_num; ++i) {
  409 + if (m_start[i] <= m_stop[i]) {
  410 + start[i] = m_start[i];
  411 + stop[i] = m_stop[i];
408 412 }
  413 + }
409 414  
410   - // Free old memory
411   - if (m_start != NULL) delete [] m_start;
412   - if (m_stop != NULL) delete [] m_stop;
413   -
414   - // Set new memory
415   - m_start = start;
416   - m_stop = stop;
  415 + // Free old memory
  416 + if (m_start != NULL) delete [] m_start;
  417 + if (m_stop != NULL) delete [] m_stop;
417 418  
418   - // Set attributes
419   - m_num = num;
420   - set_attributes();
  419 + // Set new memory
  420 + m_start = start;
  421 + m_stop = stop;
421 422  
422   - } // endif: there were still valid GTIs
  423 + // Set attributes
  424 + m_num = num;
  425 + set_attributes();
423 426  
424   - // ... otherwise we remove all GTIs
425   - else {
426   - clear();
427   - }
  427 + } // endif: there were still valid GTIs
428 428  
429   - } // endif: Time interval was valid
  429 + // ... otherwise we remove all GTIs
  430 + else {
  431 + clear();
  432 + }
430 433  
431 434 // Return
432 435 return;
... ... @@ -1103,63 +1106,69 @@ void GGti::set_attributes(void)
1103 1106 * @param[in] tstart Start time of interval.
1104 1107 * @param[in] tstop Stop time of interval.
1105 1108 *
  1109 + * @exception GException::invalid_argument
  1110 + * Start time later than stop time
  1111 + *
1106 1112 * Inserts a Good Time Interval after the specified @p index in the Good
1107 1113 * Time Intervals. The method does not reorder the intervals by time,
1108 1114 * instead the client needs to determine the approriate @p index.
1109 1115 *
1110 1116 * Invalid parameters do not produce any exception, but are handled
1111   - * transparently. If the interval is invalid (i.e. @p tstart >= @p tstop)
1112   - * then nothing is done. If the @p index is out of the valid range, the
  1117 + * transparently. If the interval is invalid (i.e. @p tstart > @p tstop)
  1118 + * an exception is thrown. If the @p index is out of the valid range, the
1113 1119 * index will be adjusted to either the first or the last element.
1114 1120 ***************************************************************************/
1115 1121 void GGti::insert_gti(const int& index, const GTime& tstart, const GTime& tstop)
1116 1122 {
1117   - // Continue only if time interval is valid
1118   - if (tstop > tstart) {
1119   -
1120   - // Set index
1121   - int inx = index;
  1123 + // Throw an exception if time interval is invalid
  1124 + if (tstart > tstop) {
  1125 + std::string msg = "Invalid time interval specified. Start time "+
  1126 + tstart.print(NORMAL)+" can not be later than "
  1127 + "stop time "+tstop.print(NORMAL)+".";
  1128 + throw GException::invalid_argument(G_INSERT_GTI, msg);
  1129 + }
1122 1130  
1123   - // If inx is out of range then adjust it
1124   - if (inx < 0) inx = 0;
1125   - if (inx > m_num) inx = m_num;
  1131 + // Set index
  1132 + int inx = index;
1126 1133  
1127   - // Allocate new intervals
1128   - int num = m_num+1;
1129   - GTime* start = new GTime[num];
1130   - GTime* stop = new GTime[num];
  1134 + // If inx is out of range then adjust it
  1135 + if (inx < 0) inx = 0;
  1136 + if (inx > m_num) inx = m_num;
1131 1137  
1132   - // Copy intervals before GTI to be inserted
1133   - for (int i = 0; i < inx; ++i) {
1134   - start[i] = m_start[i];
1135   - stop[i] = m_stop[i];
1136   - }
  1138 + // Allocate new intervals
  1139 + int num = m_num+1;
  1140 + GTime* start = new GTime[num];
  1141 + GTime* stop = new GTime[num];
1137 1142  
1138   - // Insert GTI
1139   - start[inx] = tstart;
1140   - stop[inx] = tstop;
  1143 + // Copy intervals before GTI to be inserted
  1144 + for (int i = 0; i < inx; ++i) {
  1145 + start[i] = m_start[i];
  1146 + stop[i] = m_stop[i];
  1147 + }
1141 1148  
1142   - // Copy intervals after GTI to be inserted
1143   - for (int i = inx+1; i < num; ++i) {
1144   - start[i] = m_start[i-1];
1145   - stop[i] = m_stop[i-1];
1146   - }
  1149 + // Insert GTI
  1150 + start[inx] = tstart;
  1151 + stop[inx] = tstop;
1147 1152  
1148   - // Free memory
1149   - if (m_start != NULL) delete [] m_start;
1150   - if (m_stop != NULL) delete [] m_stop;
  1153 + // Copy intervals after GTI to be inserted
  1154 + for (int i = inx+1; i < num; ++i) {
  1155 + start[i] = m_start[i-1];
  1156 + stop[i] = m_stop[i-1];
  1157 + }
1151 1158  
1152   - // Set new memory
1153   - m_start = start;
1154   - m_stop = stop;
  1159 + // Free memory
  1160 + if (m_start != NULL) delete [] m_start;
  1161 + if (m_stop != NULL) delete [] m_stop;
1155 1162  
1156   - // Set number of elements
1157   - m_num = num;
1158   -
1159   - // Set attributes
1160   - set_attributes();
  1163 + // Set new memory
  1164 + m_start = start;
  1165 + m_stop = stop;
1161 1166  
1162   - } // endif: Time interval was valid
  1167 + // Set number of elements
  1168 + m_num = num;
  1169 +
  1170 + // Set attributes
  1171 + set_attributes();
1163 1172  
1164 1173 // Return
1165 1174 return;
... ...
test/test_GObservation.cpp
... ... @@ -271,20 +271,21 @@ void TestGObservation::test_gti(void)
271 271  
272 272 // Add empty interval
273 273 gti.append(GTime(1.0), GTime(1.0));
274   - test_value(gti.size(), 0, "GGti should have zero size.");
275   - test_assert(gti.is_empty(), "GGti should be empty.");
276   - test_value(gti.tstart().secs(), 0.0, 1.0e-10, "Start time should be 0.");
277   - test_value(gti.tstop().secs(), 0.0, 1.0e-10, "Stop time should be 0.");
  274 + test_value(gti.size(), 1, "GGti should have 1 interval.");
  275 + test_assert(!gti.is_empty(), "GGti should not be empty.");
  276 + test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1.");
  277 + test_value(gti.tstop().secs(), 1.0, 1.0e-10, "Stop time should be 1.");
278 278  
279 279 // Add one interval
280 280 gti.append(GTime(1.0), GTime(10.0));
281   - test_value(gti.size(), 1, "GGti should have 1 interval.");
  281 + test_value(gti.size(), 2, "GGti should have 2 intervals.");
282 282 test_assert(!gti.is_empty(), "GGti should not be empty.");
283 283 test_value(gti.tstart().secs(), 1.0, 1.0e-10, "Start time should be 1.");
284 284 test_value(gti.tstop().secs(), 10.0, 1.0e-10, "Stop time should be 10.");
285 285  
286 286 // Remove interval
287 287 gti.remove(0);
  288 + gti.remove(0);
288 289 test_value(gti.size(), 0, "GGti should have zero size.");
289 290 test_assert(gti.is_empty(), "GGti should be empty.");
290 291 test_value(gti.tstart().secs(), 0.0, 1.0e-10, "Start time should be 0.");
... ...