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 | 45 | ``outfile [file]`` |
| 46 | 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 | 48 | ``duration [real]`` |
| 55 | 49 | Effective exposure time (in seconds). |
| 56 | 50 | |
| ... | ... | @@ -75,6 +69,9 @@ General parameters |
| 75 | 69 | ``(binsz = 0.05) [real]`` |
| 76 | 70 | Pixel size for binned analysis. |
| 77 | 71 | |
| 72 | +``(type = Differential) <Differential|Integral> [string]`` | |
| 73 | + Sensitivity type. | |
| 74 | + | |
| 78 | 75 | ``(sigma = 5.0) [real]`` |
| 79 | 76 | Significance threshold. |
| 80 | 77 | ... | ... |
examples/show_sensitivity.py
100644 → 100755
| ... | ... | @@ -46,13 +46,35 @@ def read_sensitivity(filename): |
| 46 | 46 | values.append(float(csv[row+1,column])) |
| 47 | 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 | 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 | 79 | # Return |
| 58 | 80 | return sensitivity |
| ... | ... | @@ -61,10 +83,13 @@ def read_sensitivity(filename): |
| 61 | 83 | # ===================== # |
| 62 | 84 | # Show sensitivity data # |
| 63 | 85 | # ===================== # |
| 64 | -def show_sensitivity(sensitivity, title="Sensitivity"): | |
| 86 | +def show_sensitivity(sensitivity, filename): | |
| 65 | 87 | """ |
| 66 | 88 | Plot sensitivity. |
| 67 | 89 | """ |
| 90 | + # Build title | |
| 91 | + title = sensitivity['mode'] + ' sensitivity ('+filename+')' | |
| 92 | + | |
| 68 | 93 | # Create figure |
| 69 | 94 | plt.figure() |
| 70 | 95 | |
| ... | ... | @@ -78,7 +103,10 @@ def show_sensitivity(sensitivity, title="Sensitivity"): |
| 78 | 103 | |
| 79 | 104 | # Set labels |
| 80 | 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 | 111 | # Show plot |
| 84 | 112 | plt.show() |
| ... | ... | @@ -105,11 +133,8 @@ if __name__ == '__main__': |
| 105 | 133 | else: |
| 106 | 134 | filename = sys.argv[1] |
| 107 | 135 | |
| 108 | - # Set title | |
| 109 | - title = 'Differential sensitivity ('+filename+')' | |
| 110 | - | |
| 111 | 136 | # Read sensitivity data |
| 112 | 137 | sensitivity = read_sensitivity(filename) |
| 113 | 138 | |
| 114 | 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 | 47 | self.version = "1.0.0" |
| 48 | 48 | |
| 49 | 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 | 54 | # Make sure that parfile exists |
| 55 | 55 | file = self.parfile() |
| ... | ... | @@ -113,6 +113,7 @@ class cssens(ctools.cscript): |
| 113 | 113 | pars.append(gammalib.GApplicationPar("enumbins","i","h","0","","","Number of energy bins (0=unbinned)")) |
| 114 | 114 | pars.append(gammalib.GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) |
| 115 | 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 | 117 | pars.append(gammalib.GApplicationPar("sigma","r","h","5.0","","","Significance threshold")) |
| 117 | 118 | pars.append(gammalib.GApplicationPar("max_iter","i","h","50","","","Maximum number of iterations")) |
| 118 | 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 | 148 | # Read parameters for binned if requested |
| 148 | 149 | self.m_enumbins = self["enumbins"].integer() |
| 149 | 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 | 153 | else: |
| 153 | 154 | # Set dummy values (required by obsutils) |
| 154 | - self.m_npix = 0 | |
| 155 | + self.m_npix = 0 | |
| 155 | 156 | self.m_binsz = 0.0 |
| 156 | 157 | |
| 157 | 158 | # Read remaining parameters |
| 158 | 159 | self.m_ts_thres = self["sigma"].real()*self["sigma"].real() |
| 159 | 160 | self.m_max_iter = self["max_iter"].integer() |
| 160 | 161 | self.m_num_avg = self["num_avg"].integer() |
| 162 | + self.m_type = self["type"].string() | |
| 161 | 163 | |
| 162 | 164 | # Set some fixed parameters |
| 163 | 165 | self.m_log = False # Logging in client tools |
| ... | ... | @@ -219,20 +221,28 @@ class cssens(ctools.cscript): |
| 219 | 221 | if self.logTerse(): |
| 220 | 222 | self.log("\n") |
| 221 | 223 | self.log.header1("Sensitivity determination") |
| 224 | + self.log.parformat("Type") | |
| 225 | + self.log(self.m_type) | |
| 226 | + self.log("\n") | |
| 222 | 227 | |
| 223 | 228 | # Loop over energy bins |
| 224 | 229 | for ieng in range(self.m_ebounds.size()): |
| 225 | 230 | |
| 226 | 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 | 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 | 247 | # Write results |
| 238 | 248 | if ieng == 0: |
| ... | ... | @@ -305,13 +315,16 @@ class cssens(ctools.cscript): |
| 305 | 315 | def set_obs_ebounds(self, emin, emax): |
| 306 | 316 | """ |
| 307 | 317 | Set energy boundaries for observation in container. |
| 318 | + | |
| 319 | + Parameters: | |
| 320 | + emin - Minimum energy | |
| 321 | + emax - Maximum energy | |
| 308 | 322 | """ |
| 309 | 323 | # Loop over all observations in container |
| 310 | 324 | for obs in self.obs: |
| 311 | 325 | |
| 312 | 326 | # Set energy boundaries |
| 313 | - ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, "TeV"), \ | |
| 314 | - gammalib.GEnergy(emax, "TeV")) | |
| 327 | + ebounds = gammalib.GEbounds(emin, emax) | |
| 315 | 328 | obs.events().ebounds(ebounds) |
| 316 | 329 | |
| 317 | 330 | # Return |
| ... | ... | @@ -382,27 +395,35 @@ class cssens(ctools.cscript): |
| 382 | 395 | # Return models |
| 383 | 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 | 402 | Parameters: |
| 390 | 403 | obs - Observation container |
| 404 | + emin - Minimum energy for fitting and flux computation | |
| 405 | + emax - Maximum energy for fitting and flux computation | |
| 391 | 406 | bkg_model - Background model |
| 392 | 407 | full_model - Source model |
| 393 | 408 | """ |
| 394 | 409 | # Set TeV->erg conversion factor |
| 395 | 410 | tev2erg = 1.6021764 |
| 411 | + | |
| 412 | + # Set energy boundaries | |
| 413 | + self.set_obs_ebounds(emin, emax) | |
| 396 | 414 | |
| 397 | 415 | # Determine energy boundaries from first observation in |
| 398 | 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 | 428 | # Compute Crab unit (this is the factor with which the Prefactor needs |
| 408 | 429 | # to be multiplied to get 1 Crab | ... | ... |