Line Background Estimation Using Adjacent Energy Bins
H.Yoneda, S. Mittal
This is a tutorial notebook on background estimation for gamma-ray lines. The basic idea is as follows:
Extracting the event distribution in the Compton data space from adjacent energy bins of the energy of interest.
Making a binned histogram using the extracted events.
Estimate the total number of expected background counts in the line energy bin by fitting the adjacent energy bin data, and modify the normalization of the binned histogram accordingly.
Here, we make a background model for Al-26. These processes will be performed in the LineBackgroundEstimation
class, and you can see how it works as follows.
This class is very preliminary, and there are several areas for improvement. Future ideas include:
We may add more options in the minuit fitting, e.g., limiting the parameter region, fixing some parameters.
We may apply smoothing to the background histogram, which may help to mitigate Poisson fluctuation in the model.
[1]:
import logging
import sys
logger = logging.getLogger('cosipy')
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler(sys.stdout))
[3]:
from histpy import Histogram, Axis, Axes
import astropy.units as u
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy import integrate
from iminuit import Minuit
from cosipy import BinnedData, LineBackgroundEstimation
[4]:
%matplotlib inline
%config InlineBackend.figure_format='retina'
0. Create dataset for the line background estimation
We need an event histogram binned finely along the energy axis.
[5]:
#need to change them
path_to_Al = "path/to/data"
path_to_bkg = "path/to/data"
[5]:
#yaml files containing binning information
spectrum_bkg = BinnedData("inputs_bkg_estimation.yaml")
spectrum_Al = BinnedData("inputs_bkg_estimation.yaml")
[6]:
%%time
#path to unbinned fits file for source and background to create binned dataset
spectrum_Al.get_binned_data(unbinned_data=path_to_Al, make_binning_plots=True,
output_name='Al_binned', show_plots=True)
binning data...
Time unit: s
Em unit: keV
Phi unit: deg
PsiChi unit: None





plotting psichi in Galactic coordinates...

CPU times: user 6.48 s, sys: 1.73 s, total: 8.21 s
Wall time: 4.5 s
[7]:
%%time
#path to unbinned fits file for source and background to create binned dataset
spectrum_bkg.get_binned_data(unbinned_data=path_to_bkg, make_binning_plots=True,
output_name='bkg_binned', show_plots=True)
binning data...
Time unit: s
Em unit: keV
Phi unit: deg
PsiChi unit: None





plotting psichi in Galactic coordinates...

CPU times: user 10min 9s, sys: 46.7 s, total: 10min 56s
Wall time: 11min 53s
[8]:
#combine source and background binned data
spectrum_total = spectrum_Al.binned_data + spectrum_bkg.binned_data
spectrum_total.write('combined_al_bkg_nside_16.hdf5')
This spectrum_total
can be considered as the actual event histogram in COSI observations.
[7]:
# load data
spectrum_bkg = Histogram.open("bkg_binned.hdf5")
spectrum_Al = Histogram.open("Al_binned.hdf5")
spectrum_total = Histogram.open("combined_al_bkg_nside_16.hdf5")
1. Instantiate the LineBackgroundEstimation
[8]:
instance = LineBackgroundEstimation(spectrum_total)
2. Set background model and fit it
Define a background spectrum model for fitting data
[9]:
def powerlaw(x, a, b, pivot):
return a * (x/pivot)**b
def gaussian(x, a, mu, sigma):
return a / (sigma) / np.sqrt(2 * np.pi) * np.exp( -(x-mu)**2 / (2*sigma**2))
def bkg_model(x, a, b, a1, mu1, a2, mu2, a3, mu3, a4, mu4, sigma):
pivot = 1800.0
return powerlaw(x,a,b, pivot) + \
gaussian(x , a1, mu1, sigma) + \
gaussian(x , a2, mu2, sigma) + \
gaussian(x , a3, mu3, sigma) + \
gaussian(x , a4, mu4, sigma)
[10]:
instance.set_bkg_energy_spectrum_model(bkg_model, [18000.0, -1.0, 40000.0, 1612, 50000.0, 1635, 10000.0, 1765, 30000.0, 1780, 1.0])
instance.plot_energy_spectrum()
[10]:
(<Axes: xlabel='Em [keV]'>, <ErrorbarContainer object of 3 artists>)

