Commit 65b8bf7b08ae0a27dd66c3c00cf6ab705d961a50

Authored by Jürgen Knödlseder
1 parent d30d1e5d

Implement gammalib.test() function to Python unit testing.

inst/cta/test/caldb/prod1_gauss.fits 0 → 100644
No preview for this file type
inst/cta/test/caldb/prod1_king.fits 0 → 100644
No preview for this file type
inst/cta/test/test_CTA.py
1 1 # ==========================================================================
2 2 # This module performs unit tests for the GammaLib CTA module.
3 3 #
4   -# Copyright (C) 2012-2014 Juergen Knoedlseder
  4 +# Copyright (C) 2012-2015 Juergen Knoedlseder
5 5 #
6 6 # This program is free software: you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
... ... @@ -17,15 +17,15 @@
17 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18 #
19 19 # ==========================================================================
20   -from gammalib import *
21   -from math import *
  20 +import gammalib
22 21 import os
  22 +import math
23 23  
24 24  
25 25 # ================================== #
26 26 # Test class for GammaLib CTA module #
27 27 # ================================== #
28   -class Test(GPythonTestSuite):
  28 +class Test(gammalib.GPythonTestSuite):
29 29 """
30 30 Test class for GammaLib CTA module.
31 31 """
... ... @@ -35,7 +35,21 @@ class Test(GPythonTestSuite):
35 35 Constructor.
36 36 """
37 37 # Call base class constructor
38   - GPythonTestSuite.__init__(self)
  38 + gammalib.GPythonTestSuite.__init__(self)
  39 +
  40 + # Initialise CALDB
  41 + self.caldb = "../inst/cta/test/caldb"
  42 +
  43 + # Return
  44 + return
  45 +
  46 + # Define CALDB
  47 + def caldb_path(self, path):
  48 + """
  49 + Set path to calibration database for test.
  50 + """
  51 + # Set path
  52 + self.caldb = path
39 53  
40 54 # Return
41 55 return
... ... @@ -66,10 +80,8 @@ class Test(GPythonTestSuite):
66 80 # Load 2D Aeff
67 81 self.test_try("Test GCTAAeff2D file constructor")
68 82 try:
69   - db = GCaldb("../inst/cta/caldb")
70   - db.open("cta", "e")
71   - filename = db.filename("","","EFF_AREA","","","NAME(IFAE20120510_50h)")
72   - aeff = GCTAAeff2D(filename)
  83 + filename = self.caldb + "/prod1_gauss.fits"
  84 + aeff = gammalib.GCTAAeff2D(filename)
73 85 self.test_try_success()
74 86 except:
75 87 self.test_try_failure("Unable to allocate GCTAAeff2D from file.")
... ... @@ -83,8 +95,8 @@ class Test(GPythonTestSuite):
83 95 # Load performance file
84 96 self.test_try("Test GCTAAeffPerfTable file constructor")
85 97 try:
86   - filename = "../inst/cta/caldb/cta_dummy_irf.dat"
87   - aeff = GCTAAeffPerfTable(filename)
  98 + filename = self.caldb + "/cta_dummy_irf.dat"
  99 + aeff = gammalib.GCTAAeffPerfTable(filename)
88 100 self.test_try_success()
89 101 except:
90 102 self.test_try_failure("Unable to allocate GCTAAeffPerfTable from file.")
... ... @@ -98,8 +110,8 @@ class Test(GPythonTestSuite):
98 110 # Load 1DC ARF response file
99 111 self.test_try("Test GCTAAeffArf file constructor")
100 112 try:
101   - filename = "../inst/cta/test/caldb/dc1/arf.fits"
102   - aeff = GCTAAeffArf(filename)
  113 + filename = self.caldb + "/dc1/arf.fits"
  114 + aeff = gammalib.GCTAAeffArf(filename)
103 115 self.test_try_success()
104 116 except:
105 117 self.test_try_failure("Unable to allocate GCTAAeffArf from file.")
... ... @@ -121,21 +133,13 @@ class Test(GPythonTestSuite):
121 133 # Load 2D PSF
122 134 self.test_try("Test GCTAPsf2D file constructor")
123 135 try:
124   - db = GCaldb("../inst/cta/caldb")
125   - db.open("cta", "e")
126   - filename = db.filename("","","RPSF","","","NAME(IFAE20120510_50h)")
127   - psf = GCTAPsf2D(filename)
  136 + filename = self.caldb + "/prod1_gauss.fits"
  137 + psf = gammalib.GCTAPsf2D(filename)
128 138 self.test_try_success()
129 139 except:
130 140 self.test_try_failure("Unable to allocate GCTAPsf2D from file.")
131 141  
132 142 # Test PSF values
133   - #self.test_value(psf(0.0, 0.0, 0.0), 71870.069895, 1.0e-6)
134   - #self.test_value(psf(0.001, 0.0, 0.0), 57344.19598, 1.0e-6)
135   - #self.test_value(psf(0.0, 1.0, 0.0), 270343.322467, 1.0e-6)
136   - #self.test_value(psf(0.001, 1.0, 0.0), 115627.748759, 1.0e-6)
137   - #self.test_value(psf(0.0, 1.0, 0.01745), 190115.060762, 1.0e-6)
138   - #self.test_value(psf(0.001, 1.0, 0.01745), 104622.655773, 1.0e-6)
139 143 self.test_value(psf(0.0, 0.0, 0.0), 163782.469465, 1.0e-6)
140 144 self.test_value(psf(0.001, 0.0, 0.0), 97904.9307797, 1.0e-6)
141 145 self.test_value(psf(0.0, 1.0, 0.0), 616076.98558, 1.0e-6)
... ... @@ -143,14 +147,11 @@ class Test(GPythonTestSuite):
143 147 self.test_value(psf(0.0, 1.0, 0.01745), 433247.309504, 1.0e-6)
144 148 self.test_value(psf(0.001, 1.0, 0.01745), 111075.0692681, 1.0e-6)
145 149  
146   -
147 150 # Load King profile PSF
148 151 self.test_try("Test GCTAPsfKing file constructor")
149 152 try:
150   - db = GCaldb("../inst/cta/caldb")
151   - db.open("cta", "e")
152   - filename = db.filename("","","RPSF","","","NAME(IFAE20120510_50h_King)")
153   - psf = GCTAPsfKing(filename)
  153 + filename = self.caldb + "/prod1_king.fits"
  154 + psf = gammalib.GCTAPsfKing(filename)
154 155 self.test_try_success()
155 156 except:
156 157 self.test_try_failure("Unable to allocate GCTAPsfKing from file.")
... ... @@ -166,8 +167,8 @@ class Test(GPythonTestSuite):
166 167 # Load performance file
167 168 self.test_try("Test GCTAPsfPerfTable file constructor")
168 169 try:
169   - filename = "../inst/cta/caldb/cta_dummy_irf.dat"
170   - psf = GCTAPsfPerfTable(filename)
  170 + filename = self.caldb + "/cta_dummy_irf.dat"
  171 + psf = gammalib.GCTAPsfPerfTable(filename)
171 172 self.test_try_success()
172 173 except:
173 174 self.test_try_failure("Unable to allocate GCTAPsfPerfTable from file.")
... ... @@ -183,8 +184,8 @@ class Test(GPythonTestSuite):
183 184 # Load 1DC PSF file
184 185 self.test_try("Test GCTAPsfVector file constructor")
185 186 try:
186   - filename = "../inst/cta/test/caldb/dc1/psf_magic.fits"
187   - psf = GCTAPsfVector(filename)
  187 + filename = self.caldb + "/dc1/psf_magic.fits"
  188 + psf = gammalib.GCTAPsfVector(filename)
188 189 self.test_try_success()
189 190 except:
190 191 self.test_try_failure("Unable to allocate GCTAPsfVector from file.")
... ... @@ -200,7 +201,7 @@ class Test(GPythonTestSuite):
200 201 # Return
201 202 return
202 203  
203   - # Test point spread function response
  204 + # Test energy dispersion
204 205 def test_edisp(self):
205 206 """
206 207 Test GCTAEdisp classes.
... ... @@ -208,20 +209,21 @@ class Test(GPythonTestSuite):
208 209 # Load RMF file
209 210 self.test_try("Test GCTAEdispRmf file constructor")
210 211 try:
211   - edisp = GCTAEdispRmf("../inst/cta/test/caldb/dc1/rmf.fits")
  212 + filename = self.caldb + "/dc1/rmf.fits"
  213 + edisp = gammalib.GCTAEdispRmf(filename)
