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 | 3 | Jean-Baptiste Cayrou (cayrou@etud.insa-toulouse.fr) |
| 4 | 4 | Christoph Deil (Christoph.Deil@mpi-hd.mpg.de) |
| 5 | 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 | 9 | Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu) |
| 7 | 10 | Chia-Chun Lu (Chia-Chun.Lu@mpi-hd.mpg.de) |
| 11 | +Pierrick Martin (pierrick.martin@irap.omp.eu) | |
| 8 | 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 | 84 | virtual void execute(void); |
| 85 | 85 | |
| 86 | 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 | 108 | // Protected methods |
| 112 | 109 | const bool& read_ahead(void) const; |
| ... | ... | @@ -140,6 +137,10 @@ public: |
| 140 | 137 | GSkyDir get_mean_pointing(const GObservations& obs); |
| 141 | 138 | size_t get_current_rss(void); |
| 142 | 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 | 345 | user_name = CTBIN_NAME; |
| 346 | 346 | } |
| 347 | 347 | |
| 348 | - // Log counts cube name | |
| 348 | + // Write counts cube name into logger | |
| 349 | 349 | log_value(NORMAL, "Counts cube name", user_name); |
| 350 | 350 | |
| 351 | 351 | // Publish counts cube | ... | ... |
src/ctbkgcube/ctbkgcube.cpp
| ... | ... | @@ -218,23 +218,7 @@ void ctbkgcube::run(void) |
| 218 | 218 | get_parameters(); |
| 219 | 219 | |
| 220 | 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 | 223 | // Write input observation container into logger |
| 240 | 224 | log_observations(NORMAL, m_obs, "Input observation"); |
| ... | ... | @@ -242,6 +226,9 @@ void ctbkgcube::run(void) |
| 242 | 226 | // Write input model container into logger |
| 243 | 227 | log_models(NORMAL, m_obs.models(), "Input model"); |
| 244 | 228 | |
| 229 | + // Initialise exposure cube | |
| 230 | + init_cube(); | |
| 231 | + | |
| 245 | 232 | // Write header |
| 246 | 233 | log_header1(TERSE, "Prepare model"); |
| 247 | 234 | |
| ... | ... | @@ -296,11 +283,11 @@ void ctbkgcube::run(void) |
| 296 | 283 | // Assign background models to container |
| 297 | 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 | 289 | // Fill background cube from observations |
| 303 | - m_background.fill(m_obs, logp); | |
| 290 | + m_background.fill(m_obs, logger); | |
| 304 | 291 | |
| 305 | 292 | // Create a background model for the output background cube and append |
| 306 | 293 | // that model to the input model in place of the original |
| ... | ... | @@ -356,28 +343,33 @@ void ctbkgcube::save(void) |
| 356 | 343 | m_outcube = (*this)["outcube"].filename(); |
| 357 | 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 | 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 | 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 | 374 | // Return |
| 383 | 375 | return; |
| ... | ... | @@ -394,7 +386,7 @@ void ctbkgcube::publish(const std::string& name) |
| 394 | 386 | // Write header |
| 395 | 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 | 390 | std::string user_name(name); |
| 399 | 391 | if (user_name.empty()) { |
| 400 | 392 | user_name = CTBKGCUBE_NAME; |
| ... | ... | @@ -588,9 +580,6 @@ void ctbkgcube::init_cube(void) |
| 588 | 580 | // If requested, insert energies at all event list energy boundaries |
| 589 | 581 | if (m_addbounds) { |
| 590 | 582 | |
| 591 | - // Set pointer on logger depending on chattiness | |
| 592 | - GLog* logp = (logNormal()) ? &log : NULL; | |
| 593 | - | |
| 594 | 583 | // Loop over all observations |
| 595 | 584 | for (int i = 0; i < m_obs.size(); ++i) { |
| 596 | 585 | |
| ... | ... | @@ -609,7 +598,7 @@ void ctbkgcube::init_cube(void) |
| 609 | 598 | } |
| 610 | 599 | |
| 611 | 600 | // Insert energy boundaries |
| 612 | - energies = insert_energy_boundaries(energies, *cta, logp); | |
| 601 | + energies = insert_energy_boundaries(energies, *cta); | |
| 613 | 602 | |
| 614 | 603 | } // endfor: looped over all observations |
| 615 | 604 | |
| ... | ... | @@ -623,4 +612,4 @@ void ctbkgcube::init_cube(void) |
| 623 | 612 | |
| 624 | 613 | // Return |
| 625 | 614 | return; |
| 626 | -}; | |
| 615 | +} | ... | ... |
src/ctedispcube/ctedispcube.cpp
| ... | ... | @@ -227,35 +227,23 @@ void ctedispcube::run(void) |
| 227 | 227 | // Get task parameters |
| 228 | 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 | 233 | // Initialise energy dispersion cube |
| 237 | 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 | 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 | 248 | // Return |
| 261 | 249 | return; |
| ... | ... | @@ -270,28 +258,29 @@ void ctedispcube::run(void) |
| 270 | 258 | ***************************************************************************/ |
| 271 | 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 | 264 | // Get output filename |
| 280 | 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 | 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 | 285 | // Return |
| 297 | 286 | return; |
| ... | ... | @@ -430,6 +419,9 @@ void ctedispcube::get_parameters(void) |
| 430 | 419 | ***************************************************************************/ |
| 431 | 420 | void ctedispcube::init_cube(void) |
| 432 | 421 | { |
| 422 | + // Write header into logger | |
| 423 | + log_header1(TERSE, "Initialise energy dispersion cube"); | |
| 424 | + | |
| 433 | 425 | // Extract energy dispersion definition |
| 434 | 426 | const GWcs* proj = static_cast<const GWcs*>(m_edispcube.cube().projection()); |
| 435 | 427 | std::string wcs = m_edispcube.cube().projection()->code(); |
| ... | ... | @@ -449,12 +441,6 @@ void ctedispcube::init_cube(void) |
| 449 | 441 | // If requested, insert energies at all event list energy boundaries |
| 450 | 442 | if (m_addbounds) { |
| 451 | 443 | |
| 452 | - // Set logger | |
| 453 | - GLog* logger = NULL; | |
| 454 | - if (logTerse()) { | |
| 455 | - logger = &log; | |
| 456 | - } | |
| 457 | - | |
| 458 | 444 | // Loop over all observations |
| 459 | 445 | for (int i = 0; i < m_obs.size(); ++i) { |
| 460 | 446 | |
| ... | ... | @@ -473,7 +459,7 @@ void ctedispcube::init_cube(void) |
| 473 | 459 | } |
| 474 | 460 | |
| 475 | 461 | // Insert energy boundaries |
| 476 | - energies = insert_energy_boundaries(energies, *cta, logger); | |
| 462 | + energies = insert_energy_boundaries(energies, *cta); | |
| 477 | 463 | |
| 478 | 464 | } // endfor: looped over all observations |
| 479 | 465 | |
| ... | ... | @@ -483,11 +469,9 @@ void ctedispcube::init_cube(void) |
| 483 | 469 | m_edispcube = GCTACubeEdisp(wcs, coords, x, y, dx, dy, nx, ny, energies, |
| 484 | 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 | 475 | // Return |
| 492 | 476 | return; |
| 493 | -}; | |
| 477 | +} | ... | ... |
src/ctexpcube/ctexpcube.cpp
| ... | ... | @@ -218,53 +218,25 @@ void ctexpcube::run(void) |
| 218 | 218 | get_parameters(); |
| 219 | 219 | |
| 220 | 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 | 226 | // Initialise exposure cube |
| 246 | 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 | 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 | 241 | // Optionally publish exposure cube |
| 270 | 242 | if (m_publish) { |
| ... | ... | @@ -283,28 +255,28 @@ void ctexpcube::run(void) |
| 283 | 255 | ***************************************************************************/ |
| 284 | 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 | 261 | // Get exposure cube filename |
| 293 | 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 | 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 | 281 | // Return |
| 310 | 282 | return; |
| ... | ... | @@ -318,23 +290,17 @@ void ctexpcube::save(void) |
| 318 | 290 | ***************************************************************************/ |
| 319 | 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 | 297 | std::string user_name(name); |
| 329 | 298 | if (user_name.empty()) { |
| 330 | 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 | 305 | // Publish exposure cube |
| 340 | 306 | m_expcube.cube().publish(user_name); |
| ... | ... | @@ -475,6 +441,9 @@ void ctexpcube::get_parameters(void) |
| 475 | 441 | ***************************************************************************/ |
| 476 | 442 | void ctexpcube::init_cube(void) |
| 477 | 443 | { |
| 444 | + // Write header into logger | |
| 445 | + log_header1(TERSE, "Initialise exposure cube"); | |
| 446 | + | |
| 478 | 447 | // Extract exposure cube definition |
| 479 | 448 | const GWcs* proj = static_cast<const GWcs*>(m_expcube.cube().projection()); |
| 480 | 449 | std::string wcs = m_expcube.cube().projection()->code(); |
| ... | ... | @@ -492,12 +461,6 @@ void ctexpcube::init_cube(void) |
| 492 | 461 | // If requested, insert energies at all event list energy boundaries |
| 493 | 462 | if (m_addbounds) { |
| 494 | 463 | |
| 495 | - // Set logger | |
| 496 | - GLog* logger = NULL; | |
| 497 | - if (logTerse()) { | |
| 498 | - logger = &log; | |
| 499 | - } | |
| 500 | - | |
| 501 | 464 | // Loop over all observations |
| 502 | 465 | for (int i = 0; i < m_obs.size(); ++i) { |
| 503 | 466 | |
| ... | ... | @@ -516,7 +479,7 @@ void ctexpcube::init_cube(void) |
| 516 | 479 | } |
| 517 | 480 | |
| 518 | 481 | // Insert energy boundaries |
| 519 | - energies = insert_energy_boundaries(energies, *cta, logger); | |
| 482 | + energies = insert_energy_boundaries(energies, *cta); | |
| 520 | 483 | |
| 521 | 484 | } // endfor: looped over all observations |
| 522 | 485 | |
| ... | ... | @@ -525,11 +488,9 @@ void ctexpcube::init_cube(void) |
| 525 | 488 | // Setup exposure cube |
| 526 | 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 | 494 | // Return |
| 534 | 495 | return; |
| 535 | -}; | |
| 496 | +} | ... | ... |
src/ctobssim/ctobssim.cpp
| ... | ... | @@ -324,7 +324,7 @@ void ctobssim::run(void) |
| 324 | 324 | wrklog.name(log.name()); |
| 325 | 325 | |
| 326 | 326 | // Set a big value to avoid flushing |
| 327 | - wrklog.max_size(10000000); | |
| 327 | + wrklog.buffer_size(10000000); | |
| 328 | 328 | |
| 329 | 329 | // Loop over all observation in the container. If OpenMP support |
| 330 | 330 | // is enabled, this loop will be parallelized. | ... | ... |
src/ctpsfcube/ctpsfcube.cpp
| ... | ... | @@ -216,35 +216,20 @@ void ctpsfcube::run(void) |
| 216 | 216 | // Get task parameters |
| 217 | 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 | 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 | 228 | // Fill PSF cube |
| 242 | 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 | 234 | // Return |
| 250 | 235 | return; |
| ... | ... | @@ -253,31 +238,34 @@ void ctpsfcube::run(void) |
| 253 | 238 | |
| 254 | 239 | /***********************************************************************//** |
| 255 | 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 | 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 | 250 | // Get output filename |
| 266 | 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 | 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 | 270 | // Return |
| 283 | 271 | return; |
| ... | ... | @@ -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 | 373 | else { |
| 386 | 374 | |
| 387 | 375 | // Load event cube from filename |
| ... | ... | @@ -416,7 +404,10 @@ void ctpsfcube::get_parameters(void) |
| 416 | 404 | ***************************************************************************/ |
| 417 | 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 | 411 | const GWcs* proj = static_cast<const GWcs*>(m_psfcube.cube().projection()); |
| 421 | 412 | std::string wcs = m_psfcube.cube().projection()->code(); |
| 422 | 413 | std::string coords = m_psfcube.cube().projection()->coordsys(); |
| ... | ... | @@ -435,12 +426,6 @@ void ctpsfcube::init_cube(void) |
| 435 | 426 | // If requested, insert energies at all event list energy boundaries |
| 436 | 427 | if (m_addbounds) { |
| 437 | 428 | |
| 438 | - // Set logger | |
| 439 | - GLog* logger = NULL; | |
| 440 | - if (logTerse()) { | |
| 441 | - logger = &log; | |
| 442 | - } | |
| 443 | - | |
| 444 | 429 | // Loop over all observations |
| 445 | 430 | for (int i = 0; i < m_obs.size(); ++i) { |
| 446 | 431 | |
| ... | ... | @@ -459,7 +444,7 @@ void ctpsfcube::init_cube(void) |
| 459 | 444 | } |
| 460 | 445 | |
| 461 | 446 | // Insert energy boundaries |
| 462 | - energies = insert_energy_boundaries(energies, *cta, logger); | |
| 447 | + energies = insert_energy_boundaries(energies, *cta); | |
| 463 | 448 | |
| 464 | 449 | } // endfor: looped over all observations |
| 465 | 450 | |
| ... | ... | @@ -469,11 +454,9 @@ void ctpsfcube::init_cube(void) |
| 469 | 454 | m_psfcube = GCTACubePsf(wcs, coords, x, y, dx, dy, nx, ny, energies, |
| 470 | 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 | 460 | // Return |
| 478 | 461 | return; |
| 479 | -}; | |
| 462 | +} | ... | ... |
src/support/ctool.cpp
| ... | ... | @@ -68,15 +68,14 @@ |
| 68 | 68 | |
| 69 | 69 | /***********************************************************************//** |
| 70 | 70 | * @brief Void constructor |
| 71 | + * | |
| 72 | + * Constructs an empty ctools. | |
| 71 | 73 | ***************************************************************************/ |
| 72 | 74 | ctool::ctool(void) : GApplication() |
| 73 | 75 | { |
| 74 | 76 | // Initialise members |
| 75 | 77 | init_members(); |
| 76 | 78 | |
| 77 | - // Write header into logger | |
| 78 | - log_header(); | |
| 79 | - | |
| 80 | 79 | // Return |
| 81 | 80 | return; |
| 82 | 81 | } |
| ... | ... | @@ -87,6 +86,16 @@ ctool::ctool(void) : GApplication() |
| 87 | 86 | * |
| 88 | 87 | * @param[in] name Application name. |
| 89 | 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 | 100 | ctool::ctool(const std::string& name, const std::string& version) : |
| 92 | 101 | GApplication(name, version) |
| ... | ... | @@ -94,9 +103,6 @@ ctool::ctool(const std::string& name, const std::string& version) : |
| 94 | 103 | // Initialise members |
| 95 | 104 | init_members(); |
| 96 | 105 | |
| 97 | - // Write header into logger | |
| 98 | - log_header(); | |
| 99 | - | |
| 100 | 106 | // Return |
| 101 | 107 | return; |
| 102 | 108 | } |
| ... | ... | @@ -109,6 +115,16 @@ ctool::ctool(const std::string& name, const std::string& version) : |
| 109 | 115 | * @param[in] version Application version. |
| 110 | 116 | * @param[in] argc Number of arguments in command line. |
| 111 | 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 | 129 | ctool::ctool(const std::string& name, const std::string& version, |
| 114 | 130 | int argc, char *argv[]) : |
| ... | ... | @@ -123,8 +139,8 @@ ctool::ctool(const std::string& name, const std::string& version, |
| 123 | 139 | // Initialise members |
| 124 | 140 | init_members(); |
| 125 | 141 | |
| 126 | - // Write header into logger | |
| 127 | - log_header(); | |
| 142 | + // Open the log file | |
| 143 | + logFileOpen(); | |
| 128 | 144 | |
| 129 | 145 | // Return |
| 130 | 146 | return; |
| ... | ... | @@ -135,6 +151,8 @@ ctool::ctool(const std::string& name, const std::string& version, |
| 135 | 151 | * @brief Copy constructor |
| 136 | 152 | * |
| 137 | 153 | * @param[in] app Application. |
| 154 | + * | |
| 155 | + * Construct a ctools from another ctool instance. | |
| 138 | 156 | ***************************************************************************/ |
| 139 | 157 | ctool::ctool(const ctool& app) : GApplication(app) |
| 140 | 158 | { |
| ... | ... | @@ -172,6 +190,8 @@ ctool::~ctool(void) |
| 172 | 190 | * @brief Assignment operator |
| 173 | 191 | * |
| 174 | 192 | * @param[in] app Application. |
| 193 | + * | |
| 194 | + * Assigns one ctool to another. | |
| 175 | 195 | ***************************************************************************/ |
| 176 | 196 | ctool& ctool::operator=(const ctool& app) |
| 177 | 197 | { |
| ... | ... | @@ -207,7 +227,8 @@ ctool& ctool::operator=(const ctool& app) |
| 207 | 227 | * @brief Execute application |
| 208 | 228 | * |
| 209 | 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 | 233 | void ctool::execute(void) |
| 213 | 234 | { |
| ... | ... | @@ -275,9 +296,6 @@ void ctool::copy_members(const ctool& app) |
| 275 | 296 | ***************************************************************************/ |
| 276 | 297 | void ctool::free_members(void) |
| 277 | 298 | { |
| 278 | - // Write separator into logger | |
| 279 | - log_string(TERSE, ""); | |
| 280 | - | |
| 281 | 299 | // Return |
| 282 | 300 | return; |
| 283 | 301 | } |
| ... | ... | @@ -1374,10 +1392,11 @@ std::string ctool::get_obs_header(const GObservation* obs) |
| 1374 | 1392 | * @param[in] energies Energies. |
| 1375 | 1393 | * @param[in] obs Observation container. |
| 1376 | 1394 | * @return Energies. |
| 1395 | + * | |
| 1396 | + * Inserts the energy boundaries of an observation in a list of @p energies. | |
| 1377 | 1397 | ***************************************************************************/ |
| 1378 | 1398 | GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, |
| 1379 | - const GCTAObservation& obs, | |
| 1380 | - GLog* log) const | |
| 1399 | + const GCTAObservation& obs) | |
| 1381 | 1400 | { |
| 1382 | 1401 | // Create copy of input energies |
| 1383 | 1402 | GEnergies engs = energies; |
| ... | ... | @@ -1428,11 +1447,8 @@ GEnergies ctool::insert_energy_boundaries(const GEnergies& energies, |
| 1428 | 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 | 1453 | } // endif: energy insertion requested |
| 1438 | 1454 | |
| ... | ... | @@ -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 | 1521 | void ctool::provide_help(void) const |
| 1450 | 1522 | { | ... | ... |
src/support/ctool.hpp
| ... | ... | @@ -101,8 +101,10 @@ protected: |
| 101 | 101 | size_t get_current_rss(void); |
| 102 | 102 | std::string get_obs_header(const GObservation* obs); |
| 103 | 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 | 109 | // Protected members |
| 108 | 110 | bool m_read_ahead; //!< Read ahead output parameters | ... | ... |
test/test_ctbin.py
| ... | ... | @@ -134,7 +134,6 @@ class Test(test): |
| 134 | 134 | bin.clear() |
| 135 | 135 | |
| 136 | 136 | # Now set ctbin parameters |
| 137 | - #bin = ctools.ctbin() | |
| 138 | 137 | bin['inobs'] = self._events |
| 139 | 138 | bin['outcube'] = 'ctbin_py1.fits' |
| 140 | 139 | bin['ebinalg'] = 'LOG' |
| ... | ... | @@ -159,7 +158,7 @@ class Test(test): |
| 159 | 158 | self._check_observation(bin, 5542) |
| 160 | 159 | self._check_cube(bin.cube(), 5542) |
| 161 | 160 | |
| 162 | - # Test copy constructor | |
| 161 | + # Copy ctbin tool | |
| 163 | 162 | cpy_bin = bin.copy() |
| 164 | 163 | |
| 165 | 164 | # Check content of observation container and counts cube | ... | ... |
test/test_ctbkgcube.py
| ... | ... | @@ -18,6 +18,7 @@ |
| 18 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | 19 | # |
| 20 | 20 | # ========================================================================== |
| 21 | +import os | |
| 21 | 22 | import gammalib |
| 22 | 23 | import ctools |
| 23 | 24 | from testing import test |
| ... | ... | @@ -85,7 +86,7 @@ class Test(test): |
| 85 | 86 | 'Check successful execution from command line') |
| 86 | 87 | |
| 87 | 88 | # Check result file |
| 88 | - self._check_result_file('ctbkgcube_cmd1.fits') | |
| 89 | + self._check_result_files('ctbkgcube_cmd1') | |
| 89 | 90 | |
| 90 | 91 | # Setup ctbkgcube command |
| 91 | 92 | cmd = ctbkgcube+' inobs="event_file_that_does_not_exist.fits"'+ \ |
| ... | ... | @@ -111,8 +112,29 @@ class Test(test): |
| 111 | 112 | """ |
| 112 | 113 | Test ctbkgcube from Python |
| 113 | 114 | """ |
| 114 | - # Set-up ctbkgcube | |
| 115 | + # Allocate ctbkgcube | |
| 115 | 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 | 138 | bkgcube['inobs'] = self._events |
| 117 | 139 | bkgcube['inmodel'] = self._model |
| 118 | 140 | bkgcube['incube'] = 'NONE' |
| ... | ... | @@ -120,7 +142,7 @@ class Test(test): |
| 120 | 142 | bkgcube['irf'] = self._irf |
| 121 | 143 | bkgcube['ebinalg'] = 'LOG' |
| 122 | 144 | bkgcube['emin'] = 0.1 |
| 123 | - bkgcube['emax'] = 100 | |
| 145 | + bkgcube['emax'] = 100.0 | |
| 124 | 146 | bkgcube['enumbins'] = 20 |
| 125 | 147 | bkgcube['nxpix'] = 10 |
| 126 | 148 | bkgcube['nypix'] = 10 |
| ... | ... | @@ -139,45 +161,43 @@ class Test(test): |
| 139 | 161 | bkgcube.run() |
| 140 | 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 | 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 | 202 | # Prepare observation container |
| 183 | 203 | obs1 = gammalib.GCTAObservation(self._events) |
| ... | ... | @@ -195,47 +215,94 @@ class Test(test): |
| 195 | 215 | |
| 196 | 216 | # Set-up ctbkgcube from observation container |
| 197 | 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 | 238 | # Execute ctbkgcube tool |
| 220 | 239 | bkgcube.logFileOpen() # Make sure we get a log file |
| 221 | 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 | 245 | # Return |
| 227 | 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 | 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 | 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 | 291 | # Return |
| 241 | 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 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | 19 | # |
| 20 | 20 | # ========================================================================== |
| 21 | +import os | |
| 21 | 22 | import gammalib |
| 22 | 23 | import ctools |
| 23 | 24 | from testing import test |
| ... | ... | @@ -109,16 +110,32 @@ class Test(test): |
| 109 | 110 | """ |
| 110 | 111 | Test ctedispcube from Python |
| 111 | 112 | """ |
| 112 | - # Set-up ctedispcube | |
| 113 | + # Allocate ctedispcube | |
| 113 | 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 | 132 | edispcube['inobs'] = self._events |
| 115 | 133 | edispcube['incube'] = 'NONE' |
| 116 | - edispcube['outcube'] = 'ctedispcube_py1.fits' | |
| 117 | 134 | edispcube['caldb'] = self._caldb |
| 118 | 135 | edispcube['irf'] = self._irf |
| 119 | 136 | edispcube['ebinalg'] = 'LOG' |
| 120 | 137 | edispcube['emin'] = 0.1 |
| 121 | - edispcube['emax'] = 100 | |
| 138 | + edispcube['emax'] = 100.0 | |
| 122 | 139 | edispcube['enumbins'] = 20 |
| 123 | 140 | edispcube['nxpix'] = 10 |
| 124 | 141 | edispcube['nypix'] = 10 |
| ... | ... | @@ -129,31 +146,88 @@ class Test(test): |
| 129 | 146 | edispcube['yref'] = 22.01 |
| 130 | 147 | edispcube['migramax'] = 2.0 |
| 131 | 148 | edispcube['migrabins'] = 10 |
| 149 | + edispcube['outcube'] = 'ctedispcube_py1.fits' | |
| 132 | 150 | edispcube['logfile'] = 'ctedispcube_py1.log' |
| 133 | 151 | edispcube['chatter'] = 2 |
| 134 | 152 | |
| 135 | 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 | 155 | edispcube.run() |
| 138 | 156 | edispcube.save() |
| 139 | 157 | |
| 140 | 158 | # Check result file |
| 141 | 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 | 188 | # Return |
| 144 | 189 | return |
| 145 | 190 | |
| 146 | 191 | # Check result file |
| 147 | - def _check_result_file(self, filename): | |
| 192 | + def _check_result_file(self, filename, nenergies=21): | |
| 148 | 193 | """ |
| 149 | 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 | 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 | 232 | # Return |
| 159 | 233 | return | ... | ... |
test/test_ctexpcube.py
| ... | ... | @@ -18,6 +18,7 @@ |
| 18 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | 19 | # |
| 20 | 20 | # ========================================================================== |
| 21 | +import os | |
| 21 | 22 | import gammalib |
| 22 | 23 | import ctools |
| 23 | 24 | from testing import test |
| ... | ... | @@ -107,16 +108,32 @@ class Test(test): |
| 107 | 108 | """ |
| 108 | 109 | Test ctexpcube from Python |
| 109 | 110 | """ |
| 110 | - # Set-up ctexpcube | |
| 111 | + # Allocate ctexpcube | |
| 111 | 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 | 130 | expcube['inobs'] = self._events |
| 113 | 131 | expcube['incube'] = 'NONE' |
| 114 | - expcube['outcube'] = 'ctexpcube_py1.fits' | |
| 115 | 132 | expcube['caldb'] = self._caldb |
| 116 | 133 | expcube['irf'] = self._irf |
| 117 | 134 | expcube['ebinalg'] = 'LOG' |
| 118 | 135 | expcube['emin'] = 0.1 |
| 119 | - expcube['emax'] = 100 | |
| 136 | + expcube['emax'] = 100.0 | |
| 120 | 137 | expcube['enumbins'] = 20 |
| 121 | 138 | expcube['nxpix'] = 200 |
| 122 | 139 | expcube['nypix'] = 200 |
| ... | ... | @@ -126,6 +143,7 @@ class Test(test): |
| 126 | 143 | expcube['xref'] = 83.63 |
| 127 | 144 | expcube['yref'] = 22.01 |
| 128 | 145 | expcube['logfile'] = 'ctexpcube_py1.log' |
| 146 | + expcube['outcube'] = 'ctexpcube_py1.fits' | |
| 129 | 147 | expcube['chatter'] = 2 |
| 130 | 148 | |
| 131 | 149 | # Run ctexpcube tool |
| ... | ... | @@ -136,19 +154,72 @@ class Test(test): |
| 136 | 154 | # Check result file |
| 137 | 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 | 184 | # Return |
| 140 | 185 | return |
| 141 | 186 | |
| 142 | 187 | # Check result file |
| 143 | - def _check_result_file(self, filename): | |
| 188 | + def _check_result_file(self, filename, nenergies=21): | |
| 144 | 189 | """ |
| 145 | 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 | 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 | 224 | # Return |
| 154 | 225 | return | ... | ... |
test/test_ctpsfcube.py
| ... | ... | @@ -18,6 +18,7 @@ |
| 18 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | 19 | # |
| 20 | 20 | # ========================================================================== |
| 21 | +import os | |
| 21 | 22 | import gammalib |
| 22 | 23 | import ctools |
| 23 | 24 | from testing import test |
| ... | ... | @@ -109,8 +110,25 @@ class Test(test): |
| 109 | 110 | """ |
| 110 | 111 | Test ctpsfcube from Python |
| 111 | 112 | """ |
| 112 | - # Set-up ctpsfcube | |
| 113 | + # Allocate ctpsfcube | |
| 113 | 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 | 132 | psfcube['inobs'] = self._events |
| 115 | 133 | psfcube['incube'] = 'NONE' |
| 116 | 134 | psfcube['outcube'] = 'ctpsfcube_py1.fits' |
| ... | ... | @@ -140,19 +158,71 @@ class Test(test): |
| 140 | 158 | # Check result file |
| 141 | 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 | 187 | # Return |
| 144 | 188 | return |
| 145 | 189 | |
| 146 | 190 | # Check result file |
| 147 | - def _check_result_file(self, filename): | |
| 191 | + def _check_result_file(self, filename, nenergies=21): | |
| 148 | 192 | """ |
| 149 | 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 | 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 | 227 | # Return |
| 158 | 228 | return | ... | ... |