Line data Source code
1 : /** Unit tests for Output modules of CRPropa
2 : Output
3 : TextOutput
4 : ParticleCollector
5 : */
6 :
7 : #include "CRPropa.h"
8 :
9 : #include "gtest/gtest.h"
10 : #include <iostream>
11 : #include <string>
12 :
13 :
14 : #ifdef CRPROPA_HAVE_HDF5
15 : #include <hdf5.h>
16 : #endif
17 :
18 : // compare two arrays (intead of using Google Mock)
19 : // https://stackoverflow.com/a/10062016/6819103
20 : template <typename T, size_t size>
21 1 : ::testing::AssertionResult ArraysMatch(const T (&expected)[size],
22 : const T (&actual)[size]) {
23 11 : for (size_t i(0); i < size; ++i) {
24 10 : if (expected[i] != actual[i]) {
25 : return ::testing::AssertionFailure()
26 0 : << "array[" << i << "] (" << actual[i] << ") != expected["
27 0 : << i << "] (" << expected[i] << ")";
28 : }
29 : }
30 :
31 1 : return ::testing::AssertionSuccess();
32 : }
33 :
34 : namespace crpropa {
35 :
36 : //-- Output
37 1 : TEST(Output, size) {
38 1 : Candidate c;
39 1 : Output output;
40 6 : for (int it = 0; it < 5; ++it, output.process(&c));
41 :
42 1 : EXPECT_EQ(output.size(), 5);
43 1 : }
44 :
45 : //-- TextOutput
46 1 : TEST(TextOutput, printHeader_Trajectory1D) {
47 1 : Candidate c;
48 1 : TextOutput output(Output::Trajectory1D);
49 :
50 1 : ::testing::internal::CaptureStdout();
51 1 : output.process(&c);
52 1 : std::string captured = testing::internal::GetCapturedStdout();
53 :
54 2 : EXPECT_EQ(captured.substr(0, captured.find("\n")), "#\tID\tE\tX");
55 1 : }
56 :
57 1 : TEST(TextOutput, printHeader_Event1D) {
58 1 : Candidate c;
59 1 : TextOutput output(Output::Event1D);
60 :
61 1 : ::testing::internal::CaptureStdout();
62 1 : output.process(&c);
63 1 : std::string captured = testing::internal::GetCapturedStdout();
64 :
65 2 : EXPECT_EQ(captured.substr(0, captured.find("\n")), "#\tD\tID\tE\tID0\tE0");
66 1 : }
67 :
68 1 : TEST(TextOutput, printHeader_Trajectory3D) {
69 1 : Candidate c;
70 1 : TextOutput output(Output::Trajectory3D);
71 :
72 1 : ::testing::internal::CaptureStdout();
73 1 : output.process(&c);
74 1 : std::string captured = testing::internal::GetCapturedStdout();
75 :
76 2 : EXPECT_EQ(captured.substr(0, captured.find("\n")),
77 : "#\tD\tID\tE\tX\tY\tZ\tPx\tPy\tPz");
78 1 : }
79 :
80 1 : TEST(TextOutput, printHeader_Event3D) {
81 1 : Candidate c;
82 1 : TextOutput output(Output::Event3D);
83 :
84 1 : ::testing::internal::CaptureStdout();
85 1 : output.process(&c);
86 1 : std::string captured = testing::internal::GetCapturedStdout();
87 :
88 2 : EXPECT_EQ(
89 : captured.substr(0, captured.find("\n")),
90 : "#\tD\tID\tE\tX\tY\tZ\tPx\tPy\tPz\tID0\tE0\tX0\tY0\tZ0\tP0x\tP0y\tP0z");
91 1 : }
92 :
93 1 : TEST(TextOutput, printHeader_Custom) {
94 1 : Candidate c;
95 1 : TextOutput output(Output::Event1D);
96 :
97 1 : output.enable(Output::SerialNumberColumn);
98 1 : output.disable(Output::TrajectoryLengthColumn);
99 1 : output.set(Output::RedshiftColumn, false);
100 1 : output.enable(Output::CandidateTagColumn);
101 :
102 1 : ::testing::internal::CaptureStdout();
103 1 : output.process(&c);
104 1 : std::string captured = testing::internal::GetCapturedStdout();
105 :
106 2 : EXPECT_EQ(captured.substr(0, captured.find("\n")),
107 : "#\tSN\tID\tE\tSN0\tID0\tE0\tSN1\ttag");
108 1 : }
109 :
110 1 : TEST(TextOutput, printProperty) {
111 1 : Candidate c;
112 1 : TextOutput output(Output::Event1D);
113 1 : output.disableAll();
114 2 : output.enableProperty("foo", 2.0, "Bar");
115 :
116 1 : ::testing::internal::CaptureStdout();
117 1 : output.process(&c);
118 1 : std::string captured = testing::internal::GetCapturedStdout();
119 :
120 : // name in first line of header
121 2 : EXPECT_EQ(captured.substr(0, captured.find("\n")), "#\tfoo");
122 1 : }
123 :
124 1 : TEST(TextOutput, printHeader_Version) {
125 1 : Candidate c;
126 1 : TextOutput output(Output::Event1D);
127 :
128 1 : ::testing::internal::CaptureStdout();
129 1 : output.process(&c);
130 1 : std::string captured = testing::internal::GetCapturedStdout();
131 :
132 : // length of the prefix is 19 chars
133 1 : size_t version_pos = captured.find("# CRPropa version: ") + 19;
134 :
135 2 : EXPECT_EQ(captured.substr(version_pos,
136 : captured.find("\n", version_pos) - version_pos),
137 : g_GIT_DESC);
138 1 : }
139 :
140 : #ifndef CRPROPA_TESTS_SKIP_EXCEPTIONS
141 1 : TEST(TextOutput, failOnIllegalOutputFile) {
142 2 : EXPECT_THROW(
143 : TextOutput output("THIS_FOLDER_MUST_NOT_EXISTS_12345+/FILE.txt"),
144 : std::runtime_error);
145 1 : }
146 : #endif
147 :
148 : #ifdef CRPROPA_HAVE_HDF5
149 : #ifndef CRPROPA_TESTS_SKIP_EXCEPTIONS
150 1 : TEST(HDF5Output, failOnIllegalOutputFile) {
151 1 : HDF5Output out;
152 : // disable default error output of HDF5
153 1 : H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
154 2 : EXPECT_THROW(out.open("THIS_FOLDER_MUST_NOT_EXISTS_12345+/FILE.h5"),
155 : std::runtime_error);
156 1 : }
157 : #endif
158 : #endif
159 :
160 : //-- ParticleCollector
161 2 : TEST(ParticleCollector, size) {
162 2 : ref_ptr<Candidate> c = new Candidate();
163 1 : ParticleCollector output;
164 :
165 6 : for (int it = 0; it < 5; ++it, output.process(c))
166 : ;
167 :
168 1 : EXPECT_EQ(output.size(), 5);
169 2 : }
170 :
171 1 : TEST(ParticleCollector, fetchItem) {
172 2 : ref_ptr<Candidate> c = new Candidate(nucleusId(1, 1), 1 * EeV);
173 1 : ParticleCollector output;
174 :
175 1 : output.process(c);
176 :
177 2 : EXPECT_EQ(output[0], c);
178 2 : }
179 :
180 1 : TEST(ParticleCollector, reprocess) {
181 2 : ref_ptr<Candidate> c = new Candidate(nucleusId(1, 1), 1 * EeV);
182 1 : ParticleCollector collector;
183 1 : ParticleCollector output;
184 :
185 1 : collector.process(c);
186 1 : collector.reprocess(&output);
187 :
188 2 : EXPECT_EQ(output[0], c);
189 2 : }
190 :
191 1 : TEST(ParticleCollector, dumpload) {
192 2 : ref_ptr<Candidate> c = new Candidate(nucleusId(1, 1), 1.234 * EeV);
193 1 : c->current.setPosition(Vector3d(1, 2, 3));
194 1 : c->current.setDirection(Vector3d(-1, -1, -1));
195 1 : c->setTrajectoryLength(1 * Mpc);
196 1 : c->setRedshift(2);
197 :
198 1 : ParticleCollector input;
199 1 : ParticleCollector output;
200 :
201 12 : for (int i = 0; i <= 10; ++i) {
202 22 : input.process(c);
203 : }
204 :
205 : // Well, it would be nicer if we don't need to receate any file
206 1 : input.dump("ParticleCollector_DumpTest.txt");
207 1 : output.load("ParticleCollector_DumpTest.txt");
208 :
209 1 : EXPECT_EQ(input.size(), output.size());
210 2 : EXPECT_EQ(output[0]->current.getEnergy(), c->current.getEnergy());
211 2 : EXPECT_EQ(output[1]->getTrajectoryLength(), c->getTrajectoryLength());
212 2 : EXPECT_EQ(output[2]->current.getId(), c->current.getId());
213 2 : EXPECT_EQ(output[3]->getRedshift(), c->getRedshift());
214 2 : }
215 :
216 : // Just test if the trajectory is on a line for rectilinear propagation
217 1 : TEST(ParticleCollector, getTrajectory) {
218 : int pos_x[10];
219 1 : int pos_x_expected[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
220 :
221 1 : ParticleState p;
222 1 : p.setPosition(Vector3d(10, 0, 0));
223 1 : p.setDirection(Vector3d(-1, 0, 0));
224 1 : ref_ptr<Candidate> c = new Candidate(p);
225 :
226 1 : ref_ptr<ParticleCollector> output = new ParticleCollector();
227 1 : ref_ptr<ParticleCollector> trajectory = new ParticleCollector();
228 1 : trajectory->setClone(true);
229 :
230 1 : ref_ptr<ModuleList> sim = new ModuleList();
231 1 : sim->add(new SimplePropagation(1, 1));
232 :
233 1 : ref_ptr<Observer> obs = new Observer();
234 1 : obs->add(new Observer1D());
235 1 : obs->onDetection(output);
236 1 : sim->add(obs);
237 :
238 2 : sim->run(c);
239 :
240 2 : output->getTrajectory(sim, 0, trajectory);
241 :
242 : Vector3d pos;
243 : int i = 0;
244 :
245 1 : for (ParticleCollector::iterator itr = trajectory->begin();
246 11 : itr != trajectory->end(); ++itr) {
247 10 : pos = (*(itr->get())).current.getPosition();
248 10 : pos_x[i] = pos.getX();
249 10 : ++i;
250 : }
251 :
252 1 : EXPECT_TRUE(ArraysMatch(pos_x_expected, pos_x));
253 1 : }
254 :
255 1 : TEST(ParticleCollector, runModuleList) {
256 1 : ModuleList modules;
257 2 : modules.add(new SimplePropagation());
258 1 : modules.add(new MaximumTrajectoryLength(1 * Mpc));
259 :
260 1 : ParticleState p;
261 1 : p.setPosition(Vector3d(10, 0, 0));
262 1 : p.setDirection(Vector3d(-1, 0, 0));
263 1 : ref_ptr<Candidate> c = new Candidate(p);
264 :
265 1 : ref_ptr<ParticleCollector> collector = new ParticleCollector();
266 :
267 1 : collector->process(c);
268 :
269 1 : modules.setShowProgress(false);
270 1 : auto candidates = collector->getContainer();
271 1 : modules.run(&candidates);
272 2 : }
273 :
274 0 : int main(int argc, char **argv) {
275 0 : ::testing::InitGoogleTest(&argc, argv);
276 0 : return RUN_ALL_TESTS();
277 : }
278 :
279 : } // namespace crpropa
|