Commit 035428e5dd926dcc08bfeed5917417fb4ab6c342

Authored by Jürgen Knödlseder
1 parent d9ea7da3

Also compute TS in csspec for On/Off analysis using wstat statistic (#2312)

ChangeLog
1   -2018-06-14
  1 +2018-06-15
2 2  
3 3 * Version 1.6.0 released
4 4 ========================
... ... @@ -10,8 +10,9 @@
10 10 Keep existing library path in installation script on Mac OS X (#2420)
11 11 csphagen produces Xspec compliant data (#2404)
12 12 Add show_rmf.py example script
13   - Allow specifying of input sky map in ctskymap (#2311)
14 13 Add ras() and decs() methods to csobsinfo (#2313)
  14 + Also compute TS in csspec for On/Off analysis using wstat statistic (#2312)
  15 + Allow specifying of input sky map in ctskymap (#2311)
15 16 Accelerate IRF and RING background methods in ctskymap (#2309)
16 17 Define MET with respect to the observation time reference or "mjdref"
17 18 parameter (#2054)
... ...
1 1 New Features and Important Changes in ctools 1.6.0
2 2  
3   -14 June 2018
  3 +15 June 2018
4 4  
5 5  
6 6 Introduction
... ... @@ -282,7 +282,9 @@ None
282 282  
283 283 csspec - Generates Spectral Energy Distribution
284 284 -----------------------------------------------
285   -None
  285 +csspec now properly computes the Test Statistic for an On/Off analysis using
  286 +the "wstat" statistic in the case that the input model definition XML file
  287 +did not contain a background model (#2312).
286 288  
287 289  
288 290 cssrcdetect - Detects sources in sky map
... ...
cscripts/csspec.py
... ... @@ -369,13 +369,15 @@ class csspec(ctools.csobservation):
369 369 spectrum = gammalib.GModelSpectralNodes(model.spectral(), energies)
370 370 spectrum.autoscale()
371 371  
372   - # Make sure that all nodes are positive
  372 + # Make sure that all nodes are positive. Autoscale all
  373 + # parameters so that their nominal value is unity.
373 374 for i in range(spectrum.nodes()):
374 375 par = spectrum[i*2+1]
  376 + par.autoscale()
375 377 value = par.value()
376 378 minimum = 1.0e-20 * value
377 379 if minimum <= 0.0:
378   - minimum = 1.0e-40
  380 + minimum = 1.0e-20
379 381 if minimum < value:
380 382 value = minimum
381 383 par.value(value)
... ... @@ -384,6 +386,10 @@ class csspec(ctools.csobservation):
384 386 # Set spectral component of source model
385 387 model.spectral(spectrum)
386 388  
  389 + # Make sure that TS computation is disabled (makes computation
  390 + # faster)
  391 + model.tscalc(False)
  392 +
387 393 # Append model
388 394 models.append(model)
389 395  
... ... @@ -590,13 +596,14 @@ class csspec(ctools.csobservation):
590 596 # Write header for fitting
591 597 self._log_header3(gammalib.EXPLICIT, 'Performing fit')
592 598  
593   - # Perform maximum likelihood fit
  599 + # Perform maximum likelihood fit. Skip bins that have no events.
594 600 like = ctools.ctlike(obs)
595 601 like['edisp'] = self['edisp'].boolean()
596   - like.run()
  602 + if like.obs().nobserved() > 0:
  603 + like.run()
597 604  
598 605 # Continue only if log-likelihood is non-zero
599   - if like.obs().logL() != 0.0:
  606 + if like.obs().logL() != 0.0 and like.obs().nobserved() > 0:
600 607  
601 608 # Get results
602 609 fitted_models = like.obs().models()
... ... @@ -726,7 +733,7 @@ class csspec(ctools.csobservation):
726 733 # Extract fit results
727 734 model = like.obs().models()[self['srcname'].string()]
728 735 spectrum = model.spectral()
729   - ts = model.ts()
  736 + logL0 = like.obs().logL()
730 737  
731 738 # Loop over all nodes
732 739 for i in range(spectrum.nodes()):
... ... @@ -757,12 +764,13 @@ class csspec(ctools.csobservation):
757 764 # Copy observation container
758 765 obs = like.obs().copy()
759 766  
760   - # Set intensity of node to tiny value
  767 + # Set intensity of node to tiny value by scaling the value
  768 + # by a factor 1e-8.
761 769 par = obs.models()[self['srcname'].string()].spectral()[i*2+1]
762   - value = 1.0e-20 * par.value()
763   - if par.min() > value:
764   - par.min(value)
765   - par.value(value)
  770 + par.autoscale()
  771 + par.factor_min(1.0e-8)
  772 + par.factor_value(1.0e-8)
  773 + par.autoscale()
766 774 par.fix()
767 775  
768 776 # Perform maximum likelihood fit
... ... @@ -772,7 +780,8 @@ class csspec(ctools.csobservation):
772 780  
773 781 # Store Test Statistic
774 782 model = tslike.obs().models()[self['srcname'].string()]
775   - result['TS'] = ts - model.ts()
  783 + logL1 = tslike.obs().logL()
  784 + result['TS'] = 2.0 * (logL1 - logL0)
776 785  
777 786 # Log information
778 787 value = '%e +/- %e' % (result['flux'], result['flux_err'])
... ...
doc/source/admin/release_history/1.6.rst
... ... @@ -35,6 +35,8 @@ Improvements
35 35 * Add ``show_rmf.py`` example script
36 36 * [`2313 <https://cta-redmine.irap.omp.eu/issues/2313>`_] -
37 37 Add `ras()` and `decs()` methods to :ref:`csobsinfo`
  38 +* [`2312 <https://cta-redmine.irap.omp.eu/issues/2312>`_] -
  39 + Also compute TS in :ref:`csspec` for On/Off analysis using wstat statistic
38 40 * [`2311 <https://cta-redmine.irap.omp.eu/issues/2311>`_] -
39 41 Allow specifying of input skymap to :ref:`ctskymap` tool
40 42 * [`2309 <https://cta-redmine.irap.omp.eu/issues/2309>`_] -
... ...