Commit e67369a1fa26fff55ed00f30db2b06483c43ef72
1 parent
e8978f2a
Increase comment density (#1828)
Showing
2 changed files
with
62 additions
and
17 deletions
examples/show_obs.py
| @@ -61,7 +61,7 @@ def run_csobsinfo(filename, ra, dec, debug=True): | @@ -61,7 +61,7 @@ def run_csobsinfo(filename, ra, dec, debug=True): | ||
| 61 | info['inobs'] = obsdef.url() | 61 | info['inobs'] = obsdef.url() |
| 62 | info['debug'] = debug | 62 | info['debug'] = debug |
| 63 | 63 | ||
| 64 | - # Set offset | 64 | + # Set offset if the "ra" and "dec" arguments are not empty strings |
| 65 | if ra != '' and dec != '': | 65 | if ra != '' and dec != '': |
| 66 | info['ra'] = float(ra) | 66 | info['ra'] = float(ra) |
| 67 | info['dec'] = float(dec) | 67 | info['dec'] = float(dec) |
| @@ -94,14 +94,15 @@ def plot_information(info, ra, dec, plotfile): | @@ -94,14 +94,15 @@ def plot_information(info, ra, dec, plotfile): | ||
| 94 | plotfile : str | 94 | plotfile : str |
| 95 | Plot filename | 95 | Plot filename |
| 96 | """ | 96 | """ |
| 97 | - # Retrieve observation info | 97 | + # Retrieve observation information |
| 98 | zeniths = info.zeniths() | 98 | zeniths = info.zeniths() |
| 99 | azimuths = info.azimuths() | 99 | azimuths = info.azimuths() |
| 100 | offsets = info.offsets() | 100 | offsets = info.offsets() |
| 101 | ebounds = info.ebounds() | 101 | ebounds = info.ebounds() |
| 102 | gti = info.gti() | 102 | gti = info.gti() |
| 103 | 103 | ||
| 104 | - # Create figure with subplots | 104 | + # Create figure with subplots. In case that offset and energy boundary |
| 105 | + # information is available a column is added to the subplots | ||
| 105 | nrows = 2 | 106 | nrows = 2 |
| 106 | ncols = 2 | 107 | ncols = 2 |
| 107 | if info['offset'].boolean() and ebounds.size() > 0: | 108 | if info['offset'].boolean() and ebounds.size() > 0: |
| @@ -110,7 +111,7 @@ def plot_information(info, ra, dec, plotfile): | @@ -110,7 +111,7 @@ def plot_information(info, ra, dec, plotfile): | ||
| 110 | plt.figure() | 111 | plt.figure() |
| 111 | plt.subplot(nrows, ncols, iplot) | 112 | plt.subplot(nrows, ncols, iplot) |
| 112 | 113 | ||
| 113 | - # Plot zenith angle distribution | 114 | + # Plot zenith angle histogram |
| 114 | zmin = min(zeniths) | 115 | zmin = min(zeniths) |
| 115 | zmax = max(zeniths) | 116 | zmax = max(zeniths) |
| 116 | plt.hist(zeniths, bins=30, range=(zmin, zmax), fc='blue') | 117 | plt.hist(zeniths, bins=30, range=(zmin, zmax), fc='blue') |
| @@ -118,7 +119,7 @@ def plot_information(info, ra, dec, plotfile): | @@ -118,7 +119,7 @@ def plot_information(info, ra, dec, plotfile): | ||
| 118 | plt.ylabel('Frequency') | 119 | plt.ylabel('Frequency') |
| 119 | plt.title('Zenith angle distribution') | 120 | plt.title('Zenith angle distribution') |
| 120 | 121 | ||
| 121 | - # Plot azimuth angle distribution | 122 | + # Plot azimuth angle histogram |
| 122 | iplot += 1 | 123 | iplot += 1 |
| 123 | plt.subplot(nrows, ncols, iplot) | 124 | plt.subplot(nrows, ncols, iplot) |
| 124 | amin = min(azimuths) | 125 | amin = min(azimuths) |
| @@ -128,7 +129,7 @@ def plot_information(info, ra, dec, plotfile): | @@ -128,7 +129,7 @@ def plot_information(info, ra, dec, plotfile): | ||
| 128 | plt.ylabel('Frequency') | 129 | plt.ylabel('Frequency') |
| 129 | plt.title('Azimuth distribution') | 130 | plt.title('Azimuth distribution') |
| 130 | 131 | ||
| 131 | - # Plot offset if possible | 132 | + # If available, plot offset from target histogram |
| 132 | if info['offset'].boolean(): | 133 | if info['offset'].boolean(): |
| 133 | iplot += 1 | 134 | iplot += 1 |
| 134 | plt.subplot(nrows, ncols, iplot) | 135 | plt.subplot(nrows, ncols, iplot) |
| @@ -139,7 +140,7 @@ def plot_information(info, ra, dec, plotfile): | @@ -139,7 +140,7 @@ def plot_information(info, ra, dec, plotfile): | ||
| 139 | plt.ylabel('Frequency') | 140 | plt.ylabel('Frequency') |
| 140 | plt.title('Offset distribution') | 141 | plt.title('Offset distribution') |
| 141 | 142 | ||
| 142 | - # Plot energy thresholds if possible | 143 | + # If available, plot energy thresholds histogram |
| 143 | if ebounds.size() > 0: | 144 | if ebounds.size() > 0: |
| 144 | emin = [] | 145 | emin = [] |
| 145 | emax = [] | 146 | emax = [] |
| @@ -155,7 +156,7 @@ def plot_information(info, ra, dec, plotfile): | @@ -155,7 +156,7 @@ def plot_information(info, ra, dec, plotfile): | ||
| 155 | plt.legend(loc='upper left') | 156 | plt.legend(loc='upper left') |
| 156 | plt.title('Energy threshold') | 157 | plt.title('Energy threshold') |
| 157 | 158 | ||
| 158 | - # Plot observation point in time wrt zenith angle | 159 | + # Plot zenith angle versus mean observing time for all observations |
| 159 | iplot += 1 | 160 | iplot += 1 |
| 160 | plt.subplot(nrows, ncols, iplot) | 161 | plt.subplot(nrows, ncols, iplot) |
| 161 | times = [] | 162 | times = [] |
examples/show_response.py
| @@ -52,7 +52,7 @@ def sigma_lima(Non, Noff, alpha=0.2): | @@ -52,7 +52,7 @@ def sigma_lima(Non, Noff, alpha=0.2): | ||
| 52 | sigma : float | 52 | sigma : float |
| 53 | Detection significance in Gaussian sigma | 53 | Detection significance in Gaussian sigma |
| 54 | """ | 54 | """ |
| 55 | - # Compute sensitivity | 55 | + # Compute sensitivity in Gaussian sigma |
| 56 | alpha1 = alpha + 1.0 | 56 | alpha1 = alpha + 1.0 |
| 57 | sum = Non + Noff | 57 | sum = Non + Noff |
| 58 | arg1 = Non / sum | 58 | arg1 = Non / sum |
| @@ -230,23 +230,67 @@ def show_one_sensitivity(rsp, name, color='r', duration=180000.0, alpha=0.2, | @@ -230,23 +230,67 @@ def show_one_sensitivity(rsp, name, color='r', duration=180000.0, alpha=0.2, | ||
| 230 | logE = [-1.7+0.2*i for i in range(nbins)] | 230 | logE = [-1.7+0.2*i for i in range(nbins)] |
| 231 | E = [math.pow(10.0, e) for e in logE] | 231 | E = [math.pow(10.0, e) for e in logE] |
| 232 | 232 | ||
| 233 | - # Generate sensitivity vector | 233 | + # Initialise sensitivity vector |
| 234 | flux = [0.0 for i in range(nbins)] | 234 | flux = [0.0 for i in range(nbins)] |
| 235 | + | ||
| 236 | + # Loop over all energy bins | ||
| 235 | for i in range(nbins): | 237 | for i in range(nbins): |
| 236 | - ewidth = (math.pow(10.0, logE[i]+0.1) - \ | ||
| 237 | - math.pow(10.0, logE[i]-0.1))*1.0e6 | ||
| 238 | - aeff = rsp.aeff()(logE[i]) | ||
| 239 | - r68 = rsp.psf().delta_max(logE[i]) / 5.0 / r68_to_sigma | 238 | + |
| 239 | + # Compute the energy width in MeV | ||
| 240 | + ewidth = (math.pow(10.0, logE[i]+0.1) - math.pow(10.0, logE[i]-0.1)) * \ | ||
| 241 | + 1.0e6 | ||
| 242 | + | ||
| 243 | + # Extract effective area in cm2 from Instrument Response Function | ||
| 244 | + aeff = rsp.aeff()(logE[i]) | ||
| 245 | + | ||
| 246 | + # Extract 68% containment radius in radians from Instrument Response | ||
| 247 | + # Function. | ||
| 248 | + # A kluge is used since this information is not directly available, | ||
| 249 | + # but the "delta_max()" method returns 5 times the "sigma" of the | ||
| 250 | + # Gaussian PSF. Hence dividing by 5 gives the "sigma", and dividing | ||
| 251 | + # by the 68% containment radius to sigma conversion factor gives | ||
| 252 | + # r68. | ||
| 253 | + r68 = rsp.psf().delta_max(logE[i]) / 5.0 / r68_to_sigma | ||
| 254 | + | ||
| 255 | + # Compute the solid angle of the 68% containment radius | ||
| 240 | solidangle = gammalib.twopi * (1.0 - math.cos(r68)) | 256 | solidangle = gammalib.twopi * (1.0 - math.cos(r68)) |
| 241 | - bgd_counts = rsp.background()(logE[i], 0.0, 0.0) * duration * ewidth * solidangle | ||
| 242 | - Noff = bgd_counts/alpha | 257 | + |
| 258 | + # Compute the total number of background counts by multiplying the | ||
| 259 | + # background rate by the observation duration, the energy width and | ||
| 260 | + # the solid angle | ||
| 261 | + bgd_counts = rsp.background()(logE[i], 0.0, 0.0) * \ | ||
| 262 | + duration * ewidth * solidangle | ||
| 263 | + | ||
| 264 | + # The number of Off counts is the total number of background counts | ||
| 265 | + # divided by the "alpha" parameter | ||
| 266 | + Noff = bgd_counts/alpha | ||
| 267 | + | ||
| 268 | + # If there are Off counts then compute the corresponding On counts | ||
| 269 | + # for "sigma" detection significance | ||
| 243 | if Noff > 0: | 270 | if Noff > 0: |
| 244 | - Non = Non_lima(sigma, Noff) | 271 | + |
| 272 | + # Compute On counts using Li & Ma | ||
| 273 | + Non = Non_lima(sigma, Noff) | ||
| 274 | + | ||
| 275 | + # Get the source counts by subtracting the background counts | ||
| 276 | + # under the source. Make sure that the source counts are at least | ||
| 277 | + # 5% of the background counts (low-energy background systematics) | ||
| 278 | + # and that there are at least 10 source events (high-energy limit) | ||
| 245 | src_counts = Non - bgd_counts | 279 | src_counts = Non - bgd_counts |
| 246 | if src_counts < 0.05*bgd_counts: | 280 | if src_counts < 0.05*bgd_counts: |
| 247 | src_counts = 0.05*bgd_counts | 281 | src_counts = 0.05*bgd_counts |
| 248 | if src_counts < 10: | 282 | if src_counts < 10: |
| 249 | src_counts = 10.0 | 283 | src_counts = 10.0 |
| 284 | + | ||
| 285 | + # Compute flux under the assumption that the source spectrum is | ||
| 286 | + # a power law with index of -2.6. The flux is the source counts | ||
| 287 | + # divided by the duration and 68% of the effective area times | ||
| 288 | + # a conversion factor. The conversion factor is given by | ||
| 289 | + # | ||
| 290 | + # conv = 1.6021765 * E^2 / F(E) | ||
| 291 | + # | ||
| 292 | + # where E is the mean energy of the bin and F(E) is the flux in | ||
| 293 | + # the bin | ||
| 250 | emin = gammalib.GEnergy(math.pow(10.0, logE[i]-0.1), 'TeV') | 294 | emin = gammalib.GEnergy(math.pow(10.0, logE[i]-0.1), 'TeV') |
| 251 | emax = gammalib.GEnergy(math.pow(10.0, logE[i]+0.1), 'TeV') | 295 | emax = gammalib.GEnergy(math.pow(10.0, logE[i]+0.1), 'TeV') |
| 252 | epivot = gammalib.GEnergy(math.pow(10.0, logE[i]), 'TeV') | 296 | epivot = gammalib.GEnergy(math.pow(10.0, logE[i]), 'TeV') |