Commit f4dea160d94e5dd516edb3db9f610ee011a39c29
Merge branch 'integration' into devel
Showing
8 changed files
with
88 additions
and
7 deletions
ChangeLog
| 1 | -2018-09-22 | |
| 1 | +2018-10-17 | |
| 2 | 2 | |
| 3 | 3 | * Version 1.6.0 released |
| 4 | 4 | ======================== |
| 5 | 5 | |
| 6 | + Compute DETX and DETY in ctmodel if they are not available (#2694) | |
| 6 | 7 | Do no longer set missing boundaries in ctool::get_observations and |
| 7 | 8 | ctool::setup_observations (#2686) |
| 8 | 9 | Unnormalize background cube values in ctbkgcube (#2685) | ... | ... |
NEWS
| 1 | 1 | New Features and Important Changes in ctools 1.6.0 |
| 2 | 2 | |
| 3 | -22 September 2018 | |
| 3 | +17 October 2018 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | Introduction |
| ... | ... | @@ -112,6 +112,10 @@ None |
| 112 | 112 | |
| 113 | 113 | ctmodel - CTA counts cube modelling |
| 114 | 114 | ----------------------------------- |
| 115 | +The tools now computes DETX and DETY for every event bin if they are not | |
| 116 | +available so that model that rely on the existence of these parameters can | |
| 117 | +be handled (#2694). | |
| 118 | + | |
| 115 | 119 | Add hidden "nthreads" parameter to control parallel computations (#2421). |
| 116 | 120 | |
| 117 | 121 | ... | ... |
cscripts/csresmap.py
| ... | ... | @@ -285,6 +285,18 @@ class csresmap(ctools.csobservation): |
| 285 | 285 | # Return |
| 286 | 286 | return |
| 287 | 287 | |
| 288 | + def resmap(self): | |
| 289 | + """ | |
| 290 | + Return residual map | |
| 291 | + | |
| 292 | + Returns | |
| 293 | + ------- | |
| 294 | + map : `~gammalib.GSkyMap' | |
| 295 | + Residual sky map | |
| 296 | + """ | |
| 297 | + # Return | |
| 298 | + return self._resmap | |
| 299 | + | |
| 288 | 300 | |
| 289 | 301 | # ======================== # |
| 290 | 302 | # Main routine entry point # | ... | ... |
cscripts/csresspec.py
| ... | ... | @@ -703,6 +703,18 @@ class csresspec(ctools.csobservation): |
| 703 | 703 | # Return |
| 704 | 704 | return |
| 705 | 705 | |
| 706 | + def resspec(self): | |
| 707 | + """ | |
| 708 | + Return residual FITS file | |
| 709 | + | |
| 710 | + Returns | |
| 711 | + ------- | |
| 712 | + fits : `~gammalib.GFits' | |
| 713 | + FITS file containing residuals | |
| 714 | + """ | |
| 715 | + # Return | |
| 716 | + return self._fits | |
| 717 | + | |
| 706 | 718 | |
| 707 | 719 | # ======================== # |
| 708 | 720 | # Main routine entry point # | ... | ... |
doc/source/admin/release_history/1.6.rst
| ... | ... | @@ -19,6 +19,8 @@ In particular, this release provides: |
| 19 | 19 | Bug fixes |
| 20 | 20 | --------- |
| 21 | 21 | |
| 22 | +* [`2694 <https://cta-redmine.irap.omp.eu/issues/2694>`_] - | |
| 23 | + Compute ``DETX`` and ``DETY`` in :ref:`ctmodel` if they are not available | |
| 22 | 24 | * [`2686 <https://cta-redmine.irap.omp.eu/issues/2686>`_] - |
| 23 | 25 | Do no longer set missing boundaries in ``ctool::get_observations`` and |
| 24 | 26 | ``ctool::setup_observations`` | ... | ... |
src/ctmodel/ctmodel.cpp
| ... | ... | @@ -852,6 +852,10 @@ void ctmodel::fill_cube(const GCTAObservation* obs, GModels& models) |
| 852 | 852 | int npix = m_cube.npix(); |
| 853 | 853 | int nebins = m_cube.ebins(); |
| 854 | 854 | |
| 855 | + // Get reference to the pointing for DETX and DETY computation, if | |
| 856 | + // required | |
| 857 | + const GCTAPointing& pnt = obs->pointing(); | |
| 858 | + | |
| 855 | 859 | // Get references to GTI and energy boundaries for the event list |
| 856 | 860 | const GGti& gti = obs->events()->gti(); |
| 857 | 861 | const GEbounds& obs_ebounds = obs->ebounds(); |
| ... | ... | @@ -898,8 +902,15 @@ void ctmodel::fill_cube(const GCTAObservation* obs, GModels& models) |
| 898 | 902 | continue; |
| 899 | 903 | } |
| 900 | 904 | |
| 905 | + // Get instrument direction for spatial pixel. Compute DETX and DETY | |
| 906 | + // if they are not provided | |
| 907 | + GCTAInstDir dir = m_dir[i]; | |
| 908 | + if (!dir.has_detx() || !dir.has_dety()) { | |
| 909 | + dir = pnt.instdir(dir.dir()); | |
| 910 | + } | |
| 911 | + | |
| 901 | 912 | // Set instrument direction, solid angle and pixel index of bin |
| 902 | - bin.dir(m_dir[i]); | |
| 913 | + bin.dir(dir); | |
| 903 | 914 | bin.solidangle(m_solidangle[i]); |
| 904 | 915 | bin.ipix(i); |
| 905 | 916 | ... | ... |
src/ctselect/ctselect.cpp
| ... | ... | @@ -1066,8 +1066,9 @@ void ctselect::select_events(GCTAObservation* obs, |
| 1066 | 1066 | // If RoI selection has been applied without forcing then set the event |
| 1067 | 1067 | // list RoI |
| 1068 | 1068 | if (select_roi && !enforced_roi) { |
| 1069 | - GCTAInstDir instdir; | |
| 1070 | - instdir.dir().radec_deg(ra, dec); | |
| 1069 | + GSkyDir skydir; | |
| 1070 | + skydir.radec_deg(ra, dec); | |
| 1071 | + GCTAInstDir instdir(skydir); | |
| 1071 | 1072 | list->roi(GCTARoi(instdir, rad)); |
| 1072 | 1073 | } |
| 1073 | 1074 | ... | ... |
test/test_obsutils.py
| ... | ... | @@ -255,7 +255,7 @@ class Test(test): |
| 255 | 255 | obs.append(run) |
| 256 | 256 | obs.models(gammalib.GModels(self._model)) |
| 257 | 257 | |
| 258 | - # Simulate stacked observations | |
| 258 | + # Simulate On/Off observations | |
| 259 | 259 | res = obsutils.sim(obs, onsrc='Crab', nbins=5) |
| 260 | 260 | |
| 261 | 261 | # Check simulation results |
| ... | ... | @@ -263,6 +263,8 @@ class Test(test): |
| 263 | 263 | self.test_value(res.models().size(), 2, 'Check number of models') |
| 264 | 264 | self.test_value(res.nobserved(), 46, 'Check number of observed events') |
| 265 | 265 | self.test_value(res.npred(), 0.0, 'Check number of predicted events') |
| 266 | + | |
| 267 | + # Check results of first observation | |
| 266 | 268 | self.test_value(res[0].on_spec().ebounds().emin().TeV(), 1.0, |
| 267 | 269 | 'Check minimum energy of On spectrum') |
| 268 | 270 | self.test_value(res[0].on_spec().ebounds().emax().TeV(), 10.0, |
| ... | ... | @@ -277,7 +279,7 @@ class Test(test): |
| 277 | 279 | 'Check maximum energy of Off spectrum') |
| 278 | 280 | self.test_value(res[0].off_spec().ebounds().size(), 5, |
| 279 | 281 | 'Check number of energy bins of Off spectrum') |
| 280 | - self.test_value(res[0].off_spec().counts(), 2, | |
| 282 | + self.test_value(res[0].off_spec().counts(), 1, | |
| 281 | 283 | 'Check number of events in of Off spectrum') |
| 282 | 284 | self.test_value(res[0].arf().ebounds().emin().TeV(), 0.5, |
| 283 | 285 | 'Check minimum energy of ARF') |
| ... | ... | @@ -298,6 +300,42 @@ class Test(test): |
| 298 | 300 | self.test_value(res[0].rmf().emeasured().size(), 5, |
| 299 | 301 | 'Check number of reconstructed energy bins of RMF') |
| 300 | 302 | |
| 303 | + # Check results of second observation | |
| 304 | + self.test_value(res[1].on_spec().ebounds().emin().TeV(), 1.0, | |
| 305 | + 'Check minimum energy of On spectrum') | |
| 306 | + self.test_value(res[1].on_spec().ebounds().emax().TeV(), 10.0, | |
| 307 | + 'Check maximum energy of On spectrum') | |
| 308 | + self.test_value(res[1].on_spec().ebounds().size(), 5, | |
| 309 | + 'Check number of energy bins of On spectrum') | |
| 310 | + self.test_value(res[1].on_spec().counts(), 22, | |
| 311 | + 'Check number of events in of On spectrum') | |
| 312 | + self.test_value(res[1].off_spec().ebounds().emin().TeV(), 1.0, | |
| 313 | + 'Check minimum energy of Off spectrum') | |
| 314 | + self.test_value(res[1].off_spec().ebounds().emax().TeV(), 10.0, | |
| 315 | + 'Check maximum energy of Off spectrum') | |
| 316 | + self.test_value(res[1].off_spec().ebounds().size(), 5, | |
| 317 | + 'Check number of energy bins of Off spectrum') | |
| 318 | + self.test_value(res[1].off_spec().counts(), 0, | |
| 319 | + 'Check number of events in of Off spectrum') | |
| 320 | + self.test_value(res[1].arf().ebounds().emin().TeV(), 0.5, | |
| 321 | + 'Check minimum energy of ARF') | |
| 322 | + self.test_value(res[1].arf().ebounds().emax().TeV(), 12.0, | |
| 323 | + 'Check maximum energy of ARF') | |
| 324 | + self.test_value(res[1].arf().ebounds().size(), 41, | |
| 325 | + 'Check number of energy bins of ARF') | |
| 326 | + self.test_value(res[1].rmf().etrue().emin().TeV(), 0.5, | |
| 327 | + 'Check minimum true energy of RMF') | |
| 328 | + self.test_value(res[1].rmf().etrue().emax().TeV(), 12.0, | |
| 329 | + 'Check maximum true energy of RMF') | |
| 330 | + self.test_value(res[1].rmf().etrue().size(), 41, | |
| 331 | + 'Check number of true energy bins of RMF') | |
| 332 | + self.test_value(res[1].rmf().emeasured().emin().TeV(), 1.0, | |
| 333 | + 'Check minimum reconstructed energy of RMF') | |
| 334 | + self.test_value(res[1].rmf().emeasured().emax().TeV(), 10.0, | |
| 335 | + 'Check maximum reconstructed energy of RMF') | |
| 336 | + self.test_value(res[1].rmf().emeasured().size(), 5, | |
| 337 | + 'Check number of reconstructed energy bins of RMF') | |
| 338 | + | |
| 301 | 339 | # Return |
| 302 | 340 | return |
| 303 | 341 | ... | ... |