diff --git a/test/test_ctobssim.py b/test/test_ctobssim.py new file mode 100755 index 0000000..f5b05fb --- /dev/null +++ b/test/test_ctobssim.py @@ -0,0 +1,108 @@ +#! /usr/bin/env python +# ========================================================================== +# This scripts performs unit tests for the ctobssim tool. +# +# Copyright (C) 2014 Juergen Knoedlseder +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ========================================================================== +import gammalib +import ctools + + +# ============================ # +# Test class for ctobssim tool # +# ============================ # +class Test(gammalib.GPythonTestSuite): + """ + Test class for ctobssim tool. + """ + # Constructor + def __init__(self): + """ + Constructor. + """ + # Call base class constructor + gammalib.GPythonTestSuite.__init__(self) + + # Set members + self.model_name = "data/crab.xml" + self.events_name = "events.fits" + self.caldb = "irf" + self.irf = "cta_dummy_irf" + + # Return + return + + # Set test functions + def set(self): + """ + Set all test functions. + """ + # Set test name + self.name("ctobssim") + + # Append tests + self.append(self.test_functional, "Test ctobssim functionality") + + # Return + return + + # Test ctobssim functionnality + def test_functional(self): + """ + Test ctobssim functionnality. + """ + # Set-up ctobssim + sim = ctools.ctobssim() + sim["infile"].filename(self.model_name) + sim["outfile"].filename("events.fits") + sim["caldb"].string(self.caldb) + sim["irf"].string(self.irf) + sim["ra"].real(83.63) + sim["dec"].real(22.01) + sim["rad"].real(10.0) + sim["tmin"].real(0.0) + sim["tmax"].real(1800.0) + sim["emin"].real(0.1) + sim["emax"].real(100.0) + + # Run tool + self.test_try("Run ctobssim") + try: + sim.run() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctobssim.") + + # Retrieve observation and check content + obs = gammalib.GCTAObservation(sim.obs()[0]) + pnt = obs.pointing() + evt = obs.events() + self.test_assert(obs.instrument() == "CTA", "Observation not a CTA observation") + self.test_value(sim.obs().size(), 1, "There is not a single observation") + self.test_value(obs.ontime(), 1800.0, 1.0e-6, "Ontime is not 1800 sec") + self.test_value(obs.livetime(), 1710.0, 1.0e-6, "Livetime is not 1710 sec") + self.test_value(pnt.dir().ra_deg(), 83.63, 1.0e-6, "ROI Right Ascension is not 83.63 deg") + self.test_value(pnt.dir().dec_deg(), 22.01, 1.0e-6, "ROI Declination is not 22.01 deg") + self.test_value(evt.size(), 4134, "Number of events is not 4134") + + # Save events + self.test_try("Save events") + try: + sim.save() + self.test_try_success() + except: + self.test_try_failure("Exception occured in saving events.") diff --git a/test/test_pipelines.py b/test/test_pipelines.py new file mode 100755 index 0000000..9af009e --- /dev/null +++ b/test/test_pipelines.py @@ -0,0 +1,192 @@ +#! /usr/bin/env python +# ========================================================================== +# This scripts performs tests processing pipelines. +# +# Copyright (C) 2014 Juergen Knoedlseder +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ========================================================================== +import gammalib +import ctools + + +# ============================ # +# Test class for ctobssim tool # +# ============================ # +class Test(gammalib.GPythonTestSuite): + """ + Test class for pipelines. + """ + # Constructor + def __init__(self): + """ + Constructor. + """ + # Call base class constructor + gammalib.GPythonTestSuite.__init__(self) + + # Return + return + + # Set test functions + def set(self): + """ + Set all test functions. + """ + # Set test name + self.name("pipelines") + + # Append tests + self.append(self.test_unbinned_fits, "Test unbinned pipeline with FITS file saving") + self.append(self.test_unbinned_mem, "Test unbinned in-memory pipeline") + + # Return + return + + # Test unbinned pipeline with FITS file saving + def test_unbinned_fits(self): + """ + Test unbinned pipeline with FITS file saving. + """ + # Set script parameters + model_name = "data/crab.xml" + events_name = "events.fits" + selected_events_name = "selected_events.fits" + result_name = "results.xml" + caldb = "irf" + irf = "cta_dummy_irf" + ra = 83.63 + dec = 22.01 + rad_sim = 10.0 + tstart = 0.0 + tstop = 1800.0 + emin = 0.1 + emax = 100.0 + rad_select = 3.0 + + # Simulate events + sim = ctools.ctobssim() + sim["infile"].filename(model_name) + sim["outfile"].filename(events_name) + sim["caldb"].string(caldb) + sim["irf"].string(irf) + sim["ra"].real(ra) + sim["dec"].real(dec) + sim["rad"].real(rad_sim) + sim["tmin"].real(tstart) + sim["tmax"].real(tstop) + sim["emin"].real(emin) + sim["emax"].real(emax) + self.test_try("Execute ctobssim") + try: + sim.execute() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctobssim.") + + # Select events + select = ctools.ctselect() + select["infile"].filename(events_name) + select["outfile"].filename(selected_events_name) + select["ra"].real(ra) + select["dec"].real(dec) + select["rad"].real(rad_select) + select["tmin"].real(tstart) + select["tmax"].real(tstop) + select["emin"].real(emin) + select["emax"].real(emax) + self.test_try("Execute ctselect") + try: + select.execute() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctselect.") + + # Perform maximum likelihood fitting + like = ctools.ctlike() + like["infile"].filename(selected_events_name) + like["srcmdl"].filename(model_name) + like["outmdl"].filename(result_name) + like["caldb"].string(caldb) + like["irf"].string(irf) + self.test_try("Execute ctlike") + try: + like.execute() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctlike.") + + + # Test unbinned in-memory pipeline + def test_unbinned_mem(self): + """ + Test unbinned in-memory pipeline. + """ + # Set script parameters + model_name = "data/crab.xml" + caldb = "irf" + irf = "cta_dummy_irf" + ra = 83.63 + dec = 22.01 + rad_sim = 10.0 + tstart = 0.0 + tstop = 1800.0 + emin = 0.1 + emax = 100.0 + rad_select = 3.0 + + # Simulate events + sim = ctools.ctobssim() + sim["infile"].filename(model_name) + sim["caldb"].string(caldb) + sim["irf"].string(irf) + sim["ra"].real(ra) + sim["dec"].real(dec) + sim["rad"].real(rad_sim) + sim["tmin"].real(tstart) + sim["tmax"].real(tstop) + sim["emin"].real(emin) + sim["emax"].real(emax) + self.test_try("Run ctobssim") + try: + sim.run() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctobssim.") + + # Select events + select = ctools.ctselect(sim.obs()) + select["ra"].real(ra) + select["dec"].real(dec) + select["rad"].real(rad_select) + select["tmin"].real(tstart) + select["tmax"].real(tstop) + select["emin"].real(emin) + select["emax"].real(emax) + self.test_try("Run ctselect") + try: + select.run() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctselect.") + + # Perform maximum likelihood fitting + like = ctools.ctlike(select.obs()) + self.test_try("Run ctlike") + try: + like.run() + self.test_try_success() + except: + self.test_try_failure("Exception occured in ctlike.") diff --git a/test/test_python.py b/test/test_python.py index 33f215d..e385d72 100755 --- a/test/test_python.py +++ b/test/test_python.py @@ -1,9 +1,8 @@ #! /usr/bin/env python # ========================================================================== -# This script illustrates how to build an unbinned analysis pipeline using -# the ctools. +# This scripts performs unit tests for the ctools package. # -# Copyright (C) 2011-2014 Juergen Knoedlseder +# Copyright (C) 2012-2014 Juergen Knoedlseder # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,177 +18,36 @@ # along with this program. If not, see . # # ========================================================================== -from ctools import * -from gammalib import * -from math import * -import os -import glob +import gammalib +import ctools import sys - -# ============================= # -# Analysis pipeline - version 1 # -# ============================= # -def pipeline_v1(): - """ - Unbinned analysis pipeline - save intermediate results. - - This function implements an analysis pipeline that successively calls - ctobssim, ctselect and ctlike by saving the intermediate results as FITS - files on disk. This replicates the way how the analysis would be done - in a ftools-like approach. - """ - # Set script parameters - model_name = "data/crab.xml" - events_name = "events.fits" - selected_events_name = "selected_events.fits" - result_name = "results.xml" - caldb = "irf" - irf = "cta_dummy_irf" - ra = 83.63 - dec = 22.01 - rad_sim = 10.0 - tstart = 0.0 - tstop = 1800.0 - emin = 0.1 - emax = 100.0 - rad_select = 3.0 - - # Initialise timing - wall_seconds = 0.0 - cpu_seconds = 0.0 - - # Simulate events - sim = ctobssim() - sim.logFileOpen() - sim["infile"].filename(model_name) - sim["outfile"].filename(events_name) - sim["caldb"].string(caldb) - sim["irf"].string(irf) - sim["ra"].real(ra) - sim["dec"].real(dec) - sim["rad"].real(rad_sim) - sim["tmin"].real(tstart) - sim["tmax"].real(tstop) - sim["emin"].real(emin) - sim["emax"].real(emax) - sim.execute() - sys.stdout.write(".") - - # Select events - select = ctselect() - select.logFileOpen() - select["infile"].filename(events_name) - select["outfile"].filename(selected_events_name) - select["ra"].real(ra) - select["dec"].real(dec) - select["rad"].real(rad_select) - select["tmin"].real(tstart) - select["tmax"].real(tstop) - select["emin"].real(emin) - select["emax"].real(emax) - select.execute() - sys.stdout.write(".") - - # Perform maximum likelihood fitting - like = ctlike() - like.logFileOpen() - like["infile"].filename(selected_events_name) - like["srcmdl"].filename(model_name) - like["outmdl"].filename(result_name) - like["caldb"].string(caldb) - like["irf"].string(irf) - like.execute() - sys.stdout.write(".") - - # Return - return +import os +import test_ctobssim +import test_pipelines -# ============================= # -# Analysis pipeline - version 2 # -# ============================= # -def pipeline_v2(model_name="data/crab.xml", \ - ra_sim=83.63, dec_sim=22.01, rad_sim=10.0, \ - ra_select=83.63, dec_select=22.01, rad_select=3.0, \ - tstart=0.0, tstop=1800.0, \ - emin=0.1, emax=100.0, \ - ref={}): +# ======================== # +# Main routine entry point # +# ======================== # +if __name__ == '__main__': """ - Unbinned analysis pipeline - keep intermediate results in memory. - - This function implements an analysis pipeline that successively calls - ctobssim, ctselect and ctlike without saving the intermediate results as - FITS files on disk. All data is only hold in memory. + Perform unit testing for Python interface. """ - # Set script parameters - caldb = "irf" - irf = "cta_dummy_irf" - - # Simulate events - sim = ctobssim() - sim["infile"].filename(model_name) - sim["caldb"].string(caldb) - sim["irf"].string(irf) - sim["ra"].real(ra_sim) - sim["dec"].real(dec_sim) - sim["rad"].real(rad_sim) - sim["tmin"].real(tstart) - sim["tmax"].real(tstop) - sim["emin"].real(emin) - sim["emax"].real(emax) - sim.run() - sys.stdout.write(".") - - # Select events - select = ctselect(sim.obs()) - select["ra"].real(ra_select) - select["dec"].real(dec_select) - select["rad"].real(rad_select) - select["tmin"].real(tstart) - select["tmax"].real(tstop) - select["emin"].real(emin) - select["emax"].real(emax) - select.run() - sys.stdout.write(".") - - # Perform maximum likelihood fitting - like = ctlike(select.obs()) - like.run() - sys.stdout.write(".") + # Allocate test suite container + suites = gammalib.GTestSuites("ctools unit testing") - # Analyse results - errors = 0 - models = like.obs().models() - #print(models) - for model in models: - for key in ref: - if key == model.name(): - for par in model: - for value in ref[key]: - if value == par.name(): - if abs(float(ref[key][value])-par.value()) < 0.0001: - sys.stdout.write(".") - else: - sys.stdout.write("E") - errors += 1 + # Allocate test suites and append them to the container + suite_ctobssim = test_ctobssim.Test() + suite_pipelines = test_pipelines.Test() - # Return number of errors - return errors + # Setup unit tests + suite_ctobssim.set() + suite_pipelines.set() + # Append tests to container + suites.append(suite_ctobssim) + suites.append(suite_pipelines) -#==========================# -# Main routine entry point # -#==========================# -if __name__ == '__main__': - """ - Test ctools Python modules. - """ - # Dump header - print("") - print("***********************************") - print("* ctools Python interface testing *") - print("***********************************") - # Set PFILES environment variable try: os.mkdir("pfiles") @@ -197,51 +55,18 @@ if __name__ == '__main__': pass os.system("cp -r ../src/*/*.par pfiles/") os.environ['PFILES'] = "pfiles" - - # Remove any existing result files - list = [glob.glob("*.fits"), glob.glob("*.xml")] - for files in list: - for file in files: - os.remove(file) - # Save intermediate results on disk - sys.stdout.write("Test executable analysis: ") - pipeline_v1() - print(" ok") + # Run test suite + success = suites.run() - # Keep results in memory - sys.stdout.write("Test in-memory analysis: ") - err = pipeline_v2() - if err == 0: - print(" ok") - else: - print(" NOK") - - # Test diffuse map cube with constant spectrum - sys.stdout.write("Test diffuse map cube with constant analysis: ") - ref = {'CTABackgroundModel': {'Value': 0.242717}} - err = pipeline_v2(model_name="data/model_background_cube_const.xml", \ - ra_sim=84.17263, dec_sim=22.01444, rad_sim=2.0, \ - ra_select=83.80, dec_select=22.20, rad_select=1.0, \ - tstart=0.0, tstop=1.0, \ - emin=0.3, emax=8.0, \ - ref=ref) - if err == 0: - print(" ok") - else: - print(" NOK") + # Save test results + suites.save("reports/ctools.xml") - # Test diffuse map cube with power law spectrum - sys.stdout.write("Test diffuse map cube with power law analysis: ") - ref = {'CTABackgroundModel': {'Prefactor': 0.513946, 'Index': -1.22388}} - err = pipeline_v2(model_name="data/model_background_cube.xml", \ - ra_sim=84.17263, dec_sim=22.01444, rad_sim=2.0, \ - ra_select=84.00, dec_select=22.20, rad_select=1.0, \ - tstart=0.0, tstop=1.0, \ - emin=0.3, emax=8.0, \ - ref=ref) - if err == 0: - print(" ok") + # Set return code + if success: + rc = 0 else: - print(" NOK") + rc = 1 + # Exit with return code + sys.exit(rc)