Commit ca35e8850ad18ff189a63713794aa760f3d349e4

Authored by Jürgen Knödlseder
1 parent 77884dc8

Change names of cssrcdetect robustness parameters (#2498)

ChangeLog
1   -2018-09-07
  1 +2018-09-10
2 2  
3 3 * Version 1.6.0 released
4 4 ========================
... ... @@ -9,6 +9,7 @@
9 9 Use full RMF true energy range for On/Off analysis in csspec (#2656)
10 10 Defer import of ROOT module in csroot2caldb to run method (#2652)
11 11 Transparently update parameter files (#2513)
  12 + Make cssrcdetect more robust (#2498)
12 13 Change formula for number of true energy bins in csphagen (#2490)
13 14 Remove ctools::is_valid_filename() method
14 15 Handle zero model for SUBDIV method in show_response.py (#2456)
... ...
1 1 New Features and Important Changes in ctools 1.6.0
2 2  
3   -7 September 2018
  3 +10 September 2018
4 4  
5 5  
6 6 Introduction
... ... @@ -335,7 +335,12 @@ certain amount (#2233).
335 335  
336 336 cssrcdetect - Detects sources in sky map
337 337 ----------------------------------------
338   -None
  338 +The script was made more robust by optionally convolving the input sky map
  339 +with a smoothing kernel with a specified correlation radius (options are a
  340 +"DISK" or a "GAUSSIAN" kernel, default is now "DISK"). In addition, the mean
  341 +and standard deviation of the pixel values are now computed locally over a
  342 +given radius, controlled through the "avgrad" parameter. This accomodates for
  343 +counts variations in the field of view (#2498).
339 344  
340 345  
341 346 cstsdist - Computes Test Statistic distribution
... ...
cscripts/cssrcdetect.par
... ... @@ -23,16 +23,16 @@ outds9file, f, a, ds9.reg,,, "Output DS9 region file"
23 23 #
24 24 # Script parameters
25 25 #==================
26   -srcmodel, s, a, POINT,POINT,, "Source model type"
27   -bkgmodel, s, a, NONE,NONE|IRF|AEFF|CUBE,, "Background model type"
28   -threshold, r, a, 5.0,,, "Detection threshold (Gaussian sigma)"
29   -maxsrcs, i, h, 20,1,1000, "Maximum number of sources"
30   -exclrad, r, h, 0.2,,, "Exclusion radius (deg)"
31   -fit_pos, b, h, yes,,, "Fit source positions?"
32   -fit_shape, b, h, yes,,, "Fit source shapes?"
33   -momentradius, r, a, 200,,, "Radius (deg) for computing map mean and std-deviation values"
34   -smoothkernel, s, a, NONE,NONE|DISK|GAUSSIAN,,"Smoothing kernel to use for smoothing the input sky map"
35   -smoothparam, r, a, 0.05,,,"Smoothing kernel parameters (sigma for GAUS, radius for DISK)"
  26 +srcmodel, s, a, POINT,POINT,, "Source model type"
  27 +bkgmodel, s, a, NONE,NONE|IRF|AEFF|CUBE,, "Background model type"
  28 +threshold, r, a, 5.0,,, "Detection threshold (Gaussian sigma)"
  29 +maxsrcs, i, h, 20,1,1000, "Maximum number of sources"
  30 +avgrad, r, h, 1.0,,, "Averaging radius (deg) for significance computation"
  31 +corr_rad, r, a, 0.1,,, "Correlation kernel radius (deg)"
  32 +corr_kern, s, h, DISK,NONE|DISK|GAUSSIAN,, "Correlation kernel to apply to input sky map"
  33 +exclrad, r, h, 0.3,,, "Exclusion radius (deg)"
  34 +fit_pos, b, h, yes,,, "Fit source positions?"
  35 +fit_shape, b, h, yes,,, "Fit source shapes?"
36 36  
37 37 #
38 38 # Standard parameters
... ...
cscripts/cssrcdetect.py
... ... @@ -77,15 +77,15 @@ class cssrcdetect(ctools.cscript):
77 77 self['fit_shape'].boolean()
78 78  
79 79 # Query the smoothing parameters
80   - self['smoothkernel'].string()
81   - if self['smoothkernel'].string().upper() != 'NONE':
82   - self['smoothparam'].real()
  80 + self['avgrad'].real()
  81 + self['corr_kern'].string()
  82 + if self['corr_kern'].string().upper() != 'NONE':
  83 + self['corr_rad'].real()
83 84  
84 85 # Query ahead output model filename
85 86 if self._read_ahead():
86 87 self['outmodel'].filename()
87 88 self['outds9file'].filename()
88   - self['momentradius'].real()
89 89  
90 90 # Write input parameters into logger
91 91 self._log_parameters(gammalib.TERSE)
... ... @@ -109,11 +109,11 @@ class cssrcdetect(ctools.cscript):
109 109 self._log_header3(gammalib.NORMAL, 'Iteration '+str(i+1))
110 110  
111 111 # Get map moments
112   - mean, std = self._map_moments(counts, self['momentradius'].real())
113   -
  112 + mean, std = self._map_moments(counts, self['avgrad'].real())
  113 +
114 114 # Compute threshold
115 115 sigmap = (counts - mean)/std
116   -
  116 +
117 117 # Get maximum value and corresponding sky direction
118 118 value, pos = self._find_maximum(sigmap)
119 119  
... ... @@ -126,7 +126,7 @@ class cssrcdetect(ctools.cscript):
126 126 # Log maximum
127 127 self._log_value(gammalib.NORMAL, 'Map maximum', str(value))
128 128 self._log_value(gammalib.NORMAL, name+' position', str(pos))
129   -
  129 +
130 130 # Add model
131 131 self._add_model(pos, name)
132 132  
... ... @@ -196,7 +196,7 @@ class cssrcdetect(ctools.cscript):
196 196 """
197 197 # Copy skymap
198 198 skymap_copy = skymap.copy()
199   -
  199 +
200 200 # Cache the cosine of the radius
201 201 cos_radius = math.cos(math.radians(radius))
202 202  
... ... @@ -354,16 +354,13 @@ class cssrcdetect(ctools.cscript):
354 354 self._log_header3(gammalib.NORMAL, 'Smoothing Skymap')
355 355  
356 356 # Make sure the smoothing kernel is not 'NONE'
357   - if self['smoothkernel'].string().upper() != 'NONE':
358   - self._log_value(gammalib.NORMAL, 'Kernel',
359   - self['smoothkernel'].string())
360   - self._log_value(gammalib.NORMAL, 'Parameter',
361   - self['smoothparam'].real())
362   - skymap.smooth(self['smoothkernel'].string(),
363   - self['smoothparam'].real())
  357 + if self['corr_kern'].string().upper() != 'NONE':
  358 + self._log_value(gammalib.NORMAL, 'Kernel', self['corr_kern'].string())
  359 + self._log_value(gammalib.NORMAL, 'Parameter', self['corr_rad'].real())
  360 + skymap.smooth(self['corr_kern'].string(), self['corr_rad'].real())
364 361 else:
365 362 self._log_string(gammalib.NORMAL,
366   - 'Smoothing kernel is NONE, smoothing will be ignored.')
  363 + 'Smoothing kernel is "NONE", smoothing will be ignored.')
367 364  
368 365 return
369 366  
... ...
doc/source/admin/release_history/1.6.rst
... ... @@ -43,6 +43,8 @@ Improvements
43 43 Use full ``RMF`` true energy range for On/Off analysis in :ref:`csspec`
44 44 * [`2513 <https://cta-redmine.irap.omp.eu/issues/2513>`_] -
45 45 Transparently update parameter files
  46 +* [`2498 <https://cta-redmine.irap.omp.eu/issues/2498>`_] -
  47 + Make :ref:`cssrcdetect` more robust
46 48 * [`2490 <https://cta-redmine.irap.omp.eu/issues/2490>`_] -
47 49 Change formula for number of true energy bins in :ref:`csphagen`
48 50 * [`2421 <https://cta-redmine.irap.omp.eu/issues/2421>`_] -
... ...
doc/source/users/reference_manual/cssrcdetect.rst
... ... @@ -48,18 +48,19 @@ General parameters
48 48 Detection threshold (Gaussian sigma). Only sources above this detection
49 49 threshold will be added to the model definiton XML file.
50 50  
51   -``momentradius [real]``
52   - Radius (deg) for computing map mean and std-deviation values.
  51 +``(maxsrcs = 20) [integer]``
  52 + Maximum number of sources that should be detected.
53 53  
54   -``smoothkernel <NONE|DISK|GAUSSIAN> [string]``
55   - Smoothing kernel to use for smoothing the input sky map.
  54 +``(avgrad = 1.0) [real]``
  55 + Averaging radius for significance computation (degrees). The script computes
  56 + the mean pixel value and standard deviation value over this radius and
  57 + uses the result to estimate the excess significance.
56 58  
57   -``smoothparam [real]``
58   - Smoothing kernel parameters (sigma for GAUS, radius for DISK, both in
59   - degrees).
  59 +``corr_rad [real]``
  60 + Correlation kernel radius (degrees).
60 61  
61   -``(maxsrcs = 20) [integer]``
62   - Maximum number of sources that should be detected.
  62 +``(corr_kern = DISK) <NONE|DISK|GAUSSIAN> [string]``
  63 + Correlation kernel to use for smoothing the input sky map.
63 64  
64 65 ``(exclrad = 0.2) [real]``
65 66 Radius around a detected source that is excluded from further source
... ...
test/test_cssrcdetect.py
... ... @@ -33,7 +33,7 @@ class Test(test):
33 33 This test class makes unit tests for the cssrcdetect script by using it
34 34 from the command line and from Python.
35 35 """
36   -
  36 +
37 37 # Constructor
38 38 def __init__(self):
39 39 """
... ... @@ -75,9 +75,8 @@ class Test(test):
75 75 cmd = cssrcdetect+' inmap="'+self._map+'"'+ \
76 76 ' outmodel="cssrcdetect_cmd1.xml"'+ \
77 77 ' outds9file="cssrcdetect_cmd1.reg"'+ \
78   - ' momentradius=200.0'+ \
79   - ' smoothkernel=NONE smoothparam=0.1'+ \
80   - ' srcmodel="POINT" bkgmodel="NONE" threshold=10.0'+ \
  78 + ' corr_rad=0.1'+ \
  79 + ' srcmodel="POINT" bkgmodel="NONE" threshold=8.0'+ \
81 80 ' logfile="cssrcdetect_cmd1.log" chatter=1'
82 81  
83 82 # Check if execution was successful
... ... @@ -91,9 +90,8 @@ class Test(test):
91 90 cmd = cssrcdetect+' inmap="skymap_that_does_not_exist"'+ \
92 91 ' outmodel="cssrcdetect_cmd1.xml"'+ \
93 92 ' outds9file="cssrcdetect_cmd1.reg"'+ \
94   - ' momentradius=200.0'+ \
95   - ' smoothkernel=NONE smoothparam=0.1'+ \
96   - ' srcmodel="POINT" bkgmodel="NONE" threshold=10.0'+ \
  93 + ' corr_rad=0.1'+ \
  94 + ' srcmodel="POINT" bkgmodel="NONE" threshold=8.0'+ \
97 95 ' logfile="cssrcdetect_cmd2.log" debug=yes chatter=2'
98 96  
99 97 # Check if execution failed
... ... @@ -133,12 +131,10 @@ class Test(test):
133 131 srcdetect['outds9file'] = 'cssrcdetect_py1.reg'
134 132 srcdetect['srcmodel'] = 'POINT'
135 133 srcdetect['bkgmodel'] = 'NONE'
136   - srcdetect['threshold'] = 10.0
137   - srcdetect['momentradius'] = 200.0
138   - srcdetect['smoothkernel'] = "NONE"
139   - srcdetect['smoothparam'] = 0.1
  134 + srcdetect['threshold'] = 8.0
  135 + srcdetect['corr_rad'] = 0.1
140 136 srcdetect['logfile'] = 'cssrcdetect_py1.log'
141   - srcdetect['chatter'] = 2
  137 + srcdetect['chatter'] = 4
142 138  
143 139 # Run cssrcdetect script and save models
144 140 srcdetect.logFileOpen() # Make sure we get a log file
... ... @@ -153,6 +149,7 @@ class Test(test):
153 149 srcdetect['outmodel'] = 'cssrcdetect_py2.xml'
154 150 srcdetect['outds9file'] = 'cssrcdetect_py2.reg'
155 151 srcdetect['bkgmodel'] = 'IRF'
  152 + srcdetect['threshold'] = 8.0
156 153 srcdetect['logfile'] = 'cssrcdetect_py2.log'
157 154 srcdetect['chatter'] = 3
158 155 srcdetect.logFileOpen() # Needed to get a new log file
... ... @@ -175,6 +172,6 @@ class Test(test):
175 172 # Check number of models
176 173 self.test_value(models.size(), number, 'Check for '+str(number)+
177 174 ' models in XML file')
178   -
  175 +
179 176 # Return
180 177 return
... ...