Commit 76afa729ffd96927d239cf699dce53d4fa17b95e

Authored by Jürgen Knödlseder
1 parent ce48d505

Enhance ctools unit tests

src/ctbkgcube/ctbkgcube.cpp
... ... @@ -488,6 +488,12 @@ void ctbkgcube::get_parameters(void)
488 488  
489 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 497 // Get the incube filename
492 498 std::string incube = (*this)["incube"].filename();
493 499  
... ...
src/ctbutterfly/ctbutterfly.cpp
... ... @@ -573,9 +573,8 @@ void ctbutterfly::free_members(void)
573 573 /***********************************************************************//**
574 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 579 * Get all task parameters from parameter file or (if required) by querying
581 580 * the user. Most parameters are only required if no observation exists so
... ... @@ -597,6 +596,11 @@ void ctbutterfly::get_parameters(void)
597 596  
598 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 605 // If there is are no models associated with the observations then
602 606 // load now the model definition
... ...
src/ctcubemask/ctcubemask.cpp
... ... @@ -301,7 +301,7 @@ void ctcubemask::save(void)
301 301 // Get counts cube filename
302 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 305 if (m_use_xml) {
306 306  
307 307 // Get prefix
... ... @@ -311,7 +311,7 @@ void ctcubemask::save(void)
311 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 315 else {
316 316 save_fits();
317 317 }
... ... @@ -404,9 +404,9 @@ void ctcubemask::init_members(void)
404 404 void ctcubemask::copy_members(const ctcubemask& app)
405 405 {
406 406 // Copy parameters
407   - m_regfile = app.m_regfile;
  407 + m_regfile = app.m_regfile;
408 408 m_outcube = app.m_outcube;
409   - m_prefix = app.m_prefix;
  409 + m_prefix = app.m_prefix;
410 410 m_usepnt = app.m_usepnt;
411 411 m_ra = app.m_ra;
412 412 m_dec = app.m_dec;
... ... @@ -471,7 +471,7 @@ void ctcubemask::get_parameters(void)
471 471 } // endif: there was no observation in the container
472 472  
473 473 // Get parameters
474   - m_regfile = (*this)["regfile"].filename();
  474 + m_regfile = (*this)["regfile"].filename();
475 475 m_usepnt = (*this)["usepnt"].boolean();
476 476 if (!m_usepnt) {
477 477  
... ... @@ -725,18 +725,23 @@ std::string ctcubemask::set_outfile_name(const std::string& filename) const
725 725 ***************************************************************************/
726 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 731 // Get CTA observation from observation container
732 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 747 // Return
... ... @@ -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 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 763 void ctcubemask::save_xml(void)
759 764 {
760 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 768 // Loop over all observation in the container
774 769 for (int i = 0; i < m_obs.size(); ++i) {
... ... @@ -788,8 +783,8 @@ void ctcubemask::save_xml(void)
788 783 // Log counts cube file name
789 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 789 } // endif: observation was a CTA observations
795 790  
... ... @@ -801,30 +796,3 @@ void ctcubemask::save_xml(void)
801 796 // Return
802 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 36  
37 37 /* __Definitions _________________________________________________________ */
38 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 75 std::string set_outfile_name(const std::string& filename) const;
76 76 void save_fits(void);
77 77 void save_xml(void);
78   - void save_counts_map(const GCTAObservation* obs,
79   - const std::string& outfile) const;
80 78  
81 79 // User parameters
82 80 GFilename m_regfile; //!< ds9 region file
... ...
src/ctedispcube/ctedispcube.cpp
... ... @@ -361,6 +361,12 @@ void ctedispcube::get_parameters(void)
361 361  
362 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 370 // Get the incube filename
365 371 std::string incube = (*this)["incube"].filename();
366 372  
... ...
src/cterror/cterror.cpp
... ... @@ -475,6 +475,11 @@ void cterror::get_parameters(void)
475 475  
476 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 484 // If there are no models associated with the observations then
480 485 // load now the model definition
... ...
src/ctexpcube/ctexpcube.cpp
... ... @@ -386,6 +386,12 @@ void ctexpcube::get_parameters(void)
386 386  
387 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 395 // Get the incube filename
390 396 std::string incube = (*this)["incube"].filename();
391 397  
... ...
src/ctlike/ctlike.cpp
... ... @@ -373,6 +373,12 @@ void ctlike::get_parameters(void)
373 373  
374 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 382 // If only single observation is used, read statistics parameter
377 383 if (!m_use_xml) {
378 384  
... ...
src/ctmodel/ctmodel.cpp
... ... @@ -456,6 +456,12 @@ void ctmodel::get_parameters(void)
456 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 465 // If we have now excactly one CTA observation (but no cube has yet been
460 466 // appended to the observation) then check whether this observation
461 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 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 566 else {
566   - set_obs_bounds(m_obs);
  567 + setup_observations(m_obs);
567 568 }
568 569  
569 570 // Read model definition file if required
... ...
src/ctpsfcube/ctpsfcube.cpp
... ... @@ -346,6 +346,12 @@ void ctpsfcube::get_parameters(void)
346 346  
347 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 355 // Get the incube filename
350 356 std::string incube = (*this)["incube"].filename();
351 357  
... ...
src/cttsmap/cttsmap.cpp
... ... @@ -523,6 +523,12 @@ void cttsmap::get_parameters(void)
523 523  
524 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 532 // If there is are no models associated with the observations then
527 533 // load now the model definition
528 534 if (m_obs.models().size() == 0) {
... ...
src/ctulimit/ctulimit.cpp
... ... @@ -481,6 +481,11 @@ void ctulimit::get_parameters(void)
481 481  
482 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 490 // If there is are no models associated with the observations then
486 491 // load now the model definition
... ...
src/support/ctool.cpp
... ... @@ -1646,7 +1646,7 @@ std::string ctool::warn_xml_suffix(const GFilename&amp; filename) const
1646 1646  
1647 1647 // Warn if there are not enough energy bins
1648 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 1650 "\""+filename+"\" does not terminate with \".xml\"."
1651 1651 "\n This is not an error, but may be misleading. "
1652 1652 "It is recommended to use the suffix"
... ...
test/test_ctbin.py
... ... @@ -194,15 +194,9 @@ class Test(test):
194 194 self.test_value(bin.cube().size(), 0,
195 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 201 # Set-up ctbin using an observation container
208 202 bin = ctools.ctbin(obs)
... ...
test/test_ctbkgcube.py
... ... @@ -213,18 +213,8 @@ class Test(test):
213 213 self._check_cube(cpy_bkgcube.bkgcube(), nenergies=0)
214 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 218 obs.models(gammalib.GModels(self._model))
229 219  
230 220 # Set-up ctbkgcube from observation container
... ...
test/test_ctcubemask.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
... ... @@ -106,8 +107,24 @@ class Test(test):
106 107 """
107 108 Test ctcubemask from Python
108 109 """
109   - # Set-up ctcubemask
  110 + # Allocate ctcubemask
110 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 128 mask['inobs'] = self._cntcube
112 129 mask['regfile'] = self._exclusion
113 130 mask['ra'] = 83.63
... ... @@ -127,14 +144,15 @@ class Test(test):
127 144 # Check result file
128 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 149 mask = ctools.ctcubemask()
132 150 mask['inobs'] = self._cntcube
133 151 mask['regfile'] = 'NONE'
134 152 mask['ra'] = 83.63
135 153 mask['dec'] = 22.01
136 154 mask['rad'] = 3.0
137   - mask['emin'] = 0.1
  155 + mask['emin'] = 1.0
138 156 mask['emax'] = 100.0
139 157 mask['outcube'] = 'ctcubemask_py2.fits'
140 158 mask['logfile'] = 'ctcubemask_py2.log'
... ... @@ -146,22 +164,54 @@ class Test(test):
146 164 mask.execute()
147 165  
148 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 177 cpy_mask['outcube'] = 'ctcubemask_py3.fits'
154 178 cpy_mask['logfile'] = 'ctcubemask_py3.log'
155   - cpy_mask['chatter'] = 4
  179 + cpy_mask['chatter'] = 4
156 180 cpy_mask.execute()
157 181  
158 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 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 216 # Return
167 217 return
... ... @@ -180,3 +230,21 @@ class Test(test):
180 230  
181 231 # Return
182 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 185 # cube
186 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 220 # Return
189 221 return
190 222  
... ...
test/test_ctexpcube.py
... ... @@ -181,6 +181,36 @@ class Test(test):
181 181 # Check that the cleared copy has also cleared the exposure cube
182 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 214 # Return
185 215 return
186 216  
... ...
test/test_ctpsfcube.py
... ... @@ -131,7 +131,6 @@ class Test(test):
131 131 # Now set ctpsfcube parameters
132 132 psfcube['inobs'] = self._events
133 133 psfcube['incube'] = 'NONE'
134   - psfcube['outcube'] = 'ctpsfcube_py1.fits'
135 134 psfcube['caldb'] = self._caldb
136 135 psfcube['irf'] = self._irf
137 136 psfcube['ebinalg'] = 'LOG'
... ... @@ -147,6 +146,7 @@ class Test(test):
147 146 psfcube['yref'] = 22.01
148 147 psfcube['amax'] = 0.3
149 148 psfcube['anumbins'] = 10
  149 + psfcube['outcube'] = 'ctpsfcube_py1.fits'
150 150 psfcube['logfile'] = 'ctpsfcube_py1.log'
151 151 psfcube['chatter'] = 2
152 152  
... ... @@ -184,6 +184,38 @@ class Test(test):
184 184 # Check that the cleared copy has also cleared the PSF cube
185 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 219 # Return
188 220 return
189 221  
... ...
test/testing.py.in
... ... @@ -97,3 +97,70 @@ class test(gammalib.GPythonTestSuite):
97 97  
98 98 # Return return code
99 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
... ...