Commit e3a0f9eb0ebfeaf22e0e63006ae0a32189d6ece7

Authored by Jürgen Knödlseder
1 parent 2eec961d

Implement computation of integral sensitivity

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=&quot;Sensitivity&quot;): @@ -78,7 +103,10 @@ def show_sensitivity(sensitivity, title=&quot;Sensitivity&quot;):
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__ == &#39;__main__&#39;: @@ -105,11 +133,8 @@ if __name__ == &#39;__main__&#39;:
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