212 214 self.test_try_success()
213 215 except:
214 216 self.test_try_failure("Unable to allocate GCTAEdispRmf from file.")
215 217  
216 218 # Test energy dispersion values
217   - self.test_value(edisp(log10(30),log10(1)), 0.0, 1.0e-9)
218   - #self.test_value(edisp(log10(30),log10(30)), 0.354952753, 1.0e-9)
219   - self.test_value(edisp(log10(1),log10(30)), 0.0, 1.0e-9)
  219 + self.test_value(edisp(math.log10(30),math.log10(1)), 0.0, 1.0e-9)
  220 + self.test_value(edisp(math.log10(1),math.log10(30)), 0.0, 1.0e-9)
220 221  
221 222 # Load performance file
222 223 self.test_try("Test GCTAEdispPerfTable file constructor")
223 224 try:
224   - edisp = GCTAEdispPerfTable("../inst/cta/test/caldb/cta_dummy_irf.dat")
  225 + filename = self.caldb + "/cta_dummy_irf.dat"
  226 + edisp = gammalib.GCTAEdispPerfTable(filename)
225 227 self.test_try_success()
226 228 except:
227 229 self.test_try_failure("Unable to allocate GCTAEdispPerfTable from file.")
... ... @@ -237,15 +239,17 @@ class Test(GPythonTestSuite):
237 239 # Load response
238 240 self.test_try("Test GCTAResponseIrf file constructor")
239 241 try:
240   - rsp = GCTAResponseIrf("cta_dummy_irf", GCaldb("../inst/cta/test/caldb"))
  242 + db = gammalib.GCaldb(self.caldb)
  243 + irf = "cta_dummy_irf"
  244 + rsp = gammalib.GCTAResponseIrf(irf, db)
