diff --git a/ChangeLog b/ChangeLog index 959b8d3..b43887a 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -2018-06-15 +2018-06-29 * Version 1.6.0 released ======================== @@ -14,8 +14,10 @@ Also compute TS in csspec for On/Off analysis using wstat statistic (#2312) Allow specifying of input sky map in ctskymap (#2311) Accelerate IRF and RING background methods in ctskymap (#2309) + Add upper limit computation is csspec for NODES method (#2233) Define MET with respect to the observation time reference or "mjdref" parameter (#2054) + Implement Python pickeling support (#1938) 2018-04-26 diff --git a/NEWS b/NEWS index 3432c8f..72c5f79 100755 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ New Features and Important Changes in ctools 1.6.0 -20 June 2018 +29 June 2018 Introduction @@ -11,12 +11,12 @@ ctools release with respect to the precedent release. Configuration ------------- -Keep existing library path in installation script on Mac OS X (#2420) +Keep existing library path in installation script on Mac OS X (#2420). Python interface ---------------- -None +ctools and cscripts can now be pickled from Python (#1938). Support model @@ -288,6 +288,10 @@ csspec now properly computes the Test Statistic for an On/Off analysis using the "wstat" statistic in the case that the input model definition XML file did not contain a background model (#2312). +csspec now computes upper limits also for the NODES method by fixing all node +intensities and varying each node until the log-likelihood increases by a +certain amount (#2233). + cssrcdetect - Detects sources in sky map ---------------------------------------- diff --git a/cscripts/csspec.py b/cscripts/csspec.py index 6e88fb5..6905dff 100755 --- a/cscripts/csspec.py +++ b/cscripts/csspec.py @@ -758,6 +758,42 @@ class csspec(ctools.csobservation): result['flux'] = spectrum[i*2+1].value() * norm result['flux_err'] = spectrum[i*2+1].error() * norm + # Compute upper flux limit + ulimit_value = -1.0 + if self['calc_ulim'].boolean(): + + # Logging information + self._log_header3(gammalib.EXPLICIT, 'Computing upper limit') + + # Copy observation container + obs = like.obs().copy() + + # Fix intensities of all nodes + spectral = obs.models()[self['srcname'].string()].spectral() + for par in spectral: + par.fix() + + # Create upper limit object + ulimit = ctools.ctulimit(obs) + ulimit['srcname'] = self['srcname'].string() + ulimit['parname'] = 'Intensity%d' % i + ulimit['eref'] = elogmean.TeV() + ulimit['tol'] = 1.0e-3 + + # Try to run upper limit and catch exceptions + try: + ulimit.run() + ulimit_value = ulimit.diff_ulimit() + except: + self._log_string(gammalib.EXPLICIT, 'Upper limit ' + 'calculation failed.') + ulimit_value = -1.0 + + # Compute upper limit + if ulimit_value > 0.0: + result['ulimit'] = ulimit_value * elogmean.MeV() * \ + elogmean.MeV() * gammalib.MeV2erg + # Compute TS if self['calc_ts'].boolean(): diff --git a/doc/source/admin/release_history/1.6.rst b/doc/source/admin/release_history/1.6.rst index c50a064..f935326 100644 --- a/doc/source/admin/release_history/1.6.rst +++ b/doc/source/admin/release_history/1.6.rst @@ -12,6 +12,7 @@ In particular, this release provides: * Support for Xspec spectral analysis * Improved computation speed for :ref:`ctskymap` and :ref:`csphagen` +* Support for Python pickeling Bug fixes @@ -41,6 +42,8 @@ Improvements Allow specifying of input skymap to :ref:`ctskymap` tool * [`2309 `_] - Accelerate `IRF` and `RING` background methods in :ref:`ctskymap` +* [`2233 `_] - + Add upper limit computation is :ref:`csspec` for ``NODES`` method * [`2045 `_] - Define MET with respect to the observation time reference or the ``mjdref`` user parameter (#2054) @@ -49,7 +52,8 @@ Improvements New features ------------ -* ... +* [`1938 `_] - + Support pickeling of ctools and cscripts in Python Clean up diff --git a/pyext/ctlikelihood.i b/pyext/ctlikelihood.i index cf7da7d..b1f8cee 100755 --- a/pyext/ctlikelihood.i +++ b/pyext/ctlikelihood.i @@ -1,7 +1,7 @@ /*************************************************************************** * ctlikelihood - Base class for likelihood tools * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2017 by Juergen Knoedlseder * + * copyright (C) 2016-2018 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -42,14 +42,22 @@ class cslikelihood : public ctlikelihood { public: // Constructors and destructors - cslikelihood(const std::string& name, const std::string& version) : + cslikelihood(const std::string& name, + const std::string& version) : ctlikelihood(name, version) {} - cslikelihood(const std::string& name, const std::string& version, + cslikelihood(const std::string& name, + const std::string& version, const GObservations& obs) : ctlikelihood(name, version, obs) {} - cslikelihood(const std::string& name, const std::string& version, - int argc, char* argv[]) : - ctlikelihood(name, version, argc, argv){} + cslikelihood(const std::string& name, + const std::string& version, + const std::vector& args) : + ctlikelihood(name, version, args) {} + cslikelihood(const std::string& name, + const std::string& version, + int argc, + char* argv[]) : + ctlikelihood(name, version, argc, argv) {} cslikelihood(const cslikelihood& app) : ctlikelihood(app) {} virtual ~cslikelihood(void) {} @@ -74,11 +82,18 @@ class ctlikelihood : public ctobservation { public: // Constructors and destructors - ctlikelihood(const std::string& name, const std::string& version); - ctlikelihood(const std::string& name, const std::string& version, + ctlikelihood(const std::string& name, + const std::string& version); + ctlikelihood(const std::string& name, + const std::string& version, const GObservations& obs); - ctlikelihood(const std::string& name, const std::string& version, - int argc, char* argv[]); + ctlikelihood(const std::string& name, + const std::string& version, + const std::vector& args); + ctlikelihood(const std::string& name, + const std::string& version, + int argc, + char* argv[]); ctlikelihood(const ctlikelihood& app); virtual ~ctlikelihood(void); @@ -108,11 +123,18 @@ public: class cslikelihood : public ctlikelihood { public: // Constructors and destructors - cslikelihood(const std::string& name, const std::string& version); - cslikelihood(const std::string& name, const std::string& version, + cslikelihood(const std::string& name, + const std::string& version); + cslikelihood(const std::string& name, + const std::string& version, const GObservations& obs); - cslikelihood(const std::string& name, const std::string& version, - int ARGC, char **ARGV); + cslikelihood(const std::string& name, + const std::string& version, + const std::vector& args); + cslikelihood(const std::string& name, + const std::string& version, + int ARGC, + char **ARGV); cslikelihood(const cslikelihood& app); virtual ~cslikelihood(void); @@ -133,6 +155,21 @@ public: /***********************************************************************//** * @brief Likelihood tool base class Python extensions ***************************************************************************/ +%extend cslikelihood { +%pythoncode { + def __getstate__(self): + state = (ctool.__getstate__(self), self.obs()) + return state + def __setstate__(self, state): + ctool.__setstate__(self, state[0]) + self.obs(state[1]) +} +} + + +/***********************************************************************//** + * @brief Likelihood tool base class Python extensions + ***************************************************************************/ %pythoncode %{ # Initialise application by calling the appropriate base class constructor. @@ -143,7 +180,10 @@ def _init_cslikelihood(self, name, version, argv): if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations): cslikelihood.__init__(self, name, version, argv[0]) elif len(argv) > 0: - cslikelihood.__init__(self, name, version, *argv) + if len(argv) == 3 and argv[0] == name and argv[1] == version: + cslikelihood.__init__(self, name, version, argv[2]) + else: + cslikelihood.__init__(self, name, version, *argv) else: cslikelihood.__init__(self, name, version) # Set logger properties diff --git a/pyext/ctobservation.i b/pyext/ctobservation.i index 38f221f..7b1bf75 100755 --- a/pyext/ctobservation.i +++ b/pyext/ctobservation.i @@ -1,7 +1,7 @@ /*************************************************************************** * ctobservation - Base class for observation tools * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2017 by Juergen Knoedlseder * + * copyright (C) 2016-2018 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -42,14 +42,22 @@ class csobservation : public ctobservation { public: // Constructors and destructors - csobservation(const std::string& name, const std::string& version) : + csobservation(const std::string& name, + const std::string& version) : ctobservation(name, version) {} - csobservation(const std::string& name, const std::string& version, + csobservation(const std::string& name, + const std::string& version, const GObservations& obs) : ctobservation(name, version, obs) {} - csobservation(const std::string& name, const std::string& version, - int argc, char* argv[]) : - ctobservation(name, version, argc, argv){} + csobservation(const std::string& name, + const std::string& version, + const std::vector& args) : + ctobservation(name, version, args) {} + csobservation(const std::string& name, + const std::string& version, + int argc, + char* argv[]) : + ctobservation(name, version, argc, argv) {} csobservation(const csobservation& app) : ctobservation(app) {} virtual ~csobservation(void) {} @@ -74,11 +82,18 @@ class ctobservation : public ctool { public: // Constructors and destructors - ctobservation(const std::string& name, const std::string& version); - ctobservation(const std::string& name, const std::string& version, + ctobservation(const std::string& name, + const std::string& version); + ctobservation(const std::string& name, + const std::string& version, const GObservations& obs); - ctobservation(const std::string& name, const std::string& version, - int ARGC, char **ARGV); + ctobservation(const std::string& name, + const std::string& version, + const std::vector& args); + ctobservation(const std::string& name, + const std::string& version, + int ARGC, + char **ARGV); ctobservation(const ctobservation& app); virtual ~ctobservation(void); @@ -120,11 +135,18 @@ public: class csobservation : public ctobservation { public: // Constructors and destructors - csobservation(const std::string& name, const std::string& version); - csobservation(const std::string& name, const std::string& version, + csobservation(const std::string& name, + const std::string& version); + csobservation(const std::string& name, + const std::string& version, const GObservations& obs); - csobservation(const std::string& name, const std::string& version, - int ARGC, char **ARGV); + csobservation(const std::string& name, + const std::string& version, + const std::vector& args); + csobservation(const std::string& name, + const std::string& version, + int ARGC, + char **ARGV); csobservation(const csobservation& app); virtual ~csobservation(void); @@ -145,6 +167,21 @@ public: /***********************************************************************//** * @brief Observation tool base class Python extensions ***************************************************************************/ +%extend csobservation { +%pythoncode { + def __getstate__(self): + state = (ctool.__getstate__(self), self.obs()) + return state + def __setstate__(self, state): + ctool.__setstate__(self, state[0]) + self.obs(state[1]) +} +} + + +/***********************************************************************//** + * @brief Observation tool base class Python extensions + ***************************************************************************/ %pythoncode %{ # Initialise application by calling the appropriate base class constructor. @@ -155,7 +192,10 @@ def _init_csobservation(self, name, version, argv): if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations): csobservation.__init__(self, name, version, argv[0]) elif len(argv) > 0: - csobservation.__init__(self, name, version, *argv) + if len(argv) == 3 and argv[0] == name and argv[1] == version: + csobservation.__init__(self, name, version, argv[2]) + else: + csobservation.__init__(self, name, version, *argv) else: csobservation.__init__(self, name, version) # Set logger properties diff --git a/pyext/ctool.i b/pyext/ctool.i index c5bbed7..80137f5 100755 --- a/pyext/ctool.i +++ b/pyext/ctool.i @@ -36,9 +36,15 @@ class cscript : public ctool { public: // Constructors and destructors - cscript(const std::string& name, const std::string& version) : ctool(name, version) {} - cscript(const std::string& name, const std::string& version, - int argc, char* argv[]) : ctool(name, version, argc, argv) {} + cscript(const std::string& name, + const std::string& version) : ctool(name, version) {} + cscript(const std::string& name, + const std::string& version, + const std::vector& args) : ctool(name, version, args) {} + cscript(const std::string& name, + const std::string& version, + int argc, + char* argv[]) : ctool(name, version, argc, argv) {} cscript(const ctool& app) : ctool(app) {} virtual ~cscript(void) {} @@ -67,9 +73,15 @@ public: class ctool : public GApplication { public: // Constructors and destructors - ctool(const std::string& name, const std::string& version); - ctool(const std::string& name, const std::string& version, - int ARGC, char **ARGV); + ctool(const std::string& name, + const std::string& version); + ctool(const std::string& name, + const std::string& version, + const std::vector& args); + ctool(const std::string& name, + const std::string& version, + int ARGC, + char **ARGV); ctool(const ctool& app); virtual ~ctool(void); @@ -219,7 +231,27 @@ public: self->m_read_ahead = flag; return; } +%pythoncode { + def __getstate__(self): + state = (gammalib.GApplication.__getstate__(self),) + return state + def __setstate__(self, state): + gammalib.GApplication.__setstate__(self, state[0]) +} +}; + +/***********************************************************************//** + * @brief ctool base class Python extensions + ***************************************************************************/ +%extend cscript { +%pythoncode { + def __getstate__(self): + state = (gammalib.GApplication.__getstate__(self),) + return state + def __setstate__(self, state): + gammalib.GApplication.__setstate__(self, state[0]) } +}; /***********************************************************************//** @@ -246,6 +278,8 @@ def _init_cscript(self, name, version, argv): cscript.__init__(self, name, version) elif len(argv) == 1: cscript.__init__(self, name, version, *argv) + elif len(argv) == 3: + cscript.__init__(self, name, version, argv[2]) else: raise TypeError('Invalid number of arguments given.') # Set logger properties diff --git a/pyext/ctools/tools.i b/pyext/ctools/tools.i index 60229e3..1ba39cc 100755 --- a/pyext/ctools/tools.i +++ b/pyext/ctools/tools.i @@ -1,7 +1,7 @@ /*************************************************************************** * ctools - SWIG file * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2016 by Juergen Knoedlseder * + * copyright (C) 2010-2018 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -36,11 +36,13 @@ /* __ Include standard typemaps for vectors and strings __________________ */ %include stl.i -%include "std_vector.i" +%include std_string.i +%include std_vector.i namespace std { %template(vector_int) vector; %template(vector_double) vector; %template(vector_bool) vector; + %template(vector_sring) vector; }; /* __ Make sure that exceptions are catched ______________________________ */ diff --git a/src/support/ctlikelihood.cpp b/src/support/ctlikelihood.cpp index 6efcd7e..d251d54 100755 --- a/src/support/ctlikelihood.cpp +++ b/src/support/ctlikelihood.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * ctlikelihood - Base class for likelihood tools * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2017 by Juergen Knoedlseder * + * copyright (C) 2016-2018 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -78,7 +78,30 @@ ctlikelihood::ctlikelihood(const std::string& name, ctlikelihood::ctlikelihood(const std::string& name, const std::string& version, const GObservations& obs) : - ctobservation(name, version, obs) + ctobservation(name, version, obs) +{ + // Initialise members + init_members(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Command line constructor + * + * @param[in] name Likelihood tool name. + * @param[in] version Likelihood tool version. + * @param[in] args Arguments vector. + * + * Constructs a likelihood tool from the @p name, @p version and command + * line arguments. See the equivalent ctool constructor for details. + ***************************************************************************/ +ctlikelihood::ctlikelihood(const std::string& name, + const std::string& version, + const std::vector& args) : + ctobservation(name, version, args) { // Initialise members init_members(); @@ -103,7 +126,7 @@ ctlikelihood::ctlikelihood(const std::string& name, const std::string& version, int argc, char *argv[]) : - ctobservation(name, version, argc, argv) + ctobservation(name, version, argc, argv) { // Initialise members init_members(); diff --git a/src/support/ctlikelihood.hpp b/src/support/ctlikelihood.hpp index 399b80d..8ffb9a9 100755 --- a/src/support/ctlikelihood.hpp +++ b/src/support/ctlikelihood.hpp @@ -1,7 +1,7 @@ /*************************************************************************** * ctlikelihood - Base class for likelihood tools * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2017 by Juergen Knoedlseder * + * copyright (C) 2016-2018 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -42,11 +42,18 @@ class ctlikelihood : public ctobservation { public: // Constructors and destructors - ctlikelihood(const std::string& name, const std::string& version); - ctlikelihood(const std::string& name, const std::string& version, + ctlikelihood(const std::string& name, + const std::string& version); + ctlikelihood(const std::string& name, + const std::string& version, const GObservations& obs); - ctlikelihood(const std::string& name, const std::string& version, - int argc, char* argv[]); + ctlikelihood(const std::string& name, + const std::string& version, + const std::vector& args); + ctlikelihood(const std::string& name, + const std::string& version, + int argc, + char* argv[]); ctlikelihood(const ctlikelihood& app); virtual ~ctlikelihood(void); diff --git a/src/support/ctobservation.cpp b/src/support/ctobservation.cpp index e6511ec..170167d 100755 --- a/src/support/ctobservation.cpp +++ b/src/support/ctobservation.cpp @@ -93,6 +93,29 @@ ctobservation::ctobservation(const std::string& name, * * @param[in] name Observation tool name. * @param[in] version Observation tool version. + * @param[in] args Arguments vector. + * + * Constructs a observation tool from the @p name, @p version and command + * line arguments. See the equivalent ctool constructor for details. + ***************************************************************************/ +ctobservation::ctobservation(const std::string& name, + const std::string& version, + const std::vector& args) : + ctool(name, version, args) +{ + // Initialise members + init_members(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Command line constructor + * + * @param[in] name Observation tool name. + * @param[in] version Observation tool version. * @param[in] argc Number of arguments in command line. * @param[in] argv Array of command line arguments. * diff --git a/src/support/ctobservation.hpp b/src/support/ctobservation.hpp index 797ac92..3548580 100755 --- a/src/support/ctobservation.hpp +++ b/src/support/ctobservation.hpp @@ -45,11 +45,18 @@ class ctobservation : public ctool { public: // Constructors and destructors - ctobservation(const std::string& name, const std::string& version); - ctobservation(const std::string& name, const std::string& version, + ctobservation(const std::string& name, + const std::string& version); + ctobservation(const std::string& name, + const std::string& version, const GObservations& obs); - ctobservation(const std::string& name, const std::string& version, - int argc, char* argv[]); + ctobservation(const std::string& name, + const std::string& version, + const std::vector& args); + ctobservation(const std::string& name, + const std::string& version, + int argc, + char* argv[]); ctobservation(const ctobservation& app); virtual ~ctobservation(void); diff --git a/src/support/ctool.cpp b/src/support/ctool.cpp index 0e8f7cc..715815e 100755 --- a/src/support/ctool.cpp +++ b/src/support/ctool.cpp @@ -116,6 +116,58 @@ ctool::ctool(const std::string& name, * * @param[in] name Application name. * @param[in] version Application version. + * @param[in] args Arguments vector. + * + * Constructs a ctool from the @p name, @p version and command line + * arguments. The constructor uses the equivalent GApplication constructor + * to set the parameter filename to ".par" and the log filename to + * "".log. The parameters will be loaded from the parameter file. + * In addition, the constructor opens the log file. + * + * If the "--help" option is provided as command line argument a help text + * about the usage of the ctool will be shown in the console and the ctool + * will exit. No log file will be opened in that case. + ***************************************************************************/ +ctool::ctool(const std::string& name, + const std::string& version, + const std::vector& args) : GApplication(name, version, args) +{ + // Catch --help option before doing anything else + if (need_help()) { + provide_help(); + exit(0); + } + + // Initialise members + init_members(); + + // If CTOOLS environment variable is set and if a parameter exists in + // the syspfiles folder then set syspfiles folder and reload parameter + // file + char* ptr = std::getenv("CTOOLS"); + if (ptr != NULL) { + std::string path = std::string(ptr) + "/syspfiles"; + std::string filename = path + "/" + par_filename(); + if (access(filename.c_str(), R_OK) == 0) { + m_pars.clear(); + m_pars.syspfiles(path); + m_pars.load(par_filename(), m_args); + } + } + + // Open the log file + logFileOpen(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Command line constructor + * + * @param[in] name Application name. + * @param[in] version Application version. * @param[in] argc Number of arguments in command line. * @param[in] argv Array of command line arguments. * diff --git a/src/support/ctool.hpp b/src/support/ctool.hpp index 7b09697..f7a287a 100755 --- a/src/support/ctool.hpp +++ b/src/support/ctool.hpp @@ -50,9 +50,15 @@ class ctool : public GApplication { public: // Constructors and destructors - ctool(const std::string& name, const std::string& version); - ctool(const std::string& name, const std::string& version, - int argc, char* argv[]); + ctool(const std::string& name, + const std::string& version); + ctool(const std::string& name, + const std::string& version, + const std::vector& args); + ctool(const std::string& name, + const std::string& version, + int argc, + char* argv[]); ctool(const ctool& app); virtual ~ctool(void); diff --git a/test/test_cscaldb.py b/test/test_cscaldb.py index 0376c9f..afa4320 100755 --- a/test/test_cscaldb.py +++ b/test/test_cscaldb.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # # ========================================================================== -#import gammalib import cscripts from testing import test @@ -34,7 +33,7 @@ class Test(test): # Constructor def __init__(self): """ - Constructor. + Constructor """ # Call base class constructor test.__init__(self) @@ -45,7 +44,7 @@ class Test(test): # Set test functions def set(self): """ - Set all test functions. + Set all test functions """ # Set test name self.name('cscaldb') @@ -53,6 +52,7 @@ class Test(test): # Append tests self.append(self._test_cmd, 'Test cscaldb on command line') self.append(self._test_python, 'Test cscaldb from Python') + self.append(self._test_pickeling, 'Test cscaldb pickeling') # Return return @@ -60,7 +60,7 @@ class Test(test): # Test cscaldb on command line def _test_cmd(self): """ - Test cscaldb on the command line. + Test cscaldb on the command line """ # Set script name cscaldb = self._script('cscaldb') @@ -81,7 +81,7 @@ class Test(test): # Test cscaldb from Python def _test_python(self): """ - Test cscaldb from Python. + Test cscaldb from Python """ # Set-up cscaldb caldb = cscripts.cscaldb() @@ -94,3 +94,26 @@ class Test(test): # Return return + + # Test cscaldb pickeling + def _test_pickeling(self): + """ + Test cscaldb pickeling + """ + # Perform pickeling tests of empty class + self._pickeling(cscripts.cscaldb()) + + # Set-up cscaldb + caldb = cscripts.cscaldb() + caldb['logfile'] = 'cscaldb_py1_pickle.log' + caldb['chatter'] = 2 + + # Perform pickeling tests of filled class + obj = self._pickeling(caldb) + + # Run script + obj.logFileOpen() # Make sure we get a log file + obj.run() + + # Return + return diff --git a/test/test_cslightcrv.py b/test/test_cslightcrv.py index abbc507..cad4547 100755 --- a/test/test_cslightcrv.py +++ b/test/test_cslightcrv.py @@ -33,7 +33,7 @@ class Test(test): This test class makes unit tests for the cslightcrv script by using it from the command line and from Python. """ - + # Constructor def __init__(self): """ @@ -60,6 +60,7 @@ class Test(test): # Append tests self.append(self._test_cmd, 'Test cslightcrv on command line') self.append(self._test_python, 'Test cslightcrv from Python') + self.append(self._test_pickeling, 'Test cslightcrv pickeling') # Return return @@ -274,6 +275,45 @@ class Test(test): # Return return + # Test cslightcrv pickeling + def _test_pickeling(self): + """ + Test cslightcrv pickeling + """ + # Perform pickeling tests of empty class + self._pickeling(cscripts.cslightcrv()) + + # Set-up unbinned cslightcrv + lcrv = cscripts.cslightcrv() + lcrv['inobs'] = self._events + lcrv['inmodel'] = self._model + lcrv['srcname'] = 'Crab' + lcrv['caldb'] = self._caldb + lcrv['irf'] = self._irf + lcrv['tbinalg'] = 'LIN' + lcrv['tmin'] = '2020-01-01T00:00:00' + lcrv['tmax'] = '2020-01-01T00:05:00' + lcrv['tbins'] = 3 + lcrv['method'] = '3D' + lcrv['enumbins'] = 0 + lcrv['emin'] = 0.1 + lcrv['emax'] = 100.0 + lcrv['outfile'] = 'cslightcrv_py1_pickle.fits' + lcrv['logfile'] = 'cslightcrv_py1_pickle.log' + lcrv['chatter'] = 2 + lcrv['publish'] = True + + # Perform pickeling tests of filled class + obj = self._pickeling(lcrv) + + # Run cslightcrv script and save light curve + obj.logFileOpen() # Make sure we get a log file + obj.run() + obj.save() + + # Return + return + # Check light curve result file def _check_light_curve(self, filename, bins, prefactor=5.7e-16): """ @@ -312,6 +352,6 @@ class Test(test): # Close FITS file fits.close() - + # Return return diff --git a/test/test_cstsmapsplit.py b/test/test_cstsmapsplit.py index 5fee17c..04f5e9a 100755 --- a/test/test_cstsmapsplit.py +++ b/test/test_cstsmapsplit.py @@ -56,6 +56,7 @@ class Test(test): # Append tests self.append(self._test_cmd, 'Test cstsmapsplit on command line') self.append(self._test_python, 'Test cstsmapsplit from Python') + self.append(self._test_pickeling, 'Test cstsmapsplit pickeling') # Return return @@ -178,6 +179,46 @@ class Test(test): # Return return + # Test cstsmapsplit pickeling + def _test_pickeling(self): + """ + Test cstsmapsplit pickeling + """ + # Perform pickeling tests of empty class + self._pickeling(cscripts.cstsmapsplit()) + + # Set-up cstsmapsplit + tsmapsplit = cscripts.cstsmapsplit() + tsmapsplit['inobs'] = self._events + tsmapsplit['inmodel'] = self._model + tsmapsplit['srcname'] = 'Crab' + tsmapsplit['caldb'] = self._caldb + tsmapsplit['irf'] = self._irf + tsmapsplit['outmap'] = 'tsmap.fits' + tsmapsplit['bins_per_job'] = 5 + tsmapsplit['compute_null'] = False + tsmapsplit['outfile'] = 'cstsmapsplit_py1_pickle.dat' + tsmapsplit['nxpix'] = 5 + tsmapsplit['nypix'] = 5 + tsmapsplit['binsz'] = 0.05 + tsmapsplit['coordsys'] = 'CEL' + tsmapsplit['xref'] = 83.6331 + tsmapsplit['yref'] = 22.01 + tsmapsplit['proj'] = 'CAR' + tsmapsplit['logfile'] = 'cstsmapsplit_py1_pickle.log' + tsmapsplit['chatter'] = 2 + + # Perform pickeling tests of filled class + obj = self._pickeling(tsmapsplit) + + # Run cstsmapsplit script and save the commands + obj.logFileOpen() # Make sure we get a log file + obj.run() + obj.save() + + # Return + return + # Check observation definition XML file def _check_cmdfile(self, filename): """ diff --git a/test/testing.py.in b/test/testing.py.in index b1437e0..3a49aff 100755 --- a/test/testing.py.in +++ b/test/testing.py.in @@ -18,6 +18,8 @@ # # ========================================================================== import os +import sys +import pickle import gammalib @@ -232,3 +234,36 @@ class test(gammalib.GPythonTestSuite): # Return return + + # Test pickeling + def _pickeling(self, object): + """ + Test class pickeling + + Parameters + ---------- + object : `~gammalib.GBase` + Class instance + """ + # Get class name + name = object.__class__.__name__ + + # Start exception catching + self.test_try('Test pickeling of "%s" class.' % name) + + # Test if pickling results in an exception + try: + dump = pickle.dumps(object) + obj = pickle.loads(dump) + dump_again = pickle.dumps(obj) + self.test_assert(dump == dump_again, + 'Check pickled dump of "%s\n%s\n%s"' % + (name, str(object), str(obj))) + self.test_try_success() + except: + _, e, _ = sys.exc_info() + self.test_try_failure('Error in pickeling "%s" (%s).' % + (name, str(e))) + + # Return + return obj