Commit 9ba34ae9dc7b482c5bf55e327a4498b069520aef

Authored by Jürgen Knödlseder
1 parent 396a007c

Add ctools.test() function that performs unit tests in Python (#1486).

pyext/Makefile.am
1 1 #############################################################################
2 2 # Makefile for ctools Python extension module #
3 3 # ------------------------------------------------------------------------- #
4   -# Copyright (C) 2011-2014 Juergen Knoedlseder #
  4 +# Copyright (C) 2011-2015 Juergen Knoedlseder #
5 5 # ------------------------------------------------------------------------- #
6 6 # #
7 7 # This program is free software: you can redistribute it and/or modify #
... ... @@ -29,6 +29,15 @@
29 29 # Works only if Python is available
30 30 if WITH_PYTHON
31 31  
  32 +# Test scripts to be distributed in $(pythondir)/ctools/tests
  33 +testscripts = ctools/tests/__init__.py \
  34 + ctools/tests/unbinned.py
  35 +
  36 +# Distribute scripts
  37 +EXTRA_DIST = $(testscripts)
  38 +testscriptsdir = $(pythondir)/ctools/tests
  39 +testscripts_DATA = $(testscripts)
  40 +
32 41 # Set SWIG interface filename
33 42 SWIG_INTERFACE = ctools/tools.i
34 43  
... ...
pyext/ctools/__init__.py
... ... @@ -15,3 +15,23 @@ del tools
15 15 del gammalib
16 16 del bad_entries
17 17 del entry
  18 +
  19 +# Add test function
  20 +def test(verbosity=2):
  21 + """
  22 + Run ctools tests.
  23 + """
  24 + # Imports
  25 + import unittest
  26 + from .tests.unbinned import pipelines
  27 +
  28 + # Create a test suite
  29 + test_suite = unittest.TestSuite()
  30 +
  31 + # Test cases must be listed manually here ...
  32 + # We currently don't use unittest for test collection
  33 + test_suite.addTest(unittest.makeSuite(pipelines))
  34 +
  35 + # Create a test runner and run the test
  36 + test_runner = unittest.TextTestRunner(verbosity=verbosity)
  37 + test_runner.run(test_suite)
... ...
pyext/ctools/tests/__init__.py 0 → 100644
  1 +"""
  2 +Tests that can be run for an installed ctools package.
  3 +"""
... ...
pyext/ctools/tests/unbinned.py 0 → 100644
  1 +# ==========================================================================
  2 +# This script tests the unbinned analysis.
  3 +#
  4 +# Copyright (C) 2015 Christoph Deil
  5 +#
  6 +# This program is free software: you can redistribute it and/or modify
  7 +# it under the terms of the GNU General Public License as published by
  8 +# the Free Software Foundation, either version 3 of the License, or
  9 +# (at your option) any later version.
  10 +#
  11 +# This program is distributed in the hope that it will be useful,
  12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 +# GNU General Public License for more details.
  15 +#
  16 +# You should have received a copy of the GNU General Public License
  17 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
  18 +#
  19 +# ==========================================================================
  20 +import os
  21 +from tempfile import mkdtemp
  22 +import unittest
  23 +import ctools
  24 +
  25 +
  26 +# ================== #
  27 +# Analysis pipelines #
  28 +# ================== #
  29 +class pipelines(unittest.TestCase):
  30 + """
  31 + Test a simple unbinned analysis pipeline.
  32 + """
  33 + # Setup of test class
  34 + def setUp(self):
  35 + gammalib_dir = os.environ['GAMMALIB']
  36 + self.model_name = os.path.join(gammalib_dir, "share/models/crab.xml")
  37 + self.workdir = mkdtemp()
  38 +
  39 + # Test unbinned analysis with FITS files
  40 + def test_unbinned_fits(self):
  41 + """
  42 + Test unbinned pipeline with FITS file saving.
  43 + """
  44 + # Set script parameters
  45 + model_name = self.model_name
  46 + events_name = os.path.join(self.workdir, "events.fits")
  47 + selected_events_name = os.path.join(self.workdir, "selected_events.fits")
  48 + result_name = os.path.join(self.workdir, "results.xml")
  49 + caldb = "prod2"
  50 + irf = "South_50h"
  51 + ra = 83.63
  52 + dec = 22.01
  53 + rad_sim = 10.0
  54 + tstart = 0.0
  55 + tstop = 1800.0
  56 + emin = 0.1
  57 + emax = 100.0
  58 + rad_select = 3.0
  59 +
  60 + # Simulate events
  61 + sim = ctools.ctobssim()
  62 + sim["inmodel"] = model_name
  63 + sim["outevents"] = events_name
  64 + sim["caldb"] = caldb
  65 + sim["irf"] = irf
  66 + sim["ra"] = ra
  67 + sim["dec"] = dec
  68 + sim["rad"] = rad_sim
  69 + sim["tmin"] = tstart
  70 + sim["tmax"] = tstop
  71 + sim["emin"] = emin
  72 + sim["emax"] = emax
  73 + sim.execute()
  74 +
  75 + # Select events
  76 + select = ctools.ctselect()
  77 + select["inobs"] = events_name
  78 + select["outobs"] = selected_events_name
  79 + select["ra"] = ra
  80 + select["dec"] = dec
  81 + select["rad"] = rad_select
  82 + select["tmin"] = tstart
  83 + select["tmax"] = tstop
  84 + select["emin"] = emin
  85 + select["emax"] = emax
  86 + select.execute()
  87 +
  88 + # Perform maximum likelihood fitting
  89 + like = ctools.ctlike()
  90 + like["inobs"] = selected_events_name
  91 + like["inmodel"] = model_name
  92 + like["outmodel"] = result_name
  93 + like["caldb"] = caldb
  94 + like["irf"] = irf
  95 + like.execute()
  96 +
  97 + # TODO: add asserts
  98 + assert True
  99 +
  100 + # Test unbinned analysis in memory
  101 + def test_unbinned_mem(self):
  102 + """
  103 + Test unbinned in-memory pipeline.
  104 + """
  105 + # Set script parameters
  106 + model_name = self.model_name
  107 + caldb = "prod2"
  108 + irf = "South_50h"
  109 + ra = 83.63
  110 + dec = 22.01
  111 + rad_sim = 10.0
  112 + tstart = 0.0
  113 + tstop = 1800.0
  114 + emin = 0.1
  115 + emax = 100.0
  116 + rad_select = 3.0
  117 +
  118 + # Simulate events
  119 + sim = ctools.ctobssim()
  120 + sim["inmodel"] = model_name
  121 + sim["caldb"] = caldb
  122 + sim["irf"] = irf
  123 + sim["ra"] = ra
  124 + sim["dec"] = dec
  125 + sim["rad"] = rad_sim
  126 + sim["tmin"] = tstart
  127 + sim["tmax"] = tstop
  128 + sim["emin"] = emin
  129 + sim["emax"] = emax
  130 + sim.run()
  131 +
  132 + # Select events
  133 + select = ctools.ctselect(sim.obs())
  134 + select["ra"] = ra
  135 + select["dec"] = dec
  136 + select["rad"] = rad_select
  137 + select["tmin"] = tstart
  138 + select["tmax"] = tstop
  139 + select["emin"] = emin
  140 + select["emax"] = emax
  141 + select.run()
  142 +
  143 + # Perform maximum likelihood fitting
  144 + like = ctools.ctlike(select.obs())
  145 + like.run()
  146 +
  147 + # TODO: add asserts
  148 + assert True
... ...