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 * Version 2.0.0 released 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 Add ASCL shields to "About" page (#3630) 7 Add ASCL shields to "About" page (#3630)
8 Use file function constructor in csspec (#3626) 8 Use file function constructor in csspec (#3626)
9 Add BINS method to csspec (#3606) 9 Add BINS method to csspec (#3606)
10 Add hidden "fix_spat" parameter to cttsmap (#3562) 10 Add hidden "fix_spat" parameter to cttsmap (#3562)
  11 + Use test source position in cssens (#3555)
11 Add optimizer setter to ctlikelihood base class 12 Add optimizer setter to ctlikelihood base class
12 Add Sphinx tutorials test script (#3510) 13 Add Sphinx tutorials test script (#3510)
13 Add "refit_if_failed" parameter to ctlike 14 Add "refit_if_failed" parameter to ctlike
1 New Features and Important Changes in ctools 2.0.0 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 Introduction 6 Introduction
@@ -283,6 +283,12 @@ the width, height and position angle of the rectangular sky regions (#3248). @@ -283,6 +283,12 @@ the width, height and position angle of the rectangular sky regions (#3248).
283 283
284 cssens - Computes sensitivity curve 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 The test source position is now used as pointing direction, eventually offset 292 The test source position is now used as pointing direction, eventually offset
287 in galactic latitude by a number of degrees specified using the "offset" 293 in galactic latitude by a number of degrees specified using the "offset"
288 parameter (#3555). 294 parameter (#3555).
README.md
1 ctools information 1 ctools information
2 ================== 2 ==================
3 -* Version: 2.0.0.dev (19 May 2021) 3 +* Version: 2.0.0.dev (20 May 2021)
4 * GammaLib dependency: 2.0.0.dev 4 * GammaLib dependency: 2.0.0.dev
5 5
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/) 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,8 +41,8 @@ type, s, h, Differential,Differential|Integral,, "Sensitivity type"
41 sigma, r, h, 5.0,,, "Significance threshold (Gaussian sigma)" 41 sigma, r, h, 5.0,,, "Significance threshold (Gaussian sigma)"
42 max_iter, i, h, 50,,, "Maximum number of iterations" 42 max_iter, i, h, 50,,, "Maximum number of iterations"
43 statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic" 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 bkgrad, r, h, 0.33,,, "Background radius (deg)" 46 bkgrad, r, h, 0.33,,, "Background radius (deg)"
47 seed, i, h, 1,,, "Initial random number generator seed" 47 seed, i, h, 1,,, "Initial random number generator seed"
48 48
cscripts/cssens.py
@@ -24,7 +24,6 @@ import gammalib @@ -24,7 +24,6 @@ import gammalib
24 import ctools 24 import ctools
25 from cscripts import obsutils 25 from cscripts import obsutils
26 from cscripts import modutils 26 from cscripts import modutils
27 -from cscripts import ioutils  
28 from cscripts import mputils 27 from cscripts import mputils
29 28
30 29
@@ -46,7 +45,7 @@ class cssens(ctools.csobservation): @@ -46,7 +45,7 @@ class cssens(ctools.csobservation):
46 # Constructor 45 # Constructor
47 def __init__(self, *argv): 46 def __init__(self, *argv):
48 """ 47 """
49 - Constructor. 48 + Constructor
50 """ 49 """
51 # Initialise application by calling the appropriate class constructor 50 # Initialise application by calling the appropriate class constructor
52 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv) 51 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)
@@ -154,7 +153,7 @@ class cssens(ctools.csobservation): @@ -154,7 +153,7 @@ class cssens(ctools.csobservation):
154 self['edisp'].boolean() 153 self['edisp'].boolean()
155 self['debug'].boolean() 154 self['debug'].boolean()
156 self['mincounts'].integer() 155 self['mincounts'].integer()
157 - 156 +
158 # Read seed 157 # Read seed
159 self._seed = self['seed'].integer() 158 self._seed = self['seed'].integer()
160 159
@@ -417,9 +416,6 @@ class cssens(ctools.csobservation): @@ -417,9 +416,6 @@ class cssens(ctools.csobservation):
417 edisp_orig = self['edisp'].boolean() 416 edisp_orig = self['edisp'].boolean()
418 self['edisp'] = False 417 self['edisp'] = False
419 418
420 - # Get seed parameter for generating events  
421 - seed = self['seed'].integer()  
422 -  
423 # Set flux ratio precision required for convergence to 5% 419 # Set flux ratio precision required for convergence to 5%
424 ratio_precision = 0.05 420 ratio_precision = 0.05
425 421
@@ -465,6 +461,9 @@ class cssens(ctools.csobservation): @@ -465,6 +461,9 @@ class cssens(ctools.csobservation):
465 # Update iteration counter 461 # Update iteration counter
466 iterations += 1 462 iterations += 1
467 463
  464 + # Increment the seed value
  465 + self._seed += 1
  466 +
468 # Write header for iteration into logger 467 # Write header for iteration into logger
469 self._log_header2(gammalib.EXPLICIT, 'Iteration '+str(iterations)) 468 self._log_header2(gammalib.EXPLICIT, 'Iteration '+str(iterations))
470 469
@@ -472,7 +471,7 @@ class cssens(ctools.csobservation): @@ -472,7 +471,7 @@ class cssens(ctools.csobservation):
472 471
473 # Simulate events for the models. "sim" holds an observation 472 # Simulate events for the models. "sim" holds an observation
474 # container with observations containing the simulated events. 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 binsz=binsz, npix=npix, 475 binsz=binsz, npix=npix,
477 log=self._log_clients, 476 log=self._log_clients,
478 debug=self['debug'].boolean(), 477 debug=self['debug'].boolean(),
@@ -589,7 +588,7 @@ class cssens(ctools.csobservation): @@ -589,7 +588,7 @@ class cssens(ctools.csobservation):
589 self._log_value(gammalib.TERSE, 'Converged flux ratio', ratio) 588 self._log_value(gammalib.TERSE, 'Converged flux ratio', ratio)
590 self._log_value(gammalib.TERSE, 'Regression coefficient', 589 self._log_value(gammalib.TERSE, 'Regression coefficient',
591 regcoeff) 590 regcoeff)
592 - 591 +
593 # If the flux has converged then check if the original 592 # If the flux has converged then check if the original
594 # value of edisp was set, and is not what has fo far 593 # value of edisp was set, and is not what has fo far
595 # been used 594 # been used
@@ -648,7 +647,7 @@ class cssens(ctools.csobservation): @@ -648,7 +647,7 @@ class cssens(ctools.csobservation):
648 break 647 break
649 648
650 # ... otherwise increase the test flux 649 # ... otherwise increase the test flux
651 - correct = 1 + ratio_precision 650 + correct = 1.0 + ratio_precision
652 crab_flux = correct * crab_flux 651 crab_flux = correct * crab_flux
653 photon_flux = correct * photon_flux 652 photon_flux = correct * photon_flux
654 energy_flux = correct * energy_flux 653 energy_flux = correct * energy_flux
@@ -744,7 +743,7 @@ class cssens(ctools.csobservation): @@ -744,7 +743,7 @@ class cssens(ctools.csobservation):
744 # Return Prefactor 743 # Return Prefactor
745 return crab_prefactor 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 Simulate events 748 Simulate events
750 749
@@ -754,8 +753,6 @@ class cssens(ctools.csobservation): @@ -754,8 +753,6 @@ class cssens(ctools.csobservation):
754 Observation container 753 Observation container
755 rad : float 754 rad : float
756 Simulation selection radius (degrees) 755 Simulation selection radius (degrees)
757 - seed : integer  
758 - Random number generator seed  
759 enumbins : integer 756 enumbins : integer
760 Number of energy bins 757 Number of energy bins
761 binsz : float 758 binsz : float
@@ -769,19 +766,14 @@ class cssens(ctools.csobservation): @@ -769,19 +766,14 @@ class cssens(ctools.csobservation):
769 # Simulate events 766 # Simulate events
770 for n_sim in range(15): 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 # Simulate observations 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 debug=self['debug'].boolean(), 775 debug=self['debug'].boolean(),
783 - edisp=self['edisp'].boolean(),  
784 - nthreads=1) 776 + edisp=self['edisp'].boolean(), nthreads=1)
785 777
786 # If a selection radius is given then select only the events within 778 # If a selection radius is given then select only the events within
787 # that selection radius 779 # that selection radius
@@ -843,14 +835,11 @@ class cssens(ctools.csobservation): @@ -843,14 +835,11 @@ class cssens(ctools.csobservation):
843 835
844 # Get user parameters 836 # Get user parameters
845 mincounts = self['mincounts'].integer() 837 mincounts = self['mincounts'].integer()
846 - bkgcut = self['bkgcut'].real() 838 + bkgexcess = self['bkgexcess'].real()
847 bkgrad = self['bkgrad'].real() 839 bkgrad = self['bkgrad'].real()
848 840
849 # Continue only if cuts were specified 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 # Get models and split them into source and background 844 # Get models and split them into source and background
856 models = self.obs().models() 845 models = self.obs().models()
@@ -869,16 +858,16 @@ class cssens(ctools.csobservation): @@ -869,16 +858,16 @@ class cssens(ctools.csobservation):
869 bck_obs.models(bck_models) 858 bck_obs.models(bck_models)
870 859
871 # Simulate source events 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 # Simulate background events in case that a background fraction cut 863 # Simulate background events in case that a background fraction cut
875 # is applied and if the number of background events was not yet 864 # is applied and if the number of background events was not yet
876 # estimated 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 # Set cut results 869 # Set cut results
881 - min_bkg_events = n_bck_evts * bkgcut 870 + min_bkg_events = n_bck_evts * bkgexcess
882 has_min_evts = n_src_evts >= mincounts 871 has_min_evts = n_src_evts >= mincounts
883 is_above_bck = n_src_evts >= min_bkg_events 872 is_above_bck = n_src_evts >= min_bkg_events
884 pass_evt_cut = has_min_evts and is_above_bck 873 pass_evt_cut = has_min_evts and is_above_bck
@@ -937,7 +926,7 @@ class cssens(ctools.csobservation): @@ -937,7 +926,7 @@ class cssens(ctools.csobservation):
937 mean_xy *= norm 926 mean_xy *= norm
938 mean_xx *= norm 927 mean_xx *= norm
939 mean_yy *= norm 928 mean_yy *= norm
940 - 929 +
941 # Compute regression coefficient 930 # Compute regression coefficient
942 rxy_norm = (mean_xx - mean_x * mean_x) * (mean_yy - mean_y * mean_y) 931 rxy_norm = (mean_xx - mean_x * mean_x) * (mean_yy - mean_y * mean_y)
943 if rxy_norm < 1e-10: 932 if rxy_norm < 1e-10:
@@ -1065,6 +1054,10 @@ class cssens(ctools.csobservation): @@ -1065,6 +1054,10 @@ class cssens(ctools.csobservation):
1065 table.card('SIGMA', self['sigma'].real(), '[sigma] Sensitivity threshold') 1054 table.card('SIGMA', self['sigma'].real(), '[sigma] Sensitivity threshold')
1066 table.card('MAX_ITER', self['max_iter'].integer(), 'Maximum number of iterations') 1055 table.card('MAX_ITER', self['max_iter'].integer(), 'Maximum number of iterations')
1067 table.card('STAT', self['statistic'].string(), 'Optimization statistic') 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 # Append filled columns to fits table 1062 # Append filled columns to fits table
1070 table.append(e_mean) 1063 table.append(e_mean)
doc/source/admin/release_history/2.0.rst
1 .. _2.0: 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 Overview 6 Overview
@@ -24,8 +24,8 @@ Bug fixes @@ -24,8 +24,8 @@ Bug fixes
24 Improvements 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 * [`3630 <https://cta-redmine.irap.omp.eu/issues/3630>`_] - 29 * [`3630 <https://cta-redmine.irap.omp.eu/issues/3630>`_] -
30 Add ASCL shields to **About** page 30 Add ASCL shields to **About** page
31 * [`3626 <https://cta-redmine.irap.omp.eu/issues/3626>`_] - 31 * [`3626 <https://cta-redmine.irap.omp.eu/issues/3626>`_] -
@@ -34,6 +34,8 @@ Improvements @@ -34,6 +34,8 @@ Improvements
34 Add ``BINS`` method to :ref:`csspec` 34 Add ``BINS`` method to :ref:`csspec`
35 * [`3562 <https://cta-redmine.irap.omp.eu/issues/3562>`_] - 35 * [`3562 <https://cta-redmine.irap.omp.eu/issues/3562>`_] -
36 Add hidden ``fix_spat`` parameter to :ref:`cttsmap` 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 * Add optimizer setter to ``ctlikelihood`` base class. 39 * Add optimizer setter to ``ctlikelihood`` base class.
38 * Add ``refit_if_failed`` parameter to :ref:`ctlike` 40 * Add ``refit_if_failed`` parameter to :ref:`ctlike`
39 * [`3441 <https://cta-redmine.irap.omp.eu/issues/3441>`_] - 41 * [`3441 <https://cta-redmine.irap.omp.eu/issues/3441>`_] -
doc/source/users/reference_manual/cssens.rst
@@ -121,6 +121,23 @@ General parameters @@ -121,6 +121,23 @@ General parameters
121 observations, and ``CHI2`` uses the Chi squared statistic for all 121 observations, and ``CHI2`` uses the Chi squared statistic for all
122 binned or stacked observations. 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 Standard parameters 142 Standard parameters
126 ------------------- 143 -------------------