Commit ca35e8850ad18ff189a63713794aa760f3d349e4
1 parent
77884dc8
Change names of cssrcdetect robustness parameters (#2498)
Showing
7 changed files
with
55 additions
and
52 deletions
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) | ... | ... |
NEWS
| 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 | ... | ... |