[11]:
%%time
m = instance.fit_energy_spectrum()
m
CPU times: user 12.9 s, sys: 92.6 ms, total: 13 s
Wall time: 13.1 s
[11]:
Migrad | |
---|---|
FCN = -9.903e+07 | Nfcn = 1293 |
EDM = 0.000122 (Goal: 0.0001) | |
Valid Minimum | Below EDM threshold (goal x 10) |
No parameters at limit | Below call limit |
Hesse ok | Covariance accurate |
Name | Value | Hesse Error | Minos Error- | Minos Error+ | Limit- | Limit+ | Fixed | |
---|---|---|---|---|---|---|---|---|
0 | x0 | 17.385e3 | 0.007e3 | |||||
1 | x1 | -1.702 | 0.004 | |||||
2 | x2 | 21.7e3 | 0.5e3 | |||||
3 | x3 | 1.61183e3 | 0.00007e3 | |||||
4 | x4 | 71.7e3 | 0.6e3 | |||||
5 | x5 | 1.633314e3 | 0.000034e3 | |||||
6 | x6 | 24.8e3 | 0.5e3 | |||||
7 | x7 | 1.76410e3 | 0.00009e3 | |||||
8 | x8 | 67.2e3 | 0.5e3 | |||||
9 | x9 | 1.778490e3 | 0.000025e3 | |||||
10 | x10 | 2.136 | 0.027 |
x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | |
---|---|---|---|---|---|---|---|---|---|---|---|
x0 | 45.1 | 11.407e-3 (0.422) | -340 (-0.101) | -0.004 (-0.009) | -640 (-0.152) | -0.0103 (-0.046) | -520 (-0.165) | -0.009 (-0.015) | -600 (-0.169) | -8.5e-3 (-0.050) | -28.8e-3 (-0.158) |
x1 | 11.407e-3 (0.422) | 1.62e-05 | 260.031e-3 (0.128) | -0.005e-3 (-0.018) | 256.797e-3 (0.102) | 0 (0.003) | -36.617e-3 (-0.019) | 0.009e-3 (0.026) | -52.712e-3 (-0.025) | 0.003e-3 (0.031) | 0.007e-3 (0.060) |
x2 | -340 (-0.101) | 260.031e-3 (0.128) | 2.54e+05 | -5.590 (-0.156) | 0.03e6 (0.098) | 0.7165 (0.042) | 0.01e6 (0.044) | 1.714 (0.039) | 0.01e6 (0.049) | 713.3e-3 (0.056) | 1.8033 (0.132) |
x3 | -0.004 (-0.009) | -0.005e-3 (-0.018) | -5.590 (-0.156) | 0.00508 | 3.384 (0.076) | 0.0001 (0.054) | 0.915 (0.027) | 0.000 (0.049) | 1.405 (0.037) | 0.1e-3 (0.064) | 0.3e-3 (0.144) |
x4 | -640 (-0.152) | 256.797e-3 (0.102) | 0.03e6 (0.098) | 3.384 (0.076) | 3.91e+05 | 1.9929 (0.095) | 0.04e6 (0.130) | 10.077 (0.184) | 0.05e6 (0.164) | 3.9090 (0.246) | 9.5317 (0.561) |
x5 | -0.0103 (-0.046) | 0 (0.003) | 0.7165 (0.042) | 0.0001 (0.054) | 1.9929 (0.095) | 0.00113 | 1.1696 (0.074) | 0.0004 (0.123) | 1.7470 (0.098) | 0.1e-3 (0.161) | 0.3e-3 (0.364) |
x6 | -520 (-0.165) | -36.617e-3 (-0.019) | 0.01e6 (0.044) | 0.915 (0.027) | 0.04e6 (0.130) | 1.1696 (0.074) | 2.2e+05 | -7.432 (-0.182) | 0.02e6 (0.075) | 1.0703 (0.090) | 2.6815 (0.211) |
x7 | -0.009 (-0.015) | 0.009e-3 (0.026) | 1.714 (0.039) | 0.000 (0.049) | 10.077 (0.184) | 0.0004 (0.123) | -7.432 (-0.182) | 0.00763 | 3.914 (0.085) | 0.3e-3 (0.156) | 0.8e-3 (0.336) |
x8 | -600 (-0.169) | -52.712e-3 (-0.025) | 0.01e6 (0.049) | 1.405 (0.037) | 0.05e6 (0.164) | 1.7470 (0.098) | 0.02e6 (0.075) | 3.914 (0.085) | 2.79e+05 | 117.0e-3 (0.009) | 3.9541 (0.276) |
x9 | -8.5e-3 (-0.050) | 0.003e-3 (0.031) | 713.3e-3 (0.056) | 0.1e-3 (0.064) | 3.9090 (0.246) | 0.1e-3 (0.161) | 1.0703 (0.090) | 0.3e-3 (0.156) | 117.0e-3 (0.009) | 0.000647 | 0.3e-3 (0.441) |
x10 | -28.8e-3 (-0.158) | 0.007e-3 (0.060) | 1.8033 (0.132) | 0.3e-3 (0.144) | 9.5317 (0.561) | 0.3e-3 (0.364) | 2.6815 (0.211) | 0.8e-3 (0.336) | 3.9541 (0.276) | 0.3e-3 (0.441) | 0.000739 |
[12]:
ax, _ = instance.plot_energy_spectrum()

