Commit 6fc75aff4e295eec0a856c0980a73a43d21e44e0
1 parent
955940f1
Rebase code and update documentation (#3668)
Showing
7 changed files
with
60 additions
and
41 deletions
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 |
NEWS
| 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 | [](https://cta-jenkins.irap.omp.eu/job/ctools-integrate-os/) | 6 | [](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 | ------------------- |