241 245 self.test_try_success()
242 246 except:
243 247 self.test_try_failure("Unable to allocate GCTAResponseIrf from file.")
244 248  
245 249 # Test nedisp computations
246   - #dir = GSkyDir()
247   - #pnt = GCTAPointing()
248   - #time = GTime()
  250 + #dir = gammalib.GSkyDir()
  251 + #pnt = gammalib.GCTAPointing()
  252 + #time = gammalib.GTime()
249 253 #self.test_value(rsp.nedisp(dir, GEnergy(3.7, "TeV"), time, pnt,
250 254 # GEbounds(GEnergy(0.1, "TeV"),
251 255 # GEnergy(10.0, "TeV"))),
... ... @@ -267,7 +271,8 @@ class Test(GPythonTestSuite):
267 271 # Load 1DC CTA observation (ARF, PSF, RMF)
268 272 self.test_try("Test 1DC responses")
269 273 try:
270   - obs = GObservations("../inst/cta/test/data/irf_1dc.xml")
  274 + filname = self.caldb + "/../data/irf_1dc.xml"
  275 + obs = gammalib.GObservations(filname)
271 276 self.test_try_success()
272 277 except:
273 278 self.test_try_failure("Unable to load 1DC responses.")
... ... @@ -275,31 +280,31 @@ class Test(GPythonTestSuite):
275 280 # Return
276 281 return
277 282  
278   -
279 283 # Test ON/OFF analysis
280 284 def test_onoff(self):
281 285 """
282 286 Test ON/OFF analysis.
283 287 """
284 288 # Create ON region
285   - crab = GSkyDir()
  289 + crab = gammalib.GSkyDir()