Mask a region around Al-26
[13]:
instance.set_mask((1790.0, 1825.0) * u.keV)
instance.mask
[13]:
array([False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, True, True, True, True, True, True,
True, True, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False])
[14]:
m = instance.fit_energy_spectrum()
m
[14]:
Migrad | |
---|---|
FCN = -9.049e+07 | Nfcn = 933 |
EDM = 0.00035 (Goal: 0.0001) | |
Valid Minimum | Below EDM threshold (goal x 10) |
No parameters at limit | Below call limit |
Hesse ok | Covariance accurate |
Name | Value | Hesse Error | Minos Error- | Minos Error+ | Limit- | Limit+ | Fixed | |
---|---|---|---|---|---|---|---|---|
0 | x0 | 17.041e3 | 0.007e3 | |||||
1 | x1 | -1.797 | 0.004 | |||||
2 | x2 | 24.3e3 | 0.5e3 | |||||
3 | x3 | 1.61187e3 | 0.00007e3 | |||||
4 | x4 | 76.4e3 | 0.6e3 | |||||
5 | x5 | 1.633376e3 | 0.000030e3 | |||||
6 | x6 | 28.9e3 | 0.5e3 | |||||
7 | x7 | 1.76417e3 | 0.00008e3 | |||||
8 | x8 | 72.0e3 | 0.5e3 | |||||
9 | x9 | 1.778556e3 | 0.000027e3 | |||||
10 | x10 | 2.347 | 0.024 |
x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | |
---|---|---|---|---|---|---|---|---|---|---|---|
x0 | 50.2 | 13.120e-3 (0.450) | -410 (-0.114) | -0.006 (-0.011) | -710 (-0.163) | -6.9e-3 (-0.032) | -630 (-0.185) | -0.012 (-0.021) | -740 (-0.191) | -10.4e-3 (-0.055) | -31.4e-3 (-0.182) |
x1 | 13.120e-3 (0.450) | 1.69e-05 | 255.291e-3 (0.121) | -0.005e-3 (-0.018) | 223.419e-3 (0.088) | -0.001e-3 (-0.005) | -59.125e-3 (-0.030) | 0.005e-3 (0.016) | -79.896e-3 (-0.036) | 0.002e-3 (0.018) | 0.004e-3 (0.038) |
x2 | -410 (-0.114) | 255.291e-3 (0.121) | 2.64e+05 | -4.513 (-0.119) | 0.03e6 (0.109) | 486.9e-3 (0.032) | 0.01e6 (0.060) | 1.787 (0.042) | 0.02e6 (0.068) | 837.5e-3 (0.061) | 2.0392 (0.163) |
x3 | -0.006 (-0.011) | -0.005e-3 (-0.018) | -4.513 (-0.119) | 0.00544 | 2.659 (0.058) | 0.1e-3 (0.028) | 1.056 (0.030) | 0.000 (0.036) | 1.563 (0.039) | 0.1e-3 (0.049) | 0.2e-3 (0.124) |
x4 | -710 (-0.163) | 223.419e-3 (0.088) | 0.03e6 (0.109) | 2.659 (0.058) | 3.83e+05 | 727.7e-3 (0.039) | 0.04e6 (0.145) | 7.219 (0.139) | 0.06e6 (0.178) | 3.2111 (0.196) | 7.6133 (0.505) |
x5 | -6.9e-3 (-0.032) | -0.001e-3 (-0.005) | 486.9e-3 (0.032) | 0.1e-3 (0.028) | 727.7e-3 (0.039) | 0.000905 | 799.9e-3 (0.055) | 0.2e-3 (0.062) | 1.1569 (0.070) | 0.1e-3 (0.085) | 0.2e-3 (0.218) |
x6 | -630 (-0.185) | -59.125e-3 (-0.030) | 0.01e6 (0.060) | 1.056 (0.030) | 0.04e6 (0.145) | 799.9e-3 (0.055) | 2.33e+05 | -4.481 (-0.111) | 0.03e6 (0.105) | 1.2824 (0.100) | 3.0630 (0.261) |
x7 | -0.012 (-0.021) | 0.005e-3 (0.016) | 1.787 (0.042) | 0.000 (0.036) | 7.219 (0.139) | 0.2e-3 (0.062) | -4.481 (-0.111) | 0.007 | 3.761 (0.082) | 0.3e-3 (0.129) | 0.6e-3 (0.283) |
x8 | -740 (-0.191) | -79.896e-3 (-0.036) | 0.02e6 (0.068) | 1.563 (0.039) | 0.06e6 (0.178) | 1.1569 (0.070) | 0.03e6 (0.105) | 3.761 (0.082) | 2.98e+05 | 626.6e-3 (0.043) | 4.3838 (0.330) |
x9 | -10.4e-3 (-0.055) | 0.002e-3 (0.018) | 837.5e-3 (0.061) | 0.1e-3 (0.049) | 3.2111 (0.196) | 0.1e-3 (0.085) | 1.2824 (0.100) | 0.3e-3 (0.129) | 626.6e-3 (0.043) | 0.000704 | 0.3e-3 (0.390) |
x10 | -31.4e-3 (-0.182) | 0.004e-3 (0.038) | 2.0392 (0.163) | 0.2e-3 (0.124) | 7.6133 (0.505) | 0.2e-3 (0.218) | 3.0630 (0.261) | 0.6e-3 (0.283) | 4.3838 (0.330) | 0.3e-3 (0.390) | 0.000594 |
[15]:
ax, _ = instance.plot_energy_spectrum()

