Commit 2003d181817cdbb09050a4c4168fdef27fc55450

Authored by Jürgen Knödlseder
1 parent a92dd304

Implement Python pickling support (#1938)

ChangeLog
1   -2018-06-15
  1 +2018-06-29
2 2  
3 3 * Version 1.6.0 released
4 4 ========================
... ... @@ -14,8 +14,10 @@
14 14 Also compute TS in csspec for On/Off analysis using wstat statistic (#2312)
15 15 Allow specifying of input sky map in ctskymap (#2311)
16 16 Accelerate IRF and RING background methods in ctskymap (#2309)
  17 + Add upper limit computation is csspec for NODES method (#2233)
17 18 Define MET with respect to the observation time reference or "mjdref"
18 19 parameter (#2054)
  20 + Implement Python pickeling support (#1938)
19 21  
20 22  
21 23 2018-04-26
... ...
1 1 New Features and Important Changes in ctools 1.6.0
2 2  
3   -20 June 2018
  3 +29 June 2018
4 4  
5 5  
6 6 Introduction
... ... @@ -11,12 +11,12 @@ ctools release with respect to the precedent release.
11 11  
12 12 Configuration
13 13 -------------
14   -Keep existing library path in installation script on Mac OS X (#2420)
  14 +Keep existing library path in installation script on Mac OS X (#2420).
15 15  
16 16  
17 17 Python interface
18 18 ----------------
19   -None
  19 +ctools and cscripts can now be pickled from Python (#1938).
20 20  
21 21  
22 22 Support model
... ... @@ -288,6 +288,10 @@ csspec now properly computes the Test Statistic for an On/Off analysis using
288 288 the "wstat" statistic in the case that the input model definition XML file
289 289 did not contain a background model (#2312).
290 290  
  291 +csspec now computes upper limits also for the NODES method by fixing all node
  292 +intensities and varying each node until the log-likelihood increases by a
  293 +certain amount (#2233).
  294 +
291 295  
292 296 cssrcdetect - Detects sources in sky map
293 297 ----------------------------------------
... ...
cscripts/csspec.py
... ... @@ -758,6 +758,42 @@ class csspec(ctools.csobservation):
758 758 result['flux'] = spectrum[i*2+1].value() * norm
759 759 result['flux_err'] = spectrum[i*2+1].error() * norm
760 760  
  761 + # Compute upper flux limit
  762 + ulimit_value = -1.0
  763 + if self['calc_ulim'].boolean():
  764 +
  765 + # Logging information
  766 + self._log_header3(gammalib.EXPLICIT, 'Computing upper limit')
  767 +
  768 + # Copy observation container
  769 + obs = like.obs().copy()
  770 +
  771 + # Fix intensities of all nodes
  772 + spectral = obs.models()[self['srcname'].string()].spectral()
  773 + for par in spectral:
  774 + par.fix()
  775 +
  776 + # Create upper limit object
  777 + ulimit = ctools.ctulimit(obs)
  778 + ulimit['srcname'] = self['srcname'].string()
  779 + ulimit['parname'] = 'Intensity%d' % i
  780 + ulimit['eref'] = elogmean.TeV()
  781 + ulimit['tol'] = 1.0e-3
  782 +
  783 + # Try to run upper limit and catch exceptions
  784 + try:
  785 + ulimit.run()
  786 + ulimit_value = ulimit.diff_ulimit()
  787 + except:
  788 + self._log_string(gammalib.EXPLICIT, 'Upper limit '
  789 + 'calculation failed.')
  790 + ulimit_value = -1.0
  791 +
  792 + # Compute upper limit
  793 + if ulimit_value > 0.0:
  794 + result['ulimit'] = ulimit_value * elogmean.MeV() * \
  795 + elogmean.MeV() * gammalib.MeV2erg
  796 +
761 797 # Compute TS
762 798 if self['calc_ts'].boolean():
763 799  
... ...
doc/source/admin/release_history/1.6.rst
... ... @@ -12,6 +12,7 @@ In particular, this release provides:
12 12  
13 13 * Support for Xspec spectral analysis
14 14 * Improved computation speed for :ref:`ctskymap` and :ref:`csphagen`
  15 +* Support for Python pickeling
15 16  
16 17  
17 18 Bug fixes
... ... @@ -41,6 +42,8 @@ Improvements
41 42 Allow specifying of input skymap to :ref:`ctskymap` tool
42 43 * [`2309 <https://cta-redmine.irap.omp.eu/issues/2309>`_] -
43 44 Accelerate `IRF` and `RING` background methods in :ref:`ctskymap`
  45 +* [`2233 <https://cta-redmine.irap.omp.eu/issues/2233>`_] -
  46 + Add upper limit computation is :ref:`csspec` for ``NODES`` method
44 47 * [`2045 <https://cta-redmine.irap.omp.eu/issues/2045>`_] -
45 48 Define MET with respect to the observation time reference or the ``mjdref``
46 49 user parameter (#2054)
... ... @@ -49,7 +52,8 @@ Improvements
49 52 New features
50 53 ------------
51 54  
52   -* ...
  55 +* [`1938 <https://cta-redmine.irap.omp.eu/issues/1938>`_] -
  56 + Support pickeling of ctools and cscripts in Python
53 57  
54 58  
55 59 Clean up
... ...
pyext/ctlikelihood.i
1 1 /***************************************************************************
2 2 * ctlikelihood - Base class for likelihood tools *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2016-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2016-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -42,14 +42,22 @@
42 42 class cslikelihood : public ctlikelihood {
43 43 public:
44 44 // Constructors and destructors
45   - cslikelihood(const std::string& name, const std::string& version) :
  45 + cslikelihood(const std::string& name,
  46 + const std::string& version) :
46 47 ctlikelihood(name, version) {}
47   - cslikelihood(const std::string& name, const std::string& version,
  48 + cslikelihood(const std::string& name,
  49 + const std::string& version,
48 50 const GObservations& obs) :
49 51 ctlikelihood(name, version, obs) {}
50   - cslikelihood(const std::string& name, const std::string& version,
51   - int argc, char* argv[]) :
52   - ctlikelihood(name, version, argc, argv){}
  52 + cslikelihood(const std::string& name,
  53 + const std::string& version,
  54 + const std::vector<std::string>& args) :
  55 + ctlikelihood(name, version, args) {}
  56 + cslikelihood(const std::string& name,
  57 + const std::string& version,
  58 + int argc,
  59 + char* argv[]) :
  60 + ctlikelihood(name, version, argc, argv) {}
53 61 cslikelihood(const cslikelihood& app) : ctlikelihood(app) {}
54 62 virtual ~cslikelihood(void) {}
55 63  
... ... @@ -74,11 +82,18 @@ class ctlikelihood : public ctobservation {
74 82  
75 83 public:
76 84 // Constructors and destructors
77   - ctlikelihood(const std::string& name, const std::string& version);
78   - ctlikelihood(const std::string& name, const std::string& version,
  85 + ctlikelihood(const std::string& name,
  86 + const std::string& version);
  87 + ctlikelihood(const std::string& name,
  88 + const std::string& version,
79 89 const GObservations& obs);
80   - ctlikelihood(const std::string& name, const std::string& version,
81   - int argc, char* argv[]);
  90 + ctlikelihood(const std::string& name,
  91 + const std::string& version,
  92 + const std::vector<std::string>& args);
  93 + ctlikelihood(const std::string& name,
  94 + const std::string& version,
  95 + int argc,
  96 + char* argv[]);
82 97 ctlikelihood(const ctlikelihood& app);
83 98 virtual ~ctlikelihood(void);
84 99  
... ... @@ -108,11 +123,18 @@ public:
108 123 class cslikelihood : public ctlikelihood {
109 124 public:
110 125 // Constructors and destructors
111   - cslikelihood(const std::string& name, const std::string& version);
112   - cslikelihood(const std::string& name, const std::string& version,
  126 + cslikelihood(const std::string& name,
  127 + const std::string& version);
  128 + cslikelihood(const std::string& name,
  129 + const std::string& version,
113 130 const GObservations& obs);
114   - cslikelihood(const std::string& name, const std::string& version,
115   - int ARGC, char **ARGV);
  131 + cslikelihood(const std::string& name,
  132 + const std::string& version,
  133 + const std::vector<std::string>& args);
  134 + cslikelihood(const std::string& name,
  135 + const std::string& version,
  136 + int ARGC,
  137 + char **ARGV);
116 138 cslikelihood(const cslikelihood& app);
117 139 virtual ~cslikelihood(void);
118 140  
... ... @@ -133,6 +155,21 @@ public:
133 155 /***********************************************************************//**
134 156 * @brief Likelihood tool base class Python extensions
135 157 ***************************************************************************/
  158 +%extend cslikelihood {
  159 +%pythoncode {
  160 + def __getstate__(self):
  161 + state = (ctool.__getstate__(self), self.obs())
  162 + return state
  163 + def __setstate__(self, state):
  164 + ctool.__setstate__(self, state[0])
  165 + self.obs(state[1])
  166 +}
  167 +}
  168 +
  169 +
  170 +/***********************************************************************//**
  171 + * @brief Likelihood tool base class Python extensions
  172 + ***************************************************************************/
136 173 %pythoncode %{
137 174  
138 175 # Initialise application by calling the appropriate base class constructor.
... ... @@ -143,7 +180,10 @@ def _init_cslikelihood(self, name, version, argv):
143 180 if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations):
144 181 cslikelihood.__init__(self, name, version, argv[0])
145 182 elif len(argv) > 0:
146   - cslikelihood.__init__(self, name, version, *argv)
  183 + if len(argv) == 3 and argv[0] == name and argv[1] == version:
  184 + cslikelihood.__init__(self, name, version, argv[2])
  185 + else:
  186 + cslikelihood.__init__(self, name, version, *argv)
147 187 else:
148 188 cslikelihood.__init__(self, name, version)
149 189 # Set logger properties
... ...
pyext/ctobservation.i
1 1 /***************************************************************************
2 2 * ctobservation - Base class for observation tools *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2016-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2016-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -42,14 +42,22 @@
42 42 class csobservation : public ctobservation {
43 43 public:
44 44 // Constructors and destructors
45   - csobservation(const std::string& name, const std::string& version) :
  45 + csobservation(const std::string& name,
  46 + const std::string& version) :
46 47 ctobservation(name, version) {}
47   - csobservation(const std::string& name, const std::string& version,
  48 + csobservation(const std::string& name,
  49 + const std::string& version,
48 50 const GObservations& obs) :
49 51 ctobservation(name, version, obs) {}
50   - csobservation(const std::string& name, const std::string& version,
51   - int argc, char* argv[]) :
52   - ctobservation(name, version, argc, argv){}
  52 + csobservation(const std::string& name,
  53 + const std::string& version,
  54 + const std::vector<std::string>& args) :
  55 + ctobservation(name, version, args) {}
  56 + csobservation(const std::string& name,
  57 + const std::string& version,
  58 + int argc,
  59 + char* argv[]) :
  60 + ctobservation(name, version, argc, argv) {}
53 61 csobservation(const csobservation& app) : ctobservation(app) {}
54 62 virtual ~csobservation(void) {}
55 63  
... ... @@ -74,11 +82,18 @@ class ctobservation : public ctool {
74 82  
75 83 public:
76 84 // Constructors and destructors
77   - ctobservation(const std::string& name, const std::string& version);
78   - ctobservation(const std::string& name, const std::string& version,
  85 + ctobservation(const std::string& name,
  86 + const std::string& version);
  87 + ctobservation(const std::string& name,
  88 + const std::string& version,
79 89 const GObservations& obs);
80   - ctobservation(const std::string& name, const std::string& version,
81   - int ARGC, char **ARGV);
  90 + ctobservation(const std::string& name,
  91 + const std::string& version,
  92 + const std::vector<std::string>& args);
  93 + ctobservation(const std::string& name,
  94 + const std::string& version,
  95 + int ARGC,
  96 + char **ARGV);
82 97 ctobservation(const ctobservation& app);
83 98 virtual ~ctobservation(void);
84 99  
... ... @@ -120,11 +135,18 @@ public:
120 135 class csobservation : public ctobservation {
121 136 public:
122 137 // Constructors and destructors
123   - csobservation(const std::string& name, const std::string& version);
124   - csobservation(const std::string& name, const std::string& version,
  138 + csobservation(const std::string& name,
  139 + const std::string& version);
  140 + csobservation(const std::string& name,
  141 + const std::string& version,
125 142 const GObservations& obs);
126   - csobservation(const std::string& name, const std::string& version,
127   - int ARGC, char **ARGV);
  143 + csobservation(const std::string& name,
  144 + const std::string& version,
  145 + const std::vector<std::string>& args);
  146 + csobservation(const std::string& name,
  147 + const std::string& version,
  148 + int ARGC,
  149 + char **ARGV);
128 150 csobservation(const csobservation& app);
129 151 virtual ~csobservation(void);
130 152  
... ... @@ -145,6 +167,21 @@ public:
145 167 /***********************************************************************//**
146 168 * @brief Observation tool base class Python extensions
147 169 ***************************************************************************/
  170 +%extend csobservation {
  171 +%pythoncode {
  172 + def __getstate__(self):
  173 + state = (ctool.__getstate__(self), self.obs())
  174 + return state
  175 + def __setstate__(self, state):
  176 + ctool.__setstate__(self, state[0])
  177 + self.obs(state[1])
  178 +}
  179 +}
  180 +
  181 +
  182 +/***********************************************************************//**
  183 + * @brief Observation tool base class Python extensions
  184 + ***************************************************************************/
148 185 %pythoncode %{
149 186  
150 187 # Initialise application by calling the appropriate base class constructor.
... ... @@ -155,7 +192,10 @@ def _init_csobservation(self, name, version, argv):
155 192 if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations):
156 193 csobservation.__init__(self, name, version, argv[0])
157 194 elif len(argv) > 0:
158   - csobservation.__init__(self, name, version, *argv)
  195 + if len(argv) == 3 and argv[0] == name and argv[1] == version:
  196 + csobservation.__init__(self, name, version, argv[2])
  197 + else:
  198 + csobservation.__init__(self, name, version, *argv)
159 199 else:
160 200 csobservation.__init__(self, name, version)
161 201 # Set logger properties
... ...
pyext/ctool.i
... ... @@ -36,9 +36,15 @@
36 36 class cscript : public ctool {
37 37 public:
38 38 // Constructors and destructors
39   - cscript(const std::string& name, const std::string& version) : ctool(name, version) {}
40   - cscript(const std::string& name, const std::string& version,
41   - int argc, char* argv[]) : ctool(name, version, argc, argv) {}
  39 + cscript(const std::string& name,
  40 + const std::string& version) : ctool(name, version) {}
  41 + cscript(const std::string& name,
  42 + const std::string& version,
  43 + const std::vector<std::string>& args) : ctool(name, version, args) {}
  44 + cscript(const std::string& name,
  45 + const std::string& version,
  46 + int argc,
  47 + char* argv[]) : ctool(name, version, argc, argv) {}
42 48 cscript(const ctool& app) : ctool(app) {}
43 49 virtual ~cscript(void) {}
44 50  
... ... @@ -67,9 +73,15 @@ public:
67 73 class ctool : public GApplication {
68 74 public:
69 75 // Constructors and destructors
70   - ctool(const std::string& name, const std::string& version);
71   - ctool(const std::string& name, const std::string& version,
72   - int ARGC, char **ARGV);
  76 + ctool(const std::string& name,
  77 + const std::string& version);
  78 + ctool(const std::string& name,
  79 + const std::string& version,
  80 + const std::vector<std::string>& args);
  81 + ctool(const std::string& name,
  82 + const std::string& version,
  83 + int ARGC,
  84 + char **ARGV);
73 85 ctool(const ctool& app);
74 86 virtual ~ctool(void);
75 87  
... ... @@ -219,7 +231,27 @@ public:
219 231 self->m_read_ahead = flag;
220 232 return;
221 233 }
  234 +%pythoncode {
  235 + def __getstate__(self):
  236 + state = (gammalib.GApplication.__getstate__(self),)
  237 + return state
  238 + def __setstate__(self, state):
  239 + gammalib.GApplication.__setstate__(self, state[0])
  240 +}
  241 +};
  242 +
  243 +/***********************************************************************//**
  244 + * @brief ctool base class Python extensions
  245 + ***************************************************************************/
  246 +%extend cscript {
  247 +%pythoncode {
  248 + def __getstate__(self):
  249 + state = (gammalib.GApplication.__getstate__(self),)
  250 + return state
  251 + def __setstate__(self, state):
  252 + gammalib.GApplication.__setstate__(self, state[0])
222 253 }
  254 +};
223 255  
224 256  
225 257 /***********************************************************************//**
... ... @@ -246,6 +278,8 @@ def _init_cscript(self, name, version, argv):
246 278 cscript.__init__(self, name, version)
247 279 elif len(argv) == 1:
248 280 cscript.__init__(self, name, version, *argv)
  281 + elif len(argv) == 3:
  282 + cscript.__init__(self, name, version, argv[2])
249 283 else:
250 284 raise TypeError('Invalid number of arguments given.')
251 285 # Set logger properties
... ...
pyext/ctools/tools.i
1 1 /***************************************************************************
2 2 * ctools - SWIG file *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -36,11 +36,13 @@
36 36  
37 37 /* __ Include standard typemaps for vectors and strings __________________ */
38 38 %include stl.i
39   -%include "std_vector.i"
  39 +%include std_string.i
  40 +%include std_vector.i
40 41 namespace std {
41 42 %template(vector_int) vector<int>;
42 43 %template(vector_double) vector<double>;
43 44 %template(vector_bool) vector<bool>;
  45 + %template(vector_sring) vector<std::string>;
44 46 };
45 47  
46 48 /* __ Make sure that exceptions are catched ______________________________ */
... ...
src/support/ctlikelihood.cpp
1 1 /***************************************************************************
2 2 * ctlikelihood - Base class for likelihood tools *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2016-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2016-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -78,7 +78,30 @@ ctlikelihood::ctlikelihood(const std::string&amp; name,
78 78 ctlikelihood::ctlikelihood(const std::string& name,
79 79 const std::string& version,
80 80 const GObservations& obs) :
81   - ctobservation(name, version, obs)
  81 + ctobservation(name, version, obs)
  82 +{
  83 + // Initialise members
  84 + init_members();
  85 +
  86 + // Return
  87 + return;
  88 +}
  89 +
  90 +
  91 +/***********************************************************************//**
  92 + * @brief Command line constructor
  93 + *
  94 + * @param[in] name Likelihood tool name.
  95 + * @param[in] version Likelihood tool version.
  96 + * @param[in] args Arguments vector.
  97 + *
  98 + * Constructs a likelihood tool from the @p name, @p version and command
  99 + * line arguments. See the equivalent ctool constructor for details.
  100 + ***************************************************************************/
  101 +ctlikelihood::ctlikelihood(const std::string& name,
  102 + const std::string& version,
  103 + const std::vector<std::string>& args) :
  104 + ctobservation(name, version, args)
82 105 {
83 106 // Initialise members
84 107 init_members();
... ... @@ -103,7 +126,7 @@ ctlikelihood::ctlikelihood(const std::string&amp; name,
103 126 const std::string& version,
104 127 int argc,
105 128 char *argv[]) :
106   - ctobservation(name, version, argc, argv)
  129 + ctobservation(name, version, argc, argv)
107 130 {
108 131 // Initialise members
109 132 init_members();
... ...
src/support/ctlikelihood.hpp
1 1 /***************************************************************************
2 2 * ctlikelihood - Base class for likelihood tools *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2016-2017 by Juergen Knoedlseder *
  4 + * copyright (C) 2016-2018 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -42,11 +42,18 @@ class ctlikelihood : public ctobservation {
42 42  
43 43 public:
44 44 // Constructors and destructors
45   - ctlikelihood(const std::string& name, const std::string& version);
46   - ctlikelihood(const std::string& name, const std::string& version,
  45 + ctlikelihood(const std::string& name,
  46 + const std::string& version);
  47 + ctlikelihood(const std::string& name,
  48 + const std::string& version,
47 49 const GObservations& obs);
48   - ctlikelihood(const std::string& name, const std::string& version,
49   - int argc, char* argv[]);
  50 + ctlikelihood(const std::string& name,
  51 + const std::string& version,
  52 + const std::vector<std::string>& args);
  53 + ctlikelihood(const std::string& name,
  54 + const std::string& version,
  55 + int argc,
  56 + char* argv[]);
50 57 ctlikelihood(const ctlikelihood& app);
51 58 virtual ~ctlikelihood(void);
52 59  
... ...
src/support/ctobservation.cpp
... ... @@ -93,6 +93,29 @@ ctobservation::ctobservation(const std::string&amp; name,
93 93 *
94 94 * @param[in] name Observation tool name.
95 95 * @param[in] version Observation tool version.
  96 + * @param[in] args Arguments vector.
  97 + *
  98 + * Constructs a observation tool from the @p name, @p version and command
  99 + * line arguments. See the equivalent ctool constructor for details.
  100 + ***************************************************************************/
  101 +ctobservation::ctobservation(const std::string& name,
  102 + const std::string& version,
  103 + const std::vector<std::string>& args) :
  104 + ctool(name, version, args)
  105 +{
  106 + // Initialise members
  107 + init_members();
  108 +
  109 + // Return
  110 + return;
  111 +}
  112 +
  113 +
  114 +/***********************************************************************//**
  115 + * @brief Command line constructor
  116 + *
  117 + * @param[in] name Observation tool name.
  118 + * @param[in] version Observation tool version.
96 119 * @param[in] argc Number of arguments in command line.
97 120 * @param[in] argv Array of command line arguments.
98 121 *
... ...
src/support/ctobservation.hpp
... ... @@ -45,11 +45,18 @@ class ctobservation : public ctool {
45 45  
46 46 public:
47 47 // Constructors and destructors
48   - ctobservation(const std::string& name, const std::string& version);
49   - ctobservation(const std::string& name, const std::string& version,
  48 + ctobservation(const std::string& name,
  49 + const std::string& version);
  50 + ctobservation(const std::string& name,
  51 + const std::string& version,
50 52 const GObservations& obs);
51   - ctobservation(const std::string& name, const std::string& version,
52   - int argc, char* argv[]);
  53 + ctobservation(const std::string& name,
  54 + const std::string& version,
  55 + const std::vector<std::string>& args);
  56 + ctobservation(const std::string& name,
  57 + const std::string& version,
  58 + int argc,
  59 + char* argv[]);
53 60 ctobservation(const ctobservation& app);
54 61 virtual ~ctobservation(void);
55 62  
... ...
src/support/ctool.cpp
... ... @@ -116,6 +116,58 @@ ctool::ctool(const std::string&amp; name,
116 116 *
117 117 * @param[in] name Application name.
118 118 * @param[in] version Application version.
  119 + * @param[in] args Arguments vector.
  120 + *
  121 + * Constructs a ctool from the @p name, @p version and command line
  122 + * arguments. The constructor uses the equivalent GApplication constructor
  123 + * to set the parameter filename to "<name>.par" and the log filename to
  124 + * "<name>".log. The parameters will be loaded from the parameter file.
  125 + * In addition, the constructor opens the log file.
  126 + *
  127 + * If the "--help" option is provided as command line argument a help text
  128 + * about the usage of the ctool will be shown in the console and the ctool
  129 + * will exit. No log file will be opened in that case.
  130 + ***************************************************************************/
  131 +ctool::ctool(const std::string& name,
  132 + const std::string& version,
  133 + const std::vector<std::string>& args) : GApplication(name, version, args)
  134 +{
  135 + // Catch --help option before doing anything else
  136 + if (need_help()) {
  137 + provide_help();
  138 + exit(0);
  139 + }
  140 +
  141 + // Initialise members
  142 + init_members();
  143 +
  144 + // If CTOOLS environment variable is set and if a parameter exists in
  145 + // the syspfiles folder then set syspfiles folder and reload parameter
  146 + // file
  147 + char* ptr = std::getenv("CTOOLS");
  148 + if (ptr != NULL) {
  149 + std::string path = std::string(ptr) + "/syspfiles";
  150 + std::string filename = path + "/" + par_filename();
  151 + if (access(filename.c_str(), R_OK) == 0) {
  152 + m_pars.clear();
  153 + m_pars.syspfiles(path);
  154 + m_pars.load(par_filename(), m_args);
  155 + }
  156 + }
  157 +
  158 + // Open the log file
  159 + logFileOpen();
  160 +
  161 + // Return
  162 + return;
  163 +}
  164 +
  165 +
  166 +/***********************************************************************//**
  167 + * @brief Command line constructor
  168 + *
  169 + * @param[in] name Application name.
  170 + * @param[in] version Application version.
119 171 * @param[in] argc Number of arguments in command line.
120 172 * @param[in] argv Array of command line arguments.
121 173 *
... ...
src/support/ctool.hpp
... ... @@ -50,9 +50,15 @@
50 50 class ctool : public GApplication {
51 51 public:
52 52 // Constructors and destructors
53   - ctool(const std::string& name, const std::string& version);
54   - ctool(const std::string& name, const std::string& version,
55   - int argc, char* argv[]);
  53 + ctool(const std::string& name,
  54 + const std::string& version);
  55 + ctool(const std::string& name,
  56 + const std::string& version,
  57 + const std::vector<std::string>& args);
  58 + ctool(const std::string& name,
  59 + const std::string& version,
  60 + int argc,
  61 + char* argv[]);
56 62 ctool(const ctool& app);
57 63 virtual ~ctool(void);
58 64  
... ...
test/test_cscaldb.py
... ... @@ -18,7 +18,6 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -#import gammalib
22 21 import cscripts
23 22 from testing import test
24 23  
... ... @@ -34,7 +33,7 @@ class Test(test):
34 33 # Constructor
35 34 def __init__(self):
36 35 """
37   - Constructor.
  36 + Constructor
38 37 """
39 38 # Call base class constructor
40 39 test.__init__(self)
... ... @@ -45,7 +44,7 @@ class Test(test):
45 44 # Set test functions
46 45 def set(self):
47 46 """
48   - Set all test functions.
  47 + Set all test functions
49 48 """
50 49 # Set test name
51 50 self.name('cscaldb')
... ... @@ -53,6 +52,7 @@ class Test(test):
53 52 # Append tests
54 53 self.append(self._test_cmd, 'Test cscaldb on command line')
55 54 self.append(self._test_python, 'Test cscaldb from Python')
  55 + self.append(self._test_pickeling, 'Test cscaldb pickeling')
56 56  
57 57 # Return
58 58 return
... ... @@ -60,7 +60,7 @@ class Test(test):
60 60 # Test cscaldb on command line
61 61 def _test_cmd(self):
62 62 """
63   - Test cscaldb on the command line.
  63 + Test cscaldb on the command line
64 64 """
65 65 # Set script name
66 66 cscaldb = self._script('cscaldb')
... ... @@ -81,7 +81,7 @@ class Test(test):
81 81 # Test cscaldb from Python
82 82 def _test_python(self):
83 83 """
84   - Test cscaldb from Python.
  84 + Test cscaldb from Python
85 85 """
86 86 # Set-up cscaldb
87 87 caldb = cscripts.cscaldb()
... ... @@ -94,3 +94,26 @@ class Test(test):
94 94  
95 95 # Return
96 96 return
  97 +
  98 + # Test cscaldb pickeling
  99 + def _test_pickeling(self):
  100 + """
  101 + Test cscaldb pickeling
  102 + """
  103 + # Perform pickeling tests of empty class
  104 + self._pickeling(cscripts.cscaldb())
  105 +
  106 + # Set-up cscaldb
  107 + caldb = cscripts.cscaldb()
  108 + caldb['logfile'] = 'cscaldb_py1_pickle.log'
  109 + caldb['chatter'] = 2
  110 +
  111 + # Perform pickeling tests of filled class
  112 + obj = self._pickeling(caldb)
  113 +
  114 + # Run script
  115 + obj.logFileOpen() # Make sure we get a log file
  116 + obj.run()
  117 +
  118 + # Return
  119 + return
... ...
test/test_cslightcrv.py
... ... @@ -33,7 +33,7 @@ class Test(test):
33 33 This test class makes unit tests for the cslightcrv script by using it
34 34 from the command line and from Python.
35 35 """
36   -
  36 +
37 37 # Constructor
38 38 def __init__(self):
39 39 """
... ... @@ -60,6 +60,7 @@ class Test(test):
60 60 # Append tests
61 61 self.append(self._test_cmd, 'Test cslightcrv on command line')
62 62 self.append(self._test_python, 'Test cslightcrv from Python')
  63 + self.append(self._test_pickeling, 'Test cslightcrv pickeling')
63 64  
64 65 # Return
65 66 return
... ... @@ -274,6 +275,45 @@ class Test(test):
274 275 # Return
275 276 return
276 277  
  278 + # Test cslightcrv pickeling
  279 + def _test_pickeling(self):
  280 + """
  281 + Test cslightcrv pickeling
  282 + """
  283 + # Perform pickeling tests of empty class
  284 + self._pickeling(cscripts.cslightcrv())
  285 +
  286 + # Set-up unbinned cslightcrv
  287 + lcrv = cscripts.cslightcrv()
  288 + lcrv['inobs'] = self._events
  289 + lcrv['inmodel'] = self._model
  290 + lcrv['srcname'] = 'Crab'
  291 + lcrv['caldb'] = self._caldb
  292 + lcrv['irf'] = self._irf
  293 + lcrv['tbinalg'] = 'LIN'
  294 + lcrv['tmin'] = '2020-01-01T00:00:00'
  295 + lcrv['tmax'] = '2020-01-01T00:05:00'
  296 + lcrv['tbins'] = 3
  297 + lcrv['method'] = '3D'
  298 + lcrv['enumbins'] = 0
  299 + lcrv['emin'] = 0.1
  300 + lcrv['emax'] = 100.0
  301 + lcrv['outfile'] = 'cslightcrv_py1_pickle.fits'
  302 + lcrv['logfile'] = 'cslightcrv_py1_pickle.log'
  303 + lcrv['chatter'] = 2
  304 + lcrv['publish'] = True
  305 +
  306 + # Perform pickeling tests of filled class
  307 + obj = self._pickeling(lcrv)
  308 +
  309 + # Run cslightcrv script and save light curve
  310 + obj.logFileOpen() # Make sure we get a log file
  311 + obj.run()
  312 + obj.save()
  313 +
  314 + # Return
  315 + return
  316 +
277 317 # Check light curve result file
278 318 def _check_light_curve(self, filename, bins, prefactor=5.7e-16):
279 319 """
... ... @@ -312,6 +352,6 @@ class Test(test):
312 352  
313 353 # Close FITS file
314 354 fits.close()
315   -
  355 +
316 356 # Return
317 357 return
... ...
test/test_cstsmapsplit.py
... ... @@ -56,6 +56,7 @@ class Test(test):
56 56 # Append tests
57 57 self.append(self._test_cmd, 'Test cstsmapsplit on command line')
58 58 self.append(self._test_python, 'Test cstsmapsplit from Python')
  59 + self.append(self._test_pickeling, 'Test cstsmapsplit pickeling')
59 60  
60 61 # Return
61 62 return
... ... @@ -178,6 +179,46 @@ class Test(test):
178 179 # Return
179 180 return
180 181  
  182 + # Test cstsmapsplit pickeling
  183 + def _test_pickeling(self):
  184 + """
  185 + Test cstsmapsplit pickeling
  186 + """
  187 + # Perform pickeling tests of empty class
  188 + self._pickeling(cscripts.cstsmapsplit())
  189 +
  190 + # Set-up cstsmapsplit
  191 + tsmapsplit = cscripts.cstsmapsplit()
  192 + tsmapsplit['inobs'] = self._events
  193 + tsmapsplit['inmodel'] = self._model
  194 + tsmapsplit['srcname'] = 'Crab'
  195 + tsmapsplit['caldb'] = self._caldb
  196 + tsmapsplit['irf'] = self._irf
  197 + tsmapsplit['outmap'] = 'tsmap.fits'
  198 + tsmapsplit['bins_per_job'] = 5
  199 + tsmapsplit['compute_null'] = False
  200 + tsmapsplit['outfile'] = 'cstsmapsplit_py1_pickle.dat'
  201 + tsmapsplit['nxpix'] = 5
  202 + tsmapsplit['nypix'] = 5
  203 + tsmapsplit['binsz'] = 0.05
  204 + tsmapsplit['coordsys'] = 'CEL'
  205 + tsmapsplit['xref'] = 83.6331
  206 + tsmapsplit['yref'] = 22.01
  207 + tsmapsplit['proj'] = 'CAR'
  208 + tsmapsplit['logfile'] = 'cstsmapsplit_py1_pickle.log'
  209 + tsmapsplit['chatter'] = 2
  210 +
  211 + # Perform pickeling tests of filled class
  212 + obj = self._pickeling(tsmapsplit)
  213 +
  214 + # Run cstsmapsplit script and save the commands
  215 + obj.logFileOpen() # Make sure we get a log file
  216 + obj.run()
  217 + obj.save()
  218 +
  219 + # Return
  220 + return
  221 +
181 222 # Check observation definition XML file
182 223 def _check_cmdfile(self, filename):
183 224 """
... ...
test/testing.py.in
... ... @@ -18,6 +18,8 @@
18 18 #
19 19 # ==========================================================================
20 20 import os
  21 +import sys
  22 +import pickle
21 23 import gammalib
22 24  
23 25  
... ... @@ -232,3 +234,36 @@ class test(gammalib.GPythonTestSuite):
232 234  
233 235 # Return
234 236 return
  237 +
  238 + # Test pickeling
  239 + def _pickeling(self, object):
  240 + """
  241 + Test class pickeling
  242 +
  243 + Parameters
  244 + ----------
  245 + object : `~gammalib.GBase`
  246 + Class instance
  247 + """
  248 + # Get class name
  249 + name = object.__class__.__name__
  250 +
  251 + # Start exception catching
  252 + self.test_try('Test pickeling of "%s" class.' % name)
  253 +
  254 + # Test if pickling results in an exception
  255 + try:
  256 + dump = pickle.dumps(object)
  257 + obj = pickle.loads(dump)
  258 + dump_again = pickle.dumps(obj)
  259 + self.test_assert(dump == dump_again,
  260 + 'Check pickled dump of "%s\n%s\n%s"' %
  261 + (name, str(object), str(obj)))
  262 + self.test_try_success()
  263 + except:
  264 + _, e, _ = sys.exc_info()
  265 + self.test_try_failure('Error in pickeling "%s" (%s).' %
  266 + (name, str(e)))
  267 +
  268 + # Return
  269 + return obj
... ...