Commit 6fc75aff4e295eec0a856c0980a73a43d21e44e0

Authored by Jürgen Knödlseder
1 parent 955940f1

Rebase code and update documentation (#3668)

ChangeLog
1   -2021-05-19
  1 +2021-05-20
2 2  
3 3 * Version 2.0.0 released
4 4 ========================
5 5  
6   - Use test source position in cssens (#3555)
  6 + Add source counts constraints to cssens (#3668)
7 7 Add ASCL shields to "About" page (#3630)
8 8 Use file function constructor in csspec (#3626)
9 9 Add BINS method to csspec (#3606)
10 10 Add hidden "fix_spat" parameter to cttsmap (#3562)
  11 + Use test source position in cssens (#3555)
11 12 Add optimizer setter to ctlikelihood base class
12 13 Add Sphinx tutorials test script (#3510)
13 14 Add "refit_if_failed" parameter to ctlike
... ...
1 1 New Features and Important Changes in ctools 2.0.0
2 2  
3   -19 May 2021
  3 +20 May 2021
4 4  
5 5  
6 6 Introduction
... ... @@ -283,6 +283,12 @@ the width, height and position angle of the rectangular sky regions (#3248).
283 283  
284 284 cssens - Computes sensitivity curve
285 285 -----------------------------------
  286 +Added constraints on the minimum number of source counts in the sensitivity
  287 +computations. The constraints are specified by the new parameters "mincounts",
  288 +"bkgexcess" and "bkgrad". In addition, a "seed" parameter was added allowing
  289 +to specify the seed value for the random number generators. Changes were also
  290 +made to improve the stability of the sensitivity computation (#3668).
  291 +
286 292 The test source position is now used as pointing direction, eventually offset
287 293 in galactic latitude by a number of degrees specified using the "offset"
288 294 parameter (#3555).
... ...
README.md
1 1 ctools information
2 2 ==================
3   -* Version: 2.0.0.dev (19 May 2021)
  3 +* Version: 2.0.0.dev (20 May 2021)
4 4 * GammaLib dependency: 2.0.0.dev
5 5  
6 6 [![Build Status](https://cta-jenkins.irap.omp.eu/buildStatus/icon?job=ctools-integrate-os)](https://cta-jenkins.irap.omp.eu/job/ctools-integrate-os/)
... ...
cscripts/cssens.par
... ... @@ -41,8 +41,8 @@ type, s, h, Differential,Differential|Integral,, "Sensitivity type"
41 41 sigma, r, h, 5.0,,, "Significance threshold (Gaussian sigma)"
42 42 max_iter, i, h, 50,,, "Maximum number of iterations"
43 43 statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic"
44   -mincounts, i, h, 0,,, "Minimal number of source counts"
45   -bkgcut, r, h, 0.0,,, "Background uncertainty fraction"
  44 +mincounts, i, h, 0,,, "Minimum number of source counts"
  45 +bkgexcess, r, h, 0.0,,, "Background uncertainty fraction"
46 46 bkgrad, r, h, 0.33,,, "Background radius (deg)"
47 47 seed, i, h, 1,,, "Initial random number generator seed"
48 48  
... ...
cscripts/cssens.py
... ... @@ -24,7 +24,6 @@ import gammalib
24 24 import ctools
25 25 from cscripts import obsutils
26 26 from cscripts import modutils
27   -from cscripts import ioutils
28 27 from cscripts import mputils
29 28  
30 29  
... ... @@ -46,7 +45,7 @@ class cssens(ctools.csobservation):
46 45 # Constructor
47 46 def __init__(self, *argv):
48 47 """
49   - Constructor.
  48 + Constructor
50 49 """
51 50 # Initialise application by calling the appropriate class constructor
52 51 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)
... ... @@ -154,7 +153,7 @@ class cssens(ctools.csobservation):
154 153 self['edisp'].boolean()
155 154 self['debug'].boolean()
156 155 self['mincounts'].integer()
157   -
  156 +
158 157 # Read seed
159 158 self._seed = self['seed'].integer()
160 159  
... ... @@ -417,9 +416,6 @@ class cssens(ctools.csobservation):
417 416 edisp_orig = self['edisp'].boolean()
418 417 self['edisp'] = False
419 418  
420   - # Get seed parameter for generating events
421   - seed = self['seed'].integer()
422   -
423 419 # Set flux ratio precision required for convergence to 5%
424 420 ratio_precision = 0.05
425 421  
... ... @@ -465,6 +461,9 @@ class cssens(ctools.csobservation):
465 461 # Update iteration counter
466 462 iterations += 1
467 463  
  464 + # Increment the seed value
  465 + self._seed += 1
  466 +
468 467 # Write header for iteration into logger
469 468 self._log_header2(gammalib.EXPLICIT, 'Iteration '+str(iterations))
470 469  
... ... @@ -472,7 +471,7 @@ class cssens(ctools.csobservation):
472 471  
473 472 # Simulate events for the models. "sim" holds an observation
474 473 # container with observations containing the simulated events.
475   - sim = obsutils.sim(self.obs(), nbins=enumbins, seed=(iterations+seed),
  474 + sim = obsutils.sim(self.obs(), nbins=enumbins, seed=self._seed,
476 475 binsz=binsz, npix=npix,
477 476 log=self._log_clients,
478 477 debug=self['debug'].boolean(),
... ... @@ -589,7 +588,7 @@ class cssens(ctools.csobservation):
589 588 self._log_value(gammalib.TERSE, 'Converged flux ratio', ratio)
590 589 self._log_value(gammalib.TERSE, 'Regression coefficient',
591 590 regcoeff)
592   -
  591 +
593 592 # If the flux has converged then check if the original
594 593 # value of edisp was set, and is not what has fo far
595 594 # been used
... ... @@ -648,7 +647,7 @@ class cssens(ctools.csobservation):
648 647 break
649 648  
650 649 # ... otherwise increase the test flux
651   - correct = 1 + ratio_precision
  650 + correct = 1.0 + ratio_precision
652 651 crab_flux = correct * crab_flux
653 652 photon_flux = correct * photon_flux
654 653 energy_flux = correct * energy_flux
... ... @@ -744,7 +743,7 @@ class cssens(ctools.csobservation):
744 743 # Return Prefactor
745 744 return crab_prefactor
746 745  
747   - def _simulate_events(self, obs, rad, seed, enumbins, binsz, npix):
  746 + def _simulate_events(self, obs, rad, enumbins, binsz, npix):
748 747 """
749 748 Simulate events
750 749  
... ... @@ -754,8 +753,6 @@ class cssens(ctools.csobservation):
754 753 Observation container
755 754 rad : float
756 755 Simulation selection radius (degrees)
757   - seed : integer
758   - Random number generator seed
759 756 enumbins : integer
760 757 Number of energy bins
761 758 binsz : float
... ... @@ -769,19 +766,14 @@ class cssens(ctools.csobservation):
769 766 # Simulate events
770 767 for n_sim in range(15):
771 768  
772   - # Increment the seed
773   - seed += n_sim
  769 + # Increment the seed value
  770 + self._seed += 1
774 771  
775 772 # Simulate observations
776   - sim = obsutils.sim(obs,
777   - nbins=enumbins,
778   - seed=seed,
779   - binsz=binsz,
780   - npix=npix,
781   - log=self._log_clients,
  773 + sim = obsutils.sim(obs, nbins=enumbins, seed=self._seed, binsz=binsz,
  774 + npix=npix, log=self._log_clients,
782 775 debug=self['debug'].boolean(),
783   - edisp=self['edisp'].boolean(),
784   - nthreads=1)
  776 + edisp=self['edisp'].boolean(), nthreads=1)
785 777  
786 778 # If a selection radius is given then select only the events within
787 779 # that selection radius
... ... @@ -843,14 +835,11 @@ class cssens(ctools.csobservation):
843 835  
844 836 # Get user parameters
845 837 mincounts = self['mincounts'].integer()
846   - bkgcut = self['bkgcut'].real()
  838 + bkgexcess = self['bkgexcess'].real()
847 839 bkgrad = self['bkgrad'].real()
848 840  
849 841 # Continue only if cuts were specified
850   - if mincounts > 0 or bkgcut > 0.0:
851   -
852   - # Get seed parameter for generating events
853   - seed = self['seed'].integer()
  842 + if mincounts > 0 or bkgexcess > 0.0:
854 843  
855 844 # Get models and split them into source and background
856 845 models = self.obs().models()
... ... @@ -869,16 +858,16 @@ class cssens(ctools.csobservation):
869 858 bck_obs.models(bck_models)
870 859  
871 860 # Simulate source events
872   - n_src_evts = self._simulate_events(src_obs, 0.0, seed, enumbins, binsz, npix)
  861 + n_src_evts = self._simulate_events(src_obs, 0.0, enumbins, binsz, npix)
873 862  
874 863 # Simulate background events in case that a background fraction cut
875 864 # is applied and if the number of background events was not yet
876 865 # estimated
877   - if bkgcut > 0.0 and n_bck_evts == None:
878   - n_bck_evts = self._simulate_events(bck_obs, bkgrad, seed, enumbins, binsz, npix)
  866 + if bkgexcess > 0.0 and n_bck_evts == None:
  867 + n_bck_evts = self._simulate_events(bck_obs, bkgrad, enumbins, binsz, npix)
879 868  
880 869 # Set cut results
881   - min_bkg_events = n_bck_evts * bkgcut
  870 + min_bkg_events = n_bck_evts * bkgexcess
882 871 has_min_evts = n_src_evts >= mincounts
883 872 is_above_bck = n_src_evts >= min_bkg_events
884 873 pass_evt_cut = has_min_evts and is_above_bck
... ... @@ -937,7 +926,7 @@ class cssens(ctools.csobservation):
937 926 mean_xy *= norm
938 927 mean_xx *= norm
939 928 mean_yy *= norm
940   -
  929 +
941 930 # Compute regression coefficient
942 931 rxy_norm = (mean_xx - mean_x * mean_x) * (mean_yy - mean_y * mean_y)
943 932 if rxy_norm < 1e-10:
... ... @@ -1065,6 +1054,10 @@ class cssens(ctools.csobservation):
1065 1054 table.card('SIGMA', self['sigma'].real(), '[sigma] Sensitivity threshold')
1066 1055 table.card('MAX_ITER', self['max_iter'].integer(), 'Maximum number of iterations')
1067 1056 table.card('STAT', self['statistic'].string(), 'Optimization statistic')
  1057 + table.card('MINCOUNT', self['mincounts'].integer(), 'Minimum number of source counts')
  1058 + table.card('BKGEXCES', self['bkgexcess'].real(), 'Background uncertainty fraction')
  1059 + table.card('BKGRAD', self['bkgrad'].real(), '[deg] Background radius')
  1060 + table.card('SEED', self['seed'].integer(), 'Seed value for random numbers')
1068 1061  
1069 1062 # Append filled columns to fits table
1070 1063 table.append(e_mean)
... ...
doc/source/admin/release_history/2.0.rst
1 1 .. _2.0:
2 2  
3   -ctools 2.0 release (19 May 2021)
  3 +ctools 2.0 release (20 May 2021)
4 4 ================================
5 5  
6 6 Overview
... ... @@ -24,8 +24,8 @@ Bug fixes
24 24 Improvements
25 25 ------------
26 26  
27   -* [`3555 <https://cta-redmine.irap.omp.eu/issues/3555>`_] -
28   - Use test source position in :ref:`cssens`
  27 +* [`3668 <https://cta-redmine.irap.omp.eu/issues/3668>`_] -
  28 + Add source counts constraints to :ref:`cssens`
29 29 * [`3630 <https://cta-redmine.irap.omp.eu/issues/3630>`_] -
30 30 Add ASCL shields to **About** page
31 31 * [`3626 <https://cta-redmine.irap.omp.eu/issues/3626>`_] -
... ... @@ -34,6 +34,8 @@ Improvements
34 34 Add ``BINS`` method to :ref:`csspec`
35 35 * [`3562 <https://cta-redmine.irap.omp.eu/issues/3562>`_] -
36 36 Add hidden ``fix_spat`` parameter to :ref:`cttsmap`
  37 +* [`3555 <https://cta-redmine.irap.omp.eu/issues/3555>`_] -
  38 + Use test source position in :ref:`cssens`
37 39 * Add optimizer setter to ``ctlikelihood`` base class.
38 40 * Add ``refit_if_failed`` parameter to :ref:`ctlike`
39 41 * [`3441 <https://cta-redmine.irap.omp.eu/issues/3441>`_] -
... ...
doc/source/users/reference_manual/cssens.rst
... ... @@ -121,6 +121,23 @@ General parameters
121 121 observations, and ``CHI2`` uses the Chi squared statistic for all
122 122 binned or stacked observations.
123 123  
  124 +``(mincounts = 0) [integer]``
  125 + Constraint on the minimum number of required source counts. Conventionally,
  126 + a constraint for a minimum number of 10 source counts is applied for CTA
  127 + sensitivity estimates. If ``0`` is specified then no source counts limit
  128 + will be applied.
  129 +
  130 +``(bkgexcess = 0.0) [real]``
  131 + Constraint on the minimum number of required source counts with respect to
  132 + the number of background counts. This value is a fraction that is
  133 + conventionally set to ``0.05`` (or 5%) which means that the number of source
  134 + counts needs to exceed 5% of the number of background counts. If ``0.0``is
  135 + specifie then no constraint will be applied.
  136 +
  137 +``(bkgrad = 0.33) [real]``
  138 + Radius in degrees used to estimate the number of background counts
  139 + underlying the source. This radius is only used if ``bkgexcess > 0.0``.
  140 +
124 141  
125 142 Standard parameters
126 143 -------------------
... ...