Commit 76afa729ffd96927d239cf699dce53d4fa17b95e
1 parent
ce48d505
Enhance ctools unit tests
Showing
21 changed files
with
335 additions
and
99 deletions
src/ctbkgcube/ctbkgcube.cpp
| @@ -488,6 +488,12 @@ void ctbkgcube::get_parameters(void) | @@ -488,6 +488,12 @@ void ctbkgcube::get_parameters(void) | ||
| 488 | 488 | ||
| 489 | } // endif: there was no observation in the container | 489 | } // endif: there was no observation in the container |
| 490 | 490 | ||
| 491 | + // ... otherwise add response information and energy boundaries in case | ||
| 492 | + // that they are missing | ||
| 493 | + else { | ||
| 494 | + setup_observations(m_obs); | ||
| 495 | + } | ||
| 496 | + | ||
| 491 | // Get the incube filename | 497 | // Get the incube filename |
| 492 | std::string incube = (*this)["incube"].filename(); | 498 | std::string incube = (*this)["incube"].filename(); |
| 493 | 499 |
src/ctbutterfly/ctbutterfly.cpp
| @@ -573,9 +573,8 @@ void ctbutterfly::free_members(void) | @@ -573,9 +573,8 @@ void ctbutterfly::free_members(void) | ||
| 573 | /***********************************************************************//** | 573 | /***********************************************************************//** |
| 574 | * @brief Get application parameters | 574 | * @brief Get application parameters |
| 575 | * | 575 | * |
| 576 | - * @exception GException::invalid_value | ||
| 577 | - * Test source not found or no RA/DEC parameters found for test | ||
| 578 | - * source. | 576 | + * @exception GException::feature_not_implemented |
| 577 | + * Loading of covariance matrix is not yet implemented. | ||
| 579 | * | 578 | * |
| 580 | * Get all task parameters from parameter file or (if required) by querying | 579 | * Get all task parameters from parameter file or (if required) by querying |
| 581 | * the user. Most parameters are only required if no observation exists so | 580 | * the user. Most parameters are only required if no observation exists so |
| @@ -597,6 +596,11 @@ void ctbutterfly::get_parameters(void) | @@ -597,6 +596,11 @@ void ctbutterfly::get_parameters(void) | ||
| 597 | 596 | ||
| 598 | } // endif: there was no observation in the container | 597 | } // endif: there was no observation in the container |
| 599 | 598 | ||
| 599 | + // ... otherwise add response information and energy boundaries in case | ||
| 600 | + // that they are missing | ||
| 601 | + else { | ||
| 602 | + setup_observations(m_obs); | ||
| 603 | + } | ||
| 600 | 604 | ||
| 601 | // If there is are no models associated with the observations then | 605 | // If there is are no models associated with the observations then |
| 602 | // load now the model definition | 606 | // load now the model definition |
src/ctcubemask/ctcubemask.cpp
| @@ -301,7 +301,7 @@ void ctcubemask::save(void) | @@ -301,7 +301,7 @@ void ctcubemask::save(void) | ||
| 301 | // Get counts cube filename | 301 | // Get counts cube filename |
| 302 | m_outcube = (*this)["outcube"].filename(); | 302 | m_outcube = (*this)["outcube"].filename(); |
| 303 | 303 | ||
| 304 | - // Case A: Save event file(s) and XML metadata information | 304 | + // Case A: Save counts cube(s) and XML metadata information |
| 305 | if (m_use_xml) { | 305 | if (m_use_xml) { |
| 306 | 306 | ||
| 307 | // Get prefix | 307 | // Get prefix |
| @@ -311,7 +311,7 @@ void ctcubemask::save(void) | @@ -311,7 +311,7 @@ void ctcubemask::save(void) | ||
| 311 | save_xml(); | 311 | save_xml(); |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | - // Case B: Save event file as FITS file | 314 | + // Case B: Save counts cube as FITS file |
| 315 | else { | 315 | else { |
| 316 | save_fits(); | 316 | save_fits(); |
| 317 | } | 317 | } |
| @@ -404,9 +404,9 @@ void ctcubemask::init_members(void) | @@ -404,9 +404,9 @@ void ctcubemask::init_members(void) | ||
| 404 | void ctcubemask::copy_members(const ctcubemask& app) | 404 | void ctcubemask::copy_members(const ctcubemask& app) |
| 405 | { | 405 | { |
| 406 | // Copy parameters | 406 | // Copy parameters |
| 407 | - m_regfile = app.m_regfile; | 407 | + m_regfile = app.m_regfile; |
| 408 | m_outcube = app.m_outcube; | 408 | m_outcube = app.m_outcube; |
| 409 | - m_prefix = app.m_prefix; | 409 | + m_prefix = app.m_prefix; |
| 410 | m_usepnt = app.m_usepnt; | 410 | m_usepnt = app.m_usepnt; |
| 411 | m_ra = app.m_ra; | 411 | m_ra = app.m_ra; |
| 412 | m_dec = app.m_dec; | 412 | m_dec = app.m_dec; |
| @@ -471,7 +471,7 @@ void ctcubemask::get_parameters(void) | @@ -471,7 +471,7 @@ void ctcubemask::get_parameters(void) | ||
| 471 | } // endif: there was no observation in the container | 471 | } // endif: there was no observation in the container |
| 472 | 472 | ||
| 473 | // Get parameters | 473 | // Get parameters |
| 474 | - m_regfile = (*this)["regfile"].filename(); | 474 | + m_regfile = (*this)["regfile"].filename(); |
| 475 | m_usepnt = (*this)["usepnt"].boolean(); | 475 | m_usepnt = (*this)["usepnt"].boolean(); |
| 476 | if (!m_usepnt) { | 476 | if (!m_usepnt) { |
| 477 | 477 | ||
| @@ -725,18 +725,23 @@ std::string ctcubemask::set_outfile_name(const std::string& filename) const | @@ -725,18 +725,23 @@ std::string ctcubemask::set_outfile_name(const std::string& filename) const | ||
| 725 | ***************************************************************************/ | 725 | ***************************************************************************/ |
| 726 | void ctcubemask::save_fits(void) | 726 | void ctcubemask::save_fits(void) |
| 727 | { | 727 | { |
| 728 | - // Save only if filename is non-empty | ||
| 729 | - if (!m_outcube.is_empty()) { | 728 | + // Save only if filename is non-empty and if there are observations |
| 729 | + if (!m_outcube.is_empty() && m_obs.size() > 0) { | ||
| 730 | 730 | ||
| 731 | // Get CTA observation from observation container | 731 | // Get CTA observation from observation container |
| 732 | GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); | 732 | GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); |
| 733 | 733 | ||
| 734 | - // Log counts cube file name | ||
| 735 | - log_value(NORMAL, "Counts cube file", m_outcube.url()); | 734 | + // Handle only CTA observations |
| 735 | + if (obs != NULL) { | ||
| 736 | + | ||
| 737 | + // Log counts cube file name | ||
| 738 | + log_value(NORMAL, "Counts cube file", m_outcube.url()); | ||
| 736 | 739 | ||
| 737 | - // Save event list | ||
| 738 | - save_counts_map(obs, m_outcube); | 740 | + // Save counts cube |
| 741 | + obs->save(m_outcube, clobber()); | ||
| 739 | 742 | ||
| 743 | + } // endif: observation was a CTA observation | ||
| 744 | + | ||
| 740 | } | 745 | } |
| 741 | 746 | ||
| 742 | // Return | 747 | // Return |
| @@ -745,30 +750,20 @@ void ctcubemask::save_fits(void) | @@ -745,30 +750,20 @@ void ctcubemask::save_fits(void) | ||
| 745 | 750 | ||
| 746 | 751 | ||
| 747 | /***********************************************************************//** | 752 | /***********************************************************************//** |
| 748 | - * @brief Save counts map(s) in XML format. | 753 | + * @brief Save counts cube(s) in XML format. |
| 749 | * | 754 | * |
| 750 | - * Save the counts map(s) into FITS files and write the file path information | ||
| 751 | - * into a XML file. The filename of the XML file is specified by the | ||
| 752 | - * m_outfile member, the filename(s) of the counts map(s) are built by | 755 | + * Save the counts cube(s) into FITS files and write the file path |
| 756 | + * information into an XML file. The filename of the XML file is specified by | ||
| 757 | + * the m_outfile member, the filename(s) of the counts cube(s) are built by | ||
| 753 | * prepending the prefix given by the m_prefix member to the input counts | 758 | * prepending the prefix given by the m_prefix member to the input counts |
| 754 | - * map(s) filenames. Any path present in the input filename will be stripped, | ||
| 755 | - * i.e. the counts map(s) will be written in the local working directory | ||
| 756 | - * (unless a path is specified in the m_prefix member). | 759 | + * cube(s) filenames. Any path present in the input filename will be |
| 760 | + * stripped, i.e. the counts cube(s) will be written in the local working | ||
| 761 | + * directory (unless a path is specified in the m_prefix member). | ||
| 757 | ***************************************************************************/ | 762 | ***************************************************************************/ |
| 758 | void ctcubemask::save_xml(void) | 763 | void ctcubemask::save_xml(void) |
| 759 | { | 764 | { |
| 760 | // Issue warning if output filename has no .xml suffix | 765 | // Issue warning if output filename has no .xml suffix |
| 761 | - std::string suffix = gammalib::tolower(m_outcube.url().substr( | ||
| 762 | - m_outcube.length()-4,4)); | ||
| 763 | - if (suffix != ".xml") { | ||
| 764 | - std::string msg = "\nWARNING: Name of observation definition output " | ||
| 765 | - "file \""+m_outcube+"\" does not terminate with\n" | ||
| 766 | - " \".xml\". This is not an error, but may " | ||
| 767 | - "be misleading. It is recommended to use the\n" | ||
| 768 | - " suffix \".xml\" for observation definition " | ||
| 769 | - "files."; | ||
| 770 | - log_string(TERSE, msg); | ||
| 771 | - } | 766 | + log_string(TERSE, warn_xml_suffix(m_outcube.url())); |
| 772 | 767 | ||
| 773 | // Loop over all observation in the container | 768 | // Loop over all observation in the container |
| 774 | for (int i = 0; i < m_obs.size(); ++i) { | 769 | for (int i = 0; i < m_obs.size(); ++i) { |
| @@ -788,8 +783,8 @@ void ctcubemask::save_xml(void) | @@ -788,8 +783,8 @@ void ctcubemask::save_xml(void) | ||
| 788 | // Log counts cube file name | 783 | // Log counts cube file name |
| 789 | log_value(NORMAL, "Counts cube file", outfile); | 784 | log_value(NORMAL, "Counts cube file", outfile); |
| 790 | 785 | ||
| 791 | - // Save event list | ||
| 792 | - save_counts_map(obs, outfile); | 786 | + // Save counts cube |
| 787 | + obs->save(outfile, clobber()); | ||
| 793 | 788 | ||
| 794 | } // endif: observation was a CTA observations | 789 | } // endif: observation was a CTA observations |
| 795 | 790 | ||
| @@ -801,30 +796,3 @@ void ctcubemask::save_xml(void) | @@ -801,30 +796,3 @@ void ctcubemask::save_xml(void) | ||
| 801 | // Return | 796 | // Return |
| 802 | return; | 797 | return; |
| 803 | } | 798 | } |
| 804 | - | ||
| 805 | - | ||
| 806 | - | ||
| 807 | -/***********************************************************************//** | ||
| 808 | - * @brief Save a single counts map into a FITS file | ||
| 809 | - * | ||
| 810 | - * @param[in] obs Pointer to CTA observation. | ||
| 811 | - * @param[in] outfile Output file name. | ||
| 812 | - * | ||
| 813 | - * This method saves a single counts map into a FITS file. The method does | ||
| 814 | - * nothing if the observation pointer is not valid. | ||
| 815 | - ***************************************************************************/ | ||
| 816 | -void ctcubemask::save_counts_map(const GCTAObservation* obs, | ||
| 817 | - const std::string& outfile) const | ||
| 818 | -{ | ||
| 819 | - // Save only if observation is valid | ||
| 820 | - if (obs != NULL) { | ||
| 821 | - | ||
| 822 | - // Save observation into FITS file | ||
| 823 | - obs->save(outfile, clobber()); | ||
| 824 | - | ||
| 825 | - } // endif: observation was valid | ||
| 826 | - | ||
| 827 | - // Return | ||
| 828 | - return; | ||
| 829 | -} | ||
| 830 | - |
src/ctcubemask/ctcubemask.hpp
| @@ -36,7 +36,7 @@ | @@ -36,7 +36,7 @@ | ||
| 36 | 36 | ||
| 37 | /* __Definitions _________________________________________________________ */ | 37 | /* __Definitions _________________________________________________________ */ |
| 38 | #define CTCUBEMASK_NAME "ctcubemask" | 38 | #define CTCUBEMASK_NAME "ctcubemask" |
| 39 | -#define CTCUBEMASK_VERSION "1.1.0" | 39 | +#define CTCUBEMASK_VERSION "1.2.0" |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | /***********************************************************************//** | 42 | /***********************************************************************//** |
| @@ -75,8 +75,6 @@ protected: | @@ -75,8 +75,6 @@ protected: | ||
| 75 | std::string set_outfile_name(const std::string& filename) const; | 75 | std::string set_outfile_name(const std::string& filename) const; |
| 76 | void save_fits(void); | 76 | void save_fits(void); |
| 77 | void save_xml(void); | 77 | void save_xml(void); |
| 78 | - void save_counts_map(const GCTAObservation* obs, | ||
| 79 | - const std::string& outfile) const; | ||
| 80 | 78 | ||
| 81 | // User parameters | 79 | // User parameters |
| 82 | GFilename m_regfile; //!< ds9 region file | 80 | GFilename m_regfile; //!< ds9 region file |
src/ctedispcube/ctedispcube.cpp
| @@ -361,6 +361,12 @@ void ctedispcube::get_parameters(void) | @@ -361,6 +361,12 @@ void ctedispcube::get_parameters(void) | ||
| 361 | 361 | ||
| 362 | } // endif: there was no observation in the container | 362 | } // endif: there was no observation in the container |
| 363 | 363 | ||
| 364 | + // ... otherwise add response information and energy boundaries in case | ||
| 365 | + // that they are missing | ||
| 366 | + else { | ||
| 367 | + setup_observations(m_obs); | ||
| 368 | + } | ||
| 369 | + | ||
| 364 | // Get the incube filename | 370 | // Get the incube filename |
| 365 | std::string incube = (*this)["incube"].filename(); | 371 | std::string incube = (*this)["incube"].filename(); |
| 366 | 372 |
src/cterror/cterror.cpp
| @@ -475,6 +475,11 @@ void cterror::get_parameters(void) | @@ -475,6 +475,11 @@ void cterror::get_parameters(void) | ||
| 475 | 475 | ||
| 476 | } // endif: there was no observation in the container | 476 | } // endif: there was no observation in the container |
| 477 | 477 | ||
| 478 | + // ... otherwise add response information and energy boundaries in case | ||
| 479 | + // that they are missing | ||
| 480 | + else { | ||
| 481 | + setup_observations(m_obs); | ||
| 482 | + } | ||
| 478 | 483 | ||
| 479 | // If there are no models associated with the observations then | 484 | // If there are no models associated with the observations then |
| 480 | // load now the model definition | 485 | // load now the model definition |
src/ctexpcube/ctexpcube.cpp
| @@ -386,6 +386,12 @@ void ctexpcube::get_parameters(void) | @@ -386,6 +386,12 @@ void ctexpcube::get_parameters(void) | ||
| 386 | 386 | ||
| 387 | } // endif: there was no observation in the container | 387 | } // endif: there was no observation in the container |
| 388 | 388 | ||
| 389 | + // ... otherwise add response information and energy boundaries in case | ||
| 390 | + // that they are missing | ||
| 391 | + else { | ||
| 392 | + setup_observations(m_obs); | ||
| 393 | + } | ||
| 394 | + | ||
| 389 | // Get the incube filename | 395 | // Get the incube filename |
| 390 | std::string incube = (*this)["incube"].filename(); | 396 | std::string incube = (*this)["incube"].filename(); |
| 391 | 397 |
src/ctlike/ctlike.cpp
| @@ -373,6 +373,12 @@ void ctlike::get_parameters(void) | @@ -373,6 +373,12 @@ void ctlike::get_parameters(void) | ||
| 373 | 373 | ||
| 374 | } // endif: there was no observation in the container | 374 | } // endif: there was no observation in the container |
| 375 | 375 | ||
| 376 | + // ... otherwise add response information and energy boundaries in case | ||
| 377 | + // that they are missing | ||
| 378 | + else { | ||
| 379 | + setup_observations(m_obs); | ||
| 380 | + } | ||
| 381 | + | ||
| 376 | // If only single observation is used, read statistics parameter | 382 | // If only single observation is used, read statistics parameter |
| 377 | if (!m_use_xml) { | 383 | if (!m_use_xml) { |
| 378 | 384 |
src/ctmodel/ctmodel.cpp
| @@ -456,6 +456,12 @@ void ctmodel::get_parameters(void) | @@ -456,6 +456,12 @@ void ctmodel::get_parameters(void) | ||
| 456 | get_obs(); | 456 | get_obs(); |
| 457 | } | 457 | } |
| 458 | 458 | ||
| 459 | + // ... otherwise add response information and energy boundaries in case | ||
| 460 | + // that they are missing | ||
| 461 | + else { | ||
| 462 | + setup_observations(m_obs); | ||
| 463 | + } | ||
| 464 | + | ||
| 459 | // If we have now excactly one CTA observation (but no cube has yet been | 465 | // If we have now excactly one CTA observation (but no cube has yet been |
| 460 | // appended to the observation) then check whether this observation | 466 | // appended to the observation) then check whether this observation |
| 461 | // is a binned observation, and if yes, extract the counts cube for | 467 | // is a binned observation, and if yes, extract the counts cube for |
src/ctobssim/ctobssim.cpp
| @@ -561,9 +561,10 @@ void ctobssim::get_parameters(void) | @@ -561,9 +561,10 @@ void ctobssim::get_parameters(void) | ||
| 561 | 561 | ||
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | - // ... otherwise make sure that observation boundaries are set | 564 | + // ... otherwise add response information and energy boundaries in case |
| 565 | + // that they are missing | ||
| 565 | else { | 566 | else { |
| 566 | - set_obs_bounds(m_obs); | 567 | + setup_observations(m_obs); |
| 567 | } | 568 | } |
| 568 | 569 | ||
| 569 | // Read model definition file if required | 570 | // Read model definition file if required |
src/ctpsfcube/ctpsfcube.cpp
| @@ -346,6 +346,12 @@ void ctpsfcube::get_parameters(void) | @@ -346,6 +346,12 @@ void ctpsfcube::get_parameters(void) | ||
| 346 | 346 | ||
| 347 | } // endif: there was no observation in the container | 347 | } // endif: there was no observation in the container |
| 348 | 348 | ||
| 349 | + // ... otherwise add response information and energy boundaries in case | ||
| 350 | + // that they are missing | ||
| 351 | + else { | ||
| 352 | + setup_observations(m_obs); | ||
| 353 | + } | ||
| 354 | + | ||
| 349 | // Get the incube filename | 355 | // Get the incube filename |
| 350 | std::string incube = (*this)["incube"].filename(); | 356 | std::string incube = (*this)["incube"].filename(); |
| 351 | 357 |
src/cttsmap/cttsmap.cpp
| @@ -523,6 +523,12 @@ void cttsmap::get_parameters(void) | @@ -523,6 +523,12 @@ void cttsmap::get_parameters(void) | ||
| 523 | 523 | ||
| 524 | } // endif: there was no observation in the container | 524 | } // endif: there was no observation in the container |
| 525 | 525 | ||
| 526 | + // ... otherwise add response information and energy boundaries in case | ||
| 527 | + // that they are missing | ||
| 528 | + else { | ||
| 529 | + setup_observations(m_obs); | ||
| 530 | + } | ||
| 531 | + | ||
| 526 | // If there is are no models associated with the observations then | 532 | // If there is are no models associated with the observations then |
| 527 | // load now the model definition | 533 | // load now the model definition |
| 528 | if (m_obs.models().size() == 0) { | 534 | if (m_obs.models().size() == 0) { |
src/ctulimit/ctulimit.cpp
| @@ -481,6 +481,11 @@ void ctulimit::get_parameters(void) | @@ -481,6 +481,11 @@ void ctulimit::get_parameters(void) | ||
| 481 | 481 | ||
| 482 | } // endif: there was no observation in the container | 482 | } // endif: there was no observation in the container |
| 483 | 483 | ||
| 484 | + // ... otherwise add response information and energy boundaries in case | ||
| 485 | + // that they are missing | ||
| 486 | + else { | ||
| 487 | + setup_observations(m_obs); | ||
| 488 | + } | ||
| 484 | 489 | ||
| 485 | // If there is are no models associated with the observations then | 490 | // If there is are no models associated with the observations then |
| 486 | // load now the model definition | 491 | // load now the model definition |
src/support/ctool.cpp
| @@ -1646,7 +1646,7 @@ std::string ctool::warn_xml_suffix(const GFilename& filename) const | @@ -1646,7 +1646,7 @@ std::string ctool::warn_xml_suffix(const GFilename& filename) const | ||
| 1646 | 1646 | ||
| 1647 | // Warn if there are not enough energy bins | 1647 | // Warn if there are not enough energy bins |
| 1648 | if (suffix != ".xml") { | 1648 | if (suffix != ".xml") { |
| 1649 | - warning.append("\nWARNING: Name of observation definition output file " | 1649 | + warning.append("WARNING: Name of observation definition output file " |
| 1650 | "\""+filename+"\" does not terminate with \".xml\"." | 1650 | "\""+filename+"\" does not terminate with \".xml\"." |
| 1651 | "\n This is not an error, but may be misleading. " | 1651 | "\n This is not an error, but may be misleading. " |
| 1652 | "It is recommended to use the suffix" | 1652 | "It is recommended to use the suffix" |
test/test_ctbin.py
| @@ -194,15 +194,9 @@ class Test(test): | @@ -194,15 +194,9 @@ class Test(test): | ||
| 194 | self.test_value(bin.cube().size(), 0, | 194 | self.test_value(bin.cube().size(), 0, |
| 195 | 'Check that empty ctbin has an empty counts cube') | 195 | 'Check that empty ctbin has an empty counts cube') |
| 196 | 196 | ||
| 197 | - # Prepare observation container for stacked analysis | ||
| 198 | - cta = gammalib.GCTAObservation(self._events) | ||
| 199 | - obs = gammalib.GObservations() | ||
| 200 | - cta.id('0001') | ||
| 201 | - obs.append(cta) | ||
| 202 | - cta.id('0002') | ||
| 203 | - obs.append(cta) | ||
| 204 | - cta.id('0003') | ||
| 205 | - obs.append(cta) | 197 | + # Prepare observation container for stacking of events into a |
| 198 | + # single counts cube | ||
| 199 | + obs = self._obs_events() | ||
| 206 | 200 | ||
| 207 | # Set-up ctbin using an observation container | 201 | # Set-up ctbin using an observation container |
| 208 | bin = ctools.ctbin(obs) | 202 | bin = ctools.ctbin(obs) |
test/test_ctbkgcube.py
| @@ -213,18 +213,8 @@ class Test(test): | @@ -213,18 +213,8 @@ class Test(test): | ||
| 213 | self._check_cube(cpy_bkgcube.bkgcube(), nenergies=0) | 213 | self._check_cube(cpy_bkgcube.bkgcube(), nenergies=0) |
| 214 | self._check_models(cpy_bkgcube.models(), nmodels=0) | 214 | self._check_models(cpy_bkgcube.models(), nmodels=0) |
| 215 | 215 | ||
| 216 | - # Prepare observation container | ||
| 217 | - obs1 = gammalib.GCTAObservation(self._events) | ||
| 218 | - obs2 = gammalib.GCTAObservation(self._cntcube) | ||
| 219 | - obs3 = gammalib.GLATObservation() | ||
| 220 | - obs1.id('0001') | ||
| 221 | - obs2.id('0002') | ||
| 222 | - obs3.id('0001') | ||
| 223 | - obs3.events(gammalib.GLATEventList()) | ||
| 224 | - obs = gammalib.GObservations() | ||
| 225 | - obs.append(obs1) | ||
| 226 | - obs.append(obs2) | ||
| 227 | - obs.append(obs3) | 216 | + # Get mixel observation container |
| 217 | + obs = self._obs_mixed() | ||
| 228 | obs.models(gammalib.GModels(self._model)) | 218 | obs.models(gammalib.GModels(self._model)) |
| 229 | 219 | ||
| 230 | # Set-up ctbkgcube from observation container | 220 | # Set-up ctbkgcube from observation container |
test/test_ctcubemask.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 |
| @@ -106,8 +107,24 @@ class Test(test): | @@ -106,8 +107,24 @@ class Test(test): | ||
| 106 | """ | 107 | """ |
| 107 | Test ctcubemask from Python | 108 | Test ctcubemask from Python |
| 108 | """ | 109 | """ |
| 109 | - # Set-up ctcubemask | 110 | + # Allocate ctcubemask |
| 110 | mask = ctools.ctcubemask() | 111 | mask = ctools.ctcubemask() |
| 112 | + | ||
| 113 | + # Check that empty ctcubemask tool holds an empty observation | ||
| 114 | + self._check_obs(mask.obs(), nobs=0) | ||
| 115 | + | ||
| 116 | + # Check that saving saves an empty counts cube | ||
| 117 | + mask['outcube'] = 'ctcubemask_py0.fits' | ||
| 118 | + mask['logfile'] = 'ctcubemask_py0.log' | ||
| 119 | + mask.logFileOpen() | ||
| 120 | + mask.save() | ||
| 121 | + self.test_assert(not os.path.isfile('ctcubemask_py0.fits'), | ||
| 122 | + 'Check that no counts cube has been created') | ||
| 123 | + | ||
| 124 | + # Check that clearing does not lead to an exception or segfault | ||
| 125 | + mask.clear() | ||
| 126 | + | ||
| 127 | + # Now set ctcubemask parameters | ||
| 111 | mask['inobs'] = self._cntcube | 128 | mask['inobs'] = self._cntcube |
| 112 | mask['regfile'] = self._exclusion | 129 | mask['regfile'] = self._exclusion |
| 113 | mask['ra'] = 83.63 | 130 | mask['ra'] = 83.63 |
| @@ -127,14 +144,15 @@ class Test(test): | @@ -127,14 +144,15 @@ class Test(test): | ||
| 127 | # Check result file | 144 | # Check result file |
| 128 | self._check_result_file('ctcubemask_py1.fits') | 145 | self._check_result_file('ctcubemask_py1.fits') |
| 129 | 146 | ||
| 130 | - # Set-up ctcubemask without exclusion regions | 147 | + # Set-up ctcubemask without exclusion regions but tighter energy |
| 148 | + # selection | ||
| 131 | mask = ctools.ctcubemask() | 149 | mask = ctools.ctcubemask() |
| 132 | mask['inobs'] = self._cntcube | 150 | mask['inobs'] = self._cntcube |
| 133 | mask['regfile'] = 'NONE' | 151 | mask['regfile'] = 'NONE' |
| 134 | mask['ra'] = 83.63 | 152 | mask['ra'] = 83.63 |
| 135 | mask['dec'] = 22.01 | 153 | mask['dec'] = 22.01 |
| 136 | mask['rad'] = 3.0 | 154 | mask['rad'] = 3.0 |
| 137 | - mask['emin'] = 0.1 | 155 | + mask['emin'] = 1.0 |
| 138 | mask['emax'] = 100.0 | 156 | mask['emax'] = 100.0 |
| 139 | mask['outcube'] = 'ctcubemask_py2.fits' | 157 | mask['outcube'] = 'ctcubemask_py2.fits' |
| 140 | mask['logfile'] = 'ctcubemask_py2.log' | 158 | mask['logfile'] = 'ctcubemask_py2.log' |
| @@ -146,22 +164,54 @@ class Test(test): | @@ -146,22 +164,54 @@ class Test(test): | ||
| 146 | mask.execute() | 164 | mask.execute() |
| 147 | 165 | ||
| 148 | # Check result file | 166 | # Check result file |
| 149 | - self._check_result_file('ctcubemask_py2.fits', events=5542) | 167 | + self._check_result_file('ctcubemask_py2.fits', events=573) |
| 168 | + | ||
| 169 | + # Copy ctcubemask tool | ||
| 170 | + cpy_mask = mask.copy() | ||
| 150 | 171 | ||
| 151 | - # Copy ctcubemask tool and execute copy | ||
| 152 | - cpy_mask = mask | 172 | + # Check that ctcubemask tool holds one observation |
| 173 | + self._check_obs(cpy_mask.obs()) | ||
| 174 | + | ||
| 175 | + # Execute copy of ctcubemask tool again, now with a higher chatter | ||
| 176 | + # level than before | ||
| 153 | cpy_mask['outcube'] = 'ctcubemask_py3.fits' | 177 | cpy_mask['outcube'] = 'ctcubemask_py3.fits' |
| 154 | cpy_mask['logfile'] = 'ctcubemask_py3.log' | 178 | cpy_mask['logfile'] = 'ctcubemask_py3.log' |
| 155 | - cpy_mask['chatter'] = 4 | 179 | + cpy_mask['chatter'] = 4 |
| 156 | cpy_mask.execute() | 180 | cpy_mask.execute() |
| 157 | 181 | ||
| 158 | # Check result file | 182 | # Check result file |
| 159 | - self._check_result_file('ctcubemask_py3.fits', events=5542) | 183 | + self._check_result_file('ctcubemask_py3.fits', events=573) |
| 160 | 184 | ||
| 161 | # Clear ctcubemask tool | 185 | # Clear ctcubemask tool |
| 162 | - mask.clear() | 186 | + cpy_mask.clear() |
| 163 | 187 | ||
| 164 | - # TODO: Do some test after clearing | 188 | + # Check that empty ctcubemask tool holds an empty observation |
| 189 | + self._check_obs(cpy_mask.obs(), nobs=0) | ||
| 190 | + | ||
| 191 | + # Prepare observation container | ||
| 192 | + obs = self._obs_mixed() | ||
| 193 | + obs.models(gammalib.GModels(self._model)) | ||
| 194 | + | ||
| 195 | + # Set-up ctcubemask from observation container, don't perform any | ||
| 196 | + # energy selection | ||
| 197 | + mask = ctools.ctcubemask(obs) | ||
| 198 | + mask['regfile'] = 'NONE' | ||
| 199 | + mask['ra'] = 83.63 | ||
| 200 | + mask['dec'] = 22.01 | ||
| 201 | + mask['rad'] = 3.0 | ||
| 202 | + mask['emin'] = 'NONE' | ||
| 203 | + mask['emax'] = 'NONE' | ||
| 204 | + mask['outcube'] = 'ctcubemask_py4.xml' | ||
| 205 | + mask['logfile'] = 'ctcubemask_py4.log' | ||
| 206 | + mask['chatter'] = 3 | ||
| 207 | + mask['debug'] = True | ||
| 208 | + | ||
| 209 | + # Execute ctcubemask tool | ||
| 210 | + mask.logFileOpen() # Make sure we get a log file | ||
| 211 | + mask.execute() | ||
| 212 | + | ||
| 213 | + # Check result file | ||
| 214 | + self._check_result_file('filtered_crab_cntmap.fits', events=5542) | ||
| 165 | 215 | ||
| 166 | # Return | 216 | # Return |
| 167 | return | 217 | return |
| @@ -180,3 +230,21 @@ class Test(test): | @@ -180,3 +230,21 @@ class Test(test): | ||
| 180 | 230 | ||
| 181 | # Return | 231 | # Return |
| 182 | return | 232 | return |
| 233 | + | ||
| 234 | + # Check observation container | ||
| 235 | + def _check_obs(self, obs, nobs=1): | ||
| 236 | + """ | ||
| 237 | + Check observation container | ||
| 238 | + | ||
| 239 | + Parameters | ||
| 240 | + ---------- | ||
| 241 | + obs : `~gammalib.GObservations` | ||
| 242 | + Observation container | ||
| 243 | + nobs : int, optional | ||
| 244 | + Expected number of observations | ||
| 245 | + """ | ||
| 246 | + # Check size of observation container | ||
| 247 | + self.test_value(obs.size(), nobs, 'Check size of observation container') | ||
| 248 | + | ||
| 249 | + # Return | ||
| 250 | + return |
test/test_ctedispcube.py
| @@ -185,6 +185,38 @@ class Test(test): | @@ -185,6 +185,38 @@ class Test(test): | ||
| 185 | # cube | 185 | # cube |
| 186 | self._check_cube(cpy_edispcube.edispcube(), nenergies=0, nmigras=0) | 186 | self._check_cube(cpy_edispcube.edispcube(), nenergies=0, nmigras=0) |
| 187 | 187 | ||
| 188 | + # Get mixed observation container | ||
| 189 | + obs = self._obs_mixed() | ||
| 190 | + | ||
| 191 | + # Set-up ctedispcube from observation container | ||
| 192 | + edispcube = ctools.ctedispcube(obs) | ||
| 193 | + edispcube['incube'] = 'NONE' | ||
| 194 | + edispcube['caldb'] = self._caldb | ||
| 195 | + edispcube['irf'] = self._irf | ||
| 196 | + edispcube['ebinalg'] = 'LOG' | ||
| 197 | + edispcube['emin'] = 0.1 | ||
| 198 | + edispcube['emax'] = 100.0 | ||
| 199 | + edispcube['enumbins'] = 20 | ||
| 200 | + edispcube['nxpix'] = 10 | ||
| 201 | + edispcube['nypix'] = 10 | ||
| 202 | + edispcube['binsz'] = 0.4 | ||
| 203 | + edispcube['coordsys'] = 'CEL' | ||
| 204 | + edispcube['proj'] = 'CAR' | ||
| 205 | + edispcube['xref'] = 83.63 | ||
| 206 | + edispcube['yref'] = 22.01 | ||
| 207 | + edispcube['migramax'] = 2.0 | ||
| 208 | + edispcube['migrabins'] = 10 | ||
| 209 | + edispcube['outcube'] = 'ctedispcube_py3.fits' | ||
| 210 | + edispcube['logfile'] = 'ctedispcube_py3.log' | ||
| 211 | + edispcube['chatter'] = 4 | ||
| 212 | + | ||
| 213 | + # Execute ctedispcube tool | ||
| 214 | + edispcube.logFileOpen() # Make sure we get a log file | ||
| 215 | + edispcube.execute() | ||
| 216 | + | ||
| 217 | + # Check result file | ||
| 218 | + self._check_result_file('ctedispcube_py3.fits') | ||
| 219 | + | ||
| 188 | # Return | 220 | # Return |
| 189 | return | 221 | return |
| 190 | 222 |
test/test_ctexpcube.py
| @@ -181,6 +181,36 @@ class Test(test): | @@ -181,6 +181,36 @@ class Test(test): | ||
| 181 | # Check that the cleared copy has also cleared the exposure cube | 181 | # Check that the cleared copy has also cleared the exposure cube |
| 182 | self._check_cube(cpy_expcube.expcube(), nenergies=0) | 182 | self._check_cube(cpy_expcube.expcube(), nenergies=0) |
| 183 | 183 | ||
| 184 | + # Get mixed observation container | ||
| 185 | + obs = self._obs_mixed() | ||
| 186 | + | ||
| 187 | + # Set-up ctexpcube from observation container | ||
| 188 | + expcube = ctools.ctexpcube(obs) | ||
| 189 | + expcube['incube'] = 'NONE' | ||
| 190 | + expcube['caldb'] = self._caldb | ||
| 191 | + expcube['irf'] = self._irf | ||
| 192 | + expcube['ebinalg'] = 'LOG' | ||
| 193 | + expcube['emin'] = 0.1 | ||
| 194 | + expcube['emax'] = 100.0 | ||
| 195 | + expcube['enumbins'] = 20 | ||
| 196 | + expcube['nxpix'] = 200 | ||
| 197 | + expcube['nypix'] = 200 | ||
| 198 | + expcube['binsz'] = 0.02 | ||
| 199 | + expcube['coordsys'] = 'CEL' | ||
| 200 | + expcube['proj'] = 'CAR' | ||
| 201 | + expcube['xref'] = 83.63 | ||
| 202 | + expcube['yref'] = 22.01 | ||
| 203 | + expcube['logfile'] = 'ctexpcube_py3.log' | ||
| 204 | + expcube['outcube'] = 'ctexpcube_py3.fits' | ||
| 205 | + expcube['chatter'] = 4 | ||
| 206 | + | ||
| 207 | + # Execute ctexpcube tool | ||
| 208 | + expcube.logFileOpen() # Needed to get a new log file | ||
| 209 | + expcube.execute() | ||
| 210 | + | ||
| 211 | + # Check result file | ||
| 212 | + self._check_result_file('ctexpcube_py3.fits') | ||
| 213 | + | ||
| 184 | # Return | 214 | # Return |
| 185 | return | 215 | return |
| 186 | 216 |
test/test_ctpsfcube.py
| @@ -131,7 +131,6 @@ class Test(test): | @@ -131,7 +131,6 @@ class Test(test): | ||
| 131 | # Now set ctpsfcube parameters | 131 | # Now set ctpsfcube parameters |
| 132 | psfcube['inobs'] = self._events | 132 | psfcube['inobs'] = self._events |
| 133 | psfcube['incube'] = 'NONE' | 133 | psfcube['incube'] = 'NONE' |
| 134 | - psfcube['outcube'] = 'ctpsfcube_py1.fits' | ||
| 135 | psfcube['caldb'] = self._caldb | 134 | psfcube['caldb'] = self._caldb |
| 136 | psfcube['irf'] = self._irf | 135 | psfcube['irf'] = self._irf |
| 137 | psfcube['ebinalg'] = 'LOG' | 136 | psfcube['ebinalg'] = 'LOG' |
| @@ -147,6 +146,7 @@ class Test(test): | @@ -147,6 +146,7 @@ class Test(test): | ||
| 147 | psfcube['yref'] = 22.01 | 146 | psfcube['yref'] = 22.01 |
| 148 | psfcube['amax'] = 0.3 | 147 | psfcube['amax'] = 0.3 |
| 149 | psfcube['anumbins'] = 10 | 148 | psfcube['anumbins'] = 10 |
| 149 | + psfcube['outcube'] = 'ctpsfcube_py1.fits' | ||
| 150 | psfcube['logfile'] = 'ctpsfcube_py1.log' | 150 | psfcube['logfile'] = 'ctpsfcube_py1.log' |
| 151 | psfcube['chatter'] = 2 | 151 | psfcube['chatter'] = 2 |
| 152 | 152 | ||
| @@ -184,6 +184,38 @@ class Test(test): | @@ -184,6 +184,38 @@ class Test(test): | ||
| 184 | # Check that the cleared copy has also cleared the PSF cube | 184 | # Check that the cleared copy has also cleared the PSF cube |
| 185 | self._check_cube(cpy_psfcube.psfcube(), nenergies=0) | 185 | self._check_cube(cpy_psfcube.psfcube(), nenergies=0) |
| 186 | 186 | ||
| 187 | + # Get mixed observation container | ||
| 188 | + obs = self._obs_mixed() | ||
| 189 | + | ||
| 190 | + # Set-up ctpsfcube from observation container | ||
| 191 | + psfcube = ctools.ctpsfcube(obs) | ||
| 192 | + psfcube['incube'] = 'NONE' | ||
| 193 | + psfcube['caldb'] = self._caldb | ||
| 194 | + psfcube['irf'] = self._irf | ||
| 195 | + psfcube['ebinalg'] = 'LOG' | ||
| 196 | + psfcube['emin'] = 0.1 | ||
| 197 | + psfcube['emax'] = 100 | ||
| 198 | + psfcube['enumbins'] = 20 | ||
| 199 | + psfcube['nxpix'] = 10 | ||
| 200 | + psfcube['nypix'] = 10 | ||
| 201 | + psfcube['binsz'] = 0.4 | ||
| 202 | + psfcube['coordsys'] = 'CEL' | ||
| 203 | + psfcube['proj'] = 'CAR' | ||
| 204 | + psfcube['xref'] = 83.63 | ||
| 205 | + psfcube['yref'] = 22.01 | ||
| 206 | + psfcube['amax'] = 0.3 | ||
| 207 | + psfcube['anumbins'] = 10 | ||
| 208 | + psfcube['outcube'] = 'ctpsfcube_py3.fits' | ||
| 209 | + psfcube['logfile'] = 'ctpsfcube_py3.log' | ||
| 210 | + psfcube['chatter'] = 4 | ||
| 211 | + | ||
| 212 | + # Execute ctpsfcube tool | ||
| 213 | + psfcube.logFileOpen() # Make sure we get a log file | ||
| 214 | + psfcube.execute() | ||
| 215 | + | ||
| 216 | + # Check result file | ||
| 217 | + self._check_result_file('ctpsfcube_py3.fits') | ||
| 218 | + | ||
| 187 | # Return | 219 | # Return |
| 188 | return | 220 | return |
| 189 | 221 |
test/testing.py.in
| @@ -97,3 +97,70 @@ class test(gammalib.GPythonTestSuite): | @@ -97,3 +97,70 @@ class test(gammalib.GPythonTestSuite): | ||
| 97 | 97 | ||
| 98 | # Return return code | 98 | # Return return code |
| 99 | return rc | 99 | return rc |
| 100 | + | ||
| 101 | + # Return observation container with 3 identical event lists | ||
| 102 | + def _obs_events(self): | ||
| 103 | + """ | ||
| 104 | + Return observation container with 3 identical event lists | ||
| 105 | + | ||
| 106 | + Returns | ||
| 107 | + ------- | ||
| 108 | + obs : `~gammalib.gammalib.GObservations` | ||
| 109 | + Observations container | ||
| 110 | + """ | ||
| 111 | + # Load CTA event list | ||
| 112 | + cta = gammalib.GCTAObservation(self._events) | ||
| 113 | + | ||
| 114 | + # Allocate observation container | ||
| 115 | + obs = gammalib.GObservations() | ||
| 116 | + | ||
| 117 | + # Append CTA observation with ID "0001" | ||
| 118 | + cta.id('0001') | ||
| 119 | + obs.append(cta) | ||
| 120 | + | ||
| 121 | + # Append CTA observation with ID "0002" | ||
| 122 | + cta.id('0002') | ||
| 123 | + obs.append(cta) | ||
| 124 | + | ||
| 125 | + # Append CTA observation with ID "0003" | ||
| 126 | + cta.id('0003') | ||
| 127 | + obs.append(cta) | ||
| 128 | + | ||
| 129 | + # Return observation container | ||
| 130 | + return obs | ||
| 131 | + | ||
| 132 | + # Return observation container with event list, counts cube and LAT | ||
| 133 | + # observation | ||
| 134 | + def _obs_mixed(self): | ||
| 135 | + """ | ||
| 136 | + Return observation container with event list, counts cube and LAT | ||
| 137 | + observation | ||
| 138 | + | ||
| 139 | + Returns | ||
| 140 | + ------- | ||
| 141 | + obs : `~gammalib.gammalib.GObservations` | ||
| 142 | + Observations container | ||
| 143 | + """ | ||
| 144 | + # Load CTA event list | ||
| 145 | + obs1 = gammalib.GCTAObservation(self._events) | ||
| 146 | + obs1.id('0001') | ||
| 147 | + | ||
| 148 | + # Load CTA counts cube | ||
| 149 | + obs2 = gammalib.GCTAObservation(self._cntcube) | ||
| 150 | + obs2.id('0002') | ||
| 151 | + | ||
| 152 | + # Create empty LAT observation | ||
| 153 | + obs3 = gammalib.GLATObservation() | ||
| 154 | + obs3.id('0001') | ||
| 155 | + obs3.events(gammalib.GLATEventList()) | ||
| 156 | + | ||
| 157 | + # Allocate observation container | ||
| 158 | + obs = gammalib.GObservations() | ||
| 159 | + | ||
| 160 | + # Append observations to container | ||
| 161 | + obs.append(obs1) | ||
| 162 | + obs.append(obs2) | ||
| 163 | + obs.append(obs3) | ||
| 164 | + | ||
| 165 | + # Return observation container | ||
| 166 | + return obs |