Mask more
[16]:
instance.set_mask((1790.0, 1825.0) * u.keV, (1500.0, 1600.0) * u.keV, (1950.0, 2000.0) * u.keV)
instance.mask
[16]:
array([ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, True, True, True, True, True, True,
True, True, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, True,
True, True, True, True, True, True, True, True, True])
[17]:
m = instance.fit_energy_spectrum()
m
[17]:
Migrad | |
---|---|
FCN = -5.934e+07 | Nfcn = 932 |
EDM = 0.000404 (Goal: 0.0001) | |
Valid Minimum | Below EDM threshold (goal x 10) |
No parameters at limit | Below call limit |
Hesse ok | Covariance accurate |
Name | Value | Hesse Error | Minos Error- | Minos Error+ | Limit- | Limit+ | Fixed | |
---|---|---|---|---|---|---|---|---|
0 | x0 | 17.119e3 | 0.008e3 | |||||
1 | x1 | -1.816 | 0.008 | |||||
2 | x2 | 22.6e3 | 0.5e3 | |||||
3 | x3 | 1.61187e3 | 0.00007e3 | |||||
4 | x4 | 74.1e3 | 0.7e3 | |||||
5 | x5 | 1.633360e3 | 0.000031e3 | |||||
6 | x6 | 27.6e3 | 0.5e3 | |||||
7 | x7 | 1.76412e3 | 0.00008e3 | |||||
8 | x8 | 70.5e3 | 0.5e3 | |||||
9 | x9 | 1.778526e3 | 0.000026e3 | |||||
10 | x10 | 2.262 | 0.027 |
x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | |
---|---|---|---|---|---|---|---|---|---|---|---|
x0 | 71.6 | 15.55e-3 (0.230) | -650 (-0.141) | -0.007 (-0.011) | -1.12e3 (-0.200) | -12.5e-3 (-0.047) | -900 (-0.220) | -0.022 (-0.031) | -1.05e3 (-0.226) | -16.1e-3 (-0.073) | -49.1e-3 (-0.217) |
x1 | 15.55e-3 (0.230) | 6.39e-05 | 1.46470 (0.337) | -0.02e-3 (-0.035) | 1.62313 (0.306) | 0 (0.020) | 267.55e-3 (0.069) | 0.04e-3 (0.062) | 266.40e-3 (0.061) | 0.02e-3 (0.092) | 0.05e-3 (0.221) |
x2 | -650 (-0.141) | 1.46470 (0.337) | 2.95e+05 | -5.593 (-0.138) | 0.08e6 (0.212) | 761e-3 (0.045) | 0.03e6 (0.098) | 2.909 (0.063) | 0.03e6 (0.104) | 1.3286 (0.093) | 3.3261 (0.229) |
x3 | -0.007 (-0.011) | -0.02e-3 (-0.035) | -5.593 (-0.138) | 0.00557 | 2.547 (0.052) | 0.1e-3 (0.035) | 0.944 (0.026) | 0.000 (0.041) | 1.468 (0.036) | 0.1e-3 (0.052) | 0.2e-3 (0.118) |
x4 | -1.12e3 (-0.200) | 1.62313 (0.306) | 0.08e6 (0.212) | 2.547 (0.052) | 4.39e+05 | 1.3646 (0.066) | 0.06e6 (0.184) | 10.071 (0.180) | 0.08e6 (0.216) | 4.2213 (0.243) | 10.1576 (0.574) |
x5 | -12.5e-3 (-0.047) | 0 (0.020) | 761e-3 (0.045) | 0.1e-3 (0.035) | 1.3646 (0.066) | 0.000979 | 1.0465 (0.069) | 0.2e-3 (0.088) | 1.5065 (0.088) | 0.1e-3 (0.115) | 0.2e-3 (0.265) |
x6 | -900 (-0.220) | 267.55e-3 (0.069) | 0.03e6 (0.098) | 0.944 (0.026) | 0.06e6 (0.184) | 1.0465 (0.069) | 2.35e+05 | -4.936 (-0.120) | 0.03e6 (0.122) | 1.4595 (0.115) | 3.5779 (0.277) |
x7 | -0.022 (-0.031) | 0.04e-3 (0.062) | 2.909 (0.063) | 0.000 (0.041) | 10.071 (0.180) | 0.2e-3 (0.088) | -4.936 (-0.120) | 0.00716 | 4.655 (0.100) | 0.3e-3 (0.154) | 0.7e-3 (0.327) |
x8 | -1.05e3 (-0.226) | 266.40e-3 (0.061) | 0.03e6 (0.104) | 1.468 (0.036) | 0.08e6 (0.216) | 1.5065 (0.088) | 0.03e6 (0.122) | 4.655 (0.100) | 3e+05 | 757.8e-3 (0.053) | 5.0118 (0.343) |
x9 | -16.1e-3 (-0.073) | 0.02e-3 (0.092) | 1.3286 (0.093) | 0.1e-3 (0.052) | 4.2213 (0.243) | 0.1e-3 (0.115) | 1.4595 (0.115) | 0.3e-3 (0.154) | 757.8e-3 (0.053) | 0.000686 | 0.3e-3 (0.430) |
x10 | -49.1e-3 (-0.217) | 0.05e-3 (0.221) | 3.3261 (0.229) | 0.2e-3 (0.118) | 10.1576 (0.574) | 0.2e-3 (0.265) | 3.5779 (0.277) | 0.7e-3 (0.327) | 5.0118 (0.343) | 0.3e-3 (0.430) | 0.000713 |
[18]:
ax, _ = instance.plot_energy_spectrum()