286 290 crab.radec_deg(83.6331, 22.0145)
287   - on = GSkyRegions()
288   - on.append(GSkyRegionCircle(crab, 1.0))
  291 + on = gammalib.GSkyRegions()
  292 + on.append(gammalib.GSkyRegionCircle(crab, 1.0))
289 293  
290 294 # Create OFF region
291 295 off = on
292 296  
293 297 # Set energy binning
294   - etrue = GEbounds(10, GEnergy(0.1, "TeV"), GEnergy(10.0, "TeV"))
295   - ereco = GEbounds(10, GEnergy(0.1, "TeV"), GEnergy(10.0, "TeV"))
  298 + etrue = gammalib.GEbounds(10, gammalib.GEnergy(0.1, "TeV"), gammalib.GEnergy(10.0, "TeV"))
  299 + ereco = gammalib.GEbounds(10, gammalib.GEnergy(0.1, "TeV"), gammalib.GEnergy(10.0, "TeV"))
296 300  
297 301 # Create ON/OFF observations by filling all events found in
298 302 # the observation container and computing the response
299   - obs = GObservations("../inst/cta/test/data/irf_unbinned.xml")
300   - onoffs = GCTAOnOffObservations()
  303 + filename = self.caldb + "/../data/irf_unbinned.xml"
  304 + obs = gammalib.GObservations(filename)
  305 + onoffs = gammalib.GCTAOnOffObservations()
301 306 for run in obs:
302   - onoff = GCTAOnOffObservation(ereco, on, off)
  307 + onoff = gammalib.GCTAOnOffObservation(ereco, on, off)
303 308 onoff.fill(run)
304 309 onoff.compute_response(run, etrue)
305 310 onoffs.append(onoff)
... ...
pyext/Makefile.am
... ... @@ -32,21 +32,73 @@ if WITH_PYTHON
32 32 # Set instrument specific SWIG targets
33 33 if WITH_INST_MWL
34 34 MWL_SWIG_TARGETS = gammalib/mwl_wrap.cpp gammalib/mwl.py
  35 + MWL_TESTS = $(abs_top_srcdir)/inst/mwl/test/test_MWL.py
35 36 endif
36 37 if WITH_INST_CTA
37 38 CTA_SWIG_TARGETS = gammalib/cta_wrap.cpp gammalib/cta.py
  39 + CTA_TESTS = $(abs_top_srcdir)/inst/cta/test/test_CTA.py
38 40 endif
39 41 if WITH_INST_LAT
40 42 LAT_SWIG_TARGETS = gammalib/lat_wrap.cpp gammalib/lat.py
  43 + LAT_TESTS = $(abs_top_srcdir)/inst/lat/test/test_LAT.py
41 44 endif
42 45 if WITH_INST_COM
43 46 COM_SWIG_TARGETS = gammalib/com_wrap.cpp gammalib/com.py
  47 + COM_TESTS = $(abs_top_srcdir)/inst/com/test/test_COM.py
