def test_AdvectivePropagation(self): ConstMagVec = crpropa.Vector3d(0.) BField = crpropa.UniformMagneticField(ConstMagVec) ConstAdvVec = crpropa.Vector3d(0., 1e6, 0.) AdvField = crpropa.UniformAdvectionField(ConstAdvVec) precision = 1e-4 minStep = 1*pc maxStep = 10*kpc epsilon = 0. Dif = crpropa.DiffusionSDE(BField, AdvField, precision, minStep, maxStep, epsilon) c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(10*TeV) c.current.setDirection(crpropa.Vector3d(1,0,0)) # check for position Dif.process(c) pos = c.current.getPosition() self.assertEqual(pos.x, 0.) self.assertAlmostEqual(pos.y, minStep/c_light*1e6) self.assertEqual(pos.z, 0.) # Step size is increased to maxStep self.assertAlmostEqual(c.getNextStep()/minStep, 5.) #AlmostEqual due to rounding error
def compute_field(self, seed): # Extracts grid information assert self.grid.grid_type == 'cartesian', 'Only cartesian grids are supported' box = self.grid.box boxOrigin = crp.Vector3d(box[0][0].si.value, box[1][0].si.value, box[2][0].si.value) boxEnd = crp.Vector3d(box[0][1].si.value, box[1][1].si.value, box[2][1].si.value) gridPoints = crp.Vector3d(*self.grid.resolution.astype(float)) gridSpacing = (boxEnd - boxOrigin) / gridPoints # Creates CRPropa-compatible grid object boxSize = [int(i) for i in self.grid.resolution] self._crp_grid = crp.Grid3f(boxOrigin, *boxSize, gridSpacing) # CRPropa uses units in SI internally # and SWIG does not like numpy types Brms = float(self.parameters['Brms'].si.value) minScale = float(self.parameters['min_scale'].si.value) maxScale = float(self.parameters['max_scale'].si.value) alpha = float(self.parameters['alpha']) seed = int(seed) helicity_factor = float(self.parameters['helicity_factor']) # Initializes the field generator print(self._crp_grid, Brms, minScale / crp.kpc, maxScale / crp.Mpc, alpha, seed, helicity_factor, sep='\n') crp.initHelicalTurbulence(self._crp_grid, Brms, minScale, maxScale, alpha, seed, helicity_factor) crp_field = crp.MagneticFieldGrid(self._crp_grid) # Evaluates on the grid def mapper(quantities): positions = [float(q.si.value) for q in quantities] vec = crp_field.getField(crp.Vector3d(*positions)) return vec[0], vec[1], vec[2] field = np.array( list( map( mapper, zip(self.grid.x.ravel(), self.grid.y.ravel(), self.grid.z.ravel())))) return field.reshape(self.data_shape) << u.T
def testPublicReferenceAccess(self): v = crp.Vector3d(1., 2., 3.) self.assertEqual(v.x, 1.) self.assertEqual(v.y, 2.) self.assertEqual(v.z, 3.) v.x = 23. self.assertEqual(v.x, 23.)
def testGridTurbulence(self): N = 64 boxSize = 1 * crp.Mpc l_bo = boxSize / 8 spacing = boxSize / N tf = crp.GridTurbulence( crp.TurbulenceSpectrum(1.0, 2 * spacing, boxSize, l_bo), crp.GridProperties(crp.Vector3d(0), N, spacing))
def initial_directions(M, source_l, source_b, weights, d, NN, energies=None): lons0 = [] lats0 = [] for isource in range(len(source_l)): l = source_l[isource] * np.pi / 180.0 - (2.0 * np.pi) b = Lat2CoLat(source_b[isource] * np.pi / 180.0) #M.addParticles(Id, E, l, b, E0**-1) print(isource, weights[isource], l, b) meanDir = crpropa.Vector3d(-1, 0, 0) meanDir.setRThetaPhi(-1, b, l) kappa = 50.0 ncrs = int((weights[isource] / total) * NN) #if ncrs>0: ncrs = 500 #Emin = 10.0 energies = powerlaw.Power_Law(xmin=10.0, xmax=100.0, parameters=[2.2]).generate_random(ncrs) #print (energies) for i in xrange(ncrs): particleId = crpropa.nucleusId(1, 1) energy = (energies[i]) * crpropa.EeV energy = 10.0 * crpropa.EeV galCenter = crpropa.Vector3d(-1, 0, 0) theta_k = 0.8 * (100.0 * crpropa.EeV / energy) * np.sqrt( d[isource] / 10.0) kappa = (81.0 / theta_k)**2 #print (kappa) momentumVector = crpropa.Random.instance().randFisherVector( meanDir, kappa) M.addParticle(particleId, energy, momentumVector) lons0.append(momentumVector.getPhi()) lats0.append(momentumVector.getTheta()) lons0 = np.array(lons0) - np.pi lats0 = -CoLat2Lat(np.array(lats0)) return (lons0, lats0)
def testCustomAdvectionField(self): class CustomAdvectionField(crp.AdvectionField): def __init__(self, val): crp.AdvectionField.__init__(self) self.val = val def getField(self, position): return crp.Vector3d(self.val) def getDivergence(self, position): return 0.0 constMagVec = crp.Vector3d(0 * crp.nG, 0 * crp.nG, 1 * crp.nG) magField = crp.UniformMagneticField(constMagVec) advField = CustomAdvectionField(1) propSDE = crp.DiffusionSDE(magField, advField) pos = crp.Vector3d(1, 0, 0) advFieldAtPos = advField.getField(pos) self.assertEqual(advFieldAtPos, propSDE.getAdvectionFieldAtPosition(pos))
def testAddParticleVectorInterface(self): try: import numpy as np except: print("Cannot import numpy. Not testing AddParticleVectorInterface!") return self.maps.addParticle(12, 1 * EeV, crpropa.Vector3d(1, 0, 0)) self.assertEquals(len(self.maps.getParticleIds()), 1) self.assertEquals(self.maps.getParticleIds()[0], 12) self.assertEquals(len(self.maps.getEnergies(12)), 1)
def testRepr(self): v = crp.Vector3d(1., 2., 3.) if sys.version_info >= (3, 3): import unittest.mock import io with unittest.mock.patch('sys.stdout', new=io.StringIO()) as fake_out: print(v) else: import StringIO fake_out = StringIO.StringIO() sys.stdout = fake_out print(v) sys.stdout = sys.__stdout__ self.assertEqual(fake_out.getvalue().rstrip(), v.getDescription())
def test_NeutralPropagation(self): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,0)) c.current.setEnergy(10*TeV) c.current.setDirection(crpropa.Vector3d(1,0,0)) # check for position self.Dif.process(c) pos = c.current.getPosition() self.assertAlmostEqual(pos.x/pc, 1.) #AlmostEqual due to rounding error self.assertEqual(pos.y, 0.) self.assertEqual(pos.z, 0.) # Step size is increased to maxStep self.assertAlmostEqual(c.getNextStep()/self.maxStep, 1.) #AlmostEqual due to rounding error
def testCustomMassDensity(self): class CustomMassDensity(crp.Density): def __init__(self, density, HIDensity, HIIDensity, H2Density, nucleonDensity): crp.Density.__init__(self) self.density = density self.HIDensity = HIDensity self.HIIDensity = HIIDensity self.H2Density = H2Density self.nucleonDensity = nucleonDensity def getDensity(self, position): return self.density def getHIDensity(self, position): return self.HIDensity def getHIIDensity(self, position): return self.HIIDensity def getH2Density(self, position): return self.H2Density def NucleonDensity(self, position): return self.nucleonDensity density = 10 HIDensity = 5 HIIDensity = 2 H2Density = 1 nucleonDensity = 0.5 massDensity = CustomMassDensity(density, HIDensity, HIIDensity, H2Density, nucleonDensity) pos = crp.Vector3d(1, 0, 0) self.assertEqual(density, massDensity.getDensity(pos)) self.assertEqual(HIDensity, massDensity.getHIDensity(pos)) self.assertEqual(HIIDensity, massDensity.getHIIDensity(pos)) self.assertEqual(H2Density, massDensity.getH2Density(pos))
def testCustomMagneticField(self): class CustomMagneticField(crp.MagneticField): def __init__(self, val): crp.MagneticField.__init__(self) self.val = val def getField(self, position): return crp.Vector3d(self.val) def getField(self, position, z): return crp.Vector3d(self.val) field = CustomMagneticField(crp.gauss) propBP = crp.PropagationBP(field, 1e-4, 1 * crp.Mpc, 1 * crp.Mpc) propCK = crp.PropagationCK(field, 1e-4, 1 * crp.Mpc, 1 * crp.Mpc) propSDE = crp.DiffusionSDE(field) pos = crp.Vector3d(-1, 0, 0) z = 0 fieldAtPos = field.getField(pos, z) self.assertEqual(fieldAtPos, propBP.getFieldAtPosition(pos, z)) self.assertEqual(fieldAtPos, propCK.getFieldAtPosition(pos, z)) self.assertEqual(fieldAtPos, propSDE.getMagneticFieldAtPosition(pos, z))
def getField(self, position, z): return crp.Vector3d(self.val)
def testArrayInterface(self): if numpy_available: v = crp.Vector3d(1., 2., 3.) self.assertEqual(2., np.mean(v)) x = np.ones(3) self.assertEqual(6., sum(v * x))
def test_FullTransport(self): x, y, z = [], [], [] E = 10 * TeV D = self.DifAdv.getScale()*6.1e24*(E/(4*GeV))**self.DifAdv.getAlpha() L_max = 50 * kpc epsilon = 0.1 advSpeed = 1e6 std_exp_x = np.sqrt(2*epsilon*D*L_max/c_light) std_exp_y = np.sqrt(2*epsilon*D*L_max/c_light) std_exp_z = np.sqrt(2*D*L_max/c_light) mean_exp_x = advSpeed * L_max / c_light mean_exp_y = 0. mean_exp_z = 0. N = 10**4 maxTra = crpropa.MaximumTrajectoryLength(L_max) ConstMagVec = crpropa.Vector3d(0*nG,0*nG,1*nG) BField = crpropa.UniformMagneticField(ConstMagVec) ConstAdvVec = crpropa.Vector3d(advSpeed, 0., 0.) AdvField = crpropa.UniformAdvectionField(ConstAdvVec) precision = 1e-4 minStep = 1*pc maxStep = 10*kpc DifAdv = crpropa.DiffusionSDE(BField, AdvField, precision, minStep, maxStep, epsilon) for i in range(N): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(E) while c.getTrajectoryLength() < L_max: maxTra.process(c) DifAdv.process(c) x.append(c.current.getPosition().x) y.append(c.current.getPosition().y) z.append(c.current.getPosition().z) # test for normality A2 = Anderson(x)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) A2 = Anderson(y)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) A2 = Anderson(z)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) meanX, meanY, meanZ = np.mean(x), np.mean(y), np.mean(z) stdX, stdY, stdZ = np.std(x), np.std(y), np.std(z) # diffusion in parallel direction # compare the mean and std of the z-positions with expected values # z_mean = 0. (no advection) # z_ std = (2*D_parallel*t)^0.5 # Take 4 sigma errors due to limited number of candidates into account stdOfMeans_x = std_exp_x/np.sqrt(N) stdOfStds_x = std_exp_x/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanX-mean_exp_x)/4./stdOfMeans_x), 1., msg=self.msg1) self.assertLess(abs((stdX-std_exp_x)/4./stdOfStds_x), 1., msg=self.msg1) stdOfMeans_y = std_exp_y/np.sqrt(N) stdOfStds_y = std_exp_y/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanY-mean_exp_y)/4./stdOfMeans_y), 1., msg=self.msg1) self.assertLess(abs((stdY-std_exp_y)/4./stdOfStds_y), 1., msg=self.msg1) stdOfMeans_z = std_exp_z/np.sqrt(N) stdOfStds_z = std_exp_z/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanZ-mean_exp_z)/4./stdOfMeans_z), 1., msg=self.msg1) self.assertLess(abs((stdZ-std_exp_z)/4./stdOfStds_z), 1., msg=self.msg1)
E = crdata[:, 3] * crpropa.EeV E0 = crdata[:, 4] * crpropa.EeV px = crdata[:, 11] py = crdata[:, 12] pz = crdata[:, 13] galactic_longitude = np.arctan2(-1. * py, -1. * px) galactic_latitude = np.pi / 2 - np.arccos(-pz / (px * px + py * py + pz * pz)) M.addParticles(id, E, galactic_longitude, galactic_latitude, E0**-1) # Alternatively, data can be added manually. # This provides freedom to adapt to customized weights used in the simulation for i in xrange(1000): particleId = crpropa.nucleusId(1, 1) energy = 10 * crpropa.EeV galCenter = crpropa.Vector3d(-1, 0, 0) momentumVector = crpropa.Random.instance().randFisherVector(galCenter, 200) M.addParticle(particleId, energy, momentumVector) # ## Plot Maps # # The probability maps for the individual particles can be accessed directly and plotted with healpy. # # In[2]: get_ipython().magic('matplotlib inline') import healpy from pylab import *
draw_map_lines() plt.savefig("fig/earth_data.eps", bbox_inches="tight") plt.clf() # crpropa backtracking # set up GMF B = crp.JF12Field() B.randomStriated(seed) B.randomTurbulent(seed) # set up simulation sim = crp.ModuleList() sim.add(crp.PropagationCK(B, 1e-3, 0.1 * crp.parsec, 100 * crp.parsec)) obs = crp.Observer() obs.add(crp.ObserverLargeSphere(crp.Vector3d(0), gal_size * crp.kpc)) sim.add(obs) position = crp.Vector3d(-8.5, 0, 0) * crp.kpc # start at the earth pid = crp.nucleusId(1, 1) # proton pid *= -1 # antiparticle, for backtracking if read_in_galaxy_map: galaxy_map = np.genfromtxt("maps/galaxy_map.txt") else: galaxy_map = np.zeros(hp.nside2npix(nside)) for i in xrange(len(events)): if i % 10 == 0: print i, len(events) event = events[i] if event["is_Auger"]:
def testGridPropertiesConstructor(self): N = 32 gp = crp.GridProperties(crp.Vector3d(0), N, 0.1) grid = crp.Grid1f(gp) self.assertEqual(grid.getNx(), 32)
import healpy as hp a1, b1 = (12.6 - 18.25) / 2.75, (19.5 - 18.25) / 2.75 a2, b2 = (0. - 0.2) / 0.12, (1 - 0.2) / 0.12 a3, b3 = (0 - 10.97) / 3.80, (25. - 10.97) / 3.8 a4, b4 = (0 - 2.84) / 1.3, (8 - 2.84) / 1.3 E = float(sys.argv[1]) lon = float(sys.argv[2]) lat = float(sys.argv[3]) s1 = int(sys.argv[4]) s2 = int(sys.argv[5]) s3 = int(sys.argv[6]) pid = -crp.nucleusId(1, 1) sun = crp.Vector3d(-8.5, 0, 0) * crp.kpc E = E * crp.EeV nhat = hp.dir2vec(lon, lat, lonlat=True) direc = crp.Vector3d() direc.setXYZ(nhat[0], nhat[1], nhat[2]) ps = crp.ParticleState(pid, E, sun, direc) cr = crp.Candidate(ps) sim = crp.ModuleList() sim.add(crp.Redshift()) sim.add(crp.PhotoPionProduction(crp.CMB)) sim.add(crp.PhotoPionProduction(crp.IRB)) sim.add(crp.PhotoDisintegration(crp.CMB)) sim.add(crp.PhotoDisintegration(crp.IRB)) sim.add(crp.NuclearDecay())
def mapper(quantities): positions = [float(q.si.value) for q in quantities] vec = crp_field.getField(crp.Vector3d(*positions)) return vec[0], vec[1], vec[2]
def testOutOfBound(self): v = crp.Vector3d(1., 2., 3.) self.assertRaises(IndexError, v.__getitem__, 3) self.assertRaises(IndexError, v.__setitem__, 3, 10)
candidate.limitNextStep(abs(currentDistance)) if np.sign(currentDistance) == np.sign(previousDistance): return crpropa.NOTHING else: return crpropa.DETECTED # As test, we propagate some particels in a random field with a sheet observer: # In[2]: from crpropa import Mpc, nG, EeV import numpy as np vgrid = crpropa.VectorGrid(crpropa.Vector3d(0), 128, 1 * Mpc) crpropa.initTurbulence(vgrid, 1 * nG, 2 * Mpc, 5 * Mpc, -11. / 3.) BField = crpropa.MagneticFieldGrid(vgrid) m = crpropa.ModuleList() m.add(crpropa.PropagationCK(BField, 1e-4, 0.1 * Mpc, 5 * Mpc)) m.add(crpropa.MaximumTrajectoryLength(25 * Mpc)) # Observer out = crpropa.TextOutput("sheet.txt") o = crpropa.Observer() # The Observer feature has to be created outside of the class attribute # o.add(ObserverPlane(...)) will not work for custom python modules plo = ObserverPlane( np.asarray([0., 0, 0]) * Mpc, np.asarray([0., 1., 0.]) * Mpc,
# In[1]: import crpropa import numpy as np n = 10000000 # simulation setup sim = crpropa.ModuleList() # we just need propagation in straight lines here to demonstrate the effect sim.add(crpropa.SimplePropagation()) # collect arriving cosmic rays at observer 19 kpc outside of the Galactic center # to exaggerate effects obs = crpropa.Observer() pos_earth = crpropa.Vector3d(-19, 0, 0) * crpropa.kpc # observer with radius 500 pc to collect fast reasonable statistics obs.add(crpropa.ObserverSurface(crpropa.Sphere(pos_earth, 0.5 * crpropa.kpc))) # Use crpropa's particle collector to only collect the cosmic rays at Earth output = crpropa.ParticleCollector() obs.onDetection(output) sim.add(obs) # discard outwards going cosmic rays, that missed Earth and leave the Galaxy obs_trash = crpropa.Observer() obs_trash.add( crpropa.ObserverSurface( crpropa.Sphere(crpropa.Vector3d(0), 21 * crpropa.kpc))) sim.add(obs_trash) # ## Lambert's distribution
class DiffusionOneDirection(unittest.TestCase): ConstMagVec = crpropa.Vector3d(0*nG,0*nG,1*nG) BField = crpropa.UniformMagneticField(ConstMagVec) precision = 1e-4 minStep = 1*pc maxStep = 10*kpc epsilon = 0. Dif = crpropa.DiffusionSDE(BField, precision, minStep, maxStep, epsilon) DifAdv = crpropa.DiffusionSDE(BField, precision, minStep, maxStep, epsilon) def test_Simple(self): self.assertEqual(self.Dif.getTolerance(), self.precision) self.assertEqual(self.Dif.getMinimumStep(), self.minStep) self.assertEqual(self.Dif.getMaximumStep(), self.maxStep) self.assertEqual(self.Dif.getEpsilon(), self.epsilon) self.assertEqual(self.Dif.getAlpha(), 1./3.) # default Kolmogorov diffusion self.assertEqual(self.Dif.getScale(), 1.) # default D(4GeV) = 6.1e28 cm^2/s def test_NeutralPropagation(self): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,0)) c.current.setEnergy(10*TeV) c.current.setDirection(crpropa.Vector3d(1,0,0)) # check for position self.Dif.process(c) pos = c.current.getPosition() self.assertAlmostEqual(pos.x/pc, 1.) #AlmostEqual due to rounding error self.assertEqual(pos.y, 0.) self.assertEqual(pos.z, 0.) # Step size is increased to maxStep self.assertAlmostEqual(c.getNextStep()/self.maxStep, 1.) #AlmostEqual due to rounding error def test_NoBFieldPropagation(self): ConstMagVec = crpropa.Vector3d(0.) BField = crpropa.UniformMagneticField(ConstMagVec) precision = 1e-4 minStep = 1*pc maxStep = 10*kpc epsilon = 0. Dif = crpropa.DiffusionSDE(BField, precision, minStep, maxStep, epsilon) c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(10*TeV) c.current.setDirection(crpropa.Vector3d(1,0,0)) # check for position Dif.process(c) pos = c.current.getPosition() self.assertAlmostEqual(pos.x/pc, 1.) #AlmostEqual due to rounding error self.assertEqual(pos.y, 0.) self.assertEqual(pos.z, 0.) # Step size is increased to maxStep self.assertAlmostEqual(c.getNextStep()/minStep, 5.) #AlmostEqual due to rounding error def test_AdvectivePropagation(self): ConstMagVec = crpropa.Vector3d(0.) BField = crpropa.UniformMagneticField(ConstMagVec) ConstAdvVec = crpropa.Vector3d(0., 1e6, 0.) AdvField = crpropa.UniformAdvectionField(ConstAdvVec) precision = 1e-4 minStep = 1*pc maxStep = 10*kpc epsilon = 0. Dif = crpropa.DiffusionSDE(BField, AdvField, precision, minStep, maxStep, epsilon) c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(10*TeV) c.current.setDirection(crpropa.Vector3d(1,0,0)) # check for position Dif.process(c) pos = c.current.getPosition() self.assertEqual(pos.x, 0.) self.assertAlmostEqual(pos.y, minStep/c_light*1e6) self.assertEqual(pos.z, 0.) # Step size is increased to maxStep self.assertAlmostEqual(c.getNextStep()/minStep, 5.) #AlmostEqual due to rounding error msg1 = "Note that this is a statistical test. It might fail by chance with a probabilty O(0.00001)! You should rerun the test to make sure there is a bug." def test_DiffusionEnergy10TeV(self): x, y, z = [], [], [] E = 10 * TeV D = self.Dif.getScale()*6.1e24*(E/(4*GeV))**self.Dif.getAlpha() L_max = 50 * kpc std_exp = np.sqrt(2*D*L_max/c_light) mean_exp = 0. N = 10**4 maxTra = crpropa.MaximumTrajectoryLength(L_max) for i in range(N): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(E) while c.getTrajectoryLength() < L_max: maxTra.process(c) self.Dif.process(c) x.append(c.current.getPosition().x) y.append(c.current.getPosition().y) z.append(c.current.getPosition().z) A2 = Anderson(z)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) meanX, meanY, meanZ = np.mean(x), np.mean(y), np.mean(z) stdZ = np.std(z) # no diffusion in perpendicular direction self.assertAlmostEqual(meanX, 0.) self.assertAlmostEqual(meanY, 0.) # diffusion in parallel direction # compare the mean and std of the z-positions with expected values # z_mean = 0. (no advection) # z_ std = (2*D_parallel*t)^0.5 # Take 4 sigma errors due to limited number of candidates into account stdOfMeans = std_exp/np.sqrt(N) stdOfStds = std_exp/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanZ-mean_exp)/4./stdOfMeans), 1., msg=self.msg1) self.assertLess(abs((stdZ-std_exp)/4./stdOfStds), 1., msg=self.msg1) def test_DiffusionEnergy1PeV(self): x, y, z = [], [], [] E = 1 * TeV D = self.Dif.getScale()*6.1e24*(E/(4*GeV))**self.Dif.getAlpha() L_max = 50 * kpc std_exp = np.sqrt(2*D*L_max/c_light) mean_exp = 0. N = 10**4 maxTra = crpropa.MaximumTrajectoryLength(L_max) for i in range(N): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(E) while c.getTrajectoryLength() < L_max: maxTra.process(c) self.Dif.process(c) x.append(c.current.getPosition().x) y.append(c.current.getPosition().y) z.append(c.current.getPosition().z) A2 = Anderson(z)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) meanX, meanY, meanZ = np.mean(x), np.mean(y), np.mean(z) stdZ = np.std(z) # no diffusion in perpendicular direction self.assertAlmostEqual(meanX, 0.) self.assertAlmostEqual(meanY, 0.) # diffusion in parallel direction # compare the mean and std of the z-positions with expected values # z_mean = 0. (no advection) # z_ std = (2*D_parallel*t)^0.5 # Take 4 sigma errors due to limited number of candidates into account stdOfMeans = std_exp/np.sqrt(N) stdOfStds = std_exp/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanZ-mean_exp)/4./stdOfMeans), 1., msg=self.msg1) self.assertLess(abs((stdZ-std_exp)/4./stdOfStds), 1., msg=self.msg1) def test_DiffusionEnergy100PeV(self): x, y, z = [], [], [] E = 10 * PeV D = self.Dif.getScale()*6.1e24*(E/(4*GeV))**self.Dif.getAlpha() L_max = 50 * kpc std_exp = np.sqrt(2*D*L_max/c_light) mean_exp = 0. N = 10**4 maxTra = crpropa.MaximumTrajectoryLength(L_max) for i in range(N): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(E) while c.getTrajectoryLength() < L_max: maxTra.process(c) self.Dif.process(c) x.append(c.current.getPosition().x) y.append(c.current.getPosition().y) z.append(c.current.getPosition().z) A2 = Anderson(z)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) meanX, meanY, meanZ = np.mean(x), np.mean(y), np.mean(z) stdZ = np.std(z) # no diffusion in perpendicular direction self.assertAlmostEqual(meanX, 0.) self.assertAlmostEqual(meanY, 0.) # diffusion in parallel direction # compare the mean and std of the z-positions with expected values # z_mean = 0. (no advection) # z_ std = (2*D_parallel*t)^0.5 # Take 4 sigma errors due to limited number of candidates into account stdOfMeans = std_exp/np.sqrt(N) stdOfStds = std_exp/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanZ-mean_exp)/4./stdOfMeans), 1., msg=self.msg1) self.assertLess(abs((stdZ-std_exp)/4./stdOfStds), 1., msg=self.msg1) def test_FullTransport(self): x, y, z = [], [], [] E = 10 * TeV D = self.DifAdv.getScale()*6.1e24*(E/(4*GeV))**self.DifAdv.getAlpha() L_max = 50 * kpc epsilon = 0.1 advSpeed = 1e6 std_exp_x = np.sqrt(2*epsilon*D*L_max/c_light) std_exp_y = np.sqrt(2*epsilon*D*L_max/c_light) std_exp_z = np.sqrt(2*D*L_max/c_light) mean_exp_x = advSpeed * L_max / c_light mean_exp_y = 0. mean_exp_z = 0. N = 10**4 maxTra = crpropa.MaximumTrajectoryLength(L_max) ConstMagVec = crpropa.Vector3d(0*nG,0*nG,1*nG) BField = crpropa.UniformMagneticField(ConstMagVec) ConstAdvVec = crpropa.Vector3d(advSpeed, 0., 0.) AdvField = crpropa.UniformAdvectionField(ConstAdvVec) precision = 1e-4 minStep = 1*pc maxStep = 10*kpc DifAdv = crpropa.DiffusionSDE(BField, AdvField, precision, minStep, maxStep, epsilon) for i in range(N): c = crpropa.Candidate() c.current.setId(crpropa.nucleusId(1,1)) c.current.setEnergy(E) while c.getTrajectoryLength() < L_max: maxTra.process(c) DifAdv.process(c) x.append(c.current.getPosition().x) y.append(c.current.getPosition().y) z.append(c.current.getPosition().z) # test for normality A2 = Anderson(x)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) A2 = Anderson(y)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) A2 = Anderson(z)['testStatistic'] self.assertLess(A2, 2.274, msg=self.msg1) meanX, meanY, meanZ = np.mean(x), np.mean(y), np.mean(z) stdX, stdY, stdZ = np.std(x), np.std(y), np.std(z) # diffusion in parallel direction # compare the mean and std of the z-positions with expected values # z_mean = 0. (no advection) # z_ std = (2*D_parallel*t)^0.5 # Take 4 sigma errors due to limited number of candidates into account stdOfMeans_x = std_exp_x/np.sqrt(N) stdOfStds_x = std_exp_x/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanX-mean_exp_x)/4./stdOfMeans_x), 1., msg=self.msg1) self.assertLess(abs((stdX-std_exp_x)/4./stdOfStds_x), 1., msg=self.msg1) stdOfMeans_y = std_exp_y/np.sqrt(N) stdOfStds_y = std_exp_y/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanY-mean_exp_y)/4./stdOfMeans_y), 1., msg=self.msg1) self.assertLess(abs((stdY-std_exp_y)/4./stdOfStds_y), 1., msg=self.msg1) stdOfMeans_z = std_exp_z/np.sqrt(N) stdOfStds_z = std_exp_z/np.sqrt(N)/np.sqrt(2.) self.assertLess(abs((meanZ-mean_exp_z)/4./stdOfMeans_z), 1., msg=self.msg1) self.assertLess(abs((stdZ-std_exp_z)/4./stdOfStds_z), 1., msg=self.msg1)