3. Generate Background Histogram
[38]:
source_range = (1805, 1812) * u.keV #counts estimation in Al26 line
background_region_1 = (1650, 1750) * u.keV #background counts estimation before the line
background_region_2 = (1850, 1950) * u.keV #background counts estimation before the line
[39]:
bkg_model_histogram = instance.generate_bkg_model_histogram(source_range, [background_region_1, background_region_2])
The energy range [1650. 1750.] is modified to [1651.51515152, 1747.47474747]
The energy range [1850. 1950.] is modified to [1853.53535354, 1949.49494949]
[40]:
ax, _ = instance.plot_energy_spectrum()
ax.axvspan(source_range[0].value, source_range[1].value, color='red', alpha=0.2, label = 'source range')
ax.axvspan(background_region_1[0].value, background_region_1[1].value, color='blue', alpha=0.2, label = 'bkg extracted region 1')
ax.axvspan(background_region_2[0].value, background_region_2[1].value, color='green', alpha=0.2, label = 'bkg extracted region 1')
ax.legend()
[40]:
<matplotlib.legend.Legend at 0x3c1cbee90>

[41]:
bkg_model_histogram.write('bkg_model_al26_line.hdf5', overwrite=True)
4. Compare the background model with the actual background data
[24]:
%%time
bkg_histogram_in_Al26line = BinnedData("inputs_check_results.yaml")
bkg_histogram_in_Al26line.get_binned_data(unbinned_data=path_to_bkg, make_binning_plots=False,
output_name='bkg_data_al26_line_for_comparison', show_plots=False)
binning data...
Time unit: s
Em unit: keV
Phi unit: deg
PsiChi unit: None
CPU times: user 9min 42s, sys: 43.6 s, total: 10min 26s
Wall time: 11min 21s
[42]:
bkg_histogram_in_Al26line = Histogram.open("bkg_data_al26_line_for_comparison.hdf5")
[43]:
bkg_model_histogram = bkg_model_histogram.todense()
bkg_histogram_in_Al26line = bkg_histogram_in_Al26line.todense()
[44]:
bkg_model_histogram.clear_underflow_and_overflow()
bkg_histogram_in_Al26line.clear_underflow_and_overflow()
Normalization
[45]:
count_model = np.sum(bkg_model_histogram[:])
count_obs = np.sum(bkg_histogram_in_Al26line[:])
print("model:", count_model)
print("data:", count_obs)
print("difference:", (count_obs/count_model - 1)*1e2, "%")
model: 115660.74857012795
data: 121530.0
difference: 5.074540414472062 %
Phi distritbuion
[46]:
bkg_model_phi = bkg_model_histogram.project("Phi").todense()
bkg_obs_phi = bkg_histogram_in_Al26line.project("Phi").todense()
[47]:
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 8), sharex=True, gridspec_kw={'height_ratios': [3, 1, 1]})
ax3.set_xlabel(r'$\phi$ (deg.)')
ax1.bar(bkg_model_phi.axis.centers, bkg_model_phi.contents, width = 3, alpha=0.5, label='Model')
#ax1.bar(bkg_obs_phi.axis.centers, bkg_obs_phi.contents, width = 3, alpha=0.5, label='Data', capsize=3, yerr = np.sqrt(bkg_obs_phi.contents))
ax1.errorbar(bkg_obs_phi.axis.centers, bkg_obs_phi.contents, color = 'black', label='Data', fmt='.', capsize=3, yerr = np.sqrt(bkg_obs_phi.contents))
ax1.set_ylabel('Counts')
ax1.legend(fontsize = 10)
ax1.grid()
ax1.set_yscale('log')
# ratio
diff = bkg_obs_phi.contents / bkg_model_phi.contents - 1
diff_err = np.sqrt(bkg_obs_phi.contents) / bkg_model_phi.contents
ax2.errorbar(bkg_model_phi.axis.centers, diff, yerr=diff_err, fmt='.', capsize=3, color = 'black')
ax2.axhline(y = 0, color = 'grey', linestyle = '--')
ax2.grid()
ax2.set_ylabel('(Data / Model) - 1')
ax2.set_ylim(-1, 1)
# chi
xi = (bkg_obs_phi.contents - bkg_model_phi.contents) / np.sqrt(bkg_obs_phi.contents)
ax3.plot(bkg_model_phi.axis.centers, xi, '.', color = 'black')
ax3.axhspan(-5, 5, color = 'grey', alpha = 0.25, label = r"$\pm 5 \sigma$")
ax3.set_ylabel(r"$\chi$")
ax3.grid()
ax3.legend(fontsize = 10)
ax3.set_ylim(-20, 20)
[47]:
(-20.0, 20.0)

