def plot_counts(self, x, S, B, logPgg, xerr='None', alpha=0.2, filename='counts.pdf'): """ Plot the expected counts spectra of a gamma-ray observation. Arguments --------- S: dictionary with n-dim arrays, containing the expected signal counts B: dictionary with n-dim arrays, containing the expected bkg counts logPgg: Function for photon survival log(probability) versus log(energy) kwargs ------ xerr: (n+1)-dim array, bin boundaries. If not given it will be caclulated alpha: float, ratio of exposure between ON and OFF """ import matplotlib.pyplot as plt # calculate the bin bounds if xerr == 'None': xerr = calc_bin_bounds(x) xplot = 10.**np.linspace(np.log10(xerr[0]), np.log10(xerr[-1]), 200) # plot everything fig = plt.figure(1) ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') cp = plt.cm.Dark2 marker = ['s', 'o'] for i, k in enumerate(S.keys()): plt.errorbar( x, S[k], xerr=[x - xerr[:-1], xerr[1:] - x], ls='None', marker='o', lw=1., color=cp(i / (len(S.keys()) + 1.)), mec=cp(i / (len(S.keys()) + 1.)), mfc='None', label='exp. signal {0:s}'.format(k), ) plt.errorbar( x, B[k], xerr=[x - xerr[:-1], xerr[1:] - x], ls='None', lw=1., marker='s', color=cp(i / (len(S.keys()) + 1.)), mec=cp(i / (len(S.keys()) + 1.)), mfc='None', label='exp. bkg {0:s}'.format(k), ) plt.legend(loc=0) plt.xlabel('Energy') plt.ylabel('$\mathrm{d}N / \mathrm{d} E$') v = plt.axis() plt.axis([xerr[0] * 0.8, xerr[-1] / 0.8, v[2], v[3]]) ax2 = ax.twinx() ax2.set_xscale('log') ax2.set_yscale('log') plt.plot(xplot, np.exp(-self.tau.opt_depth_array(self.z, xplot))[0], lw=2., color='0.') plt.plot(xplot, np.exp(logPgg(np.log(xplot * 1e3))), lw=2., color='red') v = plt.axis() plt.axis([xerr[0] * 0.8, xerr[-1] / 0.8, v[2], v[3]]) plt.savefig(filename + '.spec', format=filename.split('.')[-1]) # histogramm with NON values from scipy.stats import poisson fig = plt.figure(2) for i, k in enumerate(S.keys()): NonExp = (S[k] + B[k])[0] * np.ones(5000) NON = poisson.rvs(NonExp) plt.hist(NON, label=k) plt.legend(loc=0) plt.savefig(filename + '.hist', format=filename.split('.')[-1]) plt.show() return
def plot_spectrum(self, x, y, s, logPgg='None', xerr='None', filename='spectrum.pdf', Emin=0., Emax=0.): """ Plot an observed gamma-ray spectrum together with it's abosrption corrected (w/ and w/o ALPs) versions. Arguments --------- x: n-dim array, Energy of spectrum in TeV y: n-dim array, observed Flux of spectrum in dN / dE s: n-dim array, dF kwargs ------ logPgg: Function for photon survival log(probability) versus log(energy). If not given it will be calculated. xerr: (n+1)-dim array, bin boundaries. If not given it will be caclulated Emin: minimum plot energy in TeV Emax: maximum plot energy in TeV """ import matplotlib.pyplot as plt assert x.shape[0] == y.shape[0] assert x.shape[0] == s.shape[0] m = y > 0. x = x[m] y = y[m] s = s[m] stat, p, err, merr, cov, func, dfunc = {}, {}, {}, {}, {}, {}, {} f, df = {'obs': y}, {'obs': s} # calculate the bin bounds if xerr == 'None': xerr = calc_bin_bounds(x) if not Emin: Emin = xerr[0] if not Emax: Emin = xerr[-1] xplot = 10.**np.linspace(np.log10(Emin), np.log10(Emax), 200) # pl fit to observed spectrum stat['obs'], p['obs'], err['obs'], merr['obs'], cov[ 'obs'] = MinuitFitPL(x, y, s, full_output=True) func['obs'] = pl dfunc['obs'] = butterfly_pl # calculate the average absorption correction pggAve = self.calc_pggave_conversion(xerr * 1e3, func=func['obs'], pfunc=p['obs'], logPgg=logPgg) tauAve = self.tau.opt_depth_Ebin(self.z, xerr, func['obs'], p['obs']) atten = np.exp(-tauAve) f['alp'] = y / pggAve df['alp'] = s / pggAve f['tau'] = y / atten df['tau'] = s / atten # pl fit to deabs spectra stat['alp'], p['alp'], err['alp'], merr['alp'], cov[ 'alp'] = MinuitFitPL(x, y / pggAve, s / pggAve, full_output=True) func['alp'] = pl dfunc['alp'] = butterfly_pl stat['tau'], p['tau'], err['tau'], merr['tau'], cov[ 'tau'] = MinuitFitPL(x, y / atten, s / atten, full_output=True) func['tau'] = pl dfunc['tau'] = butterfly_pl for k in stat.keys(): print '{0:s}:'.format(k) for l in p[k].keys(): print "{0:s} = {1:.2e} +/- {2:.2e}".format( l, p[k][l], err[k][l]) # plot everything fig = plt.figure() ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') cp = plt.cm.Dark2 marker = {'obs': 's', 'tau': 'v', 'alp': 'o'} label = { 'obs': 'observed', 'tau': 'deabs. w/o ALPs', 'alp': 'deabs. w/ ALPs' } for i, k in enumerate(f.keys()): plt.errorbar( x, f[k], yerr=df[k], xerr=[x - xerr[:-1], xerr[1:] - x], ls='None', marker=marker[k], color=cp(i / (len(f.keys()) + 1.)), label=label[k], ) plt.plot(xplot, func[k](p[k], xplot), ls='-', lw=1., color=cp(i / (len(f.keys()) + 1.))) plt.fill_between(xplot, func[k](p[k], xplot) * (1. - dfunc[k](p[k], xplot, err[k], cov[k])), y2=func[k](p[k], xplot) * (1. + dfunc[k](p[k], xplot, err[k], cov[k])), lw=1., facecolor='None', edgecolor=cp(i / (len(f.keys()) + 1.))) plt.legend(loc=0) plt.xlabel('Energy') plt.ylabel('$\mathrm{d}N / \mathrm{d} E$') v = plt.axis() plt.axis([Emin * 0.8, Emax / 0.8, v[2], v[3]]) ax2 = ax.twinx() ax2.set_xscale('log') ax2.set_yscale('log') plt.plot(xplot, np.exp(logPgg(np.log(xplot * 1e3))), lw=2., color='red') plt.plot(xplot, np.exp(-self.tau.opt_depth_array(self.z, xplot))[0], lw=2., color='0.', ls='--') v = plt.axis() plt.axis([Emin * 0.8, Emax / 0.8, v[2], v[3]]) plt.savefig(filename, format=filename.split('.')[-1]) plt.show() return
def plot_counts(self, x,S,B, logPgg, xerr = 'None',alpha = 0.2,filename = 'counts.pdf'): """ Plot the expected counts spectra of a gamma-ray observation. Arguments --------- S: dictionary with n-dim arrays, containing the expected signal counts B: dictionary with n-dim arrays, containing the expected bkg counts logPgg: Function for photon survival log(probability) versus log(energy) kwargs ------ xerr: (n+1)-dim array, bin boundaries. If not given it will be caclulated alpha: float, ratio of exposure between ON and OFF """ import matplotlib.pyplot as plt # calculate the bin bounds if xerr == 'None': xerr = calc_bin_bounds(x) xplot = 10.**np.linspace(np.log10(xerr[0]),np.log10(xerr[-1]),200) # plot everything fig = plt.figure(1) ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') cp = plt.cm.Dark2 marker = ['s','o'] for i,k in enumerate(S.keys()): plt.errorbar(x,S[k], xerr = [x - xerr[:-1], xerr[1:] - x], ls = 'None', marker = 'o', lw = 1., color = cp(i / (len(S.keys()) + 1.)), mec = cp(i / (len(S.keys()) + 1.)), mfc = 'None', label = 'exp. signal {0:s}'.format(k), ) plt.errorbar(x,B[k], xerr = [x - xerr[:-1], xerr[1:] - x], ls = 'None', lw = 1., marker = 's', color = cp(i / (len(S.keys()) + 1.)), mec = cp(i / (len(S.keys()) + 1.)), mfc = 'None', label = 'exp. bkg {0:s}'.format(k), ) plt.legend(loc = 0) plt.xlabel('Energy') plt.ylabel('$\mathrm{d}N / \mathrm{d} E$') v = plt.axis() plt.axis([xerr[0] * 0.8, xerr[-1] / 0.8, v[2], v[3]]) ax2 = ax.twinx() ax2.set_xscale('log') ax2.set_yscale('log') plt.plot(xplot, np.exp(-self.tau.opt_depth_array(self.z,xplot))[0], lw = 2., color = '0.' ) plt.plot(xplot, np.exp(logPgg(np.log(xplot * 1e3))), lw = 2., color = 'red' ) v = plt.axis() plt.axis([xerr[0] * 0.8, xerr[-1] / 0.8, v[2], v[3]]) plt.savefig(filename + '.spec', format = filename.split('.')[-1]) # histogramm with NON values from scipy.stats import poisson fig = plt.figure(2) for i,k in enumerate(S.keys()): NonExp = (S[k] + B[k])[0] * np.ones(5000) NON = poisson.rvs(NonExp) plt.hist(NON, label = k) plt.legend(loc = 0) plt.savefig(filename + '.hist', format = filename.split('.')[-1]) plt.show() return
def plot_spectrum(self, x,y,s, logPgg = 'None', xerr = 'None',filename = 'spectrum.pdf',Emin = 0., Emax = 0.): """ Plot an observed gamma-ray spectrum together with it's abosrption corrected (w/ and w/o ALPs) versions. Arguments --------- x: n-dim array, Energy of spectrum in TeV y: n-dim array, observed Flux of spectrum in dN / dE s: n-dim array, dF kwargs ------ logPgg: Function for photon survival log(probability) versus log(energy). If not given it will be calculated. xerr: (n+1)-dim array, bin boundaries. If not given it will be caclulated Emin: minimum plot energy in TeV Emax: maximum plot energy in TeV """ import matplotlib.pyplot as plt assert x.shape[0] == y.shape[0] assert x.shape[0] == s.shape[0] m = y > 0. x = x[m] y = y[m] s = s[m] stat,p,err,merr,cov,func,dfunc = {},{},{},{},{},{},{} f,df = {'obs': y}, {'obs': s} # calculate the bin bounds if xerr == 'None': xerr = calc_bin_bounds(x) if not Emin: Emin = xerr[0] if not Emax: Emin = xerr[-1] xplot = 10.**np.linspace(np.log10(Emin),np.log10(Emax),200) # pl fit to observed spectrum stat['obs'],p['obs'], err['obs'],merr['obs'], cov['obs'] = MinuitFitPL(x,y,s , full_output = True) func['obs'] = pl dfunc['obs'] = butterfly_pl # calculate the average absorption correction pggAve = self.calc_pggave_conversion(xerr * 1e3, func=func['obs'], pfunc=p['obs'], logPgg = logPgg) tauAve = self.tau.opt_depth_Ebin(self.z,xerr,func['obs'],p['obs']) atten = np.exp(-tauAve) f['alp'] = y / pggAve df['alp'] = s / pggAve f['tau'] = y / atten df['tau'] = s / atten # pl fit to deabs spectra stat['alp'],p['alp'], err['alp'],merr['alp'], cov['alp'] = MinuitFitPL(x,y / pggAve,s / pggAve , full_output = True) func['alp'] = pl dfunc['alp'] = butterfly_pl stat['tau'],p['tau'], err['tau'],merr['tau'], cov['tau'] = MinuitFitPL(x,y / atten ,s / atten, full_output = True) func['tau'] = pl dfunc['tau'] = butterfly_pl for k in stat.keys(): print '{0:s}:'.format(k) for l in p[k].keys(): print "{0:s} = {1:.2e} +/- {2:.2e}".format(l,p[k][l],err[k][l]) # plot everything fig = plt.figure() ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') cp = plt.cm.Dark2 marker = {'obs': 's', 'tau': 'v', 'alp':'o'} label = {'obs': 'observed', 'tau': 'deabs. w/o ALPs', 'alp':'deabs. w/ ALPs'} for i,k in enumerate(f.keys()): plt.errorbar(x,f[k], yerr = df[k], xerr = [x - xerr[:-1], xerr[1:] - x], ls = 'None', marker = marker[k], color = cp(i / (len(f.keys()) + 1.)), label = label[k], ) plt.plot(xplot, func[k](p[k],xplot), ls = '-', lw = 1., color = cp(i / (len(f.keys()) + 1.)) ) plt.fill_between(xplot, func[k](p[k],xplot)*(1. - dfunc[k](p[k],xplot,err[k],cov[k])), y2 = func[k](p[k],xplot)*(1. + dfunc[k](p[k],xplot,err[k],cov[k])), lw = 1., facecolor = 'None', edgecolor = cp(i / (len(f.keys()) + 1.)) ) plt.legend(loc = 0) plt.xlabel('Energy') plt.ylabel('$\mathrm{d}N / \mathrm{d} E$') v = plt.axis() plt.axis([Emin * 0.8, Emax / 0.8, v[2], v[3]]) ax2 = ax.twinx() ax2.set_xscale('log') ax2.set_yscale('log') plt.plot(xplot, np.exp(logPgg(np.log(xplot * 1e3))), lw = 2., color = 'red' ) plt.plot(xplot, np.exp(-self.tau.opt_depth_array(self.z,xplot))[0], lw = 2., color = '0.', ls = '--' ) v = plt.axis() plt.axis([Emin * 0.8, Emax / 0.8, v[2], v[3]]) plt.savefig(filename, format = filename.split('.')[-1]) plt.show() return
def __init__(self,x,y,s,bins = None, **kwargs): """ Class to fit Powerlaw to data using minuit.migrad Data is corrected for absorption using the B-field environments of either an AGN Jet or intracluster medium and the GMF y(x) = p['Prefactor'] * ( x / p['Scale'] ) ** p['Index'] y_abs = < P gg > * y_obs < P gg > is bin averaged transfer function including ALPs. Additional fit parameters are B,g,m,Rmax,R_BLR,n Parameters ---------- x: n-dim array containing the measured x values in TeV y: n-dim array containing the measured y values, i.e. y = y(x) s: n-dim array with (symmetric) measurment uncertainties on y kwargs ------ bins: n+1 dim array with boundaries. if none, comupted from x data. func: Function that describes the observed spectrum and takes x and pobs as parameters, y = func(x,pobs) pobs: parameters for function and all kwargs from PhotALPsConv.calc_conversion.Calc_Conv. """ # --- Set the defaults kwargs.setdefault('func',None) kwargs.setdefault('pobs',None) # -------------------- kwargs.setdefault('nE',30) kwargs.setdefault('Esteps',50) # -------------------- for k in kwargs.keys(): if kwargs[k] == None: raise TypeError("kwarg {0:s} cannot be None type.".format(k)) if not len(x) == len(y) or not len(x) == len(s) or not len(y) == len(s): raise TypeError("Lists must have same length!") super(Fit_JetICMGMF,self).__init__(**kwargs) # init the jet mixing and gmf mixing, see e.g. # http://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with-multiple-inheritance # for a small example self.__dict__.update(kwargs) # form instance of kwargs self.x = np.array(x) self.y = np.array(y) self.yerr = np.array(s) self.exp = floor(np.log10(y[0])) self.y /= 10.**self.exp self.yerr /= 10.**self.exp if bins == None or not len(bins) == x.shape[0] + 1: self.bins = calc_bin_bounds(x) # --- create 2-dim energy and tau arrays to compute average mixing in each energy bin for i,E in enumerate(self.bins): if not i: self.logE_array = np.linspace(np.log(E),np.log(self.bins[i+1]),self.nE) self.t_array = self.tau.opt_depth_array(self.z,np.exp(self.logE_array))[0] elif i == len(self.bins) - 1: break else: logE = np.linspace(np.log(E),np.log(self.bins[i+1]),self.nE) self.t_array = np.vstack((self.t_array,self.tau.opt_depth_array(self.z,np.exp(logE))[0])) self.logE_array = np.vstack((self.logE_array,logE)) return
def __init__(self, x, y, s, bins=None, **kwargs): """ Class to fit Powerlaw to data using minuit.migrad Data is corrected for absorption using the B-field environments of either an AGN Jet or intracluster medium and the GMF y(x) = p['Prefactor'] * ( x / p['Scale'] ) ** p['Index'] y_abs = < P gg > * y_obs < P gg > is bin averaged transfer function including ALPs. Additional fit parameters are B,g,m,Rmax,R_BLR,n Parameters ---------- x: n-dim array containing the measured x values in TeV y: n-dim array containing the measured y values, i.e. y = y(x) s: n-dim array with (symmetric) measurment uncertainties on y kwargs ------ bins: n+1 dim array with boundaries. if none, comupted from x data. func: Function that describes the observed spectrum and takes x and pobs as parameters, y = func(x,pobs) pobs: parameters for function and all kwargs from PhotALPsConv.calc_conversion.Calc_Conv. """ # --- Set the defaults kwargs.setdefault('func', None) kwargs.setdefault('pobs', None) # -------------------- kwargs.setdefault('nE', 30) kwargs.setdefault('Esteps', 50) # -------------------- for k in kwargs.keys(): if kwargs[k] == None: raise TypeError("kwarg {0:s} cannot be None type.".format(k)) if not len(x) == len(y) or not len(x) == len(s) or not len(y) == len( s): raise TypeError("Lists must have same length!") super(Fit_JetICMGMF, self).__init__( **kwargs) # init the jet mixing and gmf mixing, see e.g. # http://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with-multiple-inheritance # for a small example self.__dict__.update(kwargs) # form instance of kwargs self.x = np.array(x) self.y = np.array(y) self.yerr = np.array(s) self.exp = floor(np.log10(y[0])) self.y /= 10.**self.exp self.yerr /= 10.**self.exp if bins == None or not len(bins) == x.shape[0] + 1: self.bins = calc_bin_bounds(x) # --- create 2-dim energy and tau arrays to compute average mixing in each energy bin for i, E in enumerate(self.bins): if not i: self.logE_array = np.linspace(np.log(E), np.log(self.bins[i + 1]), self.nE) self.t_array = self.tau.opt_depth_array( self.z, np.exp(self.logE_array))[0] elif i == len(self.bins) - 1: break else: logE = np.linspace(np.log(E), np.log(self.bins[i + 1]), self.nE) self.t_array = np.vstack( (self.t_array, self.tau.opt_depth_array(self.z, np.exp(logE))[0])) self.logE_array = np.vstack((self.logE_array, logE)) return