Commit 7acb69d5790f3b66cfb652b29d2bf8dbeddfa328

Authored by Jürgen Knödlseder
1 parent ff4fc707

Derive csspec script from cslikelihood base class and add "statistic" parameter

ChangeLog
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 * Version 1.5.0 released 3 * Version 1.5.0 released
4 ======================== 4 ========================
5 5
  6 + Add "statistic" parameter to all likelihood tools (#2237)
6 Rename ctlike "stat" parameter to "statistic" (#2237) 7 Rename ctlike "stat" parameter to "statistic" (#2237)
7 Enable handling of On/Off observations in csspec (#2231) 8 Enable handling of On/Off observations in csspec (#2231)
8 Add csphagen script (#2208) 9 Add csphagen script (#2208)
@@ -127,6 +127,11 @@ ctulimit - Compute upper limit @@ -127,6 +127,11 @@ ctulimit - Compute upper limit
127 Add "statistic" parameter to allow setting of optimizer statistic (#2237). 127 Add "statistic" parameter to allow setting of optimizer statistic (#2237).
128 128
129 129
  130 +support - Support classes
  131 +-------------------------
  132 +Add ctobservation.obs() method to set an observation container.
  133 +
  134 +
130 cscaldb - Inspect calibration database 135 cscaldb - Inspect calibration database
131 -------------------------------------- 136 --------------------------------------
132 None 137 None
@@ -238,6 +243,10 @@ None @@ -238,6 +243,10 @@ None
238 243
239 csspec - Generates Spectral Energy Distribution 244 csspec - Generates Spectral Energy Distribution
240 ----------------------------------------------- 245 -----------------------------------------------
  246 +The csspec script now derived from the cslikelihood base class. A "statistic"
  247 +parameter was added to allow setting the optimizer statistic for the spectrum
  248 +generation (#2237).
  249 +
241 The csspec script now can also handle On/Off spectra for SED generation (#2231). 250 The csspec script now can also handle On/Off spectra for SED generation (#2231).
242 251
243 The csspec script now can also handle non-CTA data. For that purpose a "method" 252 The csspec script now can also handle non-CTA data. For that purpose a "method"
cscripts/csspec.par
@@ -37,6 +37,7 @@ emax, r, a, 100.0,,, "Upper energy limit (TeV)" @@ -37,6 +37,7 @@ emax, r, a, 100.0,,, "Upper energy limit (TeV)"
37 enumbins, i, a, 20,,, "Number of energy bins" 37 enumbins, i, a, 20,,, "Number of energy bins"
38 ebinalg, s, a, LOG,LIN|LOG|FILE,, "Binning algorithm" 38 ebinalg, s, a, LOG,LIN|LOG|FILE,, "Binning algorithm"
39 ebinfile, f, a, NONE,,, "Name of the file containing the energy bin definition" 39 ebinfile, f, a, NONE,,, "Name of the file containing the energy bin definition"
  40 +statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic"
40 calc_ts, b, h, yes,,, "Compute TS value in each bin" 41 calc_ts, b, h, yes,,, "Compute TS value in each bin"
41 calc_ulim, b, h, yes,,, "Compute upper limit in each bin" 42 calc_ulim, b, h, yes,,, "Compute upper limit in each bin"
42 fix_srcs, b, h, yes,,, "Fix other skymodel parameters" 43 fix_srcs, b, h, yes,,, "Fix other skymodel parameters"
cscripts/csspec.py
@@ -26,12 +26,12 @@ import ctools @@ -26,12 +26,12 @@ import ctools
26 # ============ # 26 # ============ #
27 # csspec class # 27 # csspec class #
28 # ============ # 28 # ============ #
29 -class csspec(ctools.cscript): 29 +class csspec(ctools.cslikelihood):
30 """ 30 """
31 Generates a spectrum 31 Generates a spectrum
32 32
33 - This class implements the generation of a spectral energy distribution  
34 - from data. 33 + This class implements the generation of a Spectral Energy Distribution
  34 + (SED) from gamma-ray observations.
35 """ 35 """
36 36
37 # Constructors and destructors 37 # Constructors and destructors
@@ -39,9 +39,8 @@ class csspec(ctools.cscript): @@ -39,9 +39,8 @@ class csspec(ctools.cscript):
39 """ 39 """
40 Constructor 40 Constructor
41 """ 41 """
42 - # Set name  
43 - self._name = 'csspec'  
44 - self._version = ctools.__version__ 42 + # Initialise application by calling the appropriate class constructor
  43 + self._init_cslikelihood('csspec', ctools.__version__, argv)
45 44
46 # Initialise data members 45 # Initialise data members
47 self._ebounds = gammalib.GEbounds() 46 self._ebounds = gammalib.GEbounds()
@@ -50,12 +49,6 @@ class csspec(ctools.cscript): @@ -50,12 +49,6 @@ class csspec(ctools.cscript):
50 self._onoff_mode = False 49 self._onoff_mode = False
51 self._method = 'AUTO' 50 self._method = 'AUTO'
52 51
53 - # Initialise observation container from constructor arguments  
54 - self._obs, argv = self._set_input_obs(argv)  
55 -  
56 - # Initialise application by calling the appropriate class constructor  
57 - self._init_cscript(argv)  
58 -  
59 # Return 52 # Return
60 return 53 return
61 54
@@ -73,13 +66,16 @@ class csspec(ctools.cscript): @@ -73,13 +66,16 @@ class csspec(ctools.cscript):
73 Get parameters from parfile and setup the observation 66 Get parameters from parfile and setup the observation
74 """ 67 """
75 # Set observation if not done before 68 # Set observation if not done before
76 - if self._obs == None or self._obs.size() == 0: 69 + if self.obs().size() == 0:
77 self._require_inobs('csspec::get_parameters()') 70 self._require_inobs('csspec::get_parameters()')
78 - self._obs = self._get_observations() 71 + self.obs(self._get_observations())
  72 +
  73 + # Set observation statistic
  74 + self._set_obs_statistic(gammalib.toupper(self['statistic'].string()))
79 75
80 # Set models if we have none 76 # Set models if we have none
81 - if self._obs.models().size() == 0:  
82 - self._obs.models(self['inmodel'].filename()) 77 + if self.obs().models().size() == 0:
  78 + self.obs().models(self['inmodel'].filename())
83 79
84 # Query source name 80 # Query source name
85 self['srcname'].string() 81 self['srcname'].string()
@@ -92,7 +88,7 @@ class csspec(ctools.cscript): @@ -92,7 +88,7 @@ class csspec(ctools.cscript):
92 n_unbinned = 0 88 n_unbinned = 0
93 n_binned = 0 89 n_binned = 0
94 n_onoff = 0 90 n_onoff = 0
95 - for obs in self._obs: 91 + for obs in self.obs():
96 if obs.classname() == 'GCTAObservation': 92 if obs.classname() == 'GCTAObservation':
97 if obs.eventtype() == 'CountsCube': 93 if obs.eventtype() == 'CountsCube':
98 n_binned += 1 94 n_binned += 1
@@ -101,7 +97,7 @@ class csspec(ctools.cscript): @@ -101,7 +97,7 @@ class csspec(ctools.cscript):
101 elif obs.classname() == 'GCTAOnOffObservation': 97 elif obs.classname() == 'GCTAOnOffObservation':
102 n_onoff += 1 98 n_onoff += 1
103 n_cta = n_unbinned + n_binned + n_onoff 99 n_cta = n_unbinned + n_binned + n_onoff
104 - n_other = self._obs.size() - n_cta 100 + n_other = self.obs().size() - n_cta
105 101
106 # If spectrum method is not "NODES" then set spectrum method and 102 # If spectrum method is not "NODES" then set spectrum method and
107 # script mode according to type of CTA observations 103 # script mode according to type of CTA observations
@@ -194,9 +190,9 @@ class csspec(ctools.cscript): @@ -194,9 +190,9 @@ class csspec(ctools.cscript):
194 # should work reasonably well since for each observation the 190 # should work reasonably well since for each observation the
195 # relevant energy bins will be selected. 191 # relevant energy bins will be selected.
196 if self._binned_mode: 192 if self._binned_mode:
197 - cube_ebounds = self._obs[0].events().ebounds() 193 + cube_ebounds = self.obs()[0].events().ebounds()
198 else: 194 else:
199 - cube_ebounds = self._obs[0].rmf().etrue() 195 + cube_ebounds = self.obs()[0].rmf().etrue()
200 196
201 # Loop over user energy boundaries and collect all energy bins 197 # Loop over user energy boundaries and collect all energy bins
202 # that overlap 198 # that overlap
@@ -244,7 +240,7 @@ class csspec(ctools.cscript): @@ -244,7 +240,7 @@ class csspec(ctools.cscript):
244 ' Specify overlapping energy range.' 240 ' Specify overlapping energy range.'
245 raise RuntimeError(msg) 241 raise RuntimeError(msg)
246 242
247 - # Unbinned mode 243 + # Unbinned mode
248 else: 244 else:
249 self._ebounds = self._create_ebounds() 245 self._ebounds = self._create_ebounds()
250 246
@@ -260,15 +256,15 @@ class csspec(ctools.cscript): @@ -260,15 +256,15 @@ class csspec(ctools.cscript):
260 256
261 # Log counts cube energy range for binned mode 257 # Log counts cube energy range for binned mode
262 if self._binned_mode: 258 if self._binned_mode:
263 - cube_ebounds = self._obs[0].events().ebounds() 259 + cube_ebounds = self.obs()[0].events().ebounds()
264 value = '%s - %s' % (str(cube_ebounds.emin()), 260 value = '%s - %s' % (str(cube_ebounds.emin()),
265 str(cube_ebounds.emax())) 261 str(cube_ebounds.emax()))
266 self._log_value(gammalib.TERSE, 'Counts cube energy range', value) 262 self._log_value(gammalib.TERSE, 'Counts cube energy range', value)
267 263
268 # Log RMF energy range for On/Off mode 264 # Log RMF energy range for On/Off mode
269 elif self._onoff_mode: 265 elif self._onoff_mode:
270 - etrue = self._obs[0].rmf().etrue()  
271 - ereco = self._obs[0].rmf().emeasured() 266 + etrue = self.obs()[0].rmf().etrue()
  267 + ereco = self.obs()[0].rmf().emeasured()
272 vtrue = '%s - %s' % (str(etrue.emin()), str(etrue.emax())) 268 vtrue = '%s - %s' % (str(etrue.emin()), str(etrue.emax()))
273 vreco = '%s - %s' % (str(ereco.emin()), str(ereco.emax())) 269 vreco = '%s - %s' % (str(ereco.emin()), str(ereco.emax()))
274 self._log_value(gammalib.TERSE, 'RMF true energy range', vtrue) 270 self._log_value(gammalib.TERSE, 'RMF true energy range', vtrue)
@@ -291,7 +287,7 @@ class csspec(ctools.cscript): @@ -291,7 +287,7 @@ class csspec(ctools.cscript):
291 self._log_header1(gammalib.TERSE, 'Adjust model parameters') 287 self._log_header1(gammalib.TERSE, 'Adjust model parameters')
292 288
293 # Adjust model parameters dependent on input user parameters 289 # Adjust model parameters dependent on input user parameters
294 - for model in self._obs.models(): 290 + for model in self.obs().models():
295 291
296 # Initialise TS flag for all models to false 292 # Initialise TS flag for all models to false
297 model.tscalc(False) 293 model.tscalc(False)
@@ -350,7 +346,7 @@ class csspec(ctools.cscript): @@ -350,7 +346,7 @@ class csspec(ctools.cscript):
350 models = gammalib.GModels() 346 models = gammalib.GModels()
351 347
352 # Loop over model containers 348 # Loop over model containers
353 - for model in self._obs.models(): 349 + for model in self.obs().models():
354 350
355 # If we deal with source model then replace the spectral model 351 # If we deal with source model then replace the spectral model
356 # by a node function 352 # by a node function
@@ -360,7 +356,7 @@ class csspec(ctools.cscript): @@ -360,7 +356,7 @@ class csspec(ctools.cscript):
360 energies = gammalib.GEnergies() 356 energies = gammalib.GEnergies()
361 for i in range(self._ebounds.size()): 357 for i in range(self._ebounds.size()):
362 energies.append(self._ebounds.elogmean(i)) 358 energies.append(self._ebounds.elogmean(i))
363 - 359 +
364 # Setup spectral node function 360 # Setup spectral node function
365 spectrum = gammalib.GModelSpectralNodes(model.spectral(), energies) 361 spectrum = gammalib.GModelSpectralNodes(model.spectral(), energies)
366 spectrum.autoscale() 362 spectrum.autoscale()
@@ -388,7 +384,7 @@ class csspec(ctools.cscript): @@ -388,7 +384,7 @@ class csspec(ctools.cscript):
388 models.append(model) 384 models.append(model)
389 385
390 # Put new model in observation containers 386 # Put new model in observation containers
391 - self._obs.models(models) 387 + self.obs().models(models)
392 388
393 # Return 389 # Return
394 return 390 return
@@ -463,9 +459,11 @@ class csspec(ctools.cscript): @@ -463,9 +459,11 @@ class csspec(ctools.cscript):
463 rmf[idst_true, idst_reco] = obs.rmf()[isrc_true, isrc_reco] 459 rmf[idst_true, idst_reco] = obs.rmf()[isrc_true, isrc_reco]
464 460
465 # Set On/Off observations 461 # Set On/Off observations
466 - id = obs.id() 462 + id = obs.id()
  463 + statistic = obs.statistic()
467 obs = gammalib.GCTAOnOffObservation(pha_on, pha_off, arf, rmf) 464 obs = gammalib.GCTAOnOffObservation(pha_on, pha_off, arf, rmf)
468 obs.id(id) 465 obs.id(id)
  466 + obs.statistic(statistic)
469 467
470 # Return observation 468 # Return observation
471 return obs 469 return obs
@@ -493,7 +491,7 @@ class csspec(ctools.cscript): @@ -493,7 +491,7 @@ class csspec(ctools.cscript):
493 self._log_header3(gammalib.EXPLICIT, 'Filtering cube') 491 self._log_header3(gammalib.EXPLICIT, 'Filtering cube')
494 492
495 # Select layers 493 # Select layers
496 - cubemask = ctools.ctcubemask(self._obs) 494 + cubemask = ctools.ctcubemask(self.obs())
497 cubemask['regfile'] = 'NONE' 495 cubemask['regfile'] = 'NONE'
498 cubemask['ra'] = 'UNDEFINED' 496 cubemask['ra'] = 'UNDEFINED'
499 cubemask['dec'] = 'UNDEFINED' 497 cubemask['dec'] = 'UNDEFINED'
@@ -516,12 +514,12 @@ class csspec(ctools.cscript): @@ -516,12 +514,12 @@ class csspec(ctools.cscript):
516 514
517 # Loop over all input observations and select energy bins for 515 # Loop over all input observations and select energy bins for
518 # all On/Off observations 516 # all On/Off observations
519 - for run in self._obs: 517 + for run in self.obs():
520 if run.classname() == 'GCTAOnOffObservation': 518 if run.classname() == 'GCTAOnOffObservation':
521 obs.append(self._select_onoff_obs(run, emin, emax)) 519 obs.append(self._select_onoff_obs(run, emin, emax))
522 520
523 # Append models 521 # Append models
524 - obs.models(self._obs.models()) 522 + obs.models(self.obs().models())
525 523
526 # Use ctselect for unbinned analysis 524 # Use ctselect for unbinned analysis
527 else: 525 else:
@@ -530,7 +528,7 @@ class csspec(ctools.cscript): @@ -530,7 +528,7 @@ class csspec(ctools.cscript):
530 self._log_header3(gammalib.EXPLICIT, 'Selecting events') 528 self._log_header3(gammalib.EXPLICIT, 'Selecting events')
531 529
532 # Select events 530 # Select events
533 - select = ctools.ctselect(self._obs) 531 + select = ctools.ctselect(self.obs())
534 select['ra'] = 'UNDEFINED' 532 select['ra'] = 'UNDEFINED'
535 select['dec'] = 'UNDEFINED' 533 select['dec'] = 'UNDEFINED'
536 select['rad'] = 'UNDEFINED' 534 select['rad'] = 'UNDEFINED'
@@ -707,7 +705,7 @@ class csspec(ctools.cscript): @@ -707,7 +705,7 @@ class csspec(ctools.cscript):
707 self._log_header3(gammalib.EXPLICIT, 'Performing fit') 705 self._log_header3(gammalib.EXPLICIT, 'Performing fit')
708 706
709 # Perform maximum likelihood fit 707 # Perform maximum likelihood fit
710 - like = ctools.ctlike(self._obs) 708 + like = ctools.ctlike(self.obs())
711 like['edisp'] = self['edisp'].boolean() 709 like['edisp'] = self['edisp'].boolean()
712 like.run() 710 like.run()
713 711
@@ -856,7 +854,7 @@ class csspec(ctools.cscript): @@ -856,7 +854,7 @@ class csspec(ctools.cscript):
856 self._get_parameters() 854 self._get_parameters()
857 855
858 # Write input observation container into logger 856 # Write input observation container into logger
859 - self._log_observations(gammalib.NORMAL, self._obs, 'Input observation') 857 + self._log_observations(gammalib.NORMAL, self.obs(), 'Input observation')
860 858
861 # Write spectral binning into logger 859 # Write spectral binning into logger
862 self._log_spectral_binning() 860 self._log_spectral_binning()
@@ -931,7 +929,7 @@ class csspec(ctools.cscript): @@ -931,7 +929,7 @@ class csspec(ctools.cscript):
931 929
932 # Set default name is user name is empty 930 # Set default name is user name is empty
933 if not name: 931 if not name:
934 - user_name = self._name 932 + user_name = self._name()
935 else: 933 else:
936 user_name = name 934 user_name = name
937 935
@@ -959,7 +957,7 @@ class csspec(ctools.cscript): @@ -959,7 +957,7 @@ class csspec(ctools.cscript):
959 Set model 957 Set model
960 """ 958 """
961 # Copy models 959 # Copy models
962 - self._obs.models(models.clone()) 960 + self.obs().models(models.clone())
963 961
964 # Return 962 # Return
965 return 963 return
doc/source/users/reference_manual/csspec.rst
@@ -68,7 +68,7 @@ General parameters @@ -68,7 +68,7 @@ General parameters
68 68
69 ``caldb [string]`` 69 ``caldb [string]``
70 Calibration database. 70 Calibration database.
71 - 71 +
72 ``irf [string]`` 72 ``irf [string]``
73 Instrumental response function. 73 Instrumental response function.
74 74
@@ -89,19 +89,27 @@ General parameters @@ -89,19 +89,27 @@ General parameters
89 89
90 ``emin [real]`` 90 ``emin [real]``
91 Lower energy limit of events (in TeV). 91 Lower energy limit of events (in TeV).
92 - 92 +
93 ``emax [real]`` 93 ``emax [real]``
94 Upper energy limit of events (in TeV). 94 Upper energy limit of events (in TeV).
95 - 95 +
96 ``enumbins [integer]`` 96 ``enumbins [integer]``
97 Number of energy bins. 97 Number of energy bins.
98 - 98 +
99 ``ebinalg <FILE|LIN|LOG> [string]`` 99 ``ebinalg <FILE|LIN|LOG> [string]``
100 Algorithm for defining energy bins. 100 Algorithm for defining energy bins.
101 - 101 +
102 ``ebinfile [file]`` 102 ``ebinfile [file]``
103 Name of the file containing the energy bin definition. 103 Name of the file containing the energy bin definition.
104 104
  105 +``(statistic = DEFAULT) <DEFAULT|CSTAT|WSTAT|CHI2> [string]``
  106 + Optimization statistic. ``DEFAULT`` uses the default statistic for all
  107 + observations, which is ``CSTAT`` or the statistic specified in the
  108 + observation definition XML file. ``CSTAT`` uses the C statistic for
  109 + all observations, ``WSTAT`` uses the W statistic for all On/Off
  110 + observations, and ``CHI2`` uses the Chi squared statistic for all
  111 + binned or stacked observations.
  112 +
105 ``(calc_ts = yes) [boolean]`` 113 ``(calc_ts = yes) [boolean]``
106 Compute TS for each spectral point? 114 Compute TS for each spectral point?
107 115
@@ -124,21 +132,23 @@ Standard parameters @@ -124,21 +132,23 @@ Standard parameters
124 ``(chatter = 2) [integer]`` 132 ``(chatter = 2) [integer]``
125 Verbosity of the executable: 133 Verbosity of the executable:
126 ``chatter = 0``: no information will be logged 134 ``chatter = 0``: no information will be logged
127 - 135 +
128 ``chatter = 1``: only errors will be logged 136 ``chatter = 1``: only errors will be logged
129 - 137 +
130 ``chatter = 2``: errors and actions will be logged 138 ``chatter = 2``: errors and actions will be logged
131 - 139 +
132 ``chatter = 3``: report about the task execution 140 ``chatter = 3``: report about the task execution
133 - 141 +
134 ``chatter = 4``: detailed report about the task execution 142 ``chatter = 4``: detailed report about the task execution
135 - 143 +
136 ``(clobber = yes) [boolean]`` 144 ``(clobber = yes) [boolean]``
137 - Specifies whether an existing source spectrum output file should be overwritten.  
138 - 145 + Specifies whether an existing source spectrum output file should be
  146 + overwritten.
  147 +
139 ``(debug = no) [boolean]`` 148 ``(debug = no) [boolean]``
140 - Enables debug mode. In debug mode the executable will dump any log file output to the console.  
141 - 149 + Enables debug mode. In debug mode the executable will dump any log file
  150 + output to the console.
  151 +
142 ``(mode = ql) [string]`` 152 ``(mode = ql) [string]``
143 Mode of automatic parameters (default is "ql", i.e. "query and learn"). 153 Mode of automatic parameters (default is "ql", i.e. "query and learn").
144 154
pyext/ctlikelihood.i
@@ -141,15 +141,23 @@ public: @@ -141,15 +141,23 @@ public:
141 # The function supports either an observation container, or an argument 141 # The function supports either an observation container, or an argument
142 # list or no argument as "argv" parameter. The function also writes the 142 # list or no argument as "argv" parameter. The function also writes the
143 # header in the log file and switches the date on for logging. 143 # header in the log file and switches the date on for logging.
144 -def _init_cslikelihood(self, argv): 144 +def _init_cslikelihood(self, name, version, argv):
145 if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations): 145 if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations):
146 - cslikelihood.__init__(self, self._name, self._version, argv[0]) 146 + cslikelihood.__init__(self, name, version, argv[0])
147 elif len(argv) > 0: 147 elif len(argv) > 0:
148 - cslikelihood.__init__(self, self._name, self._version, *argv) 148 + cslikelihood.__init__(self, name, version, *argv)
149 else: 149 else:
150 - cslikelihood.__init__(self, self._name, self._version) 150 + cslikelihood.__init__(self, name, version)
151 # Set logger properties 151 # Set logger properties
152 self._log_header() 152 self._log_header()
153 self._log.date(True) 153 self._log.date(True)
154 cslikelihood._init_cslikelihood = _init_cslikelihood 154 cslikelihood._init_cslikelihood = _init_cslikelihood
  155 +
  156 +# Execute the script
  157 +def _execute(self):
  158 + self.logFileOpen()
  159 + self._read_ahead(True)
  160 + self.run()
  161 + self.save()
  162 +cslikelihood.execute = _execute
155 %} 163 %}
pyext/ctobservation.i
@@ -88,6 +88,7 @@ public: @@ -88,6 +88,7 @@ public:
88 virtual void save(void) = 0; 88 virtual void save(void) = 0;
89 89
90 // Public methods 90 // Public methods
  91 + void obs(const GObservations& obs);
91 const GObservations& obs(void) const; 92 const GObservations& obs(void) const;
92 void write_ogip_keywords(GFitsHDU* hdu) const; 93 void write_ogip_keywords(GFitsHDU* hdu) const;
93 94
@@ -142,19 +143,19 @@ public: @@ -142,19 +143,19 @@ public:
142 # The function supports either an observation container, or an argument 143 # The function supports either an observation container, or an argument
143 # list or no argument as "argv" parameter. The function also writes the 144 # list or no argument as "argv" parameter. The function also writes the
144 # header in the log file and switches the date on for logging. 145 # header in the log file and switches the date on for logging.
145 -def _init_csobservation(self, argv): 146 +def _init_csobservation(self, name, version, argv):
146 if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations): 147 if len(argv) > 0 and isinstance(argv[0],gammalib.GObservations):
147 - csobservation.__init__(self, self._name, self._version, argv[0]) 148 + csobservation.__init__(self, name, version, argv[0])
148 elif len(argv) > 0: 149 elif len(argv) > 0:
149 - csobservation.__init__(self, self._name, self._version, *argv) 150 + csobservation.__init__(self, name, version, *argv)
150 else: 151 else:
151 - csobservation.__init__(self, self._name, self._version) 152 + csobservation.__init__(self, name, version)
152 # Set logger properties 153 # Set logger properties
153 self._log_header() 154 self._log_header()
154 self._log.date(True) 155 self._log.date(True)
155 csobservation._init_csobservation = _init_csobservation 156 csobservation._init_csobservation = _init_csobservation
156 157
157 -# Define an iterator over all observations 158 +# Define an iterator over all unbinned observations
158 def _unbinned_observations(self): 159 def _unbinned_observations(self):
159 obs = self._first_unbinned_observation() 160 obs = self._first_unbinned_observation()
160 while obs != None: 161 while obs != None:
@@ -162,4 +163,12 @@ def _unbinned_observations(self): @@ -162,4 +163,12 @@ def _unbinned_observations(self):
162 obs = self._next_unbinned_observation() 163 obs = self._next_unbinned_observation()
163 ctool._unbinned_observations = _unbinned_observations 164 ctool._unbinned_observations = _unbinned_observations
164 cscript._unbinned_observations = _unbinned_observations 165 cscript._unbinned_observations = _unbinned_observations
  166 +
  167 +# Execute the script
  168 +def _execute(self):
  169 + self.logFileOpen()
  170 + self._read_ahead(True)
  171 + self.run()
  172 + self.save()
  173 +csobservation.execute = _execute
165 %} 174 %}
src/support/ctlikelihood.cpp
@@ -305,6 +305,9 @@ double ctlikelihood::evaluate(GModelPar&amp; par, const double&amp; value) @@ -305,6 +305,9 @@ double ctlikelihood::evaluate(GModelPar&amp; par, const double&amp; value)
305 * For On/Off CTA observations of type GCTAOnOffObservation the fit statistic 305 * For On/Off CTA observations of type GCTAOnOffObservation the fit statistic
306 * is always set. Possible values are @c POISSON, @c CSTAT or @c WSTAT (case 306 * is always set. Possible values are @c POISSON, @c CSTAT or @c WSTAT (case
307 * insensitive). 307 * insensitive).
  308 + *
  309 + * If @p statistic is any other string the fit statistic of the observations
  310 + * will not be modified.
308 ***************************************************************************/ 311 ***************************************************************************/
309 void ctlikelihood::set_obs_statistic(const std::string& statistic) 312 void ctlikelihood::set_obs_statistic(const std::string& statistic)
310 { 313 {