PsiChi distritbuion
[48]:
bkg_model_psichi = bkg_model_histogram.project("PsiChi")
bkg_obs_psichi = bkg_histogram_in_Al26line.project("PsiChi")
[49]:
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 8), sharex=True, gridspec_kw={'height_ratios': [3, 1, 1]})
ax3.set_xlabel(r'$\psi \xi$ (HEALPix index)')
ax1.bar(bkg_model_psichi.axis.centers, bkg_model_psichi.contents, width = 1, alpha=0.5, label='Model')
#ax1.bar(bkg_obs_psichi.axis.centers, bkg_obs_psichi.contents, width = 3, alpha=0.5, label='Data')#, capsize=3, yerr = np.sqrt(bkg_obs_psichi.contents))
ax1.errorbar(bkg_obs_psichi.axis.centers, bkg_obs_psichi.contents, color = 'black', alpha=0.1, label='Data', fmt='.', capsize=3, yerr = np.sqrt(bkg_obs_psichi.contents))
ax1.set_ylabel('Counts')
ax1.legend(fontsize = 10)
ax1.grid()
#ax1.set_yscale('log')
# ratio
diff = bkg_obs_psichi.contents / bkg_model_psichi.contents - 1
diff_err = np.sqrt(bkg_obs_psichi.contents) / bkg_model_psichi.contents
ax2.errorbar(bkg_model_psichi.axis.centers, diff, yerr=diff_err, fmt='.', capsize=3, color = 'black')
ax2.axhline(y = 0, color = 'grey', linestyle = '--')
ax2.grid()
ax2.set_ylabel('(Data / Model) - 1')
ax2.set_ylim(-1, 1)
# chi
xi = (bkg_obs_psichi.contents - bkg_model_psichi.contents) / np.sqrt(bkg_obs_psichi.contents)
ax3.plot(bkg_model_psichi.axis.centers, xi, '.', color = 'black')
ax3.axhspan(-5, 5, color = 'grey', alpha = 0.25, label = r"$\pm 5 \sigma$")
ax3.set_ylabel(r"$\chi$")
ax3.grid()
ax3.legend(fontsize = 10)
ax3.set_ylim(-10, 10)
[49]:
(-10.0, 10.0)

