Commit e3a0f9eb0ebfeaf22e0e63006ae0a32189d6ece7
1 parent
2eec961d
Implement computation of integral sensitivity
Showing
3 changed files
with
85 additions
and
42 deletions
doc/source/reference_manual/cssens.rst
| @@ -45,12 +45,6 @@ General parameters | @@ -45,12 +45,6 @@ General parameters | ||
| 45 | ``outfile [file]`` | 45 | ``outfile [file]`` |
| 46 | ASCII file containing the sensitivity values. | 46 | ASCII file containing the sensitivity values. |
| 47 | 47 | ||
| 48 | -``type <point|gauss|shell|disk> [string]`` | ||
| 49 | - Source model type. | ||
| 50 | - | ||
| 51 | -``offset [real]`` | ||
| 52 | - Source offset angle (in degrees). | ||
| 53 | - | ||
| 54 | ``duration [real]`` | 48 | ``duration [real]`` |
| 55 | Effective exposure time (in seconds). | 49 | Effective exposure time (in seconds). |
| 56 | 50 | ||
| @@ -75,6 +69,9 @@ General parameters | @@ -75,6 +69,9 @@ General parameters | ||
| 75 | ``(binsz = 0.05) [real]`` | 69 | ``(binsz = 0.05) [real]`` |
| 76 | Pixel size for binned analysis. | 70 | Pixel size for binned analysis. |
| 77 | 71 | ||
| 72 | +``(type = Differential) <Differential|Integral> [string]`` | ||
| 73 | + Sensitivity type. | ||
| 74 | + | ||
| 78 | ``(sigma = 5.0) [real]`` | 75 | ``(sigma = 5.0) [real]`` |
| 79 | Significance threshold. | 76 | Significance threshold. |
| 80 | 77 |
examples/show_sensitivity.py
100644 → 100755
| @@ -46,13 +46,35 @@ def read_sensitivity(filename): | @@ -46,13 +46,35 @@ def read_sensitivity(filename): | ||
| 46 | values.append(float(csv[row+1,column])) | 46 | values.append(float(csv[row+1,column])) |
| 47 | sensitivity[name] = values | 47 | sensitivity[name] = values |
| 48 | 48 | ||
| 49 | + # Check where file contains differential or integral sensitivity | ||
| 50 | + mode = "Integral" | ||
| 51 | + if sensitivity.has_key("emax"): | ||
| 52 | + emax_ref = -1.0 | ||
| 53 | + for value in sensitivity["emax"]: | ||
| 54 | + if emax_ref < 0.0: | ||
| 55 | + emax_ref = value | ||
| 56 | + elif emax_ref != value: | ||
| 57 | + mode = "Differential" | ||
| 58 | + break | ||
| 59 | + | ||
| 60 | + # Add mode | ||
| 61 | + sensitivity["mode"] = mode | ||
| 62 | + | ||
| 49 | # Add linear energy values | 63 | # Add linear energy values |
| 50 | - if sensitivity.has_key("loge"): | ||
| 51 | - name = 'energy' | ||
| 52 | - values = [] | ||
| 53 | - for value in sensitivity["loge"]: | ||
| 54 | - values.append(math.pow(10.0, value)) | ||
| 55 | - sensitivity[name] = values | 64 | + if mode == "Differential": |
| 65 | + if sensitivity.has_key("loge"): | ||
| 66 | + name = 'energy' | ||
| 67 | + values = [] | ||
| 68 | + for value in sensitivity["loge"]: | ||
| 69 | + values.append(math.pow(10.0, value)) | ||
| 70 | + sensitivity[name] = values | ||
| 71 | + else: | ||
| 72 | + if sensitivity.has_key("emin"): | ||
| 73 | + name = 'energy' | ||
| 74 | + values = [] | ||
| 75 | + for value in sensitivity["emin"]: | ||
| 76 | + values.append(value) | ||
| 77 | + sensitivity[name] = values | ||
| 56 | 78 | ||
| 57 | # Return | 79 | # Return |
| 58 | return sensitivity | 80 | return sensitivity |
| @@ -61,10 +83,13 @@ def read_sensitivity(filename): | @@ -61,10 +83,13 @@ def read_sensitivity(filename): | ||
| 61 | # ===================== # | 83 | # ===================== # |
| 62 | # Show sensitivity data # | 84 | # Show sensitivity data # |
| 63 | # ===================== # | 85 | # ===================== # |
| 64 | -def show_sensitivity(sensitivity, title="Sensitivity"): | 86 | +def show_sensitivity(sensitivity, filename): |
| 65 | """ | 87 | """ |
| 66 | Plot sensitivity. | 88 | Plot sensitivity. |
| 67 | """ | 89 | """ |
| 90 | + # Build title | ||
| 91 | + title = sensitivity['mode'] + ' sensitivity ('+filename+')' | ||
| 92 | + | ||
| 68 | # Create figure | 93 | # Create figure |
| 69 | plt.figure() | 94 | plt.figure() |
| 70 | 95 | ||
| @@ -78,7 +103,10 @@ def show_sensitivity(sensitivity, title="Sensitivity"): | @@ -78,7 +103,10 @@ def show_sensitivity(sensitivity, title="Sensitivity"): | ||
| 78 | 103 | ||
| 79 | # Set labels | 104 | # Set labels |
| 80 | plt.xlabel("Energy (TeV)") | 105 | plt.xlabel("Energy (TeV)") |
| 81 | - plt.ylabel(r"Sensitivity (erg cm$^{-2}$ s$^{-1}$)") | 106 | + if sensitivity['mode'] == "Differential": |
| 107 | + plt.ylabel(r"E$\times$ F(E) (erg cm$^{-2}$ s$^{-1}$)") | ||
| 108 | + else: | ||
| 109 | + plt.ylabel(r"E$\times$ F($>$E) (erg cm$^{-2}$ s$^{-1}$)") | ||
| 82 | 110 | ||
| 83 | # Show plot | 111 | # Show plot |
| 84 | plt.show() | 112 | plt.show() |
| @@ -105,11 +133,8 @@ if __name__ == '__main__': | @@ -105,11 +133,8 @@ if __name__ == '__main__': | ||
| 105 | else: | 133 | else: |
| 106 | filename = sys.argv[1] | 134 | filename = sys.argv[1] |
| 107 | 135 | ||
| 108 | - # Set title | ||
| 109 | - title = 'Differential sensitivity ('+filename+')' | ||
| 110 | - | ||
| 111 | # Read sensitivity data | 136 | # Read sensitivity data |
| 112 | sensitivity = read_sensitivity(filename) | 137 | sensitivity = read_sensitivity(filename) |
| 113 | 138 | ||
| 114 | # Show sensitivity data | 139 | # Show sensitivity data |
| 115 | - show_sensitivity(sensitivity, title=title) | 140 | + show_sensitivity(sensitivity, filename) |
scripts/cssens.py
| @@ -47,9 +47,9 @@ class cssens(ctools.cscript): | @@ -47,9 +47,9 @@ class cssens(ctools.cscript): | ||
| 47 | self.version = "1.0.0" | 47 | self.version = "1.0.0" |
| 48 | 48 | ||
| 49 | # Initialise some parameters | 49 | # Initialise some parameters |
| 50 | - self.obs = None | ||
| 51 | - self.m_ra = None | ||
| 52 | - self.m_dec = None | 50 | + self.obs = None |
| 51 | + self.m_ra = None | ||
| 52 | + self.m_dec = None | ||
| 53 | 53 | ||
| 54 | # Make sure that parfile exists | 54 | # Make sure that parfile exists |
| 55 | file = self.parfile() | 55 | file = self.parfile() |
| @@ -113,6 +113,7 @@ class cssens(ctools.cscript): | @@ -113,6 +113,7 @@ class cssens(ctools.cscript): | ||
| 113 | pars.append(gammalib.GApplicationPar("enumbins","i","h","0","","","Number of energy bins (0=unbinned)")) | 113 | pars.append(gammalib.GApplicationPar("enumbins","i","h","0","","","Number of energy bins (0=unbinned)")) |
| 114 | pars.append(gammalib.GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) | 114 | pars.append(gammalib.GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) |
| 115 | pars.append(gammalib.GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) | 115 | pars.append(gammalib.GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) |
| 116 | + pars.append(gammalib.GApplicationPar("type","s","h","Differential","Differential|Integral","","Sensitivity type")) | ||
| 116 | pars.append(gammalib.GApplicationPar("sigma","r","h","5.0","","","Significance threshold")) | 117 | pars.append(gammalib.GApplicationPar("sigma","r","h","5.0","","","Significance threshold")) |
| 117 | pars.append(gammalib.GApplicationPar("max_iter","i","h","50","","","Maximum number of iterations")) | 118 | pars.append(gammalib.GApplicationPar("max_iter","i","h","50","","","Maximum number of iterations")) |
| 118 | pars.append(gammalib.GApplicationPar("num_avg","i","h","3","","","Number of iterations for sliding average")) | 119 | pars.append(gammalib.GApplicationPar("num_avg","i","h","3","","","Number of iterations for sliding average")) |
| @@ -147,17 +148,18 @@ class cssens(ctools.cscript): | @@ -147,17 +148,18 @@ class cssens(ctools.cscript): | ||
| 147 | # Read parameters for binned if requested | 148 | # Read parameters for binned if requested |
| 148 | self.m_enumbins = self["enumbins"].integer() | 149 | self.m_enumbins = self["enumbins"].integer() |
| 149 | if not self.m_enumbins == 0: | 150 | if not self.m_enumbins == 0: |
| 150 | - self.m_npix = self["npix"].integer() | ||
| 151 | - self.m_binsz = self["binsz"].real() | 151 | + self.m_npix = self["npix"].integer() |
| 152 | + self.m_binsz = self["binsz"].real() | ||
| 152 | else: | 153 | else: |
| 153 | # Set dummy values (required by obsutils) | 154 | # Set dummy values (required by obsutils) |
| 154 | - self.m_npix = 0 | 155 | + self.m_npix = 0 |
| 155 | self.m_binsz = 0.0 | 156 | self.m_binsz = 0.0 |
| 156 | 157 | ||
| 157 | # Read remaining parameters | 158 | # Read remaining parameters |
| 158 | self.m_ts_thres = self["sigma"].real()*self["sigma"].real() | 159 | self.m_ts_thres = self["sigma"].real()*self["sigma"].real() |
| 159 | self.m_max_iter = self["max_iter"].integer() | 160 | self.m_max_iter = self["max_iter"].integer() |
| 160 | self.m_num_avg = self["num_avg"].integer() | 161 | self.m_num_avg = self["num_avg"].integer() |
| 162 | + self.m_type = self["type"].string() | ||
| 161 | 163 | ||
| 162 | # Set some fixed parameters | 164 | # Set some fixed parameters |
| 163 | self.m_log = False # Logging in client tools | 165 | self.m_log = False # Logging in client tools |
| @@ -219,20 +221,28 @@ class cssens(ctools.cscript): | @@ -219,20 +221,28 @@ class cssens(ctools.cscript): | ||
| 219 | if self.logTerse(): | 221 | if self.logTerse(): |
| 220 | self.log("\n") | 222 | self.log("\n") |
| 221 | self.log.header1("Sensitivity determination") | 223 | self.log.header1("Sensitivity determination") |
| 224 | + self.log.parformat("Type") | ||
| 225 | + self.log(self.m_type) | ||
| 226 | + self.log("\n") | ||
| 222 | 227 | ||
| 223 | # Loop over energy bins | 228 | # Loop over energy bins |
| 224 | for ieng in range(self.m_ebounds.size()): | 229 | for ieng in range(self.m_ebounds.size()): |
| 225 | 230 | ||
| 226 | # Set energies | 231 | # Set energies |
| 227 | - emean = self.m_ebounds.elogmean(ieng).TeV() | ||
| 228 | - emin = self.m_ebounds.emin(ieng).TeV() | ||
| 229 | - emax = self.m_ebounds.emax(ieng).TeV() | ||
| 230 | - | ||
| 231 | - # Set energy boundaries | ||
| 232 | - self.set_obs_ebounds(emin, emax) | 232 | + if self.m_type == "Differential": |
| 233 | + emin = self.m_ebounds.emin(ieng) | ||
| 234 | + emax = self.m_ebounds.emax(ieng) | ||
| 235 | + elif self.m_type == "Integral": | ||
| 236 | + emin = self.m_ebounds.emin(ieng) | ||
| 237 | + emax = self.m_ebounds.emax() | ||
| 238 | + else: | ||
| 239 | + msg = "Invalid sensitivity type \""+self.m_type+"\" encountered."+ \ | ||
| 240 | + " Either use \"Differential\" or \"Integral\"." | ||
| 241 | + raise gammalib.GException.invalid_value("cssens", msg) | ||
| 233 | 242 | ||
| 234 | # Determine sensitivity | 243 | # Determine sensitivity |
| 235 | - result = self.get_sensitivity(self.obs, bkg_model, full_model) | 244 | + result = self.get_sensitivity(self.obs, emin, emax, \ |
| 245 | + bkg_model, full_model) | ||
| 236 | 246 | ||
| 237 | # Write results | 247 | # Write results |
| 238 | if ieng == 0: | 248 | if ieng == 0: |
| @@ -305,13 +315,16 @@ class cssens(ctools.cscript): | @@ -305,13 +315,16 @@ class cssens(ctools.cscript): | ||
| 305 | def set_obs_ebounds(self, emin, emax): | 315 | def set_obs_ebounds(self, emin, emax): |
| 306 | """ | 316 | """ |
| 307 | Set energy boundaries for observation in container. | 317 | Set energy boundaries for observation in container. |
| 318 | + | ||
| 319 | + Parameters: | ||
| 320 | + emin - Minimum energy | ||
| 321 | + emax - Maximum energy | ||
| 308 | """ | 322 | """ |
| 309 | # Loop over all observations in container | 323 | # Loop over all observations in container |
| 310 | for obs in self.obs: | 324 | for obs in self.obs: |
| 311 | 325 | ||
| 312 | # Set energy boundaries | 326 | # Set energy boundaries |
| 313 | - ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, "TeV"), \ | ||
| 314 | - gammalib.GEnergy(emax, "TeV")) | 327 | + ebounds = gammalib.GEbounds(emin, emax) |
| 315 | obs.events().ebounds(ebounds) | 328 | obs.events().ebounds(ebounds) |
| 316 | 329 | ||
| 317 | # Return | 330 | # Return |
| @@ -382,27 +395,35 @@ class cssens(ctools.cscript): | @@ -382,27 +395,35 @@ class cssens(ctools.cscript): | ||
| 382 | # Return models | 395 | # Return models |
| 383 | return full_model, bkg_model | 396 | return full_model, bkg_model |
| 384 | 397 | ||
| 385 | - def get_sensitivity(self, obs, bkg_model, full_model): | 398 | + def get_sensitivity(self, obs, emin, emax, bkg_model, full_model): |
| 386 | """ | 399 | """ |
| 387 | - Determine sensitivity for a given observations. | 400 | + Determine sensitivity for given observations. |
| 388 | 401 | ||
| 389 | Parameters: | 402 | Parameters: |
| 390 | obs - Observation container | 403 | obs - Observation container |
| 404 | + emin - Minimum energy for fitting and flux computation | ||
| 405 | + emax - Maximum energy for fitting and flux computation | ||
| 391 | bkg_model - Background model | 406 | bkg_model - Background model |
| 392 | full_model - Source model | 407 | full_model - Source model |
| 393 | """ | 408 | """ |
| 394 | # Set TeV->erg conversion factor | 409 | # Set TeV->erg conversion factor |
| 395 | tev2erg = 1.6021764 | 410 | tev2erg = 1.6021764 |
| 411 | + | ||
| 412 | + # Set energy boundaries | ||
| 413 | + self.set_obs_ebounds(emin, emax) | ||
| 396 | 414 | ||
| 397 | # Determine energy boundaries from first observation in | 415 | # Determine energy boundaries from first observation in |
| 398 | # the container | 416 | # the container |
| 399 | - for run in obs: | ||
| 400 | - emin = run.events().ebounds().emin() | ||
| 401 | - emax = run.events().ebounds().emax() | ||
| 402 | - loge = math.log10(math.sqrt(emin.TeV()*emax.TeV())) | ||
| 403 | - erg_mean = math.pow(10.0, loge) * tev2erg | ||
| 404 | - erg_width = (emax.TeV()-emin.TeV()) * tev2erg | ||
| 405 | - break | 417 | + #for run in obs: |
| 418 | + # emin = run.events().ebounds().emin() | ||
| 419 | + # emax = run.events().ebounds().emax() | ||
| 420 | + # loge = math.log10(math.sqrt(emin.TeV()*emax.TeV())) | ||
| 421 | + # erg_mean = math.pow(10.0, loge) * tev2erg | ||
| 422 | + # erg_width = (emax.TeV()-emin.TeV()) * tev2erg | ||
| 423 | + # break | ||
| 424 | + loge = math.log10(math.sqrt(emin.TeV()*emax.TeV())) | ||
| 425 | + erg_mean = math.pow(10.0, loge) * tev2erg | ||
| 426 | + erg_width = (emax.TeV()-emin.TeV()) * tev2erg | ||
| 406 | 427 | ||
| 407 | # Compute Crab unit (this is the factor with which the Prefactor needs | 428 | # Compute Crab unit (this is the factor with which the Prefactor needs |
| 408 | # to be multiplied to get 1 Crab | 429 | # to be multiplied to get 1 Crab |