44 48 endif
45 49 INST_SWIG_TARGETS = $(MWL_SWIG_TARGETS) \
46 50 $(CTA_SWIG_TARGETS) \
47 51 $(LAT_SWIG_TARGETS) \
48 52 $(COM_SWIG_TARGETS)
49 53  
  54 +# Test scripts to be distributed in $(pyexecdir)/ctools/tests
  55 +testscripts = gammalib/tests/__init__.py \
  56 + $(abs_top_srcdir)/test/test_python.py \
  57 + $(abs_top_srcdir)/test/test_GApplication.py \
  58 + $(abs_top_srcdir)/test/test_GFits.py \
  59 + $(abs_top_srcdir)/test/test_GLinalg.py \
  60 + $(abs_top_srcdir)/test/test_GModel.py \
  61 + $(abs_top_srcdir)/test/test_GNumerics.py \
  62 + $(abs_top_srcdir)/test/test_GObservation.py \
  63 + $(abs_top_srcdir)/test/test_GOptimizer.py \
  64 + $(abs_top_srcdir)/test/test_GSky.py \
  65 + $(abs_top_srcdir)/test/test_GSupport.py \
  66 + $(abs_top_srcdir)/test/test_GTest.py \
  67 + $(abs_top_srcdir)/test/test_GVO.py \
  68 + $(abs_top_srcdir)/test/test_GXml.py \
  69 + $(abs_top_srcdir)/test/test_GXspec.py \
  70 + $(MWL_TESTS) $(CTA_TESTS) $(LAT_TESTS) $(COM_TESTS)
  71 +testdata = $(abs_top_srcdir)/test/data/initial_coords.txt \
  72 + $(abs_top_srcdir)/test/data/fk5_to_galactic.txt
  73 +
  74 +# Distribute scripts
  75 +EXTRA_DIST = $(testscripts) $(testdata)
  76 +testscriptsdir = $(pyexecdir)/gammalib/tests
  77 +testscripts_DATA = $(testscripts)
  78 +testdatadir = $(pyexecdir)/gammalib/tests/data
  79 +testdata_DATA = $(testdata)
  80 +
  81 +# Distribute test data
  82 +if WITH_INST_CTA
  83 + testdatacta = $(abs_top_srcdir)/inst/cta/test/data/irf_1dc.xml \
  84 + $(abs_top_srcdir)/inst/cta/test/data/irf_unbinned.xml \
  85 + $(abs_top_srcdir)/inst/cta/test/data/crab_events.fits.gz \
  86 + $(abs_top_srcdir)/inst/cta/test/data/crab_cntmap.fits.gz
  87 + testdatactadir = $(pyexecdir)/gammalib/tests/cta/data
  88 + testdatacta_DATA = $(testdatacta)
  89 + testcaldbcta = $(abs_top_srcdir)/inst/cta/test/caldb/cta_dummy_irf.dat \
  90 + $(abs_top_srcdir)/inst/cta/test/caldb/prod1_gauss.fits \
  91 + $(abs_top_srcdir)/inst/cta/test/caldb/prod1_king.fits
  92 + testcaldbctadir = $(pyexecdir)/gammalib/tests/cta/caldb
  93 + testcaldbcta_DATA = $(testcaldbcta)
  94 + testdc1cta = $(abs_top_srcdir)/inst/cta/test/caldb/dc1/arf.fits \
  95 + $(abs_top_srcdir)/inst/cta/test/caldb/dc1/psf.fits \
  96 + $(abs_top_srcdir)/inst/cta/test/caldb/dc1/psf_magic.fits \
  97 + $(abs_top_srcdir)/inst/cta/test/caldb/dc1/rmf.fits
  98 + testdc1ctadir = $(pyexecdir)/gammalib/tests/cta/caldb/dc1
  99 + testdc1cta_DATA = $(testdc1cta)
  100 +endif
  101 +
