Commit 9830efd99119e0ba7f9a09f1a668926158e2cf0b
1 parent
8d1e8235
Use new GApplication logger methods and enhance ctool unit tests (#1828)
Showing
15 changed files
with
627 additions
and
348 deletions
AUTHORS
| @@ -3,7 +3,13 @@ Rolf Buehler (rolf.buehler@desy.de) | @@ -3,7 +3,13 @@ Rolf Buehler (rolf.buehler@desy.de) | ||
| 3 | Jean-Baptiste Cayrou (cayrou@etud.insa-toulouse.fr) | 3 | Jean-Baptiste Cayrou (cayrou@etud.insa-toulouse.fr) |
| 4 | Christoph Deil (Christoph.Deil@mpi-hd.mpg.de) | 4 | Christoph Deil (Christoph.Deil@mpi-hd.mpg.de) |
| 5 | Florent Forest (florent.forest@isae.fr) | 5 | Florent Forest (florent.forest@isae.fr) |
| 6 | +Lucie Gerard (lgerard@wgs18.zeuthen.desy.de) | ||
| 7 | +Maria Haupt (maria.haupt@desy.de) | ||
| 8 | +Nathan Kelley-Hoskins (nathan.kelley-hoskins@desy.de) | ||
| 6 | Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu) | 9 | Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu) |
| 7 | Chia-Chun Lu (Chia-Chun.Lu@mpi-hd.mpg.de) | 10 | Chia-Chun Lu (Chia-Chun.Lu@mpi-hd.mpg.de) |
| 11 | +Pierrick Martin (pierrick.martin@irap.omp.eu) | ||
| 8 | Michael Mayer (michael.mayer@physik.hu-berlin.de) | 12 | Michael Mayer (michael.mayer@physik.hu-berlin.de) |
| 9 | - | 13 | +Stefan Ohm (stefan.ohm81@gmail.com) |
| 14 | +David Sanchez (david.sanchez@lapp.in2p3.fr) | ||
| 15 | +Hubert Siejkowski (h.siejkowski@cyfronet.pl) |
pyext/ctool.i
| @@ -84,29 +84,26 @@ public: | @@ -84,29 +84,26 @@ public: | ||
| 84 | virtual void execute(void); | 84 | virtual void execute(void); |
| 85 | 85 | ||
| 86 | // Make methods private in Python by prepending an underscore | 86 | // Make methods private in Python by prepending an underscore |
| 87 | - %rename(_read_ahead) read_ahead() const; | ||
| 88 | - %rename(_time_reference) time_reference() const; | ||
| 89 | - %rename(_get_observations) get_observations(const bool& get_response = true); | ||
| 90 | - %rename(_setup_observations) setup_observations(GObservations& obs); | ||
| 91 | - %rename(_create_ebounds) create_ebounds(); | ||
| 92 | - %rename(_create_map) create_map(const GObservations& obs); | ||
| 93 | - %rename(_create_cube) create_cube(const GObservations& obs); | ||
| 94 | - %rename(_create_cta_obs) create_cta_obs(); | ||
| 95 | - %rename(_require_inobs) require_inobs(const std::string& method); | ||
| 96 | - %rename(_require_inobs_nolist) require_inobs_nolist(const std::string& method); | ||
| 97 | - %rename(_require_inobs_nocube) require_inobs_nocube(const std::string& method); | ||
| 98 | - %rename(_log_observations) log_observations(const GChatter& chatter, | ||
| 99 | - const GObservations& obs, | ||
| 100 | - const std::string& what); | ||
| 101 | - %rename(_log_models) log_models(const GChatter& chatter, | ||
| 102 | - const GModels& models, | ||
| 103 | - const std::string& what); | ||
| 104 | - %rename(_set_response) set_response(GObservations& obs); | ||
| 105 | - %rename(_set_obs_response) set_obs_response(GCTAObservation* obs); | ||
| 106 | - %rename(_set_obs_bounds) set_obs_bounds(GObservations& obs); | ||
| 107 | - %rename(_get_mean_pointing) get_mean_pointing(const GObservations& obs); | ||
| 108 | - %rename(_get_current_rss) get_current_rss(); | ||
| 109 | - %rename(_get_obs_header) get_obs_header(); | 87 | + %rename(_read_ahead) read_ahead; |
| 88 | + %rename(_time_reference) time_reference; | ||
| 89 | + %rename(_get_observations) get_observations; | ||
| 90 | + %rename(_setup_observations) setup_observations; | ||
| 91 | + %rename(_create_ebounds) create_ebounds; | ||
| 92 | + %rename(_create_map) create_map; | ||
| 93 | + %rename(_create_cube) create_cube; | ||
| 94 | + %rename(_create_cta_obs) create_cta_obs; | ||
| 95 | + %rename(_require_inobs) require_inobs; | ||
| 96 | + %rename(_require_inobs_nolist) require_inobs_nolist; | ||
| 97 | + %rename(_require_inobs_nocube) require_inobs_nocube; | ||
| 98 | + %rename(_log_observations) log_observations; | ||
| 99 | + %rename(_log_models) log_models; | ||
| 100 | + %rename(_set_response) set_response; | ||
| 101 | + %rename(_set_obs_response) set_obs_response; | ||
| 102 | + %rename(_set_obs_bounds) set_obs_bounds; | ||
| 103 | + %rename(_get_mean_pointing) get_mean_pointing; | ||
| 104 | + %rename(_get_current_rss) get_current_rss; | ||
| 105 | + %rename(_get_obs_header) get_obs_header; | ||
| 106 | + %rename(_warn_too_few_energies) warn_too_few_energies; | ||
| 110 | 107 | ||
| 111 | // Protected methods | 108 | // Protected methods |
| 112 | const bool& read_ahead(void) const; | 109 | const bool& read_ahead(void) const; |
| @@ -140,6 +137,10 @@ public: | @@ -140,6 +137,10 @@ public: | ||
| 140 | GSkyDir get_mean_pointing(const GObservations& obs); | 137 | GSkyDir get_mean_pointing(const GObservations& obs); |
| 141 | size_t get_current_rss(void); | 138 | size_t get_current_rss(void); |
| 142 | std::string get_obs_header(const GObservation* obs); | 139 | std::string get_obs_header(const GObservation* obs); |
| 140 | + GEnergies insert_energy_boundaries(const GEnergies& energies, | ||
| 141 | + const GCTAObservation& obs); | ||
| 142 | + // Protected warning strings | ||
| 143 | + std::string warn_too_few_energies(const GEnergies& energies) const; | ||
| 143 | }; | 144 | }; |
| 144 | 145 | ||
| 145 | 146 |
src/ctbin/ctbin.cpp
| @@ -345,7 +345,7 @@ void ctbin::publish(const std::string& name) | @@ -345,7 +345,7 @@ void ctbin::publish(const std::string& name) | ||
| 345 | user_name = CTBIN_NAME; | 345 | user_name = CTBIN_NAME; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | - // Log counts cube name | 348 | + // Write counts cube name into logger |
| 349 | log_value(NORMAL, "Counts cube name", user_name); | 349 | log_value(NORMAL, "Counts cube name", user_name); |
| 350 | 350 | ||
| 351 | // Publish counts cube | 351 | // Publish counts cube |
src/ctbkgcube/ctbkgcube.cpp
| @@ -218,23 +218,7 @@ void ctbkgcube::run(void) | @@ -218,23 +218,7 @@ void ctbkgcube::run(void) | ||
| 218 | get_parameters(); | 218 | get_parameters(); |
| 219 | 219 | ||
| 220 | // Warn if there are not enough energy bins | 220 | // Warn if there are not enough energy bins |
| 221 | - int n = m_background.energies().size(); | ||
| 222 | - double logEmin = std::log10(m_background.energies()[0].TeV()); | ||
| 223 | - double logEmax = std::log10(m_background.energies()[n-1].TeV()); | ||
| 224 | - int nrequired = int((logEmax - logEmin) * 25.0); | ||
| 225 | - if (n < nrequired) { | ||
| 226 | - std::string msg = "\nWARNING: Only "+gammalib::str(n-1)+" energy bins " | ||
| 227 | - "have been requested. This may be too few energy " | ||
| 228 | - "bins.\n At least 25 bins per decade in " | ||
| 229 | - "energy are recommended, which in your case\n" | ||
| 230 | - " would be "+gammalib::str(nrequired-1)+ | ||
| 231 | - " bins. Consider increasing the number of energy " | ||
| 232 | - "bins."; | ||
| 233 | - log_string(TERSE, msg); | ||
| 234 | - } | ||
| 235 | - | ||
| 236 | - // Initialise exposure cube | ||
| 237 | - init_cube(); | 221 | + log_string(TERSE, warn_too_few_energies(m_background.energies())); |
| 238 | 222 | ||
| 239 | // Write input observation container into logger | 223 | // Write input observation container into logger |
| 240 | log_observations(NORMAL, m_obs, "Input observation"); | 224 | log_observations(NORMAL, m_obs, "Input observation"); |
| @@ -242,6 +226,9 @@ void ctbkgcube::run(void) | @@ -242,6 +226,9 @@ void ctbkgcube::run(void) | ||
| 242 | // Write input model container into logger | 226 | // Write input model container into logger |
| 243 | log_models(NORMAL, m_obs.models(), "Input model"); | 227 | log_models(NORMAL, m_obs.models(), "Input model"); |
| 244 | 228 | ||
| 229 | + // Initialise exposure cube | ||
| 230 | + init_cube(); | ||
| 231 | + | ||
| 245 | // Write header | 232 | // Write header |
| 246 | log_header1(TERSE, "Prepare model"); | 233 | log_header1(TERSE, "Prepare model"); |
| 247 | 234 | ||
| @@ -296,11 +283,11 @@ void ctbkgcube::run(void) | @@ -296,11 +283,11 @@ void ctbkgcube::run(void) | ||
| 296 | // Assign background models to container | 283 | // Assign background models to container |
| 297 | m_obs.models(m_bkgmdl); | 284 | m_obs.models(m_bkgmdl); |
| 298 | 285 | ||
| 299 | - // Set pointer on logger depending on chattiness | ||
| 300 | - GLog* logp = (logNormal()) ? &log : NULL; | 286 | + // Set pointer to logger dependent on chattiness |
| 287 | + GLog* logger = (logNormal()) ? &log : NULL; | ||
| 301 | 288 | ||
| 302 | // Fill background cube from observations | 289 | // Fill background cube from observations |
| 303 | - m_background.fill(m_obs, logp); | 290 | + m_background.fill(m_obs, logger); |
| 304 | 291 | ||
| 305 | // Create a background model for the output background cube and append | 292 | // Create a background model for the output background cube and append |
| 306 | // that model to the input model in place of the original | 293 | // that model to the input model in place of the original |
| @@ -356,28 +343,33 @@ void ctbkgcube::save(void) | @@ -356,28 +343,33 @@ void ctbkgcube::save(void) | ||
| 356 | m_outcube = (*this)["outcube"].filename(); | 343 | m_outcube = (*this)["outcube"].filename(); |
| 357 | m_outmodel = (*this)["outmodel"].filename(); | 344 | m_outmodel = (*this)["outmodel"].filename(); |
| 358 | 345 | ||
| 359 | - // Save only if filename is non-empty | ||
| 360 | - if (!m_outcube.is_empty()) { | 346 | + // Determine whether the cube is empty |
| 347 | + bool cube_is_empty = ((m_background.cube().nx() == 0) || | ||
| 348 | + (m_background.cube().ny() == 0) || | ||
| 349 | + (m_background.cube().nmaps() == 0)); | ||
| 361 | 350 | ||
| 362 | - // Log background cube file name | ||
| 363 | - log_value(NORMAL, "Background cube file", m_outcube.url()); | 351 | + // Determine whether a model definition file should be written |
| 352 | + bool write_moddef = ((!m_outmodel.is_empty()) && | ||
| 353 | + (gammalib::tolower(m_outmodel.url()) != "none")); | ||
| 364 | 354 | ||
| 365 | - // Save background cube | 355 | + // Save background cube if filename and the background cube are not empty |
| 356 | + if (!m_outcube.is_empty() && !cube_is_empty) { | ||
| 366 | m_background.save(m_outcube, clobber()); | 357 | m_background.save(m_outcube, clobber()); |
| 367 | - | ||
| 368 | } | 358 | } |
| 369 | 359 | ||
| 370 | - // Write output models if filename is valid | ||
| 371 | - if ((!m_outmodel.is_empty()) && | ||
| 372 | - (gammalib::tolower(m_outmodel.url()) != "none")) { | ||
| 373 | - | ||
| 374 | - // Log model definition file name | ||
| 375 | - log_value(NORMAL, "Model definition file", m_outmodel.url()); | ||
| 376 | - | ||
| 377 | - // Save output model for stacked analyses | 360 | + // Save model definition file if requested |
| 361 | + if (write_moddef) { | ||
| 378 | m_outmdl.save(m_outmodel.url()); | 362 | m_outmdl.save(m_outmodel.url()); |
| 363 | + } | ||
| 379 | 364 | ||
| 365 | + // Write into logger what has been done | ||
| 366 | + std::string fname = (m_outcube.is_empty()) ? "NONE" : m_outcube.url(); | ||
| 367 | + std::string mname = (write_moddef) ? m_outmodel.url() : "NONE"; | ||
| 368 | + if (cube_is_empty) { | ||
| 369 | + fname.append(" (cube is empty, no file created)"); | ||
| 380 | } | 370 | } |
| 371 | + log_value(NORMAL, "Background cube file", fname); | ||
| 372 | + log_value(NORMAL, "Model definition file", mname); | ||
| 381 | 373 | ||
| 382 | // Return | 374 | // Return |
| 383 | return; | 375 | return; |
| @@ -394,7 +386,7 @@ void ctbkgcube::publish(const std::string& name) | @@ -394,7 +386,7 @@ void ctbkgcube::publish(const std::string& name) | ||
| 394 | // Write header | 386 | // Write header |
| 395 | log_header1(TERSE, "Publish background cube"); | 387 | log_header1(TERSE, "Publish background cube"); |
| 396 | 388 | ||
| 397 | - // Set default name is user name is empty | 389 | + // Set default name if user name is empty |
| 398 | std::string user_name(name); | 390 | std::string user_name(name); |
| 399 | if (user_name.empty()) { | 391 | if (user_name.empty()) { |
| 400 | user_name = CTBKGCUBE_NAME; | 392 | user_name = CTBKGCUBE_NAME; |
| @@ -588,9 +580,6 @@ void ctbkgcube::init_cube(void) | @@ -588,9 +580,6 @@ void ctbkgcube::init_cube(void) | ||
| 588 | // If requested, insert energies at all event list energy boundaries | 580 | // If requested, insert energies at all event list energy boundaries |
| 589 | if (m_addbounds) { | 581 | if (m_addbounds) { |
| 590 | 582 | ||
| 591 | - // Set pointer on logger depending on chattiness | ||
| 592 | - GLog* logp = (logNormal()) ? &log : NULL; | ||
| 593 | - | ||
| 594 | // Loop over all observations | 583 | // Loop over all observations |
| 595 | for (int i = 0; i < m_obs.size(); ++i) { | 584 | for (int i = 0; i < m_obs.size(); ++i) { |
| 596 | 585 | ||
| @@ -609,7 +598,7 @@ void ctbkgcube::init_cube(void) | @@ -609,7 +598,7 @@ void ctbkgcube::init_cube(void) | ||
| 609 | } | 598 | } |
| 610 | 599 | ||
| 611 | // Insert energy boundaries | 600 | // Insert energy boundaries |
| 612 | - energies = insert_energy_boundaries(energies, *cta, logp); | 601 | + energies = insert_energy_boundaries(energies, *cta); |
| 613 | 602 | ||
| 614 | } // endfor: looped over all observations | 603 | } // endfor: looped over all observations |
| 615 | 604 | ||
| @@ -623,4 +612,4 @@ void ctbkgcube::init_cube(void) | @@ -623,4 +612,4 @@ void ctbkgcube::init_cube(void) | ||
| 623 | 612 | ||
| 624 | // Return | 613 | // Return |
| 625 | return; | 614 | return; |
| 626 | -}; | 615 | +} |
src/ctedispcube/ctedispcube.cpp
| @@ -227,35 +227,23 @@ void ctedispcube::run(void) | @@ -227,35 +227,23 @@ void ctedispcube::run(void) | ||
| 227 | // Get task parameters | 227 | // Get task parameters |
| 228 | get_parameters(); | 228 | get_parameters(); |
| 229 | 229 | ||
| 230 | - // Write header | ||
| 231 | - if (logTerse()) { | ||
| 232 | - log << std::endl; | ||
| 233 | - log.header1("Initialise energy dispersion cube"); | ||
| 234 | - } | 230 | + // Write input observation container into logger |
| 231 | + log_observations(NORMAL, m_obs, "Input observation"); | ||
| 235 | 232 | ||
| 236 | // Initialise energy dispersion cube | 233 | // Initialise energy dispersion cube |
| 237 | init_cube(); | 234 | init_cube(); |
| 238 | 235 | ||
| 239 | - // Write observation(s) into logger | ||
| 240 | - if (logTerse()) { | ||
| 241 | - log << std::endl; | ||
| 242 | - log.header1(gammalib::number("Observation",m_obs.size())); | ||
| 243 | - log << m_obs.print(m_chatter) << std::endl; | ||
| 244 | - } | 236 | + // Write header into logger |
| 237 | + log_header1(TERSE, "Generate energy dispersion cube"); | ||
| 245 | 238 | ||
| 246 | - // Write header | ||
| 247 | - if (logTerse()) { | ||
| 248 | - log << std::endl; | ||
| 249 | - log.header1("Generate energy dispersion cube"); | ||
| 250 | - } | 239 | + // Set pointer to logger dependent on chattiness |
| 240 | + GLog* logger = (logNormal()) ? &log : NULL; | ||
| 251 | 241 | ||
| 252 | // Fill energy dispersion cube | 242 | // Fill energy dispersion cube |
| 253 | - m_edispcube.fill(m_obs, &log); | 243 | + m_edispcube.fill(m_obs, logger); |
| 254 | 244 | ||
| 255 | - // Log energy dispersion cube | ||
| 256 | - if (logTerse()) { | ||
| 257 | - log << m_edispcube.print(m_chatter) << std::endl; | ||
| 258 | - } | 245 | + // Write energy dispersion cube into logger |
| 246 | + log_string(EXPLICIT, m_edispcube.print(m_chatter)); | ||
| 259 | 247 | ||
| 260 | // Return | 248 | // Return |
| 261 | return; | 249 | return; |
| @@ -270,28 +258,29 @@ void ctedispcube::run(void) | @@ -270,28 +258,29 @@ void ctedispcube::run(void) | ||
| 270 | ***************************************************************************/ | 258 | ***************************************************************************/ |
| 271 | void ctedispcube::save(void) | 259 | void ctedispcube::save(void) |
| 272 | { | 260 | { |
| 273 | - // Write header | ||
| 274 | - if (logTerse()) { | ||
| 275 | - log << std::endl; | ||
| 276 | - log.header1("Save Edisp cube"); | ||
| 277 | - } | 261 | + // Write header into logger |
| 262 | + log_header1(TERSE, "Save energy dispersion cube"); | ||
| 278 | 263 | ||
| 279 | // Get output filename | 264 | // Get output filename |
| 280 | m_outcube = (*this)["outcube"].filename(); | 265 | m_outcube = (*this)["outcube"].filename(); |
| 281 | 266 | ||
| 282 | - // Save only if filename is non-empty | ||
| 283 | - if (!m_outcube.is_empty()) { | 267 | + // Determine whether the cube is empty |
| 268 | + bool cube_is_empty = ((m_edispcube.cube().nx() == 0) || | ||
| 269 | + (m_edispcube.cube().ny() == 0) || | ||
| 270 | + (m_edispcube.cube().nmaps() == 0)); | ||
| 284 | 271 | ||
| 285 | - // Log filename | ||
| 286 | - if (logTerse()) { | ||
| 287 | - log << gammalib::parformat("Energy dispersion cube file"); | ||
| 288 | - log << m_outcube.url() << std::endl; | ||
| 289 | - } | ||
| 290 | - | ||
| 291 | - // Save energy dispersion cube | 272 | + // Save energy dispersion cube if filename and the energy dispersion cube |
| 273 | + // are not empty | ||
| 274 | + if (!m_outcube.is_empty() && !cube_is_empty) { | ||
| 292 | m_edispcube.save(m_outcube, clobber()); | 275 | m_edispcube.save(m_outcube, clobber()); |
| 276 | + } | ||
| 293 | 277 | ||
| 278 | + // Write into logger what has been done | ||
| 279 | + std::string fname = (m_outcube.is_empty()) ? "NONE" : m_outcube.url(); | ||
| 280 | + if (cube_is_empty) { | ||
| 281 | + fname.append(" (cube is empty, no file created)"); | ||
| 294 | } | 282 | } |
| 283 | + log_value(NORMAL, "Energy dispersion cube file", fname); | ||
| 295 | 284 | ||
| 296 | // Return | 285 | // Return |
| 297 | return; | 286 | return; |
| @@ -430,6 +419,9 @@ void ctedispcube::get_parameters(void) | @@ -430,6 +419,9 @@ void ctedispcube::get_parameters(void) | ||
| 430 | ***************************************************************************/ | 419 | ***************************************************************************/ |
| 431 | void ctedispcube::init_cube(void) | 420 | void ctedispcube::init_cube(void) |
| 432 | { | 421 | { |
| 422 | + // Write header into logger | ||
| 423 | + log_header1(TERSE, "Initialise energy dispersion cube"); | ||
| 424 | + | ||
| 433 | // Extract energy dispersion definition | 425 | // Extract energy dispersion definition |
| 434 | const GWcs* proj = static_cast<const GWcs*>(m_edispcube.cube().projection()); | 426 | const GWcs* proj = static_cast<const GWcs*>(m_edispcube.cube().projection()); |
| 435 | std::string wcs = m_edispcube.cube().projection()->code(); | 427 | std::string wcs = m_edispcube.cube().projection()->code(); |
| @@ -449,12 +441,6 @@ void ctedispcube::init_cube(void) | @@ -449,12 +441,6 @@ void ctedispcube::init_cube(void) | ||
| 449 | // If requested, insert energies at all event list energy boundaries | 441 | // If requested, insert energies at all event list energy boundaries |
| 450 | if (m_addbounds) { | 442 | if (m_addbounds) { |
| 451 | 443 | ||
| 452 | - // Set logger | ||
| 453 | - GLog* logger = NULL; | ||
| 454 | - if (logTerse()) { | ||
| 455 | - logger = &log; | ||
| 456 | - } | ||
| 457 | - | ||
| 458 | // Loop over all observations | 444 | // Loop over all observations |
| 459 | for (int i = 0; i < m_obs.size(); ++i) { | 445 | for (int i = 0; i < m_obs.size(); ++i) { |
| 460 | 446 | ||
| @@ -473,7 +459,7 @@ void ctedispcube::init_cube(void) | @@ -473,7 +459,7 @@ void ctedispcube::init_cube(void) | ||
| 473 | } | 459 | } |
| 474 | 460 | ||
| 475 | // Insert energy boundaries | 461 | // Insert energy boundaries |
| 476 | - energies = insert_energy_boundaries(energies, *cta, logger); | 462 | + energies = insert_energy_boundaries(energies, *cta); |
| 477 | 463 | ||
| 478 | } // endfor: looped over all observations | 464 | } // endfor: looped over all observations |
| 479 | 465 | ||
| @@ -483,11 +469,9 @@ void ctedispcube::init_cube(void) | @@ -483,11 +469,9 @@ void ctedispcube::init_cube(void) | ||
| 483 | m_edispcube = GCTACubeEdisp(wcs, coords, x, y, dx, dy, nx, ny, energies, | 469 | m_edispcube = GCTACubeEdisp(wcs, coords, x, y, dx, dy, nx, ny, energies, |
| 484 | mmax, nmbins); | 470 | mmax, nmbins); |
| 485 | 471 | ||
| 486 | - // Log energy dispersion cube | ||
| 487 | - if (logTerse()) { | ||
| 488 | - log << m_edispcube.print(m_chatter) << std::endl; | ||
| 489 | - } | 472 | + // Write energy dispersion cube in logger |
| 473 | + log_string(NORMAL, m_edispcube.print(m_chatter)); | ||
| 490 | 474 | ||
| 491 | // Return | 475 | // Return |
| 492 | return; | 476 | return; |
| 493 | -}; | 477 | +} |
src/ctexpcube/ctexpcube.cpp
| @@ -218,53 +218,25 @@ void ctexpcube::run(void) | @@ -218,53 +218,25 @@ void ctexpcube::run(void) | ||
| 218 | get_parameters(); | 218 | get_parameters(); |
| 219 | 219 | ||
| 220 | // Warn if there are not enough energy bins | 220 | // Warn if there are not enough energy bins |
| 221 | - int n = m_expcube.energies().size(); | ||
| 222 | - double logEmin = std::log10(m_expcube.energies()[0].TeV()); | ||
| 223 | - double logEmax = std::log10(m_expcube.energies()[n-1].TeV()); | ||
| 224 | - int nrequired = int((logEmax - logEmin) * 25.0); | ||
| 225 | - if ((n < nrequired) && logTerse()) { | ||
| 226 | - log << std::endl; | ||
| 227 | - log << "WARNING: "; | ||
| 228 | - log << "Only " << n-1 << " energy bins have been requested. This may be " | ||
| 229 | - "too few energy bins."; | ||
| 230 | - log << std::endl << " "; | ||
| 231 | - log << "At least 25 bins per decade in energy are recommended, which " | ||
| 232 | - "in your case"; | ||
| 233 | - log << std::endl << " "; | ||
| 234 | - log << "would be " << nrequired-1 << " bins. Consider increasing the " | ||
| 235 | - "number of energy bins."; | ||
| 236 | - log << std::endl; | ||
| 237 | - } | 221 | + log_string(TERSE, warn_too_few_energies(m_expcube.energies())); |
| 238 | 222 | ||
| 239 | - // Write header | ||
| 240 | - if (logTerse()) { | ||
| 241 | - log << std::endl; | ||
| 242 | - log.header1("Initialise exposure cube"); | ||
| 243 | - } | 223 | + // Write input observation container into logger |
| 224 | + log_observations(NORMAL, m_obs, "Input observation"); | ||
| 244 | 225 | ||
| 245 | // Initialise exposure cube | 226 | // Initialise exposure cube |
| 246 | init_cube(); | 227 | init_cube(); |
| 247 | 228 | ||
| 248 | - // Write observation(s) into logger | ||
| 249 | - if (logTerse()) { | ||
| 250 | - log << std::endl; | ||
| 251 | - log.header1(gammalib::number("Observation",m_obs.size())); | ||
| 252 | - log << m_obs.print(m_chatter) << std::endl; | ||
| 253 | - } | 229 | + // Write header into logger |
| 230 | + log_header1(TERSE, "Generate exposure cube"); | ||
| 254 | 231 | ||
| 255 | - // Write header | ||
| 256 | - if (logTerse()) { | ||
| 257 | - log << std::endl; | ||
| 258 | - log.header1("Generate exposure cube"); | ||
| 259 | - } | 232 | + // Set pointer to logger dependent on chattiness |
| 233 | + GLog* logger = (logNormal()) ? &log : NULL; | ||
| 260 | 234 | ||
| 261 | // Fill exposure cube | 235 | // Fill exposure cube |
| 262 | - m_expcube.fill(m_obs, &log); | 236 | + m_expcube.fill(m_obs, logger); |
| 263 | 237 | ||
| 264 | - // Log exposure cube | ||
| 265 | - if (logTerse()) { | ||
| 266 | - log << m_expcube.print(m_chatter) << std::endl; | ||
| 267 | - } | 238 | + // Write exposure cube into logger |
| 239 | + log_string(EXPLICIT, m_expcube.print(m_chatter)); | ||
| 268 | 240 | ||
| 269 | // Optionally publish exposure cube | 241 | // Optionally publish exposure cube |
| 270 | if (m_publish) { | 242 | if (m_publish) { |
| @@ -283,28 +255,28 @@ void ctexpcube::run(void) | @@ -283,28 +255,28 @@ void ctexpcube::run(void) | ||
| 283 | ***************************************************************************/ | 255 | ***************************************************************************/ |
| 284 | void ctexpcube::save(void) | 256 | void ctexpcube::save(void) |
| 285 | { | 257 | { |
| 286 | - // Write header | ||
| 287 | - if (logTerse()) { | ||
| 288 | - log << std::endl; | ||
| 289 | - log.header1("Save exposure cube"); | ||
| 290 | - } | 258 | + // Write header into logger |
| 259 | + log_header1(TERSE, "Save exposure cube"); | ||
| 291 | 260 | ||
| 292 | // Get exposure cube filename | 261 | // Get exposure cube filename |
| 293 | m_outcube = (*this)["outcube"].filename(); | 262 | m_outcube = (*this)["outcube"].filename(); |
| 294 | 263 | ||
| 295 | - // Save only if filename is non-empty | ||
| 296 | - if (!m_outcube.is_empty()) { | ||
| 297 | - | ||
| 298 | - // Log filename | ||
| 299 | - if (logTerse()) { | ||
| 300 | - log << gammalib::parformat("Exposure cube file"); | ||
| 301 | - log << m_outcube.url() << std::endl; | ||
| 302 | - } | 264 | + // Determine whether the cube is empty |
| 265 | + bool cube_is_empty = ((m_expcube.cube().nx() == 0) || | ||
| 266 | + (m_expcube.cube().ny() == 0) || | ||
| 267 | + (m_expcube.cube().nmaps() == 0)); | ||
| 303 | 268 | ||
| 304 | - // Save exposure cube | 269 | + // Save exposure cube if filename and the exposure cube are not empty |
| 270 | + if (!m_outcube.is_empty() && !cube_is_empty) { | ||
| 305 | m_expcube.save(m_outcube, clobber()); | 271 | m_expcube.save(m_outcube, clobber()); |
| 272 | + } | ||
| 306 | 273 | ||
| 274 | + // Write into logger what has been done | ||
| 275 | + std::string fname = (m_outcube.is_empty()) ? "NONE" : m_outcube.url(); | ||
| 276 | + if (cube_is_empty) { | ||
| 277 | + fname.append(" (cube is empty, no file created)"); | ||
| 307 | } | 278 | } |
| 279 | + log_value(NORMAL, "Exposure cube file", fname); | ||
| 308 | 280 | ||
| 309 | // Return | 281 | // Return |
| 310 | return; | 282 | return; |
| @@ -318,23 +290,17 @@ void ctexpcube::save(void) | @@ -318,23 +290,17 @@ void ctexpcube::save(void) | ||
| 318 | ***************************************************************************/ | 290 | ***************************************************************************/ |
| 319 | void ctexpcube::publish(const std::string& name) | 291 | void ctexpcube::publish(const std::string& name) |
| 320 | { | 292 | { |
| 321 | - // Write header | ||
| 322 | - if (logTerse()) { | ||
| 323 | - log << std::endl; | ||
| 324 | - log.header1("Publish exposure cube"); | ||
| 325 | - } | 293 | + // Write header into logger |
| 294 | + log_header1(TERSE, "Publish exposure cube"); | ||
| 326 | 295 | ||
| 327 | - // Set default name is user name is empty | 296 | + // Set default name if user name is empty |
| 328 | std::string user_name(name); | 297 | std::string user_name(name); |
| 329 | if (user_name.empty()) { | 298 | if (user_name.empty()) { |
| 330 | user_name = CTEXPCUBE_NAME; | 299 | user_name = CTEXPCUBE_NAME; |
| 331 | } | 300 | } |
| 332 | 301 | ||
| 333 | - // Log filename | ||
| 334 | - if (logTerse()) { | ||
| 335 | - log << gammalib::parformat("Publish exposure cube"); | ||
| 336 | - log << user_name << std::endl; | ||
| 337 | - } | 302 | + // Write exposure cube name into logger |
| 303 | + log_value(NORMAL, "Counts cube name", user_name); | ||
| 338 | 304 | ||
| 339 | // Publish exposure cube | 305 | // Publish exposure cube |
| 340 | m_expcube.cube().publish(user_name); | 306 | m_expcube.cube().publish(user_name); |
| @@ -475,6 +441,9 @@ void ctexpcube::get_parameters(void) | @@ -475,6 +441,9 @@ void ctexpcube::get_parameters(void) | ||
| 475 | ***************************************************************************/ | 441 | ***************************************************************************/ |
| 476 | void ctexpcube::init_cube(void) | 442 | void ctexpcube::init_cube(void) |
| 477 | { | 443 | { |
| 444 | + // Write header into logger | ||
| 445 | + log_header1(TERSE, "Initialise exposure cube"); | ||
| 446 | + | ||
| 478 | // Extract exposure cube definition | 447 | // Extract exposure cube definition |
| 479 | const GWcs* proj = static_cast<const GWcs*>(m_expcube.cube().projection()); | 448 | const GWcs* proj = static_cast<const GWcs*>(m_expcube.cube().projection()); |
| 480 | std::string wcs = m_expcube.cube().projection()->code(); | 449 | std::string wcs = m_expcube.cube().projection()->code(); |
| @@ -492,12 +461,6 @@ void ctexpcube::init_cube(void) | @@ -492,12 +461,6 @@ void ctexpcube::init_cube(void) | ||
| 492 | // If requested, insert energies at all event list energy boundaries | 461 | // If requested, insert energies at all event list energy boundaries |
| 493 | if (m_addbounds) { | 462 | if (m_addbounds) { |
| 494 | 463 | ||
| 495 | - // Set logger | ||
| 496 | - GLog* logger = NULL; | ||
| 497 | - if (logTerse()) { | ||
| 498 | - logger = &log; | ||
| 499 | - } | ||
| 500 | - | ||
| 501 | // Loop over all observations | 464 | // Loop over all observations |
| 502 | for (int i = 0; i < m_obs.size(); ++i) { | 465 | for (int i = 0; i < m_obs.size(); ++i) { |
| 503 | 466 | ||
| @@ -516,7 +479,7 @@ void ctexpcube::init_cube(void) | @@ -516,7 +479,7 @@ void ctexpcube::init_cube(void) | ||
| 516 | } | 479 | } |
| 517 | 480 | ||
| 518 | // Insert energy boundaries | 481 | // Insert energy boundaries |
| 519 | - energies = insert_energy_boundaries(energies, *cta, logger); | 482 | + energies = insert_energy_boundaries(energies, *cta); |
| 520 | 483 | ||
| 521 | } // endfor: looped over all observations | 484 | } // endfor: looped over all observations |
| 522 | 485 | ||
| @@ -525,11 +488,9 @@ void ctexpcube::init_cube(void) | @@ -525,11 +488,9 @@ void ctexpcube::init_cube(void) | ||
| 525 | // Setup exposure cube | 488 | // Setup exposure cube |
| 526 | m_expcube = GCTACubeExposure(wcs, coords, x, y, dx, dy, nx, ny, energies); | 489 | m_expcube = GCTACubeExposure(wcs, coords, x, y, dx, dy, nx, ny, energies); |
| 527 | 490 | ||
| 528 | - // Log exposure cube | ||
| 529 | - if (logTerse()) { | ||
| 530 | - log << m_expcube.print(m_chatter) << std::endl; | ||
| 531 | - } | 491 | + // Write exposure cube in logger |
| 492 | + log_string(NORMAL, m_expcube.print(m_chatter)); | ||
| 532 | 493 | ||
| 533 | // Return | 494 | // Return |
| 534 | return; | 495 | return; |
| 535 | -}; | 496 | +} |
src/ctobssim/ctobssim.cpp
| @@ -324,7 +324,7 @@ void ctobssim::run(void) | @@ -324,7 +324,7 @@ void ctobssim::run(void) | ||
| 324 | wrklog.name(log.name()); | 324 | wrklog.name(log.name()); |
| 325 | 325 | ||
| 326 | // Set a big value to avoid flushing | 326 | // Set a big value to avoid flushing |
| 327 | - wrklog.max_size(10000000); | 327 | + wrklog.buffer_size(10000000); |
| 328 | 328 | ||
| 329 | // Loop over all observation in the container. If OpenMP support | 329 | // Loop over all observation in the container. If OpenMP support |
| 330 | // is enabled, this loop will be parallelized. | 330 | // is enabled, this loop will be parallelized. |
src/ctpsfcube/ctpsfcube.cpp
| @@ -216,35 +216,20 @@ void ctpsfcube::run(void) | @@ -216,35 +216,20 @@ void ctpsfcube::run(void) | ||
| 216 | // Get task parameters | 216 | // Get task parameters |
| 217 | get_parameters(); | 217 | get_parameters(); |
| 218 | 218 | ||
| 219 | - // Write header | ||
| 220 | - if (logTerse()) { | ||
| 221 | - log << std::endl; | ||
| 222 | - log.header1("Initialise PSF cube"); | ||
| 223 | - } | 219 | + // Write input observation container into logger |
| 220 | + log_observations(NORMAL, m_obs, "Input observation"); | ||
| 224 | 221 | ||
| 225 | - // Initialise exposure cube | 222 | + // Initialise PSF cube |
| 226 | init_cube(); | 223 | init_cube(); |
| 227 | 224 | ||
| 228 | - // Write observation(s) into logger | ||
| 229 | - if (logTerse()) { | ||
| 230 | - log << std::endl; | ||
| 231 | - log.header1(gammalib::number("Observation",m_obs.size())); | ||
| 232 | - log << m_obs.print(m_chatter) << std::endl; | ||
| 233 | - } | ||
| 234 | - | ||
| 235 | - // Write header | ||
| 236 | - if (logTerse()) { | ||
| 237 | - log << std::endl; | ||
| 238 | - log.header1("Generate PSF cube"); | ||
| 239 | - } | 225 | + // Write header into logger |
| 226 | + log_header1(TERSE, "Generate PSF cube"); | ||
| 240 | 227 | ||
| 241 | // Fill PSF cube | 228 | // Fill PSF cube |
| 242 | m_psfcube.fill(m_obs, &log); | 229 | m_psfcube.fill(m_obs, &log); |
| 243 | 230 | ||
| 244 | - // Log PSF cube | ||
| 245 | - if (logTerse()) { | ||
| 246 | - log << m_psfcube.print(m_chatter) << std::endl; | ||
| 247 | - } | 231 | + // Write PSF cube into logger |
| 232 | + log_string(EXPLICIT, m_psfcube.print(m_chatter)); | ||
| 248 | 233 | ||
| 249 | // Return | 234 | // Return |
| 250 | return; | 235 | return; |
| @@ -253,31 +238,34 @@ void ctpsfcube::run(void) | @@ -253,31 +238,34 @@ void ctpsfcube::run(void) | ||
| 253 | 238 | ||
| 254 | /***********************************************************************//** | 239 | /***********************************************************************//** |
| 255 | * @brief Save PSF cube | 240 | * @brief Save PSF cube |
| 241 | + * | ||
| 242 | + * Saves the PSF cube into a FITS file. A file is only created if the | ||
| 243 | + * "outcube" parameter is not empty and if a PSF cube has been computed. | ||
| 256 | ***************************************************************************/ | 244 | ***************************************************************************/ |
| 257 | void ctpsfcube::save(void) | 245 | void ctpsfcube::save(void) |
| 258 | { | 246 | { |
| 259 | - // Write header | ||
| 260 | - if (logTerse()) { | ||
| 261 | - log << std::endl; | ||
| 262 | - log.header1("Save PSF cube"); | ||
| 263 | - } | 247 | + // Write header into logger |
| 248 | + log_header1(TERSE, "Save PSF cube"); | ||
| 264 | 249 | ||
| 265 | // Get output filename | 250 | // Get output filename |
| 266 | m_outcube = (*this)["outcube"].filename(); | 251 | m_outcube = (*this)["outcube"].filename(); |
| 267 | 252 | ||
| 268 | - // Save only if filename is non-empty | ||
| 269 | - if (!m_outcube.is_empty()) { | ||
| 270 | - | ||
| 271 | - // Log filename | ||
| 272 | - if (logTerse()) { | ||
| 273 | - log << gammalib::parformat("PSF cube file"); | ||
| 274 | - log << m_outcube.url() << std::endl; | ||
| 275 | - } | 253 | + // Determine whether the cube is empty |
| 254 | + bool cube_is_empty = ((m_psfcube.cube().nx() == 0) || | ||
| 255 | + (m_psfcube.cube().ny() == 0) || | ||
| 256 | + (m_psfcube.cube().nmaps() == 0)); | ||
| 276 | 257 | ||
| 277 | - // Save PSF cube | 258 | + // Save PSF cube if filename and the PSF cube are not empty |
| 259 | + if (!m_outcube.is_empty() && !cube_is_empty) { | ||
| 278 | m_psfcube.save(m_outcube, clobber()); | 260 | m_psfcube.save(m_outcube, clobber()); |
| 261 | + } | ||
| 279 | 262 | ||
| 263 | + // Write into logger what has been done | ||
| 264 | + std::string fname = (m_outcube.is_empty()) ? "NONE" : m_outcube.url(); | ||
| 265 | + if (cube_is_empty) { | ||
| 266 | + fname.append(" (cube is empty, no file created)"); | ||
| 280 | } | 267 | } |
| 268 | + log_value(NORMAL, "PSF cube file", fname); | ||
| 281 | 269 | ||
| 282 | // Return | 270 | // Return |
| 283 | return; | 271 | return; |
| @@ -381,7 +369,7 @@ void ctpsfcube::get_parameters(void) | @@ -381,7 +369,7 @@ void ctpsfcube::get_parameters(void) | ||
| 381 | 369 | ||
| 382 | } | 370 | } |
| 383 | 371 | ||
| 384 | - // ... otherwise setup the exposure cube from the counts map | 372 | + // ... otherwise setup the PSF cube from the counts map |
| 385 | else { | 373 | else { |
| 386 | 374 | ||
| 387 | // Load event cube from filename | 375 | // Load event cube from filename |
| @@ -416,7 +404,10 @@ void ctpsfcube::get_parameters(void) | @@ -416,7 +404,10 @@ void ctpsfcube::get_parameters(void) | ||
| 416 | ***************************************************************************/ | 404 | ***************************************************************************/ |
| 417 | void ctpsfcube::init_cube(void) | 405 | void ctpsfcube::init_cube(void) |
| 418 | { | 406 | { |
| 419 | - // Extract exposure cube definition | 407 | + // Write header into logger |
| 408 | + log_header1(TERSE, "Initialise PSF cube"); | ||
| 409 | + | ||
| 410 | + // Extract PSF cube definition | ||
| 420 | const GWcs* proj = static_cast<const GWcs*>(m_psfcube.cube().projection()); | 411 | const GWcs* proj = static_cast<const GWcs*>(m_psfcube.cube().projection()); |
| 421 | std::string wcs = m_psfcube.cube().projection()->code(); | 412 | std::string wcs = m_psfcube.cube().projection()->code(); |
| 422 | std::string coords = m_psfcube.cube().projection()->coordsys(); | 413 | std::string coords = m_psfcube.cube().projection()->coordsys(); |
| @@ -435,12 +426,6 @@ void ctpsfcube::init_cube(void) | @@ -435,12 +426,6 @@ void ctpsfcube::init_cube(void) | ||
| 435 | // If requested, insert energies at all event list energy boundaries | 426 | // If requested, insert energies at all event list energy boundaries |
| 436 | if (m_addbounds) { | 427 | if (m_addbounds) { |
| 437 | 428 | ||
| 438 | - // Set logger | ||
| 439 | - GLog* logger = NULL; | ||
| 440 | - if (logTerse()) { | ||
| 441 | - logger = &log; | ||
| 442 | - } | ||
| 443 | - | ||
| 444 | // Loop over all observations | 429 | // Loop over all observations |
| 445 | for (int i = 0; i < m_obs.size(); ++i) { | 430 | for (int i = 0; i < m_obs.size(); ++i) { |
| 446 | 431 | ||
| @@ -459,7 +444,7 @@ void ctpsfcube::init_cube(void) | @@ -459,7 +444,7 @@ void ctpsfcube::init_cube(void) | ||
| 459 | } | 444 | } |
| 460 | 445 | ||
| 461 | // Insert energy boundaries | 446 | // Insert energy boundaries |
| 462 | - energies = insert_energy_boundaries(energies, *cta, logger); | 447 | + energies = insert_energy_boundaries(energies, *cta); |
| 463 | 448 | ||
| 464 | } // endfor: looped over all observations | 449 | } // endfor: looped over all observations |
| 465 | 450 | ||
| @@ -469,11 +454,9 @@ void ctpsfcube::init_cube(void) | @@ -469,11 +454,9 @@ void ctpsfcube::init_cube(void) | ||
| 469 | m_psfcube = GCTACubePsf(wcs, coords, x, y, dx, dy, nx, ny, energies, | 454 | m_psfcube = GCTACubePsf(wcs, coords, x, y, dx, dy, nx, ny, energies, |
| 470 | dmax, ndbins); | 455 | dmax, ndbins); |
| 471 | 456 | ||
| 472 | - // Log PSF cube | ||
| 473 | - if (logTerse()) { | ||
| 474 | - log << m_psfcube.print(m_chatter) << std::endl; | ||
| 475 | - } | 457 | + // Write PSF cube in logger |
| 458 | + log_string(NORMAL, m_psfcube.print(m_chatter)); | ||
| 476 | 459 | ||
| 477 | // Return | 460 | // Return |
| 478 | return; | 461 | return; |
| 479 | -}; | 462 | +} |
src/support/ctool.cpp
| @@ -68,15 +68,14 @@ | @@ -68,15 +68,14 @@ | ||
| 68 | 68 | ||
| 69 | /***********************************************************************//** | 69 | /***********************************************************************//** |
| 70 | * @brief Void constructor | 70 | * @brief Void constructor |
| 71 | + * | ||
| 72 | + * Constructs an empty ctools. | ||
| 71 | ***************************************************************************/ | 73 | ***************************************************************************/ |
| 72 | ctool::ctool(void) : GApplication() | 74 | ctool::ctool(void) : GApplication() |
| 73 | { | 75 | { |
| 74 | // Initialise members | 76 | // Initialise members |
| 75 | init_members(); | 77 | init_members(); |
| 76 | 78 | ||
| 77 | - // Write header into logger | ||
| 78 | - log_header(); | ||
| 79 | - | ||
| 80 | // Return | 79 | // Return |
| 81 | return; | 80 | return; |
| 82 | } | 81 | } |
| @@ -87,6 +86,16 @@ ctool::ctool(void) : GApplication() | @@ -87,6 +86,16 @@ ctool::ctool(void) : GApplication() | ||
| 87 | * | 86 | * |
| 88 | * @param[in] name Application name. | 87 | * @param[in] name Application name. |
| 89 | * @param[in] version Application version. | 88 | * @param[in] version Application version. |
| 89 | + * | ||
| 90 | + * Constructs a ctool from the @p name and @p version. The constructor uses | ||
| 91 | + * the equivalent GApplication constructor to set the parameter filename to | ||
| 92 | + * "<name>.par" and the log filename to "<name>".log. The parameters will be | ||
| 93 | + * loaded from the parameter file. | ||
| 94 | + * | ||
| 95 | + * No log file will be opened. To open the log file an explicit call to the | ||
| 96 | + * logFileOpen() method is required. | ||
| 97 | + * | ||
| 98 | + * This constructor should be used for using a ctool from Python. | ||
| 90 | ***************************************************************************/ | 99 | ***************************************************************************/ |
| 91 | ctool::ctool(const std::string& name, const std::string& version) : | 100 | ctool::ctool(const std::string& name, const std::string& version) : |
| 92 | GApplication(name, version) | 101 | GApplication(name, version) |
| @@ -94,9 +103,6 @@ ctool::ctool(const std::string& name, const std::string& version) : | @@ -94,9 +103,6 @@ ctool::ctool(const std::string& name, const std::string& version) : | ||
| 94 | // Initialise members | 103 | // Initialise members |
| 95 | init_members(); | 104 | init_members(); |
| 96 | 105 | ||
| 97 | - // Write header into logger | ||
| 98 | - log_header(); | ||
| 99 | - | ||
| 100 | // Return | 106 | // Return |
| 101 | return; | 107 | return; |
| 102 | } | 108 | } |
| @@ -109,6 +115,16 @@ ctool::ctool(const std::string& name, const std::string& version) : | @@ -109,6 +115,16 @@ ctool::ctool(const std::string& name, const std::string& version) : | ||
| 109 | * @param[in] version Application version. | 115 | * @param[in] version Application version. |
| 110 | * @param[in] argc Number of arguments in command line. | 116 | * @param[in] argc Number of arguments in command line. |
| 111 | * @param[in] argv Array of command line arguments. | 117 | * @param[in] argv Array of command line arguments. |
| 118 | + * | ||
| 119 | + * Constructs a ctool from the @p name, @p version and command line | ||
| 120 | + * arguments. The constructor uses the equivalent GApplication constructor | ||
| 121 | + * to set the parameter filename to "<name>.par" and the log filename to | ||
| 122 | + * "<name>".log. The parameters will be loaded from the parameter file. | ||
| 123 | + * In addition, the constructor opens the log file. | ||
| 124 | + * | ||
| 125 | + * If the "--help" option is provided as command line argument a help text | ||
| 126 | + * about the usage of the ctool will be shown in the console and the ctool | ||
| 127 | + * will exit. No log file will be opened in that case. | ||
| 112 | ***************************************************************************/ | 128 | ***************************************************************************/ |
| 113 | ctool::ctool(const std::string& name, const std::string& version, | 129 | ctool::ctool(const std::string& name, const std::string& version, |
| 114 | int argc, char *argv[]) : | 130 | int argc, char *argv[]) : |
| @@ -123,8 +139,8 @@ ctool::ctool(const std::string& name, const std::string& version, | @@ -123,8 +139,8 @@ ctool::ctool(const std::string& name, const std::string& version, | ||
| 123 | // Initialise members | 139 | // Initialise members |
| 124 | init_members(); | 140 | init_members(); |
| 125 | 141 | ||
| 126 | - // Write header into logger | ||
| 127 | - log_header(); | 142 | + // Open the log file |
| 143 | + logFileOpen(); | ||
| 128 | 144 | ||
| 129 | // Return | 145 | // Return |
| 130 | return; | 146 | return; |
| @@ -135,6 +151,8 @@ ctool::ctool(const std::string& name, const std::string& version, | @@ -135,6 +151,8 @@ ctool::ctool(const std::string& name, const std::string& version, | ||
| 135 | * @brief Copy constructor | 151 | * @brief Copy constructor |
| 136 | * | 152 | * |
| 137 | * @param[in] app Application. | 153 | * @param[in] app Application. |
| 154 | + * | ||
| 155 | + * Construct a ctools from another ctool instance. | ||
| 138 | ***************************************************************************/ | 156 | ***************************************************************************/ |
| 139 | ctool::ctool(const ctool& app) : GApplication(app) | 157 | ctool::ctool(const ctool& app) : GApplication(app) |
| 140 | { | 158 | { |
| @@ -172,6 +190,8 @@ ctool::~ctool(void) | @@ -172,6 +190,8 @@ ctool::~ctool(void) | ||
| 172 | * @brief Assignment operator | 190 | * @brief Assignment operator |
| 173 | * | 191 | * |
| 174 | * @param[in] app Application. | 192 | * @param[in] app Application. |
| 193 | + * | ||
| 194 | + * Assigns one ctool to another. | ||
| 175 | ***************************************************************************/ | 195 | ***************************************************************************/ |
| 176 | ctool& ctool::operator=(const ctool& app) | 196 | ctool& ctool::operator=(const ctool& app) |
| 177 | { | 197 | { |
| @@ -207,7 +227,8 @@ ctool& ctool::operator=(const ctool& app) | @@ -207,7 +227,8 @@ ctool& ctool::operator=(const ctool& app) | ||
| 207 | * @brief Execute application | 227 | * @brief Execute application |
| 208 | * | 228 | * |
| 209 | * This is the main execution method of a ctool. The method is invoked when | 229 | * This is the main execution method of a ctool. The method is invoked when |
| 210 | - * the executable is called from command line. | 230 | + * the executable is called from the command line. It signals that output |
| 231 | + * parameters should be read ahead, runs the tools, and saves the results. | ||
| 211 | ***************************************************************************/ | 232 | ***************************************************************************/ |
| 212 | void ctool::execute(void) | 233 | void ctool::execute(void) |
| 213 | { | 234 | { |
| @@ -275,9 +296,6 @@ void ctool::copy_members(const ctool& app) | @@ -275,9 +296,6 @@ void ctool::copy_members(const ctool& app) | ||
| 275 | ***************************************************************************/ | 296 | ***************************************************************************/ |
| 276 | void ctool::free_members(void) | 297 | void ctool::free_members(void) |
| 277 | { | 298 | { |
| 278 | - // Write separator into logger | ||
| 279 | - log_string(TERSE, ""); | ||
| 280 | - | ||
| 281 | // Return | 299 | // Return |
| 282 | return; | 300 | return; |
| 283 | } | 301 | } |
| @@ -1374,10 +1392,11 @@ std::string ctool::get_obs_header(const GObservation* obs) | @@ -1374,10 +1392,11 @@ std::string ctool::get_obs_header(const GObservation* obs) | ||
| 1374 | * @param[in] energies Energies. | 1392 | * @param[in] energies Energies. |
| 1375 | * @param[in] obs Observation container. | 1393 | * @param[in] obs Observation container. |
| 1376 | * @return Energies. | 1394 | * @return Energies. |
| 1395 | + * | ||
| 1396 | + * Inserts the energy boundaries of an observation in a list of @p energies. | ||
| 1377 | ***************************************************************************/ | 1397 | ***************************************************************************/ |
| 1378 | GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, | 1398 | GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, |
| 1379 | - const GCTAObservation& obs, | ||
| 1380 | - GLog* log) const | 1399 | + const GCTAObservation& obs) |
| 1381 | { | 1400 | { |
| 1382 | // Create copy of input energies | 1401 | // Create copy of input energies |
| 1383 | GEnergies engs = energies; | 1402 | GEnergies engs = energies; |
| @@ -1428,11 +1447,8 @@ GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, | @@ -1428,11 +1447,8 @@ GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, | ||
| 1428 | engs.append(energy); | 1447 | engs.append(energy); |
| 1429 | } | 1448 | } |
| 1430 | 1449 | ||
| 1431 | - // Log energy insertion | ||
| 1432 | - if (log != NULL) { | ||
| 1433 | - *log << gammalib::parformat("Insert energy"); | ||
| 1434 | - *log << energy.print() << std::endl; | ||
| 1435 | - } | 1450 | + // Log energy insertion. Circumvent const correctness |
| 1451 | + log_value(NORMAL, "Insert energy", energy.print()); | ||
| 1436 | 1452 | ||
| 1437 | } // endif: energy insertion requested | 1453 | } // endif: energy insertion requested |
| 1438 | 1454 | ||
| @@ -1444,7 +1460,63 @@ GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, | @@ -1444,7 +1460,63 @@ GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, | ||
| 1444 | 1460 | ||
| 1445 | 1461 | ||
| 1446 | /***********************************************************************//** | 1462 | /***********************************************************************//** |
| 1447 | - * @brief Dumps help text in the console | 1463 | + * @brief Set warning string if there are too few energies |
| 1464 | + * | ||
| 1465 | + * @param[in] energies Energies. | ||
| 1466 | + * @return Warning string. | ||
| 1467 | + * | ||
| 1468 | + * Sets a warning string if there are too few @p energies in the container. | ||
| 1469 | + * For a binned or stacked analysis to be accurate, at least 25 bins per | ||
| 1470 | + * decade are required. If the provided number of energies is less than this | ||
| 1471 | + * number a warning string will be returned. Otherwise an empty string will | ||
| 1472 | + * be returned. | ||
| 1473 | + ***************************************************************************/ | ||
| 1474 | +std::string ctool::warn_too_few_energies(const GEnergies& energies) const | ||
| 1475 | +{ | ||
| 1476 | + // Initialise warning | ||
| 1477 | + std::string warning; | ||
| 1478 | + | ||
| 1479 | + // Retrieve the number of energies | ||
| 1480 | + int n = energies.size(); | ||
| 1481 | + | ||
| 1482 | + // Compute the required number of energy bins | ||
| 1483 | + double logEmin = std::log10(energies[0].TeV()); | ||
| 1484 | + double logEmax = std::log10(energies[n-1].TeV()); | ||
| 1485 | + int nrequired = int((logEmax - logEmin) * 25.0); | ||
| 1486 | + | ||
| 1487 | + // Warn if there are not enough energy bins | ||
| 1488 | + if (n < nrequired) { | ||
| 1489 | + warning.append("\nWARNING: Only "+gammalib::str(n-1)+" energy bins " | ||
| 1490 | + "have been requested. This may be too few energy " | ||
| 1491 | + "bins." | ||
| 1492 | + "\n At least 25 bins per decade in energy are " | ||
| 1493 | + "recommended, which for the given" | ||
| 1494 | + "\n energy range would be "+ | ||
| 1495 | + gammalib::str(nrequired)+" bins. Consider increasing " | ||
| 1496 | + "the number of energy bins."); | ||
| 1497 | + } | ||
| 1498 | + | ||
| 1499 | + // Return warning | ||
| 1500 | + return warning; | ||
| 1501 | +} | ||
| 1502 | + | ||
| 1503 | + | ||
| 1504 | +/*========================================================================== | ||
| 1505 | + = = | ||
| 1506 | + = Private methods for SWIG = | ||
| 1507 | + = = | ||
| 1508 | + ==========================================================================*/ | ||
| 1509 | + | ||
| 1510 | +/***********************************************************************//** | ||
| 1511 | + * @brief Dump help text in the console | ||
| 1512 | + * | ||
| 1513 | + * Dumps the help text for the ctool into the console. The help text is | ||
| 1514 | + * located in the folder | ||
| 1515 | + * | ||
| 1516 | + * $CTOOLS//share/help/ | ||
| 1517 | + * | ||
| 1518 | + * of the ctools installation and the help file has the name "<name>.txt", | ||
| 1519 | + * where <name> stands for the name of the ctool. | ||
| 1448 | ***************************************************************************/ | 1520 | ***************************************************************************/ |
| 1449 | void ctool::provide_help(void) const | 1521 | void ctool::provide_help(void) const |
| 1450 | { | 1522 | { |
src/support/ctool.hpp
| @@ -101,8 +101,10 @@ protected: | @@ -101,8 +101,10 @@ protected: | ||
| 101 | size_t get_current_rss(void); | 101 | size_t get_current_rss(void); |
| 102 | std::string get_obs_header(const GObservation* obs); | 102 | std::string get_obs_header(const GObservation* obs); |
| 103 | GEnergies insert_energy_boundaries(const GEnergies& energies, | 103 | GEnergies insert_energy_boundaries(const GEnergies& energies, |
| 104 | - const GCTAObservation& obs, | ||
| 105 | - GLog* log = NULL) const; | 104 | + const GCTAObservation& obs); |
| 105 | + | ||
| 106 | + // Protected warning strings | ||
| 107 | + std::string warn_too_few_energies(const GEnergies& energies) const; | ||
| 106 | 108 | ||
| 107 | // Protected members | 109 | // Protected members |
| 108 | bool m_read_ahead; //!< Read ahead output parameters | 110 | bool m_read_ahead; //!< Read ahead output parameters |
test/test_ctbin.py
| @@ -134,7 +134,6 @@ class Test(test): | @@ -134,7 +134,6 @@ class Test(test): | ||
| 134 | bin.clear() | 134 | bin.clear() |
| 135 | 135 | ||
| 136 | # Now set ctbin parameters | 136 | # Now set ctbin parameters |
| 137 | - #bin = ctools.ctbin() | ||
| 138 | bin['inobs'] = self._events | 137 | bin['inobs'] = self._events |
| 139 | bin['outcube'] = 'ctbin_py1.fits' | 138 | bin['outcube'] = 'ctbin_py1.fits' |
| 140 | bin['ebinalg'] = 'LOG' | 139 | bin['ebinalg'] = 'LOG' |
| @@ -159,7 +158,7 @@ class Test(test): | @@ -159,7 +158,7 @@ class Test(test): | ||
| 159 | self._check_observation(bin, 5542) | 158 | self._check_observation(bin, 5542) |
| 160 | self._check_cube(bin.cube(), 5542) | 159 | self._check_cube(bin.cube(), 5542) |
| 161 | 160 | ||
| 162 | - # Test copy constructor | 161 | + # Copy ctbin tool |
| 163 | cpy_bin = bin.copy() | 162 | cpy_bin = bin.copy() |
| 164 | 163 | ||
| 165 | # Check content of observation container and counts cube | 164 | # Check content of observation container and counts cube |
test/test_ctbkgcube.py
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | # | 19 | # |
| 20 | # ========================================================================== | 20 | # ========================================================================== |
| 21 | +import os | ||
| 21 | import gammalib | 22 | import gammalib |
| 22 | import ctools | 23 | import ctools |
| 23 | from testing import test | 24 | from testing import test |
| @@ -85,7 +86,7 @@ class Test(test): | @@ -85,7 +86,7 @@ class Test(test): | ||
| 85 | 'Check successful execution from command line') | 86 | 'Check successful execution from command line') |
| 86 | 87 | ||
| 87 | # Check result file | 88 | # Check result file |
| 88 | - self._check_result_file('ctbkgcube_cmd1.fits') | 89 | + self._check_result_files('ctbkgcube_cmd1') |
| 89 | 90 | ||
| 90 | # Setup ctbkgcube command | 91 | # Setup ctbkgcube command |
| 91 | cmd = ctbkgcube+' inobs="event_file_that_does_not_exist.fits"'+ \ | 92 | cmd = ctbkgcube+' inobs="event_file_that_does_not_exist.fits"'+ \ |
| @@ -111,8 +112,29 @@ class Test(test): | @@ -111,8 +112,29 @@ class Test(test): | ||
| 111 | """ | 112 | """ |
| 112 | Test ctbkgcube from Python | 113 | Test ctbkgcube from Python |
| 113 | """ | 114 | """ |
| 114 | - # Set-up ctbkgcube | 115 | + # Allocate ctbkgcube |
| 115 | bkgcube = ctools.ctbkgcube() | 116 | bkgcube = ctools.ctbkgcube() |
| 117 | + | ||
| 118 | + # Check that empty ctbkgcube tool holds a background cube that has | ||
| 119 | + # no energy bins | ||
| 120 | + self._check_cube(bkgcube.bkgcube(), nenergies=0) | ||
| 121 | + | ||
| 122 | + # Check that saving does not nothing | ||
| 123 | + bkgcube['outcube'] = 'ctbkgcube_py0.fits' | ||
| 124 | + bkgcube['outmodel'] = 'ctbkgcube_py0.xml' | ||
| 125 | + bkgcube['logfile'] = 'ctbkgcube_py0.log' | ||
| 126 | + bkgcube.logFileOpen() | ||
| 127 | + bkgcube.save() | ||
| 128 | + self.test_assert(not os.path.isfile('ctbkgcube_py0.fits'), | ||
| 129 | + 'Check that no background cube has been created') | ||
| 130 | + | ||
| 131 | + # Check model container | ||
| 132 | + self._check_models(gammalib.GModels('ctbkgcube_py0.xml'), nmodels=0) | ||
| 133 | + | ||
| 134 | + # Check that clearing does not lead to an exception or segfault | ||
| 135 | + bkgcube.clear() | ||
| 136 | + | ||
| 137 | + # Now set ctbkgcube parameters | ||
| 116 | bkgcube['inobs'] = self._events | 138 | bkgcube['inobs'] = self._events |
| 117 | bkgcube['inmodel'] = self._model | 139 | bkgcube['inmodel'] = self._model |
| 118 | bkgcube['incube'] = 'NONE' | 140 | bkgcube['incube'] = 'NONE' |
| @@ -120,7 +142,7 @@ class Test(test): | @@ -120,7 +142,7 @@ class Test(test): | ||
| 120 | bkgcube['irf'] = self._irf | 142 | bkgcube['irf'] = self._irf |
| 121 | bkgcube['ebinalg'] = 'LOG' | 143 | bkgcube['ebinalg'] = 'LOG' |
| 122 | bkgcube['emin'] = 0.1 | 144 | bkgcube['emin'] = 0.1 |
| 123 | - bkgcube['emax'] = 100 | 145 | + bkgcube['emax'] = 100.0 |
| 124 | bkgcube['enumbins'] = 20 | 146 | bkgcube['enumbins'] = 20 |
| 125 | bkgcube['nxpix'] = 10 | 147 | bkgcube['nxpix'] = 10 |
| 126 | bkgcube['nypix'] = 10 | 148 | bkgcube['nypix'] = 10 |
| @@ -139,45 +161,43 @@ class Test(test): | @@ -139,45 +161,43 @@ class Test(test): | ||
| 139 | bkgcube.run() | 161 | bkgcube.run() |
| 140 | bkgcube.save() | 162 | bkgcube.save() |
| 141 | 163 | ||
| 142 | - # Check result file | ||
| 143 | - self._check_result_file('ctbkgcube_py1.fits') | ||
| 144 | - | ||
| 145 | - # Set-up ctbkgcube from counts cube | ||
| 146 | - bkgcube = ctools.ctbkgcube() | ||
| 147 | - bkgcube['inobs'] = self._events | ||
| 148 | - bkgcube['inmodel'] = self._model | ||
| 149 | - bkgcube['incube'] = self._cntcube | ||
| 150 | - bkgcube['caldb'] = self._caldb | ||
| 151 | - bkgcube['irf'] = self._irf | ||
| 152 | - bkgcube['outcube'] = 'ctbkgcube_py2.fits' | ||
| 153 | - bkgcube['outmodel'] = 'ctbkgcube_py2.xml' | ||
| 154 | - bkgcube['logfile'] = 'ctbkgcube_py2.log' | ||
| 155 | - bkgcube['chatter'] = 3 | ||
| 156 | - bkgcube['publish'] = True | ||
| 157 | - bkgcube['addbounds'] = True | ||
| 158 | - | ||
| 159 | - # Execute ctbkgcube tool | ||
| 160 | - bkgcube.logFileOpen() # Make sure we get a log file | ||
| 161 | - bkgcube.execute() | ||
| 162 | - | ||
| 163 | - # Check result file | ||
| 164 | - self._check_result_file('ctbkgcube_py2.fits') | ||
| 165 | - | ||
| 166 | - # Copy ctbkgcube tool and execute copied tool | ||
| 167 | - cpy_bkgcube = bkgcube | ||
| 168 | - cpy_bkgcube['outcube'] = 'ctbkgcube_py3.fits' | ||
| 169 | - cpy_bkgcube['outmodel'] = 'ctbkgcube_py3.xml' | ||
| 170 | - cpy_bkgcube['logfile'] = 'ctbkgcube_py3.log' | ||
| 171 | - cpy_bkgcube['chatter'] = 4 | 164 | + # Check result files |
| 165 | + self._check_result_files('ctbkgcube_py1') | ||
| 166 | + | ||
| 167 | + # Copy ctbkgcube tool | ||
| 168 | + cpy_bkgcube = bkgcube.copy() | ||
| 169 | + | ||
| 170 | + # Check background cube and model container of ctbkgcube copy | ||
| 171 | + self._check_cube(cpy_bkgcube.bkgcube()) | ||
| 172 | + self._check_models(cpy_bkgcube.models()) | ||
| 173 | + | ||
| 174 | + # Execute copy of ctbkgcube tool again, now with a higher chatter | ||
| 175 | + # level than before. In addition, use counts cube to define the | ||
| 176 | + # background cube | ||
| 177 | + #cpy_bkgcube['inobs'] = self._events | ||
| 178 | + #cpy_bkgcube['inmodel'] = self._model | ||
| 179 | + cpy_bkgcube['incube'] = self._cntcube | ||
| 180 | + #cpy_bkgcube['caldb'] = self._caldb | ||
| 181 | + #cpy_bkgcube['irf'] = self._irf | ||
| 182 | + cpy_bkgcube['outcube'] = 'ctbkgcube_py2.fits' | ||
| 183 | + cpy_bkgcube['outmodel'] = 'ctbkgcube_py2.xml' | ||
| 184 | + cpy_bkgcube['logfile'] = 'ctbkgcube_py2.log' | ||
| 185 | + cpy_bkgcube['chatter'] = 3 | ||
| 186 | + cpy_bkgcube['publish'] = True | ||
| 187 | + cpy_bkgcube['addbounds'] = True | ||
| 188 | + cpy_bkgcube.logFileOpen() # Make sure we get a log file | ||
| 172 | cpy_bkgcube.execute() | 189 | cpy_bkgcube.execute() |
| 173 | 190 | ||
| 174 | - # Check result file | ||
| 175 | - self._check_result_file('ctbkgcube_py3.fits') | 191 | + # Check result files |
| 192 | + self._check_result_files('ctbkgcube_py2') | ||
| 176 | 193 | ||
| 177 | - # Clear ctbkgcube tool | ||
| 178 | - bkgcube.clear() | 194 | + # Now clear copy of ctbkgcube tool |
| 195 | + cpy_bkgcube.clear() | ||
| 179 | 196 | ||
| 180 | - # TODO: Do some test after clearing of ctbkgcube tool | 197 | + # Check that the cleared copy has also cleared the background cube |
| 198 | + # and model container | ||
| 199 | + self._check_cube(cpy_bkgcube.bkgcube(), nenergies=0) | ||
| 200 | + self._check_models(cpy_bkgcube.models(), nmodels=0) | ||
| 181 | 201 | ||
| 182 | # Prepare observation container | 202 | # Prepare observation container |
| 183 | obs1 = gammalib.GCTAObservation(self._events) | 203 | obs1 = gammalib.GCTAObservation(self._events) |
| @@ -195,47 +215,94 @@ class Test(test): | @@ -195,47 +215,94 @@ class Test(test): | ||
| 195 | 215 | ||
| 196 | # Set-up ctbkgcube from observation container | 216 | # Set-up ctbkgcube from observation container |
| 197 | bkgcube = ctools.ctbkgcube(obs) | 217 | bkgcube = ctools.ctbkgcube(obs) |
| 198 | - #bkgcube['inobs'] = self._events | ||
| 199 | - #bkgcube['inmodel'] = self._model | ||
| 200 | - bkgcube['incube'] = 'NONE' | ||
| 201 | - bkgcube['caldb'] = self._caldb | ||
| 202 | - bkgcube['irf'] = self._irf | ||
| 203 | - bkgcube['ebinalg'] = 'LOG' | ||
| 204 | - bkgcube['emin'] = 0.1 | ||
| 205 | - bkgcube['emax'] = 100 | ||
| 206 | - bkgcube['enumbins'] = 20 | ||
| 207 | - bkgcube['nxpix'] = 10 | ||
| 208 | - bkgcube['nypix'] = 10 | ||
| 209 | - bkgcube['binsz'] = 0.4 | ||
| 210 | - bkgcube['coordsys'] = 'CEL' | ||
| 211 | - bkgcube['proj'] = 'CAR' | ||
| 212 | - bkgcube['xref'] = 83.63 | ||
| 213 | - bkgcube['yref'] = 22.01 | ||
| 214 | - bkgcube['outcube'] = 'ctbkgcube_py4.fits' | ||
| 215 | - bkgcube['outmodel'] = 'ctbkgcube_py4.xml' | ||
| 216 | - bkgcube['logfile'] = 'ctbkgcube_py4.log' | ||
| 217 | - bkgcube['chatter'] = 4 | 218 | + bkgcube['incube'] = 'NONE' |
| 219 | + bkgcube['caldb'] = self._caldb | ||
| 220 | + bkgcube['irf'] = self._irf | ||
| 221 | + bkgcube['ebinalg'] = 'LOG' | ||
| 222 | + bkgcube['emin'] = 0.2 | ||
| 223 | + bkgcube['emax'] = 150.0 | ||
| 224 | + bkgcube['enumbins'] = 20 | ||
| 225 | + bkgcube['nxpix'] = 10 | ||
| 226 | + bkgcube['nypix'] = 10 | ||
| 227 | + bkgcube['binsz'] = 0.4 | ||
| 228 | + bkgcube['coordsys'] = 'CEL' | ||
| 229 | + bkgcube['proj'] = 'CAR' | ||
| 230 | + bkgcube['xref'] = 83.63 | ||
| 231 | + bkgcube['yref'] = 22.01 | ||
| 232 | + bkgcube['outcube'] = 'ctbkgcube_py3.fits' | ||
| 233 | + bkgcube['outmodel'] = 'ctbkgcube_py3.xml' | ||
| 234 | + bkgcube['logfile'] = 'ctbkgcube_py3.log' | ||
| 235 | + bkgcube['addbounds'] = True | ||
| 236 | + bkgcube['chatter'] = 4 | ||
| 218 | 237 | ||
| 219 | # Execute ctbkgcube tool | 238 | # Execute ctbkgcube tool |
| 220 | bkgcube.logFileOpen() # Make sure we get a log file | 239 | bkgcube.logFileOpen() # Make sure we get a log file |
| 221 | bkgcube.execute() | 240 | bkgcube.execute() |
| 222 | 241 | ||
| 223 | - # Check result file | ||
| 224 | - self._check_result_file('ctbkgcube_py4.fits') | 242 | + # Check result files |
| 243 | + self._check_result_files('ctbkgcube_py3', nenergies=23) | ||
| 225 | 244 | ||
| 226 | # Return | 245 | # Return |
| 227 | return | 246 | return |
| 228 | 247 | ||
| 229 | - # Check result file | ||
| 230 | - def _check_result_file(self, filename): | 248 | + # Check result files |
| 249 | + def _check_result_files(self, filename, nenergies=21, nmodels=2): | ||
| 231 | """ | 250 | """ |
| 232 | Check result file | 251 | Check result file |
| 252 | + | ||
| 253 | + Parameters | ||
| 254 | + ---------- | ||
| 255 | + filename : str | ||
| 256 | + Test file name without extension | ||
| 257 | + nenergies : int, optional | ||
| 258 | + Number of energy bins | ||
| 233 | """ | 259 | """ |
| 234 | - # Open result file | ||
| 235 | - result = gammalib.GCTACubeBackground(filename) | 260 | + # Open background cube |
| 261 | + cube = gammalib.GCTACubeBackground(filename+'.fits') | ||
| 262 | + | ||
| 263 | + # Open model definition file | ||
| 264 | + models = gammalib.GModels(filename+'.xml') | ||
| 236 | 265 | ||
| 266 | + # Check cube | ||
| 267 | + self._check_cube(cube, nenergies=nenergies) | ||
| 268 | + | ||
| 269 | + # Check models | ||
| 270 | + self._check_models(models, nmodels=nmodels) | ||
| 271 | + | ||
| 272 | + # Return | ||
| 273 | + return | ||
| 274 | + | ||
| 275 | + # Check background cube | ||
| 276 | + def _check_cube(self, cube, nenergies=21): | ||
| 277 | + """ | ||
| 278 | + Check background cube | ||
| 279 | + | ||
| 280 | + Parameters | ||
| 281 | + ---------- | ||
| 282 | + cube : `~gammalib.GCTACubeBackground` | ||
| 283 | + Background cube | ||
| 284 | + nenergies : int, optional | ||
| 285 | + Number of energy bins | ||
| 286 | + """ | ||
| 237 | # Check dimensions | 287 | # Check dimensions |
| 238 | - self.test_value(len(result.energies()), 21, 'Check for 21 energy values') | 288 | + self.test_value(len(cube.energies()), nenergies, |
| 289 | + 'Check number of energy maps') | ||
| 239 | 290 | ||
| 240 | # Return | 291 | # Return |
| 241 | return | 292 | return |
| 293 | + | ||
| 294 | + # Check model container | ||
| 295 | + def _check_models(self, models, nmodels=2): | ||
| 296 | + """ | ||
| 297 | + Check model container | ||
| 298 | + | ||
| 299 | + Parameters | ||
| 300 | + ---------- | ||
| 301 | + models : `~gammalib.GModels` | ||
| 302 | + Model container | ||
| 303 | + """ | ||
| 304 | + # Check number of models | ||
| 305 | + self.test_value(models.size(), nmodels, 'Check number of models') | ||
| 306 | + | ||
| 307 | + # Return | ||
| 308 | + return |
test/test_ctedispcube.py
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | # | 19 | # |
| 20 | # ========================================================================== | 20 | # ========================================================================== |
| 21 | +import os | ||
| 21 | import gammalib | 22 | import gammalib |
| 22 | import ctools | 23 | import ctools |
| 23 | from testing import test | 24 | from testing import test |
| @@ -109,16 +110,32 @@ class Test(test): | @@ -109,16 +110,32 @@ class Test(test): | ||
| 109 | """ | 110 | """ |
| 110 | Test ctedispcube from Python | 111 | Test ctedispcube from Python |
| 111 | """ | 112 | """ |
| 112 | - # Set-up ctedispcube | 113 | + # Allocate ctedispcube |
| 113 | edispcube = ctools.ctedispcube() | 114 | edispcube = ctools.ctedispcube() |
| 115 | + | ||
| 116 | + # Check that empty ctedispcube tool holds an energy dispersion | ||
| 117 | + # cube that has no energy and migration bins | ||
| 118 | + self._check_cube(edispcube.edispcube(), nenergies=0, nmigras=0) | ||
| 119 | + | ||
| 120 | + # Check that saving does not nothing | ||
| 121 | + edispcube['outcube'] = 'ctedispcube_py0.fits' | ||
| 122 | + edispcube['logfile'] = 'ctedispcube_py0.log' | ||
| 123 | + edispcube.logFileOpen() | ||
| 124 | + edispcube.save() | ||
| 125 | + self.test_assert(not os.path.isfile('ctedispcube_py0.fits'), | ||
| 126 | + 'Check that no energy dispersion cube has been created') | ||
| 127 | + | ||
| 128 | + # Check that clearing does not lead to an exception or segfault | ||
| 129 | + edispcube.clear() | ||
| 130 | + | ||
| 131 | + # Now set ctedispcube parameters | ||
| 114 | edispcube['inobs'] = self._events | 132 | edispcube['inobs'] = self._events |
| 115 | edispcube['incube'] = 'NONE' | 133 | edispcube['incube'] = 'NONE' |
| 116 | - edispcube['outcube'] = 'ctedispcube_py1.fits' | ||
| 117 | edispcube['caldb'] = self._caldb | 134 | edispcube['caldb'] = self._caldb |
| 118 | edispcube['irf'] = self._irf | 135 | edispcube['irf'] = self._irf |
| 119 | edispcube['ebinalg'] = 'LOG' | 136 | edispcube['ebinalg'] = 'LOG' |
| 120 | edispcube['emin'] = 0.1 | 137 | edispcube['emin'] = 0.1 |
| 121 | - edispcube['emax'] = 100 | 138 | + edispcube['emax'] = 100.0 |
| 122 | edispcube['enumbins'] = 20 | 139 | edispcube['enumbins'] = 20 |
| 123 | edispcube['nxpix'] = 10 | 140 | edispcube['nxpix'] = 10 |
| 124 | edispcube['nypix'] = 10 | 141 | edispcube['nypix'] = 10 |
| @@ -129,31 +146,88 @@ class Test(test): | @@ -129,31 +146,88 @@ class Test(test): | ||
| 129 | edispcube['yref'] = 22.01 | 146 | edispcube['yref'] = 22.01 |
| 130 | edispcube['migramax'] = 2.0 | 147 | edispcube['migramax'] = 2.0 |
| 131 | edispcube['migrabins'] = 10 | 148 | edispcube['migrabins'] = 10 |
| 149 | + edispcube['outcube'] = 'ctedispcube_py1.fits' | ||
| 132 | edispcube['logfile'] = 'ctedispcube_py1.log' | 150 | edispcube['logfile'] = 'ctedispcube_py1.log' |
| 133 | edispcube['chatter'] = 2 | 151 | edispcube['chatter'] = 2 |
| 134 | 152 | ||
| 135 | # Run ctedispcube tool | 153 | # Run ctedispcube tool |
| 136 | - edispcube.logFileOpen() # Make sure we get a log file | 154 | + edispcube.logFileOpen() # Make sure we get a log file |
| 137 | edispcube.run() | 155 | edispcube.run() |
| 138 | edispcube.save() | 156 | edispcube.save() |
| 139 | 157 | ||
| 140 | # Check result file | 158 | # Check result file |
| 141 | self._check_result_file('ctedispcube_py1.fits') | 159 | self._check_result_file('ctedispcube_py1.fits') |
| 142 | 160 | ||
| 161 | + # Copy ctedispcube tool | ||
| 162 | + cpy_edispcube = edispcube.copy() | ||
| 163 | + | ||
| 164 | + # Check energy dispersion cube of ctedispcube copy | ||
| 165 | + self._check_cube(cpy_edispcube.edispcube()) | ||
| 166 | + | ||
| 167 | + # Execute copy of ctedispcube tool again, now with a higher chatter | ||
| 168 | + # level than before | ||
| 169 | + cpy_edispcube['emin'] = 0.2 | ||
| 170 | + cpy_edispcube['emax'] = 150.0 | ||
| 171 | + cpy_edispcube['outcube'] = 'ctedispcube_py2.fits' | ||
| 172 | + cpy_edispcube['logfile'] = 'ctedispcube_py2.log' | ||
| 173 | + cpy_edispcube['addbounds'] = True | ||
| 174 | + cpy_edispcube['chatter'] = 3 | ||
| 175 | + cpy_edispcube.logFileOpen() # Needed to get a new log file | ||
| 176 | + cpy_edispcube.execute() | ||
| 177 | + | ||
| 178 | + # Check result file | ||
| 179 | + self._check_result_file('ctedispcube_py2.fits', nenergies=23) | ||
| 180 | + | ||
| 181 | + # Now clear copy of ctedispcube tool | ||
| 182 | + cpy_edispcube.clear() | ||
| 183 | + | ||
| 184 | + # Check that the cleared copy has also cleared the energy dispersion | ||
| 185 | + # cube | ||
| 186 | + self._check_cube(cpy_edispcube.edispcube(), nenergies=0, nmigras=0) | ||
| 187 | + | ||
| 143 | # Return | 188 | # Return |
| 144 | return | 189 | return |
| 145 | 190 | ||
| 146 | # Check result file | 191 | # Check result file |
| 147 | - def _check_result_file(self, filename): | 192 | + def _check_result_file(self, filename, nenergies=21): |
| 148 | """ | 193 | """ |
| 149 | Check result file | 194 | Check result file |
| 195 | + | ||
| 196 | + Parameters | ||
| 197 | + ---------- | ||
| 198 | + filename : str | ||
| 199 | + Energy dispersion cube file name | ||
| 200 | + nenergies : int, optional | ||
| 201 | + Number of energy bins | ||
| 150 | """ | 202 | """ |
| 151 | - # Open result file | ||
| 152 | - result = gammalib.GCTACubeEdisp(filename) | 203 | + # Open energy dispersion cube |
| 204 | + cube = gammalib.GCTACubeEdisp(filename) | ||
| 205 | + | ||
| 206 | + # Check cube | ||
| 207 | + self._check_cube(cube, nenergies=nenergies) | ||
| 153 | 208 | ||
| 209 | + # Return | ||
| 210 | + return | ||
| 211 | + | ||
| 212 | + # Check energy dispersion cube | ||
| 213 | + def _check_cube(self, cube, nenergies=21, nmigras=10): | ||
| 214 | + """ | ||
| 215 | + Check energy dispersion cube | ||
| 216 | + | ||
| 217 | + Parameters | ||
| 218 | + ---------- | ||
| 219 | + cube : `~gammalib.GCTACubeEdisp` | ||
| 220 | + Energy dispersion cube | ||
| 221 | + nenergies : int, optional | ||
| 222 | + Number of energy bins | ||
| 223 | + nmigras : int, optional | ||
| 224 | + Number of migration bins | ||
| 225 | + """ | ||
| 154 | # Check dimensions | 226 | # Check dimensions |
| 155 | - self.test_value(len(result.energies()), 21, 'Check for 21 energy maps') | ||
| 156 | - self.test_value(len(result.migras()), 10, 'Check for 10 migration bins') | 227 | + self.test_value(len(cube.energies()), nenergies, |
| 228 | + 'Check number of energy maps') | ||
| 229 | + self.test_value(len(cube.migras()), nmigras, | ||
| 230 | + 'Check number of migration bins') | ||
| 157 | 231 | ||
| 158 | # Return | 232 | # Return |
| 159 | return | 233 | return |
test/test_ctexpcube.py
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | # | 19 | # |
| 20 | # ========================================================================== | 20 | # ========================================================================== |
| 21 | +import os | ||
| 21 | import gammalib | 22 | import gammalib |
| 22 | import ctools | 23 | import ctools |
| 23 | from testing import test | 24 | from testing import test |
| @@ -107,16 +108,32 @@ class Test(test): | @@ -107,16 +108,32 @@ class Test(test): | ||
| 107 | """ | 108 | """ |
| 108 | Test ctexpcube from Python | 109 | Test ctexpcube from Python |
| 109 | """ | 110 | """ |
| 110 | - # Set-up ctexpcube | 111 | + # Allocate ctexpcube |
| 111 | expcube = ctools.ctexpcube() | 112 | expcube = ctools.ctexpcube() |
| 113 | + | ||
| 114 | + # Check that empty ctexpcube tool holds an exposure cube that has | ||
| 115 | + # no energy bins | ||
| 116 | + self._check_cube(expcube.expcube(), nenergies=0) | ||
| 117 | + | ||
| 118 | + # Check that saving does not nothing | ||
| 119 | + expcube['outcube'] = 'ctexpcube_py0.fits' | ||
| 120 | + expcube['logfile'] = 'ctexpcube_py0.log' | ||
| 121 | + expcube.logFileOpen() | ||
| 122 | + expcube.save() | ||
| 123 | + self.test_assert(not os.path.isfile('ctexpcube_py0.fits'), | ||
| 124 | + 'Check that no exposure cube has been created') | ||
| 125 | + | ||
| 126 | + # Check that clearing does not lead to an exception or segfault | ||
| 127 | + expcube.clear() | ||
| 128 | + | ||
| 129 | + # Now set ctexpcube parameters | ||
| 112 | expcube['inobs'] = self._events | 130 | expcube['inobs'] = self._events |
| 113 | expcube['incube'] = 'NONE' | 131 | expcube['incube'] = 'NONE' |
| 114 | - expcube['outcube'] = 'ctexpcube_py1.fits' | ||
| 115 | expcube['caldb'] = self._caldb | 132 | expcube['caldb'] = self._caldb |
| 116 | expcube['irf'] = self._irf | 133 | expcube['irf'] = self._irf |
| 117 | expcube['ebinalg'] = 'LOG' | 134 | expcube['ebinalg'] = 'LOG' |
| 118 | expcube['emin'] = 0.1 | 135 | expcube['emin'] = 0.1 |
| 119 | - expcube['emax'] = 100 | 136 | + expcube['emax'] = 100.0 |
| 120 | expcube['enumbins'] = 20 | 137 | expcube['enumbins'] = 20 |
| 121 | expcube['nxpix'] = 200 | 138 | expcube['nxpix'] = 200 |
| 122 | expcube['nypix'] = 200 | 139 | expcube['nypix'] = 200 |
| @@ -126,6 +143,7 @@ class Test(test): | @@ -126,6 +143,7 @@ class Test(test): | ||
| 126 | expcube['xref'] = 83.63 | 143 | expcube['xref'] = 83.63 |
| 127 | expcube['yref'] = 22.01 | 144 | expcube['yref'] = 22.01 |
| 128 | expcube['logfile'] = 'ctexpcube_py1.log' | 145 | expcube['logfile'] = 'ctexpcube_py1.log' |
| 146 | + expcube['outcube'] = 'ctexpcube_py1.fits' | ||
| 129 | expcube['chatter'] = 2 | 147 | expcube['chatter'] = 2 |
| 130 | 148 | ||
| 131 | # Run ctexpcube tool | 149 | # Run ctexpcube tool |
| @@ -136,19 +154,72 @@ class Test(test): | @@ -136,19 +154,72 @@ class Test(test): | ||
| 136 | # Check result file | 154 | # Check result file |
| 137 | self._check_result_file('ctexpcube_py1.fits') | 155 | self._check_result_file('ctexpcube_py1.fits') |
| 138 | 156 | ||
| 157 | + # Copy ctexpcube tool | ||
| 158 | + cpy_expcube = expcube.copy() | ||
| 159 | + | ||
| 160 | + # Check exposure cube of ctexpcube copy | ||
| 161 | + self._check_cube(cpy_expcube.expcube()) | ||
| 162 | + | ||
| 163 | + # Execute copy of ctexpcube tool again, now with a higher chatter | ||
| 164 | + # level than before | ||
| 165 | + cpy_expcube['emin'] = 0.2 | ||
| 166 | + cpy_expcube['emax'] = 150.0 | ||
| 167 | + cpy_expcube['outcube'] = 'ctexpcube_py2.fits' | ||
| 168 | + cpy_expcube['logfile'] = 'ctexpcube_py2.log' | ||
| 169 | + cpy_expcube['publish'] = True | ||
| 170 | + cpy_expcube['addbounds'] = True | ||
| 171 | + cpy_expcube['chatter'] = 3 | ||
| 172 | + cpy_expcube.logFileOpen() # Needed to get a new log file | ||
| 173 | + cpy_expcube.execute() | ||
| 174 | + | ||
| 175 | + # Check result file | ||
| 176 | + self._check_result_file('ctexpcube_py2.fits', nenergies=23) | ||
| 177 | + | ||
| 178 | + # Now clear copy of ctexpcube tool | ||
| 179 | + cpy_expcube.clear() | ||
| 180 | + | ||
| 181 | + # Check that the cleared copy has also cleared the exposure cube | ||
| 182 | + self._check_cube(cpy_expcube.expcube(), nenergies=0) | ||
| 183 | + | ||
| 139 | # Return | 184 | # Return |
| 140 | return | 185 | return |
| 141 | 186 | ||
| 142 | # Check result file | 187 | # Check result file |
| 143 | - def _check_result_file(self, filename): | 188 | + def _check_result_file(self, filename, nenergies=21): |
| 144 | """ | 189 | """ |
| 145 | Check result file | 190 | Check result file |
| 191 | + | ||
| 192 | + Parameters | ||
| 193 | + ---------- | ||
| 194 | + filename : str | ||
| 195 | + Exposure cube file name | ||
| 196 | + nenergies : int, optional | ||
| 197 | + Number of energy bins | ||
| 146 | """ | 198 | """ |
| 147 | - # Open result file | ||
| 148 | - result = gammalib.GCTACubeExposure(filename) | 199 | + # Open exposure cube |
| 200 | + cube = gammalib.GCTACubeExposure(filename) | ||
| 201 | + | ||
| 202 | + # Check cube | ||
| 203 | + self._check_cube(cube, nenergies=nenergies) | ||
| 149 | 204 | ||
| 205 | + # Return | ||
| 206 | + return | ||
| 207 | + | ||
| 208 | + # Check exposure cube | ||
| 209 | + def _check_cube(self, cube, nenergies=21): | ||
| 210 | + """ | ||
| 211 | + Check exposure cube | ||
| 212 | + | ||
| 213 | + Parameters | ||
| 214 | + ---------- | ||
| 215 | + cube : `~gammalib.GCTACubeExposure` | ||
| 216 | + Exposure cube | ||
| 217 | + nenergies : int, optional | ||
| 218 | + Number of energy bins | ||
| 219 | + """ | ||
| 150 | # Check dimensions | 220 | # Check dimensions |
| 151 | - self.test_value(len(result.energies()), 21, 'Check for 21 energy values') | 221 | + self.test_value(len(cube.energies()), nenergies, |
| 222 | + 'Check number of energy maps') | ||
| 152 | 223 | ||
| 153 | # Return | 224 | # Return |
| 154 | return | 225 | return |
test/test_ctpsfcube.py
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | # | 19 | # |
| 20 | # ========================================================================== | 20 | # ========================================================================== |
| 21 | +import os | ||
| 21 | import gammalib | 22 | import gammalib |
| 22 | import ctools | 23 | import ctools |
| 23 | from testing import test | 24 | from testing import test |
| @@ -109,8 +110,25 @@ class Test(test): | @@ -109,8 +110,25 @@ class Test(test): | ||
| 109 | """ | 110 | """ |
| 110 | Test ctpsfcube from Python | 111 | Test ctpsfcube from Python |
| 111 | """ | 112 | """ |
| 112 | - # Set-up ctpsfcube | 113 | + # Allocate ctpsfcube |
| 113 | psfcube = ctools.ctpsfcube() | 114 | psfcube = ctools.ctpsfcube() |
| 115 | + | ||
| 116 | + # Check that empty ctpsfcube tool holds a PSF cube that has no energy | ||
| 117 | + # bins | ||
| 118 | + self._check_cube(psfcube.psfcube(), nenergies=0) | ||
| 119 | + | ||
| 120 | + # Check that saving does not nothing | ||
| 121 | + psfcube['outcube'] = 'ctpsfcube_py0.fits' | ||
| 122 | + psfcube['logfile'] = 'ctpsfcube_py0.log' | ||
| 123 | + psfcube.logFileOpen() | ||
| 124 | + psfcube.save() | ||
| 125 | + self.test_assert(not os.path.isfile('ctpsfcube_py0.fits'), | ||
| 126 | + 'Check that no PSF cube has been created') | ||
| 127 | + | ||
| 128 | + # Check that clearing does not lead to an exception or segfault | ||
| 129 | + psfcube.clear() | ||
| 130 | + | ||
| 131 | + # Now set ctpsfcube parameters | ||
| 114 | psfcube['inobs'] = self._events | 132 | psfcube['inobs'] = self._events |
| 115 | psfcube['incube'] = 'NONE' | 133 | psfcube['incube'] = 'NONE' |
| 116 | psfcube['outcube'] = 'ctpsfcube_py1.fits' | 134 | psfcube['outcube'] = 'ctpsfcube_py1.fits' |
| @@ -140,19 +158,71 @@ class Test(test): | @@ -140,19 +158,71 @@ class Test(test): | ||
| 140 | # Check result file | 158 | # Check result file |
| 141 | self._check_result_file('ctpsfcube_py1.fits') | 159 | self._check_result_file('ctpsfcube_py1.fits') |
| 142 | 160 | ||
| 161 | + # Copy ctpsfcube tool | ||
| 162 | + cpy_psfcube = psfcube.copy() | ||
| 163 | + | ||
| 164 | + # Check PSF cube of ctpsfcube copy | ||
| 165 | + self._check_cube(cpy_psfcube.psfcube()) | ||
| 166 | + | ||
| 167 | + # Execute copy of ctpsfcube tool again, now with a higher chatter | ||
| 168 | + # level than before | ||
| 169 | + cpy_psfcube['emin'] = 0.2 | ||
| 170 | + cpy_psfcube['emax'] = 150.0 | ||
| 171 | + cpy_psfcube['outcube'] = 'ctpsfcube_py2.fits' | ||
| 172 | + cpy_psfcube['logfile'] = 'ctpsfcube_py2.log' | ||
| 173 | + cpy_psfcube['addbounds'] = True | ||
| 174 | + cpy_psfcube['chatter'] = 3 | ||
| 175 | + cpy_psfcube.logFileOpen() # Needed to get a new log file | ||
| 176 | + cpy_psfcube.execute() | ||
| 177 | + | ||
| 178 | + # Check result file | ||
| 179 | + self._check_result_file('ctpsfcube_py2.fits', nenergies=23) | ||
| 180 | + | ||
| 181 | + # Now clear copy of ctpsfcube tool | ||
| 182 | + cpy_psfcube.clear() | ||
| 183 | + | ||
| 184 | + # Check that the cleared copy has also cleared the PSF cube | ||
| 185 | + self._check_cube(cpy_psfcube.psfcube(), nenergies=0) | ||
| 186 | + | ||
| 143 | # Return | 187 | # Return |
| 144 | return | 188 | return |
| 145 | 189 | ||
| 146 | # Check result file | 190 | # Check result file |
| 147 | - def _check_result_file(self, filename): | 191 | + def _check_result_file(self, filename, nenergies=21): |
| 148 | """ | 192 | """ |
| 149 | Check result file | 193 | Check result file |
| 194 | + | ||
| 195 | + Parameters | ||
| 196 | + ---------- | ||
| 197 | + filename : str | ||
| 198 | + PSF cube file name | ||
| 199 | + nenergies : int, optional | ||
| 200 | + Number of energy bins | ||
| 150 | """ | 201 | """ |
| 151 | - # Open result file | ||
| 152 | - result = gammalib.GCTACubePsf(filename) | 202 | + # Open PSF cube |
| 203 | + cube = gammalib.GCTACubePsf(filename) | ||
| 153 | 204 | ||
| 205 | + # Check cube | ||
| 206 | + self._check_cube(cube, nenergies=nenergies) | ||
| 207 | + | ||
| 208 | + # Return | ||
| 209 | + return | ||
| 210 | + | ||
| 211 | + # Check PSF cube | ||
| 212 | + def _check_cube(self, cube, nenergies=21): | ||
| 213 | + """ | ||
| 214 | + Check PSF cube | ||
| 215 | + | ||
| 216 | + Parameters | ||
| 217 | + ---------- | ||
| 218 | + cube : `~gammalib.GCTACubePsf` | ||
| 219 | + PSF cube | ||
| 220 | + nenergies : int, optional | ||
| 221 | + Number of energy bins | ||
| 222 | + """ | ||
| 154 | # Check dimensions | 223 | # Check dimensions |
| 155 | - self.test_value(len(result.energies()), 21, 'Check for 21 energy values') | 224 | + self.test_value(len(cube.energies()), nenergies, |
| 225 | + 'Check number of energy maps') | ||
| 156 | 226 | ||
| 157 | # Return | 227 | # Return |
| 158 | return | 228 | return |