def model(params, cluster, data): #--- Extract parameters CR_X_E = params[0]*1e-2 CR_eta = params[1] CR_slope = params[2] #--- Set parameters cluster = perseus_model_library.set_pure_hadronic_model(cluster, ('density', CR_eta), CR_X_E, CR_slope) #--- Profile r_synch, p_synch = cluster.get_synchrotron_profile(data['profile']['radius'], freq0=data['info']['prof_freq']) #--- Spectrum sfreq_bis = np.append(np.array([1]), data['spectrum']['freq'].to_value('MHz'))*u.MHz s_synch = cluster.get_synchrotron_spectrum(sfreq_bis, Rmin=data['info']['spec_Rmin'], Rmax=data['info']['spec_Rmax'], type_integral='cylindrical')[1] s_synch = s_synch[1:] #--- Spectral index p_synch1 = cluster.get_synchrotron_profile(data['index']['radius'], freq0=data['info']['idx_freq1'])[1] p_synch2 = cluster.get_synchrotron_profile(data['index']['radius'], freq0=data['info']['idx_freq2'])[1] upper = np.log10((p_synch1/p_synch2).to_value('')) lower = np.log10((data['info']['idx_freq1']/data['info']['idx_freq2']).to_value('')) i_synch = -upper/lower return p_synch, s_synch, i_synch
def model_hadronic(params, cluster, data): ''' Compute the hadronic model Parameters ---------- - params (list of float): model parameters to be tested - cluster (minot object): cluster object - data (dict): radio data Output ------ - p_synch (quantity array): radio profile - s_synch (quantity array): radio spectrum - i_synch (quantity array): radio spectral index profile ''' #--- Extract parameters CR_X_E = params[0] * 1e-2 CR_eta = params[1] CR_slope = params[2] Norm = params[3] #--- Set parameters cluster = perseus_model_library.set_pure_hadronic_model( cluster, ('density', CR_eta), CR_X_E, CR_slope) #--- Profile r_synch, p_synch = cluster.get_synchrotron_profile( data['profile']['radius'], freq0=data['info']['prof_freq']) #--- Spectrum sfreq_bis = np.append(np.array([1]), data['spectrum']['freq'].to_value('MHz')) * u.MHz s_synch = cluster.get_synchrotron_spectrum(sfreq_bis, Rmin=data['info']['spec_Rmin'], Rmax=data['info']['spec_Rmax'], type_integral='cylindrical')[1] s_synch = s_synch[1:] #--- Spectral index if fit_index: p_synch1 = cluster.get_synchrotron_profile( data['index']['radius'], freq0=data['info']['idx_freq1'])[1] p_synch2 = cluster.get_synchrotron_profile( data['index']['radius'], freq0=data['info']['idx_freq2'])[1] upper = np.log10((p_synch1 / p_synch2).to_value('')) lower = np.log10((data['info']['idx_freq1'] / data['info']['idx_freq2']).to_value('')) i_synch = -upper / lower else: i_synch = np.nan return Norm * p_synch, s_synch, i_synch
coll2 = ['orange', 'green', 'magenta'] output_dir = [] output_dir0 = '/sps/cta/llr/radam/PerseusGammaCalib' for im in mag_case: output_dir.append(output_dir0 + '_' + model_case + '_' + im + '_' + basedata) #========== Define the cluster model cluster = [] for i in range(len(mag_case)): if model_case == 'Hadronic': cluster0 = perseus_model_library.default_model( directory=output_dir[i]) cluster0 = perseus_model_library.set_magnetic_field_model( cluster0, case=mag_case[i]) cluster0 = perseus_model_library.set_pure_hadronic_model( cluster0, ('density', 1.0), 1e-2, 2.5) cluster0.Npt_per_decade_integ = 10 elif model_case == 'Leptonic': cluster0 = perseus_model_library.default_model( directory=output_dir[i]) cluster0 = perseus_model_library.set_magnetic_field_model( cluster0, case=mag_case[i]) cluster0 = perseus_model_library.set_pure_leptonic_model( cluster0, ('density', 1.0), 1e-5, 2.0) if app_steady: cluster0.cre1_loss_model = 'Steady' cluster0.Npt_per_decade_integ = 10 else: raise ValueError('Only Hadronic or Leptonic are possible') cluster.append(cluster0) #========== Data
# Main function #======================================== if __name__ == "__main__": #========== Parameters Nmc = 10 # Number of Monte Carlo trials fit_index = False # Fit the spectral index profile mcmc_nsteps = 100 # number of MCMC points mcmc_burnin = 10 # number of MCMC burnin points mcmc_reset = False # Reset the MCMC #========== Define the cluster model cluster = perseus_model_library.default_model() cluster = perseus_model_library.set_magnetic_field_model(cluster, case='Taylor2006') cluster = perseus_model_library.set_pure_hadronic_model(cluster, ('density', 2.0), 3e-3, 2.5) cluster.Npt_per_decade_integ = 10 #========== Data radio_data = perseus_data_library.get_radio_data(cluster.cosmo, cluster.redshift) #========== MCMC fit #----- Define the MCMC par0 = np.array([0.3, 2.0, 2.5]) param_name = [r'$X_{CRp}$(%)', r'$\eta_{CRp}$', r'$\alpha_{CRp}$'] ndim, nwalkers, nsteps, burnin = len(par0), 10, mcmc_nsteps, mcmc_burnin pos = [par0 + par0*1e-1*np.random.randn(ndim) for i in range(nwalkers)] #----- Define the MCMC sampler = emcee.EnsembleSampler(nwalkers, ndim, lnlike, args=[cluster, radio_data], pool=Pool(cpu_count()))
def post_analysis(cluster, radio_data, param_name, par_min, par_max, burnin, conf=68.0, Nmc=100, model_case='Hadronic'): ''' Extract statistics and plots after runing the MCMC Parameters ---------- - cluster (minot object): cluster object - radio_data (dict): radio data - param_name (list): list of the names of the parameters - par_min/max (list): list of min and max value for the parameters - burnin (int): the burn-in phase of the chain - conf (float): the confidence limit interval - Nmc (int): the number of Monte Carlo sample to draw Output ------ - Plots and statistics ''' #========== Get the chains #----- Restore chains with open(cluster.output_dir+'/'+model_case+'_sampler.pkl', 'rb') as f: sampler = pickle.load(f) #----- Plot acceptance # Acceptance sample_acc = (np.roll(sampler.lnprobability,1,axis=1) != sampler.lnprobability) sample_acc = sample_acc[:,1:] acc_mean = np.sum(sample_acc)/float(len(sample_acc.flatten())) acc_sample = np.sum(sample_acc, axis=0)/float(len(sample_acc[:,0])) acc_chain = np.sum(sample_acc, axis=1)/float(len(sample_acc[0,:])) plt.figure(10) plt.plot(sampler.acceptance_fraction, 'k') plt.plot(acc_chain, 'r', linestyle='--') plt.ylim(0,1) plt.xlim(0,len(sampler.acceptance_fraction)-1) plt.xlabel('Chain number') plt.ylabel('Mean sample acceptance') plt.savefig(cluster.output_dir+'/'+model_case+'_chains_acceptance_chain.pdf') plt.close() plt.figure(11) plt.plot(acc_sample, 'k') plt.ylim(0,1) plt.xlim(0,len(acc_sample)-1) plt.xlabel('Sample number') plt.ylabel('Mean chain acceptance') plt.savefig(cluster.output_dir+'/'+model_case+'_chains_acceptance_sample.pdf') plt.close() print(' --> Acceptence plot done') #----- Burn in param_chains = sampler.chain[:, burnin:, :] lnL_chains = sampler.lnprobability[:, burnin:] ndim = param_chains.shape[2] print(' --> Burn-in done') #----- Chain covariance chain_list = [] for i in range(ndim): chain_list.append(param_chains[:,:,i].flatten()) par_cov = np.cov(np.array(chain_list)) print('---- Param chain covariance^1/2:') print(par_cov**0.5) print('') print(' --> Chain covariance done') #----- Get the best fit parameters wbest = (lnL_chains == np.amax(lnL_chains)) param_best = [] for i in range(ndim): param_best.append(((param_chains[:,:,i])[wbest])[0]) print(' --> Best-fit parameters done') #----- MC parameters param_flat = param_chains.reshape(param_chains.shape[0]*param_chains.shape[1],param_chains.shape[2]) Nsample = len(param_flat[:,0])-1 param_MC = np.zeros((Nmc, ndim)) for i in range(Nmc): param_MC[i,:] = param_flat[np.random.randint(0, high=Nsample), :] # randomly taken from chains print(' --> MC parameters done') #========== Statistics results #----- Chain statistics chainfname = cluster.output_dir+'/'+model_case+'_chainstat.txt' par_best, par_percentile = mcmc_common.chains_statistics(param_chains, lnL_chains, parname=param_name, conf=conf, show=True, outfile=chainfname) print(' --> Chain statistics done') #----- Parameter space try: mcmc_common.chains_plots(param_chains, param_name, cluster.output_dir+'/'+model_case+'_chains', par_best=par_best, par_percentile=par_percentile, conf=conf, par_min=par_min, par_max=par_max) except: print('Error in chains_plots --> skip it') print(' --> Chain plots done') #========== Data versus model # Best-fit if model_case == 'Hadronic': prof_best, spec_best, idx_best = model_hadronic(par_best, cluster, radio_data) if model_case == 'Leptonic': prof_best, spec_best, idx_best = model_leptonic(par_best, cluster, radio_data) # MC sampling prof_mc = [] spec_mc = [] idx_mc = [] for imc in range(Nmc): if model_case == 'Hadronic': prof_mci, spec_mci, idx_mci = model_hadronic(param_MC[imc,:], cluster, radio_data) if model_case == 'Leptonic': prof_mci, spec_mci, idx_mci = model_leptonic(param_MC[imc,:], cluster, radio_data) prof_mc.append(prof_mci) spec_mc.append(spec_mci) idx_mc.append(idx_mci) # Limits prof_u = np.percentile(np.array(prof_mc), 100-(100-conf)/2.0, axis=0)*prof_mc[0].unit prof_d = np.percentile(np.array(prof_mc), (100-conf)/2.0, axis=0)*prof_mc[0].unit spec_u = np.percentile(np.array(spec_mc), 100-(100-conf)/2.0, axis=0)*spec_mc[0].unit spec_d = np.percentile(np.array(spec_mc), (100-conf)/2.0, axis=0)*spec_mc[0].unit idx_u = np.percentile(np.array(idx_mc), 100-(100-conf)/2.0, axis=0) idx_d = np.percentile(np.array(idx_mc), (100-conf)/2.0, axis=0) #----- Spectrum fig = plt.figure(0, figsize=(8, 6)) # MC for imc in range(Nmc): plt.plot(radio_data['spectrum']['freq'].to_value('MHz'), spec_mc[imc].to_value('Jy'), color='blue', alpha=0.05) # Limits plt.plot(radio_data['spectrum']['freq'].to_value('MHz'), spec_u.to_value('Jy'), color='blue', linewidth=2, linestyle='--', label=str(conf)+'% C.L.') plt.plot(radio_data['spectrum']['freq'].to_value('MHz'), spec_d.to_value('Jy'), color='blue', linewidth=2, linestyle='--') plt.fill_between(radio_data['spectrum']['freq'].to_value('MHz'), spec_d.to_value('Jy'), spec_u.to_value('Jy'), color='blue', alpha=0.2) # Best fit and data plt.plot(radio_data['spectrum']['freq'].to_value('MHz'), spec_best.to_value('Jy'), color='blue', linewidth=3, label='Best-fit') plt.errorbar(radio_data['spectrum']['freq'].to_value('MHz'), radio_data['spectrum']['flux'].to_value('Jy'), radio_data['spectrum']['error'].to_value('Jy'), marker='o', color='k', linestyle='', label='Data') plt.xscale('log') plt.yscale('log') plt.xlabel('frequency (MHz)') plt.ylabel('flux (Jy)') plt.legend() plt.savefig(cluster.output_dir+'/'+model_case+'_Radio_spectrum.pdf') plt.close() #----- Profile fig = plt.figure(0, figsize=(8, 6)) # MC for imc in range(Nmc): plt.plot(radio_data['profile']['radius'].to_value('kpc'), prof_mc[imc].to_value('Jy arcmin-2'), color='blue', alpha=0.05) # Limits plt.plot(radio_data['profile']['radius'].to_value('kpc'), prof_u.to_value('Jy arcmin-2'), color='blue', linewidth=2, linestyle='--', label=str(conf)+'% C.L.') plt.plot(radio_data['profile']['radius'].to_value('kpc'), prof_d.to_value('Jy arcmin-2'), color='blue', linewidth=2, linestyle='--') plt.fill_between(radio_data['profile']['radius'].to_value('kpc'), prof_d.to_value('Jy arcmin-2'), prof_u.to_value('Jy arcmin-2'), color='blue', alpha=0.2) # Best and data plt.plot(radio_data['profile']['radius'].to_value('kpc'), prof_best.to_value('Jy arcmin-2'), color='blue', linewidth=3, label='Best-fit') plt.errorbar(radio_data['profile']['radius'].to_value('kpc'), radio_data['profile']['flux'].to_value('Jy arcmin-2'), yerr=radio_data['profile']['error'].to_value('Jy arcmin-2'), marker='o', linestyle='', color='k', label='Data') plt.plot([radio_data['info']['prof_Rmin'].to_value('kpc'),radio_data['info']['prof_Rmin'].to_value('kpc')], [0,1e6], linestyle='--', color='grey') plt.plot([radio_data['info']['prof_Rmax'].to_value('kpc'),radio_data['info']['prof_Rmax'].to_value('kpc')], [0,1e6], linestyle='--', color='grey') plt.fill_between([0,radio_data['info']['prof_Rmin'].to_value('kpc')], [0,0], [1e6,1e6], color='grey', alpha=0.2, label='Excluded region') plt.fill_between([radio_data['info']['prof_Rmax'].to_value('kpc'), radio_data['info']['prof_Rmax'].to_value('kpc')*1e6], [0,0], [1e6,1e6], color='grey', alpha=0.2) plt.xscale('log') plt.yscale('log') plt.xlabel('radius (kpc)') plt.ylabel('surface brightness (Jy/arcmin$^2$)') if basedata == 'Gitti2002': plt.xlim(10,250) plt.ylim(1e-3,1e1) if basedata == 'Pedlar1990': plt.xlim(13,100) plt.ylim(5e-3,5e-1) plt.savefig(cluster.output_dir+'/'+model_case+'_Radio_profile.pdf') plt.close() #----- Spectral index if fit_index: fig = plt.figure(0, figsize=(8, 6)) # MC for imc in range(Nmc): plt.plot(radio_data['index']['radius'].to_value('kpc'), idx_mc[imc], color='blue', alpha=0.05) # Limits plt.plot(radio_data['index']['radius'].to_value('kpc'), idx_u, color='blue', linewidth=2, linestyle='--', label=str(conf)+'% C.L.') plt.plot(radio_data['index']['radius'].to_value('kpc'), idx_d, color='blue', linewidth=2, linestyle='--') plt.fill_between(radio_data['index']['radius'].to_value('kpc'), idx_d, idx_u, color='blue', alpha=0.2) # Best and data plt.plot(radio_data['index']['radius'].to_value('kpc'), idx_best, color='blue', linewidth=3, label='Best-fit') plt.errorbar(radio_data['index']['radius'].to_value('kpc'), radio_data['index']['idx'], yerr=radio_data['index']['error'], marker='o', linestyle='', color='k', label='Data') plt.plot([radio_data['info']['idx_Rmin'].to_value('kpc'),radio_data['info']['idx_Rmin'].to_value('kpc')], [0,1e6], linestyle='--', color='grey') plt.plot([radio_data['info']['idx_Rmax'].to_value('kpc'),radio_data['info']['idx_Rmax'].to_value('kpc')], [0,1e6], linestyle='--', color='grey') plt.fill_between([0,radio_data['info']['idx_Rmin'].to_value('kpc')], [0,0], [1e6,1e6], color='grey', alpha=0.1, label='Excluded region') plt.fill_between([radio_data['info']['idx_Rmax'].to_value('kpc'), np.inf], [0,0], [1e6,1e6], color='grey', alpha=0.1) plt.xscale('log') plt.yscale('linear') plt.xlabel('radius (kpc)') plt.ylabel('spectral index') plt.xlim(10,250) plt.ylim(0.5,2.5) plt.savefig(cluster.output_dir+'/'+model_case+'_Radio_index.pdf') plt.close() print(' --> Radio plots done') #========== Implication for gamma rays energy = np.logspace(-2,6,100)*u.GeV radius = np.logspace(0,4,100)*u.kpc #---------- Best-fit if model_case == 'Hadronic': cluster = perseus_model_library.set_pure_hadronic_model(cluster, ('density', param_best[1]), param_best[0]*1e-2, param_best[2]) if model_case == 'Leptonic': cluster = perseus_model_library.set_pure_leptonic_model(cluster, ('density', param_best[1]), param_best[0]*1e-5, param_best[2]) if app_steady: cluster.cre1_loss_model = 'Steady' # Hadronic E, dN_dEdSdt = cluster.get_gamma_spectrum(energy, Rmin=None, Rmax=cluster.R500, type_integral='cylindrical', Rmin_los=None, NR500_los=5.0) r, dN_dSdtdO = cluster.get_gamma_profile(radius, Emin=150*u.GeV, Emax=50*u.TeV, Energy_density=False, Rmin_los=None, NR500_los=5.0) fluxH = cluster.get_gamma_flux(Emin=150*u.GeV, Emax=None, Energy_density=False, Rmax=cluster.R500, type_integral='cylindrical').to_value('s-1 cm-2') # Inverse Compton E, dNIC_dEdSdt = cluster.get_ic_spectrum(energy, Rmin=None, Rmax=cluster.R500, type_integral='cylindrical', Rmin_los=None, NR500_los=5.0) r, dNIC_dSdtdO = cluster.get_ic_profile(radius, Emin=150*u.GeV, Emax=50*u.TeV, Energy_density=False, Rmin_los=None, NR500_los=5.0) fluxIC = cluster.get_ic_flux(Emin=150*u.GeV, Emax=None, Energy_density=False, Rmax=cluster.R500, type_integral='cylindrical').to_value('s-1 cm-2') #---------- Monte Carlo sampling: hadronic prof_g_mc = [] spec_g_mc = [] flux_g_mc = [] for imc in range(Nmc): if model_case == 'Hadronic': cluster = perseus_model_library.set_pure_hadronic_model(cluster, ('density', param_MC[imc,1]), param_MC[imc,0]*1e-2, param_MC[imc,2]) if model_case == 'Leptonic': cluster = perseus_model_library.set_pure_leptonic_model(cluster, ('density', param_MC[imc,1]), param_MC[imc,0]*1e-5, param_MC[imc,2]) if app_steady: cluster.cre1_loss_model = 'Steady' spec_g_mci = cluster.get_gamma_spectrum(energy, Rmin=None, Rmax=cluster.R500, type_integral='cylindrical', Rmin_los=None, NR500_los=5.0)[1] prof_g_mci = cluster.get_gamma_profile(radius, Emin=150*u.GeV, Emax=50*u.TeV, Energy_density=False, Rmin_los=None, NR500_los=5.0)[1] flux_g_mci = cluster.get_gamma_flux(Emin=150*u.GeV, Emax=None, Energy_density=False, Rmax=cluster.R500, type_integral='cylindrical').to_value('s-1 cm-2') prof_g_mc.append(prof_g_mci) spec_g_mc.append(spec_g_mci) flux_g_mc.append(flux_g_mci) #---------- Limits: hadronic dN_dEdSdt_u = np.percentile(np.array(spec_g_mc), 100-(100-conf)/2.0, axis=0)*spec_g_mc[0].unit dN_dEdSdt_d = np.percentile(np.array(spec_g_mc), (100-conf)/2.0, axis=0)*spec_g_mc[0].unit dN_dSdtdO_u = np.percentile(np.array(prof_g_mc), 100-(100-conf)/2.0, axis=0)*prof_g_mc[0].unit dN_dSdtdO_d = np.percentile(np.array(prof_g_mc), (100-conf)/2.0, axis=0)*prof_g_mc[0].unit fluxH_u = np.percentile(np.array(flux_g_mc), 100-(100-conf)/2.0) fluxH_d = np.percentile(np.array(flux_g_mc), (100-conf)/2.0) #---------- Monte Carlo sampling: IC prof_ic_mc = [] spec_ic_mc = [] flux_ic_mc = [] for imc in range(Nmc): if model_case == 'Hadronic': cluster = perseus_model_library.set_pure_hadronic_model(cluster, ('density', param_MC[imc,1]), param_MC[imc,0]*1e-2, param_MC[imc,2]) if model_case == 'Leptonic': cluster = perseus_model_library.set_pure_leptonic_model(cluster, ('density', param_MC[imc,1]), param_MC[imc,0]*1e-5, param_MC[imc,2]) if app_steady: cluster.cre1_loss_model = 'Steady' spec_ic_mci = cluster.get_ic_spectrum(energy, Rmin=None, Rmax=cluster.R500, type_integral='cylindrical', Rmin_los=None, NR500_los=5.0)[1] prof_ic_mci = cluster.get_ic_profile(radius, Emin=150*u.GeV, Emax=50*u.TeV, Energy_density=False, Rmin_los=None, NR500_los=5.0)[1] flux_ic_mci = cluster.get_ic_flux(Emin=150*u.GeV, Emax=None, Energy_density=False, Rmax=cluster.R500, type_integral='cylindrical').to_value('s-1 cm-2') prof_ic_mc.append(prof_ic_mci) spec_ic_mc.append(spec_ic_mci) flux_ic_mc.append(flux_ic_mci) #---------- Limits: IC dNIC_dEdSdt_u = np.percentile(np.array(spec_ic_mc), 100-(100-conf)/2.0, axis=0)*spec_ic_mc[0].unit dNIC_dEdSdt_d = np.percentile(np.array(spec_ic_mc), (100-conf)/2.0, axis=0)*spec_ic_mc[0].unit dNIC_dSdtdO_u = np.percentile(np.array(prof_ic_mc), 100-(100-conf)/2.0, axis=0)*prof_ic_mc[0].unit dNIC_dSdtdO_d = np.percentile(np.array(prof_ic_mc), (100-conf)/2.0, axis=0)*prof_ic_mc[0].unit fluxIC_u = np.percentile(np.array(flux_ic_mc), 100-(100-conf)/2.0) fluxIC_d = np.percentile(np.array(flux_ic_mc), (100-conf)/2.0) #========== Figure #----- Spectrum fig = plt.figure(0, figsize=(8, 6)) # MC for imc in range(Nmc): if imc == 0: plt.plot(E.to_value('GeV'), (E**2*spec_g_mc[imc]).to_value('MeV cm-2 s-1'), color='blue', alpha=0.05, label='Monte Carlo') else: plt.plot(E.to_value('GeV'), (E**2*spec_g_mc[imc]).to_value('MeV cm-2 s-1'), color='blue', alpha=0.05) for imc in range(Nmc): plt.plot(E.to_value('GeV'), (E**2*spec_ic_mc[imc]).to_value('MeV cm-2 s-1'), color='magenta', alpha=0.05) # Limits plt.plot(E.to_value('GeV'), (E**2*dN_dEdSdt_u).to_value('MeV cm-2 s-1'), color='blue', linewidth=2, linestyle='--', label=str(conf)+'% C.L.') plt.plot(E.to_value('GeV'), (E**2*dN_dEdSdt_d).to_value('MeV cm-2 s-1'), color='blue', linewidth=2, linestyle='--') plt.fill_between(E.to_value('GeV'), (E**2*dN_dEdSdt_u).to_value('MeV cm-2 s-1'), (E**2*dN_dEdSdt_d).to_value('MeV cm-2 s-1'), color='blue', alpha=0.2) plt.plot(E.to_value('GeV'), (E**2*dNIC_dEdSdt_u).to_value('MeV cm-2 s-1'), color='magenta', linewidth=2, linestyle='--') plt.plot(E.to_value('GeV'), (E**2*dNIC_dEdSdt_d).to_value('MeV cm-2 s-1'), color='magenta', linewidth=2, linestyle='--') plt.fill_between(E.to_value('GeV'), (E**2*dNIC_dEdSdt_u).to_value('MeV cm-2 s-1'), (E**2*dNIC_dEdSdt_d).to_value('MeV cm-2 s-1'), color='magenta', alpha=0.2) # Best fit plt.plot(E.to_value('GeV'), (E**2*dN_dEdSdt).to_value('MeV cm-2 s-1'), color='blue', linewidth=3, label='Best-fit model (Hadronic)') plt.plot(E.to_value('GeV'), (E**2*dNIC_dEdSdt).to_value('MeV cm-2 s-1'), color='magenta', linewidth=3, linestyle='-',label='Best-fit model (IC)') plt.fill_between([30, 100e3], [0,0], [1e6,1e6], color='green', alpha=0.1, label='CTA energy range') plt.xscale('log') plt.yscale('log') plt.xlabel('Energy (GeV)') plt.ylabel(r'$\frac{E^2 dN}{dEdSdt}$ (MeV cm$^{-2}$ s$^{-1}$)') plt.xlim(1e-2, 2e5) plt.ylim(1e-10, 5e-6) plt.legend(fontsize=14) plt.savefig(cluster.output_dir+'/'+model_case+'_Gamma_spectrum.pdf') plt.close() #----- Profile fig = plt.figure(0, figsize=(8, 6)) # MC for imc in range(Nmc): if imc == 0: plt.plot(r.to_value('kpc'), (prof_g_mc[imc]).to_value('cm-2 s-1 deg-2'), color='blue', alpha=0.05, label='Monte Carlo') else: plt.plot(r.to_value('kpc'), (prof_g_mc[imc]).to_value('cm-2 s-1 deg-2'), color='blue', alpha=0.05) for imc in range(Nmc): plt.plot(r.to_value('kpc'), (prof_ic_mc[imc]).to_value('cm-2 s-1 deg-2'), color='magenta', alpha=0.05) # Limits plt.plot(r.to_value('kpc'), (dN_dSdtdO_u).to_value('cm-2 s-1 deg-2'), color='blue', linewidth=2, linestyle='--', label=str(conf)+'% C.L.') plt.plot(r.to_value('kpc'), (dN_dSdtdO_d).to_value('cm-2 s-1 deg-2'), color='blue', linewidth=2, linestyle='--') plt.fill_between(r.to_value('kpc'), (dN_dSdtdO_u).to_value('cm-2 s-1 deg-2'), (dN_dSdtdO_d).to_value('cm-2 s-1 deg-2'), color='blue', alpha=0.2) plt.plot(r.to_value('kpc'), (dNIC_dSdtdO_u).to_value('cm-2 s-1 deg-2'), color='magenta', linewidth=2, linestyle='--') plt.plot(r.to_value('kpc'), (dNIC_dSdtdO_d).to_value('cm-2 s-1 deg-2'), color='magenta', linewidth=2, linestyle='--') plt.fill_between(r.to_value('kpc'), (dNIC_dSdtdO_u).to_value('cm-2 s-1 deg-2'), (dNIC_dSdtdO_d).to_value('cm-2 s-1 deg-2'), color='magenta', alpha=0.2) # Best-fit plt.plot(r.to_value('kpc'), (dN_dSdtdO).to_value('cm-2 s-1 deg-2'), color='blue', linewidth=3, label='Best-fit model (Hadronic)') plt.plot(r.to_value('kpc'), (dNIC_dSdtdO).to_value('cm-2 s-1 deg-2'), color='magenta', linewidth=3, linestyle='-', label='Best-fit model (IC)') plt.vlines((0.05*u.deg*cluster.cosmo.kpc_proper_per_arcmin(cluster.redshift)).to_value('kpc'), 0,1, linestyle=':', color='k', label='CTA PSF (1 TeV)') plt.vlines(cluster.R500.to_value('kpc'), 0,1, linestyle='--', color='k', label='$R_{500}$') plt.xscale('log') plt.yscale('log') plt.xlabel('Radius (kpc)') plt.ylabel(r'$\frac{dN}{dSdtd\Omega}$ (cm$^{-2}$ s$^{-1}$ deg$^{-2}$)') plt.xlim(10,5e3) plt.ylim(1e-16,1e-9) plt.legend(fontsize=14) plt.savefig(cluster.output_dir+'/'+model_case+'_Gamma_profile.pdf') plt.close() #----- Flux file = open(cluster.output_dir+'/'+model_case+'_Gamma_flux.txt','w') file.write('Energy E_gamma > 150 GeV \n') file.write('Hadronic - Best '+str(fluxH)+' cm-2 s-1 \n') file.write(' Upper '+str(fluxH_u)+' cm-2 s-1 \n') file.write(' Lower '+str(fluxH_d)+' cm-2 s-1 \n') file.write('Inverse Compton - Best '+str(fluxIC)+' cm-2 s-1 \n') file.write(' Upper '+str(fluxIC_u)+' cm-2 s-1 \n') file.write(' Lower '+str(fluxIC_d)+' cm-2 s-1 \n') file.close() plotting.seaborn_1d(np.array(flux_g_mc)*1e12, output_fig=cluster.output_dir+'/'+model_case+'_Gamma_flux_H.pdf', ci=0.68, truth=None, best=fluxH*1e12, label='$F_{\gamma,\ hadronic}$ ($10^{-12}$ s$^{-1}$ cm$^{-2}$)', gridsize=100, alpha=(0.2, 0.4), figsize=(10,10), fontsize=12, cols=[('blue','grey', 'orange')]) plt.close("all") plotting.seaborn_1d(np.array(flux_ic_mc)*1e12, output_fig=cluster.output_dir+'/'+model_case+'_Gamma_flux_IC.pdf', ci=0.68, truth=None, best=fluxIC*1e12, label='$F_{\gamma,\ IC}$ ($10^{-12}$ s$^{-1}$ cm$^{-2}$)', gridsize=100, alpha=(0.2, 0.4), figsize=(10,10), fontsize=12, cols=[('blue','grey', 'orange')]) plt.close("all") print(' --> Gamma plots done')
print(' Number of steps: ', mcmc_nsteps) print(' Fitting for spectral index?: ', fit_index) print(' Applying SS loss (leptonic)?: ', app_steady) print('----------------------------------------') print('') #========== Make directory if not os.path.exists(output_dir): os.mkdir(output_dir) print('-----> Working in '+output_dir) #========== Define the cluster model if model_case == 'Hadronic': cluster = perseus_model_library.default_model(directory=output_dir) cluster = perseus_model_library.set_magnetic_field_model(cluster, case=mag_case) cluster = perseus_model_library.set_pure_hadronic_model(cluster, ('density', 1.0), 1e-2, 2.5) cluster.Npt_per_decade_integ = 10 elif model_case == 'Leptonic': cluster = perseus_model_library.default_model(directory=output_dir) cluster = perseus_model_library.set_magnetic_field_model(cluster, case=mag_case) cluster = perseus_model_library.set_pure_leptonic_model(cluster, ('density', 1.0), 1e-5, 2.0) if app_steady: cluster.cre1_loss_model = 'Steady' cluster.Npt_per_decade_integ = 30 else: raise ValueError('Only Hadronic or Leptonic are possible') #========== Data print('') print('-----> Getting the radio data') radio_data = perseus_data_library.get_radio_data(cluster.cosmo, cluster.redshift, prof_file=basedata)