50 102 # Sources that are required for the build. All targets in the list will be built
51 103 # before anything. These are honored by 'make all', 'make check' and 'make install'.
52 104 # We use this here to make sure that all these targets are build by swig before we
... ...
pyext/gammalib/tests/__init__.py 0 → 100644
pyext/setup.py.in
... ... @@ -244,6 +244,14 @@ for entry in bad_entries:
244 244 del locals()[entry]
245 245 del gammalib.gammalib
246 246 """)
  247 +
  248 +# Add test function
  249 +# see https://cta-redmine.irap.omp.eu/issues/1486
  250 +file.write("""
  251 +def test():
  252 + from gammalib.tests import test_python
  253 + test_python.test(installed=True)
  254 +""")
247 255 file.close()
248 256  
249 257 # Set data files to install.
... ...
test/test_python.py
... ... @@ -2,7 +2,7 @@
2 2 # ==========================================================================
3 3 # This scripts performs unit tests for the GammaLib Python bindings.
4 4 #
5   -# Copyright (C) 2012-2014 Juergen Knoedlseder
  5 +# Copyright (C) 2012-2015 Juergen Knoedlseder
6 6 #
7 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -18,9 +18,9 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -from gammalib import *
22   -from math import *
  21 +import gammalib
23 22 import sys
  23 +import os
24 24 import test_GApplication
25 25 import test_GLinalg
26 26 import test_GModel
... ... @@ -64,15 +64,15 @@ except:
64 64 has_com = False
65 65  
66 66  
67   -# ======================== #
68   -# Main routine entry point #
69   -# ======================== #
70   -if __name__ == '__main__':
  67 +# ================== #
  68 +# Perform unit tests #
  69 +# ================== #
  70 +def test(installed=False):
71 71 """
72 72 Perform unit testing for Python interface.
73 73 """
74 74 # Allocate test suites
75   - suites = GTestSuites("Python interface testing")
  75 + suites = gammalib.GTestSuites("Python interface testing")
76 76  
77 77 # Allocate test suites and append them to the container
78 78 suite1 = test_GApplication.Test()
... ... @@ -129,6 +129,8 @@ if __name__ == &#39;__main__&#39;:
129 129 if has_cta:
130 130 suite_cta = test_CTA.Test()
131 131 suite_cta.set()
  132 + if installed:
  133 + suite_cta.caldb_path("cta/caldb")
132 134 suites.append(suite_cta)
133 135  
134 136 # Optionally handle LAT suite
... ... @@ -143,11 +145,56 @@ if __name__ == &#39;__main__&#39;:
143 145 suite_com.set()
144 146 suites.append(suite_com)
145 147  
  148 + # If we have an installed version then create a temporary
  149 + # directory and copy over all information that is needed
  150 + if installed:
  151 +
  152 + # Create temporary working directory
  153 + import tempfile
  154 + path = tempfile.mkdtemp()
  155 + os.chdir(path)
  156 +
  157 + # Get tests directory
  158 + import inspect
  159 + testdir = inspect.getfile(gammalib.tests)
  160 + head, tail = os.path.split(testdir)
  161 +
  162 + # Copy over test data
  163 + os.system("cp -r %s %s" % (head+"/data", "data"))
  164 + os.system("cp -r %s %s" % (head+"/cta", "cta"))
  165 +
  166 + # Special post processing for CTA files. This is needed because
  167 + # the XML files contain absolute PATH information. This is a kluge
  168 + # that works for now, but it's not a very maintainable way to
  169 + # handle this
  170 + if has_cta:
  171 + xml = gammalib.GXml("cta/data/irf_unbinned.xml")
  172 + elements = xml.element("observation_list").element("observation")
  173 + for element in elements:
  174 + filename = element.attribute("file")
  175 + head, tail = os.path.split(filename)
  176 + head, dir = os.path.split(head)
  177 + filename = "cta/"+dir+"/"+tail
  178 + element.attribute("file", filename)
  179 + xml.save("cta/data/irf_unbinned.xml")
  180 + xml = gammalib.GXml("cta/data/irf_1dc.xml")
  181 + elements = xml.element("observation_list").element("observation")
  182 + for element in elements:
  183 + filename = element.attribute("file")
  184 + head, tail = os.path.split(filename)
  185 + head, dir = os.path.split(head)
  186 + if dir == "dc1":
  187 + dir = "caldb/dc1"
  188 + filename = "cta/"+dir+"/"+tail
  189 + element.attribute("file", filename)
  190 + xml.save("cta/data/irf_1dc.xml")
  191 +
146 192 # Run test suite
147 193 success = suites.run()
148 194  
149   - # Save test results
150   - suites.save("reports/GPython.xml")
  195 + # If we have a non-installed version then save test results
  196 + if not installed:
  197 + suites.save("reports/GPython.xml")
151 198  
152 199 # Set return code
153 200 if success:
... ... @@ -155,8 +202,19 @@ if __name__ == &#39;__main__&#39;:
155 202 else:
156 203 rc = 1
157 204  
158   - # Print a linefeed
159   - # sys.stdout.write("\n")
  205 + # Return
  206 + return rc
  207 +
  208 +
  209 +# ======================== #
  210 +# Main routine entry point #
  211 +# ======================== #
  212 +if __name__ == '__main__':
  213 + """
  214 + Perform unit testing for Python interface.
  215 + """
  216 + # Run tests
  217 + rc = test()
160 218  
161 219 # Exit with return code
162 220 sys.exit(rc)
... ...