Commit 08dd5785e9cbd8d84b5e100f28cbe4e135ca393e
1 parent
9590a9c6
Allow to append empty intervals to GGti and add single interval constructor.
Showing
6 changed files
with
155 additions
and
137 deletions
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> | ... | ... |
NEWS
| ... | ... | @@ -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
pyext/GGti.i
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& 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 != >i) { |
| ... | ... | @@ -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& tstart, const GTime& 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& tstart, const GTime& 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."); | ... | ... |