def test_03_energy(self): n = 1000 log10e_min = 19. log10e = auger.rand_energy_from_auger(n, log10e_min) self.assertTrue(log10e.size == n) self.assertTrue((log10e >= log10e_min).all() & (log10e <= 20.5).all()) self.assertTrue(len(log10e[log10e > log10e_min + 0.1]) < n)
def test_08_convert_spectrum(self): log10e = np.linspace(17.5, 20.4, 10000) spectrum15 = auger.spectrum(log10e, normalize2bin=10, year=15) spectrum17 = auger.spectrum(log10e, normalize2bin=10, year=17) self.assertTrue( np.allclose(spectrum15, spectrum17, rtol=1e-16, atol=1e-17)) n = 10000 bins = np.linspace(17.5, 20.5, 31) e_15 = np.histogram(auger.rand_energy_from_auger(n, log10e_min=17.5, log10e_max=None, ebin=0.1, year=15), bins=bins) e_17 = np.histogram(auger.rand_energy_from_auger(n, log10e_min=17.5, log10e_max=None, ebin=0.1, year=17), bins=bins) self.assertTrue(np.allclose(e_15[0], e_17[0], rtol=1.3, atol=100))
def test_07_lna_xmax_moments(self): n = 100000 log10e = auger.rand_energy_from_auger(n, log10e_min=17.8) masses = 2 * auger.rand_charge_from_auger(log10e) l_ec, mln_a, vln_a = auger.ln_a_moments(log10e, masses) # check if uhecrs get heavier self.assertTrue((mln_a[0] < mln_a[-1]) & (vln_a[0] > vln_a[-1])) m_xmax, v_xmax = auger.ln_a_moments2xmax_moments(l_ec, mln_a, vln_a) std_xmax = np.sqrt(auger.var_xmax(l_ec, 0.8 * np.exp(mln_a))) self.assertTrue((std_xmax < 100).all()) mln_a2, vln_a2 = auger.xmax_moments2ln_a_moments(l_ec, m_xmax, v_xmax) self.assertTrue(np.allclose(mln_a, mln_a2)) self.assertTrue(np.allclose(vln_a, vln_a2))
def setup_roi(nside=256, ncrs=2000, roi_size=0.25, energy_spectrum='uniform', energy_ordering=False, emin=19): npix = hpt.nside2npix(nside) roipix = 0 angles_pix_to_roi = hpt.angle(nside, roipix, np.arange(npix)) iso_map = np.zeros(npix) iso_map[angles_pix_to_roi < roi_size] = 1 p = np.cumsum(iso_map) pix = np.sort(p.searchsorted(np.random.rand(ncrs) * p[-1])) if energy_spectrum == 'auger': energies = auger.rand_energy_from_auger(ncrs, emin) elif energy_spectrum == 'uniform': energies = np.random.uniform(10, 20, ncrs) if energy_ordering: energies = np.sort(energies)[::-1] return pix, energies
capsize=0, label='Data 2017') yl = r'$E^{3} \, J(E)$ [km$^{-2}$ yr$^{-1}$ sr$^{-1}$ eV$^{2}$]' plt.ylabel(yl, fontsize=16) plt.xlabel(r'$\log_{10}$($E$/eV)', fontsize=16) # Analytic parametrization of AUGER energy spectrum log10e = np.arange(17.5, 20.5, 0.02) dN = auger.spectrum_analytic(log10e, year=19) E3_dN = 10**(3 * log10e) * dN # multiply with E^3 for better visability plt.plot(log10e, E3_dN, color='red', label='Parametrization 2017') plt.savefig('energy_spectrum.png') plt.clf() # We sample energies which follow the above parametrized energy spectrum n, emin = 1e7, 18.5 # n: number of drawn samples; emin: 10 EeV; lower energy cut log10e_sample = auger.rand_energy_from_auger(n=int(n), log10e_min=emin) log10e_bins = np.arange(18.5, 20.55, 0.05) n, bins = np.histogram(log10e_sample, bins=log10e_bins) E3_dN_sampled = 10**( (3 - 1) * (log10e_bins[:-1])) * n # -1 for correcting logarithmic bin width plt.plot(log10e[50:], E3_dN[50:], color='red') plt.plot(log10e_bins[:-1], E3_dN_sampled * E3_dN[50] / E3_dN_sampled[0], marker='s', color='k', ls='None') plt.yscale('log') plt.xlabel('log10(E[eV])', fontsize=16) plt.ylabel('E$^3$ dN', fontsize=16)
import numpy as np import matplotlib.pyplot as plt from astrotools import auger, coord, skymap print("Test: module coord.py") # Creates an isotropic arrival map and convert galactic longitudes (lons) and # galactic latitudes (lats) into cartesian vectors ncrs = 3000 # number of cosmic rays log10e_min = 18.5 # minimum energy in log10(E / eV) lons = coord.rand_phi(ncrs) # isotropic in phi (~Uniform(-pi, pi)) lats = coord.rand_theta(ncrs) # isotropic in theta (Uniform in cos(theta)) vecs = coord.ang2vec(lons, lats) log10e = auger.rand_energy_from_auger(n=ncrs, log10e_min=log10e_min) # Plot an example map with sampled energies. If you specify the opath keyword in # the skymap function, the plot will be automatically saved and closed skymap.scatter(vecs, c=log10e, opath='isotropic_sky.png') # Creates an arrival map with a source located at v_src=(1, 0, 0) and apply a # fisher distribution around it with gaussian spread sigma=10 degree v_src = np.array([1, 0, 0]) kappa = 1. / np.radians(10.)**2 vecs = coord.rand_fisher_vec(v_src, kappa=kappa, n=ncrs) # if you dont specify the opath you can use (fig, ax) to plot more stuff fig, ax = skymap.scatter(vecs, c=log10e) plt.scatter(0, 0, s=100, c='red', marker='*') # plot source in the center plt.savefig('fisher_single_source_10deg.png', bbox_inches='tight') plt.close() # We can also use the coord.rand_fisher_vec() function to apply an angular uncertainty
ncrs = 3000 # number of cosmic rays log10e_min = 18.5 # minimum energy in log10(E / eV) nside = 64 # resolution of the HEALPix map (default: 64) npix = hpt.nside2npix(nside) # Create a dipole distribution for a healpy map lon, lat = np.radians(45), np.radians(60) # Position of the maximum of the dipole (healpy and astrotools definition) vec_max = hpt.ang2vec(lat, lon) # Convert this to a vector amplitude = 0.5 # amplitude of dipole dipole = hpt.dipole_pdf(nside, amplitude, vec_max, pdf=False) skymap.heatmap(dipole, opath='dipole.png') # Draw random events from this distribution pixel = hpt.rand_pix_from_map(dipole, n=ncrs) # returns 3000 random pixel from this map vecs = hpt.rand_vec_in_pix(nside, pixel) # Random vectors within the drawn pixel skymap.scatter(vecs, c=auger.rand_energy_from_auger(ncrs, log10e_min), opath='dipole_events.png') # Create a healpy map that follows the exposure of an observatory at latitude # a0 = -35.25 (Pierre Auger Observatory) and maximum zenith angle of 60 degree exposure = hpt.exposure_pdf(nside, a0=-35.25, zmax=60) skymap.heatmap(exposure, opath='exposure.png') # Note, if you want to sample from the exposure healpy map random vectors you # have to be careful with the above method hpt.rand_vec_in_pix, # as the exposure healpy map reads out the exposure value in the pixel centers, # whereas hpt.rand_vec_in_pix might sample some directions where # the exposure already dropped to zero. If you want to sample only isoptropic # arrival directions it is instead recommended to use # coord.rand_exposure_vec(), or if you can not avoid healpy # pixelization use <code> hpt.rand_exposure_vec_in_pix </code>.
# If you just have a single cosmic ray set you want to use the ComicRaysBase. You can # set arbitrary content in the container. Objects with shape (self.crs) will be # stored in an internal array called 'shape_array', all other data in a # dictionary called 'general_object_store'. nside = 64 npix = hpt.nside2npix(nside) ncrs = 5000 exposure = hpt.exposure_pdf(nside) lon, lat = hpt.pix2ang(nside, hpt.rand_pix_from_map(exposure, n=ncrs)) crs = cosmic_rays.CosmicRaysBase(ncrs) # Initialize cosmic ray container # you can set arbitrary content in the container. Objects with different shape # than (ncrs) will be stored in an internal dictionary called 'general_object_store' crs['lon'], crs['lat'] = lon, lat crs['date'] = 'today' crs['log10e'] = auger.rand_energy_from_auger(log10e_min=19, n=ncrs) crs.set('vecs', coord.ang2vec(lon, lat)) # another possibility to set content crs.keys() # will print the keys that are existing # Save, load and plot cosmic ray base container opath = 'cr_base_container.npz' crs.save(opath) crs_load = cosmic_rays.CosmicRaysBase(opath) crs_load.plot_heatmap(opath='cr_base_healpy.png') crs_load.plot_eventmap(opath='cr_base_eventmap.png') # You can also quickly write all data in an usual ASCII file: crs.save_readable('cr_base.txt') # For a big simulation with a lot of sets (simulated skys), you should use the
######################################## # Module: auger.py ######################################## print("Test: module auger.py") # Analytic parametrization of AUGER energy spectrum log10e = np.arange(18., 20.5, 0.02) dN = auger.spectrum_analytic(log10e) E = 10**(log10e - 18) E3_dN = E**3 * dN # multiply with E^3 for better visability # We sample energies which follow the above energy spectrum n, emin = 1e7, 18.5 # n: number of drawn samples; emin: 10 EeV; lower energy cut norm = 4.85e16 * n # norm to account for solid angle area log10e_sample = auger.rand_energy_from_auger(n=int(n), log10e_min=emin) log10e_bins = np.arange(18.5, 20.55, 0.05) n, bins = np.histogram(log10e_sample, bins=log10e_bins) E3_dN_sampled = 10**( (3 - 1) * (log10e_bins[:-1] - 18)) * n # -1 for correcting logarithmic bin width plt.plot(log10e, norm * E3_dN, color='red') plt.plot(log10e_bins[:-1], E3_dN_sampled, marker='s', color='k', ls='None') plt.yscale('log') plt.xlabel('log10(E[eV])', fontsize=16) plt.ylabel('E$^3$ dN', fontsize=16) plt.savefig('energy_spectrum.png') plt.clf() ########################################