Rebinning
[50]:
import healpy as hp
[51]:
nside_out = 4
bkg_model_psichi_rebinned = hp.ud_grade(bkg_model_psichi[:], nside_out, power = -2)
bkg_obs_psichi_rebinned = hp.ud_grade(bkg_obs_psichi[:], nside_out, power = -2)
[52]:
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 8), sharex=True, gridspec_kw={'height_ratios': [3, 1, 1]})
ax3.set_xlabel(r'$\psi \xi$ (HEALPix index)')
ax1.bar(np.arange(hp.nside2npix(nside_out)), bkg_model_psichi_rebinned, width = 1, alpha=0.5, label='Model')
#ax1.bar(np.arange(hp.nside2npix(nside_out)), bkg_obs_psichi_rebinned, width = 3, alpha=0.5, label='Data', capsize=3, yerr = np.sqrt(bkg_obs_psichi_rebinned))
ax1.errorbar(np.arange(hp.nside2npix(nside_out)), bkg_obs_psichi_rebinned, color = 'black', alpha=1, label='Data', fmt='.', capsize=3, yerr = np.sqrt(bkg_obs_psichi_rebinned))
ax1.set_ylabel('Counts')
ax1.legend(fontsize = 10)
ax1.grid()
#ax1.set_yscale('log')
# ratio
diff = bkg_obs_psichi_rebinned / bkg_model_psichi_rebinned - 1
diff_err = np.sqrt(bkg_model_psichi_rebinned) / bkg_obs_psichi_rebinned
ax2.errorbar(np.arange(hp.nside2npix(nside_out)), diff, yerr=diff_err, fmt='.', capsize=3, color = 'black')
ax2.axhline(y = 0, color = 'grey', linestyle = '--')
ax2.grid()
ax2.set_ylabel('(Data / Model) - 1')
ax2.set_ylim(-0.3, 0.3)
# chi
xi = (bkg_obs_psichi_rebinned - bkg_model_psichi_rebinned) / np.sqrt(bkg_obs_psichi_rebinned)
ax3.plot(np.arange(hp.nside2npix(nside_out)), xi, '.', color = 'black')
ax3.axhspan(-5, 5, color = 'grey', alpha = 0.25, label = r"$\pm 5 \sigma$")
ax3.set_ylabel(r"$\chi$")
ax3.grid()
ax3.legend(fontsize = 10)
ax3.set_ylim(-10, 10)
[52]:
(-10.0, 10.0)

As an future idea, applying the smoothing to the background model would be useful to mitigate the Poisson fluctutation in the backgroud model. Note that the smoothing also loses high-frequency information, so there should be optimized in some ways.
[53]:
sliced_bkg_map = bkg_model_histogram[0,0,25]
hp.mollview(sliced_bkg_map)
sliced_smoothed_bkg_map = hp.smoothing(sliced_bkg_map, fwhm = (20.0 * u.deg).to('rad').value)
hp.mollview(sliced_smoothed_bkg_map)


[ ]: