LCOV - code coverage report
Current view: top level - test - testSource.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 279 283 98.6 %
Date: 2024-04-29 14:43:01 Functions: 23 24 95.8 %

          Line data    Source code
       1             : #include "crpropa/Source.h"
       2             : #include "crpropa/Units.h"
       3             : #include "crpropa/ParticleID.h"
       4             : 
       5             : #include "gtest/gtest.h"
       6             : #include <stdexcept>
       7             : 
       8             : namespace crpropa {
       9             : 
      10           2 : TEST(SourcePosition, simpleTest) {
      11             :         Vector3d position(1, 2, 3);
      12           1 :         SourcePosition source(position);
      13           1 :         ParticleState ps;
      14           1 :         source.prepareParticle(ps);
      15           2 :         EXPECT_EQ(position, ps.getPosition());
      16           1 : }
      17             : 
      18           1 : TEST(SourceMultiplePositions, simpleTest) {
      19           1 :         SourceMultiplePositions source;
      20           1 :         source.add(Vector3d(1, 0, 0), 0.25);
      21           1 :         source.add(Vector3d(2, 0, 0), 0.75);
      22           1 :         ParticleState ps;
      23             :         int n1 = 0;
      24             :         int n2 = 0;
      25       10001 :         for (int i = 0; i < 10000; i++) {
      26       10000 :                 source.prepareParticle(ps);
      27       10000 :                 if (ps.getPosition().x == 1)
      28        2536 :                         n1++;
      29        7464 :                 else if (ps.getPosition().x == 2)
      30        7464 :                         n2++;
      31             :         }
      32           1 :         EXPECT_NEAR(n1, 2500, 5 * sqrt(2500));
      33           1 :         EXPECT_NEAR(n2, 7500, 5 * sqrt(7500));
      34           1 : }
      35             : 
      36           2 : TEST(SourceUniformSphere, simpleTest) {
      37             :         Vector3d center(0, 0, 0);
      38           1 :         double radius = 110;
      39           1 :         SourceUniformSphere source(center, radius);
      40           1 :         ParticleState ps;
      41           1 :         source.prepareParticle(ps);
      42           1 :         double distance = ps.getPosition().getDistanceTo(center);
      43           1 :         EXPECT_GE(radius, distance);
      44           1 : }
      45             : 
      46           2 : TEST(SourceUniformHollowSphere, simpleTest) {
      47             :         Vector3d center(0, 0, 0);
      48           1 :         double radius_inner = 50;
      49           1 :         double radius_outer = 110;
      50             :         SourceUniformHollowSphere source(center,
      51             :                         radius_inner,
      52           1 :                         radius_outer);
      53         101 :         for (int i=0; i < 100; ++i) {
      54         100 :                 ParticleState ps;
      55         100 :                 source.prepareParticle(ps);
      56         100 :                 double distance = ps.getPosition().getDistanceTo(center);
      57         100 :                 EXPECT_GE(radius_outer, distance);
      58         100 :                 EXPECT_LE(radius_inner, distance);
      59             :         }
      60           1 : }
      61             : 
      62           2 : TEST(SourceUniformBox, simpleTest) {
      63             :         Vector3d origin(-7, -2, 0);
      64             :         Vector3d size(13, 55, 192);
      65           1 :         SourceUniformBox box(origin, size);
      66           1 :         ParticleState p;
      67           1 :         box.prepareParticle(p);
      68           1 :         Vector3d pos = p.getPosition();
      69           1 :         EXPECT_LE(origin.x, pos.x);
      70           1 :         EXPECT_LE(origin.y, pos.y);
      71           1 :         EXPECT_LE(origin.z, pos.z);
      72           1 :         EXPECT_GE(size.x, pos.x);
      73           1 :         EXPECT_GE(size.y, pos.y);
      74           1 :         EXPECT_GE(size.z, pos.z);
      75           1 : }
      76             : 
      77           2 : TEST(SourceUniformCylinder, simpleTest) {
      78             :         Vector3d center(0, 0, 0);
      79             :         double radius = 15;
      80             :         double height = 2;
      81           1 :         SourceUniformCylinder cylinder(center, height, radius);
      82           1 :         ParticleState ps;
      83           1 :         cylinder.prepareParticle(ps);
      84           1 :         Vector3d pos = ps.getPosition();
      85           1 :         double R2 = pos.x*pos.x+pos.y*pos.y;
      86           1 :         double H = pow(pos.z*pos.z, 0.5);
      87           1 :         EXPECT_GE(radius*radius, R2);
      88           1 :         EXPECT_GE(height/2., H);
      89           1 : }
      90             : 
      91           1 : TEST(SourceSNRDistribution, simpleTest) {
      92             :         double R_earth = 8.5*kpc;
      93             :         double alpha = 2.0;
      94             :         double beta = 3.53;
      95             :         double Z_G = 0.3*kpc;
      96           1 :         SourceSNRDistribution snr(R_earth,alpha, beta, Z_G);
      97           1 :         ParticleState ps;
      98           1 :         snr.prepareParticle(ps);
      99           1 :         Vector3d pos = ps.getPosition();
     100           1 :         double R2 = pos.x*pos.x+pos.y*pos.y;
     101           1 :         EXPECT_GE(20*kpc*20*kpc, R2); // radius must be smaller than 20 kpc
     102             :         
     103             :         double R2_mean = 0.;
     104             :         double Z_mean = 0.;
     105      100001 :         for (size_t i=0; i<100000; i++) {
     106      100000 :                 snr.prepareParticle(ps);
     107      100000 :                 Vector3d pos = ps.getPosition();
     108      100000 :                 R2_mean += pow(pos.x/kpc, 2.)+pow(pos.y/kpc, 2.);
     109      100000 :                 Z_mean += pos.z/kpc;
     110             :         }
     111           1 :         R2_mean/=100000.;
     112           1 :         Z_mean/=100000.;
     113           1 :         EXPECT_NEAR(100.306, R2_mean, 1);
     114           1 :         EXPECT_NEAR(0., Z_mean, 0.1);
     115           1 : }
     116             : 
     117           2 : TEST(SourceDensityGrid, withInRange) {
     118             :         // Create a grid with 10^3 cells ranging from (0, 0, 0) to (10, 10, 10)
     119             :         Vector3d origin(0, 0, 0);
     120             :         int cells = 10;
     121             :         double spacing = 1;
     122           1 :         auto grid = new Grid1f(origin, cells, spacing);
     123          11 :         for (int ix = 0; ix < cells; ix++)
     124         110 :                 for (int iy = 0; iy < cells; iy++)
     125        1100 :                         for (int iz = 0; iz < cells; iz++)
     126        1000 :                                 grid->get(ix, iy, iz) = ix * iy * iz;
     127             : 
     128           2 :         SourceDensityGrid source(grid);
     129           1 :         ParticleState p;
     130             : 
     131           1 :         source.prepareParticle(p);
     132           1 :         Vector3d pos = p.getPosition();
     133             : 
     134             :         // dialed positions should be within the volume (0, 0, 0) - (10, 10, 10)
     135           1 :         EXPECT_LE(0, pos.x);
     136           1 :         EXPECT_GE(10, pos.x);
     137           1 :         EXPECT_LE(0, pos.y);
     138           1 :         EXPECT_GE(10, pos.y);
     139           1 :         EXPECT_LE(0, pos.z);
     140           1 :         EXPECT_GE(10, pos.z);
     141           1 : }
     142             : 
     143           2 : TEST(SourceDensityGrid, OneAllowedCell) {
     144             :         // Create a grid with 2^3 cells ranging from (0, 0, 0) to (4, 4, 4)
     145             :         Vector3d origin(0, 0, 0);
     146             :         int cells = 2;
     147             :         double spacing = 2;
     148           1 :         auto grid = new Grid1f(origin, cells, spacing);
     149             :         
     150             :         // set all but one cells to 0
     151           3 :         for (int ix = 0; ix < cells; ix++)
     152           6 :                 for (int iy = 0; iy < cells; iy++)
     153          12 :                         for (int iz = 0; iz < cells; iz++)
     154           8 :                                 grid->get(ix, iy, iz) = 0;
     155             : 
     156             :         // set the first cell ((0, 0, 0) to (2, 2, 2))
     157           1 :         grid->get(0, 0, 0) = 1;
     158             : 
     159           2 :         SourceDensityGrid source(grid);
     160           1 :         ParticleState p;
     161             : 
     162           1 :         int nFalse = 0;
     163             :         Vector3d mean(0, 0, 0);
     164       10001 :         for (int i = 0; i < 10000; i++) {
     165       10000 :                 source.prepareParticle(p);
     166       10000 :                 Vector3d pos = p.getPosition();
     167             :                 mean += pos;
     168       10000 :                 if ((pos.x < 0) or (pos.x > 2) or (pos.y < 0) or (pos.y > 2)
     169       10000 :                                 or (pos.z < 0) or (pos.z > 2))
     170           0 :                         nFalse++;
     171             :         }
     172             : 
     173             :         // only the first bin should get dialed
     174           1 :         EXPECT_EQ(0, nFalse);
     175             : 
     176             :         // mean should be close to (1, 1, 1) if random positions are uniform in (0, 0, 0) - (2, 2, 2)
     177             :         mean /= 10000;
     178           1 :         EXPECT_NEAR(1, mean.x, 0.2);
     179           1 :         EXPECT_NEAR(1, mean.y, 0.2);
     180           1 :         EXPECT_NEAR(1, mean.z, 0.2);
     181           1 : }
     182             : 
     183           2 : TEST(SourceDensityGrid1D, withInRange) {
     184             :         // Create a grid with 10 cells ranging from 0 to 10
     185             :         Vector3d origin(0, 0, 0);
     186             :         int nCells = 10;
     187             :         double spacing = 1.;
     188           1 :         auto grid = new Grid1f(origin, nCells, 1, 1, spacing);
     189             : 
     190             :         // set some values
     191          11 :         for (int i = 0; i < 10; i++) {
     192          10 :                 grid->get(i, 0, 0) = 2;
     193             :         }
     194             : 
     195           2 :         SourceDensityGrid1D source(grid);
     196           1 :         ParticleState p;
     197             : 
     198           1 :         source.prepareParticle(p);
     199           1 :         Vector3d pos = p.getPosition();
     200             :         // dialed position should be within the range 0 - 10
     201           1 :         EXPECT_LE(0, pos.x);
     202           1 :         EXPECT_GE(10, pos.x);
     203           1 : }
     204             : 
     205           2 : TEST(SourceDensityGrid1D, OneAllowedCell) {
     206             :         // Test if the only allowed cells is repeatedly selected
     207             :         Vector3d origin(0, 0, 0);
     208             :         int nCells = 10;
     209             :         double spacing = 1.;
     210           1 :         auto grid = new Grid1f(origin, nCells, 1, 1, spacing);
     211             : 
     212             :         // set some values
     213          11 :         for (int i = 0; i < 10; i++) {
     214          10 :                 grid->get(i, 0, 0) = 0;
     215             :         }
     216           1 :         grid->get(5, 0, 0) = 1;
     217             : 
     218           2 :         SourceDensityGrid1D source(grid);
     219           1 :         ParticleState p;
     220             : 
     221         101 :         for (int i = 0; i < 100; i++) {
     222         100 :                 source.prepareParticle(p);
     223             :                 // dialed position should be in range 5-6
     224         100 :                 Vector3d pos = p.getPosition();
     225         100 :                 EXPECT_LE(5, pos.x);
     226         100 :                 EXPECT_GE(6, pos.x);
     227             :         }
     228           1 : }
     229             : 
     230           1 : TEST(SourcePowerLawSpectrum, simpleTest) {
     231           1 :         double Emin = 4 * EeV;
     232           1 :         double Emax = 200 * EeV;
     233             :         double index = -2.7;
     234           1 :         SourcePowerLawSpectrum spectrum(Emin, Emax, index);
     235           1 :         ParticleState ps;
     236           1 :         spectrum.prepareParticle(ps);
     237             : 
     238             :         // energy should be within Emin - Emax
     239           1 :         EXPECT_LE(Emin, ps.getEnergy());
     240           1 :         EXPECT_GE(Emax, ps.getEnergy());
     241           1 : }
     242             : 
     243           1 : TEST(SourceComposition, simpleTest) {
     244           1 :         double Emin = 10;
     245             :         double Rmax = 100;
     246             :         double index = -1;
     247           1 :         SourceComposition source(Emin, Rmax, index);
     248           1 :         source.add(nucleusId(6, 3), 1);
     249           1 :         ParticleState p;
     250           1 :         source.prepareParticle(p);
     251           1 :         EXPECT_EQ(nucleusId(6, 3), p.getId());
     252           1 :         EXPECT_LE(Emin, p.getEnergy());
     253           1 :         EXPECT_GE(6 * Rmax, p.getEnergy());
     254           1 : }
     255             : 
     256           2 : TEST(SourceDirectedEmission, simpleTest) {
     257             :         Vector3d mu(1., 0., 0.);
     258             :         double kappa = 1000.;
     259           1 :         SourceDirectedEmission source(mu, kappa);
     260           1 :         Candidate c;
     261             :         Vector3d meanDir(0., 0., 0.);
     262        1001 :         for (size_t i = 0; i < 1000; i++) {
     263        1000 :                 source.prepareCandidate(c);
     264        1000 :                 meanDir += c.source.getDirection();
     265        1000 :                 double w = c.getWeight();
     266        1000 :                 EXPECT_GE(w, 0.);
     267             :         }
     268             :         meanDir /= 1000.;
     269           1 :         EXPECT_NEAR(meanDir.x, 1., 0.1);
     270           1 :         EXPECT_NEAR(meanDir.y, 0., 0.01);
     271           1 :         EXPECT_NEAR(meanDir.z, 0., 0.01);
     272           2 : }
     273             : 
     274           2 : TEST(SourceEmissionCone, simpleTest) {
     275             :         Vector3d direction(42., 0., 0.);
     276           1 :         double aperture = 1/42.;
     277             :         
     278           1 :         SourceEmissionCone source(direction, aperture);
     279             :         
     280           1 :         ParticleState p;
     281           1 :         source.prepareParticle(p);
     282           1 :         double angle = direction.getAngleTo(p.getDirection());
     283           1 :         EXPECT_LE(angle, aperture);
     284           1 : }
     285             : 
     286             : #ifdef CRPROPA_HAVE_MUPARSER
     287           1 : TEST(SourceGenericComposition, simpleTest) {
     288             :         double Emin = 10;
     289             :         double Emax = 100;
     290           1 :         SourceGenericComposition source(Emin, Emax, "E^-2");
     291           1 :         int id1 = nucleusId(6, 3);
     292           1 :         int id2 = nucleusId(12, 6);
     293           1 :         source.add(id1, 1);
     294           1 :         source.add(id2, 10);
     295           1 :         ParticleState p;
     296             :         size_t id1Count = 0, id2Count = 0;
     297             :         size_t ElowCount = 0, EhighCount = 0;
     298           1 :         size_t n = 100000;
     299      100001 :         for (size_t i = 0; i < n; i++) {
     300      100000 :                 source.prepareParticle(p);
     301      100000 :                 if (p.getId() == id1)
     302        8937 :                         id1Count++;
     303      100000 :                 if (p.getId() == id2)
     304       91063 :                         id2Count++;
     305      100000 :                 double e = p.getEnergy();
     306      100000 :                 if ( (e >= Emin) && (e < 20))
     307       55771 :                         ElowCount++;
     308      100000 :                 if ( (e >= 20) && (e <= Emax))
     309       44229 :                         EhighCount++;
     310             : 
     311             :         }
     312           1 :         EXPECT_EQ(n, id1Count + id2Count);
     313           1 :         EXPECT_EQ(n, ElowCount + EhighCount);
     314           1 :         EXPECT_NEAR((float)id1Count/(float)id2Count, 0.1, 0.01);
     315           1 :         EXPECT_NEAR((float)ElowCount/(float)EhighCount, 1.25, 0.1);
     316           1 : }
     317             : #endif
     318             : 
     319           1 : TEST(SourceComposition, throwNoIsotope) {
     320           1 :         SourceComposition source(1, 10, -1);
     321           1 :         ParticleState ps;
     322           1 :         EXPECT_THROW(source.prepareParticle(ps), std::runtime_error);
     323           1 : }
     324             : 
     325           1 : TEST(SourceRedshiftEvolution, testInRange) {
     326           1 :         Candidate c;
     327             : 
     328           1 :         double zmin = 0.5;
     329           1 :         double zmax = 2.5;
     330             : 
     331             :         // general case: m
     332           1 :         SourceRedshiftEvolution source1(3.2, zmin, zmax);
     333         101 :         for (int i = 0; i < 100; i++) {
     334         100 :                 source1.prepareCandidate(c);
     335         100 :                 EXPECT_LE(zmin, c.getRedshift());
     336         100 :                 EXPECT_GE(zmax, c.getRedshift());
     337             :         }
     338             : 
     339             :         // general case: m = -1
     340           1 :         SourceRedshiftEvolution source2(-1, zmin, zmax);
     341         101 :         for (int i = 0; i < 100; i++) {
     342         100 :                 source2.prepareCandidate(c);
     343         100 :                 EXPECT_LE(zmin, c.getRedshift());
     344         100 :                 EXPECT_GE(zmax, c.getRedshift());
     345             :         }
     346           1 : }
     347             : 
     348           2 : TEST(Source, allPropertiesUsed) {
     349             :         Source source;
     350           1 :         source.add(new SourcePosition(Vector3d(10, 0, 0) * Mpc));
     351           2 :         source.add(new SourceIsotropicEmission());
     352           1 :         source.add(new SourcePowerLawSpectrum(5 * EeV, 100 * EeV, -2));
     353           1 :         source.add(new SourceParticleType(nucleusId(8, 4)));
     354           1 :         source.add(new SourceRedshift(2));
     355             : 
     356           1 :         Candidate c = *source.getCandidate();
     357             : 
     358           1 :         EXPECT_EQ(2, c.getRedshift());
     359             : 
     360           1 :         ParticleState p;
     361             : 
     362             :         p = c.source;
     363           1 :         EXPECT_EQ(nucleusId(8, 4), p.getId());
     364           1 :         EXPECT_LE(5 * EeV, p.getEnergy());
     365           1 :         EXPECT_GE(100 * EeV, p.getEnergy());
     366           2 :         EXPECT_EQ(Vector3d(10, 0, 0) * Mpc, p.getPosition());
     367             : 
     368             :         p = c.created;
     369           1 :         EXPECT_EQ(nucleusId(8, 4), p.getId());
     370           1 :         EXPECT_LE(5 * EeV, p.getEnergy());
     371           1 :         EXPECT_GE(100 * EeV, p.getEnergy());
     372           2 :         EXPECT_EQ(Vector3d(10, 0, 0) * Mpc, p.getPosition());
     373             : 
     374             :         p = c.previous;
     375           1 :         EXPECT_EQ(nucleusId(8, 4), p.getId());
     376           1 :         EXPECT_LE(5 * EeV, p.getEnergy());
     377           1 :         EXPECT_GE(100 * EeV, p.getEnergy());
     378           2 :         EXPECT_EQ(Vector3d(10, 0, 0) * Mpc, p.getPosition());
     379             : 
     380             :         p = c.current;
     381           1 :         EXPECT_EQ(nucleusId(8, 4), p.getId());
     382           1 :         EXPECT_LE(5 * EeV, p.getEnergy());
     383           1 :         EXPECT_GE(100 * EeV, p.getEnergy());
     384           2 :         EXPECT_EQ(Vector3d(10, 0, 0) * Mpc, p.getPosition());
     385           2 : }
     386             : 
     387           2 : TEST(SourceList, simpleTest) {
     388             :         // test if source list works with one source
     389             :         SourceList sourceList;
     390           1 :         ref_ptr<Source> source = new Source;
     391           1 :         source->add(new SourcePosition(Vector3d(10, 0, 0)));
     392           1 :         sourceList.add(source);
     393             : 
     394           1 :         ref_ptr<Candidate> c = sourceList.getCandidate();
     395             : 
     396           2 :         EXPECT_EQ(Vector3d(10, 0, 0), c->created.getPosition());
     397           2 :         EXPECT_EQ(Vector3d(10, 0, 0), c->previous.getPosition());
     398           2 :         EXPECT_EQ(Vector3d(10, 0, 0), c->current.getPosition());
     399           1 : }
     400             : 
     401           2 : TEST(SourceList, noSource) {
     402             :         // test if an error is thrown when source list empty
     403             :         SourceList sourceList;
     404           1 :         EXPECT_THROW(sourceList.getCandidate(), std::runtime_error);
     405           1 : }
     406             : 
     407           2 : TEST(SourceList, luminosity) {
     408             :         // test if the sources are dialed according to their luminosities
     409             :         SourceList sourceList;
     410             : 
     411           1 :         ref_ptr<Source> source1 = new Source;
     412           1 :         source1->add(new SourceEnergy(100));
     413           1 :         sourceList.add(source1, 80);
     414             : 
     415           1 :         ref_ptr<Source> source2 = new Source;
     416           1 :         source2->add(new SourceEnergy(0));
     417           1 :         sourceList.add(source2, 20);
     418             : 
     419             :         double meanE = 0;
     420        1001 :         for (int i = 0; i < 1000; i++) {
     421        1000 :                 ref_ptr<Candidate> c = sourceList.getCandidate();
     422        1000 :                 meanE += c->created.getEnergy();
     423             :         }
     424           1 :         meanE /= 1000;
     425           1 :         EXPECT_NEAR(80, meanE, 4); // this test can stochastically fail
     426           1 : }
     427             : 
     428           1 : TEST(SourceTag, sourceTag) {
     429           1 :         SourceTag tag("mySourceTag");
     430           1 :         Candidate c;
     431           1 :         tag.prepareCandidate(c);
     432           2 :         EXPECT_TRUE(c.getTagOrigin() == "mySourceTag");
     433           1 : }
     434             : 
     435           0 : int main(int argc, char **argv) {
     436           0 :         ::testing::InitGoogleTest(&argc, argv);
     437           0 :         return RUN_ALL_TESTS();
     438             : }
     439             : 
     440             : } // namespace crpropa

Generated by: LCOV version 1.14