28 #include <momemta/Configuration.h> 29 #include <momemta/ModuleFactory.h> 30 #include <momemta/Module.h> 31 #include <momemta/ParameterSet.h> 32 #include <momemta/Pool.h> 33 #include <momemta/Solution.h> 34 #include <momemta/Types.h> 47 void createMock(
const std::string& name,
const momemta::any& value) {
52 std::shared_ptr<std::vector<double>> addPhaseSpacePoints(std::shared_ptr<Pool> pool) {
53 auto ps_points = pool->put<std::vector<double>>({
"cuba",
"ps_points"});
54 auto weight = pool->put<
double>({
"cuba",
"ps_weight"});
56 double step = 1. / (N_PS_POINTS - 1);
58 ps_points->resize(N_PS_POINTS);
59 for (
size_t i = 0; i < N_PS_POINTS; i++) {
60 double point = i * step;
61 ps_points->operator[](i) = point;
69 std::shared_ptr<std::vector<LorentzVector>> addInputParticles(std::shared_ptr<Pool> pool) {
70 auto inputs = pool->put<std::vector<LorentzVector>>({
"input",
"particles"});
73 inputs->push_back( { 16.171895980835, -13.7919054031372, -3.42997527122497, 21.5293197631836 });
74 inputs->push_back( { 71.3899612426758, 96.0094833374023, -77.2513122558594, 142.492813110352 });
75 inputs->push_back( { -18.9018573760986, 10.0896110534668, -0.602926552295686, 21.4346446990967 });
76 inputs->push_back( { -55.7908325195313, -111.59294128418, -122.144721984863, 174.66259765625 });
79 inputs->push_back( { 26.2347,76.1854,32.6172,86.9273 } );
80 inputs->push_back( { -27.3647,30.2536,38.5939,56.1569 } );
81 inputs->push_back( { -7.0817,-63.9966,-34.8497,73.2135 } );
82 inputs->push_back( { 80.756,3.12662,33.0355,87.3078 } );
87 TEST_CASE(
"Modules",
"[modules]") {
88 std::shared_ptr<Pool> pool(
new Pool());
89 std::shared_ptr<ParameterSetMock> parameters;
91 auto createModule = [&pool, ¶meters](
const std::string& type) {
97 auto result = momemta::ModuleFactory::get().create(type, pool, *parameters);
98 REQUIRE(result.get());
104 auto ps_points = addPhaseSpacePoints(pool);
106 auto input_particles = addInputParticles(pool);
108 SECTION(
"BreitWignerGenerator") {
115 parameters->set(
"mass", mass);
116 parameters->set(
"width", width);
117 parameters->set(
"ps_point",
InputTag(
"cuba",
"ps_points", 2));
119 auto module = createModule(
"BreitWignerGenerator");
121 auto s = pool->get<
double>({
"BreitWignerGenerator",
"s"});
122 auto jacobian = pool->get<
double>({
"BreitWignerGenerator",
"jacobian"});
124 REQUIRE(module->work() == Module::Status::OK);
126 REQUIRE(*s == Approx(29941.5));
127 REQUIRE(*jacobian == Approx(2693.05));
129 ps_points->operator[](2) = 0;
131 REQUIRE(module->work() == Module::Status::OK);
133 REQUIRE(*s == Approx(0).margin(std::numeric_limits<float>::epsilon()));
136 SECTION(
"UniformGenerator") {
142 double expected_jacobian = max - min;
144 parameters->set(
"min", min);
145 parameters->set(
"max", max);
146 parameters->set(
"ps_point",
InputTag(
"cuba",
"ps_points", 0));
148 auto module = createModule(
"UniformGenerator");
150 auto output = pool->get<
double>({
"UniformGenerator",
"output"});
151 auto jacobian = pool->get<
double>({
"UniformGenerator",
"jacobian"});
153 ps_points->operator[](0) = 0;
155 REQUIRE(module->work() == Module::Status::OK);
157 REQUIRE(*output == Approx(min));
158 REQUIRE(*jacobian == Approx(expected_jacobian));
160 ps_points->operator[](0) = 1;
162 REQUIRE(module->work() == Module::Status::OK);
164 REQUIRE(*output == Approx(max));
165 REQUIRE(*jacobian == Approx(expected_jacobian));
167 ps_points->operator[](0) = 0.5;
169 REQUIRE(module->work() == Module::Status::OK);
171 REQUIRE(*output == Approx((max + min) / 2.));
172 REQUIRE(*jacobian == Approx(expected_jacobian));
179 double sqrt_s = 13000;
181 parameters->set(
"energy", sqrt_s);
183 parameters->set(
"p1",
InputTag(
"input",
"particles", 0));
184 parameters->set(
"p2",
InputTag(
"input",
"particles", 1));
185 parameters->set(
"branches", std::vector<InputTag>( {
InputTag(
"input",
"particles", 2) } ));
189 auto module = createModule(
"BlockA");
191 REQUIRE(module->work() == Module::Status::OK);
192 REQUIRE(solutions->size() == 1);
194 for (
const auto& solution: *solutions) {
195 REQUIRE(solution.valid ==
true);
197 LorentzVector test_pT = solution.values.at(0) + solution.values.at(1) + input_particles->at(2);
198 REQUIRE(test_pT.Pt() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
200 REQUIRE(solution.values.at(0).M() == Approx(input_particles->at(0).M()));
201 REQUIRE(solution.values.at(0).Phi() == Approx(input_particles->at(0).Phi()));
202 REQUIRE(solution.values.at(0).Theta() == Approx(input_particles->at(0).Theta()));
204 REQUIRE(solution.values.at(1).M() == Approx(input_particles->at(1).M()));
205 REQUIRE(solution.values.at(1).Phi() == Approx(input_particles->at(1).Phi()));
206 REQUIRE(solution.values.at(1).Theta() == Approx(input_particles->at(1).Theta()));
214 double sqrt_s = 13000;
215 bool pT_is_met =
false;
217 parameters->set(
"energy", sqrt_s);
218 parameters->set(
"pT_is_met", pT_is_met);
220 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
221 double s_12 =
SQ(200);
222 auto s12 = pool->put<
double>({
"mockS",
"s12"});
225 parameters->set(
"p2",
InputTag(
"input",
"particles", 0));
229 auto module = createModule(
"BlockB");
231 REQUIRE(module->work() == Module::Status::OK);
232 REQUIRE(solutions->size() == 2);
234 for (
const auto& solution: *solutions) {
235 REQUIRE(solution.valid ==
true);
237 LorentzVector test_p12 = input_particles->at(0) + solution.values.at(0);
239 REQUIRE(test_p12.M2() == Approx(s_12));
240 REQUIRE(test_p12.Pt() == Approx(0));
241 REQUIRE(solution.values.at(0).M() / solution.values.at(0).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
249 double sqrt_s = 13000;
250 bool pT_is_met =
false;
253 parameters->set(
"energy", sqrt_s);
254 parameters->set(
"pT_is_met", pT_is_met);
255 parameters->set(
"m1", m1);
257 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
258 parameters->set(
"s123",
InputTag(
"mockS",
"s123"));
260 double s_12 =
SQ(80);
261 double s_123 =
SQ(173);
263 auto s12 = pool->put<
double>({
"mockS",
"s12"});
264 auto s123 = pool->put<
double>({
"mockS",
"s123"});
269 parameters->set(
"p2",
InputTag(
"input",
"particles", 0));
270 parameters->set(
"p3",
InputTag(
"input",
"particles", 5));
271 parameters->set(
"branches", std::vector<InputTag>({
InputTag(
"input",
"particles", 2)}));
275 auto module = createModule(
"BlockC");
277 REQUIRE(module->work() == Module::Status::OK);
278 REQUIRE(solutions->size() >= 2);
280 for (
const auto& solution : *solutions) {
281 REQUIRE(solution.valid ==
true);
283 LorentzVector test_p12 = input_particles->at(0) + solution.values.at(0);
284 LorentzVector test_p123 = solution.values.at(1) + test_p12;
286 REQUIRE(test_p12.M2() == Approx(s_12));
287 REQUIRE(test_p123.M2() == Approx(s_123));
289 LorentzVector test_pT = test_p123 + input_particles->at(2);
290 REQUIRE(test_pT.Pt() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
292 REQUIRE(solution.values.at(0).M() == Approx(m1));
293 REQUIRE(solution.values.at(1).M() / solution.values.at(1).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
301 double sqrt_s = 13000;
302 bool pT_is_met =
false;
304 parameters->set(
"energy", sqrt_s);
305 parameters->set(
"pT_is_met", pT_is_met);
307 parameters->set(
"s13",
InputTag(
"mockS",
"s13"));
308 parameters->set(
"s134",
InputTag(
"mockS",
"s134"));
309 parameters->set(
"s25",
InputTag(
"mockS",
"s25"));
310 parameters->set(
"s256",
InputTag(
"mockS",
"s256"));
312 double s_13_25 =
SQ(80);
313 double s_134_256 =
SQ(170);
315 auto s13 = pool->put<
double>({
"mockS",
"s13"});
316 auto s134 = pool->put<
double>({
"mockS",
"s134"});
317 auto s25 = pool->put<
double>({
"mockS",
"s25"});
318 auto s256 = pool->put<
double>({
"mockS",
"s256"});
325 parameters->set(
"p3",
InputTag(
"input",
"particles", 0));
326 parameters->set(
"p4",
InputTag(
"input",
"particles", 1));
327 parameters->set(
"p5",
InputTag(
"input",
"particles", 2));
328 parameters->set(
"p6",
InputTag(
"input",
"particles", 3));
332 auto module = createModule(
"BlockD");
334 REQUIRE(module->work() == Module::Status::OK);
335 REQUIRE(solutions->size() == 2);
337 for (
const auto& solution: *solutions) {
338 REQUIRE(solution.valid ==
true);
340 LorentzVector test_p13 = input_particles->at(0) + solution.values.at(0);
341 LorentzVector test_p134 = input_particles->at(1) + test_p13;
342 LorentzVector test_p25 = input_particles->at(2) + solution.values.at(1);
343 LorentzVector test_p256 = input_particles->at(3) + test_p25;
345 REQUIRE(test_p13.M2() == Approx(s_13_25));
346 REQUIRE(test_p134.M2() == Approx(s_134_256));
347 REQUIRE(test_p25.M2() == Approx(s_13_25));
348 REQUIRE(test_p256.M2() == Approx(s_134_256));
350 LorentzVector test_pT = test_p134 + test_p256;
351 REQUIRE(test_pT.Pt() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
353 REQUIRE(solution.values.at(0).M() / solution.values.at(0).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
354 REQUIRE(solution.values.at(1).M() / solution.values.at(1).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
362 double sqrt_s = 13000;
363 parameters->set(
"energy", sqrt_s);
365 parameters->set(
"s13",
InputTag(
"mockS",
"s13"));
366 parameters->set(
"s24",
InputTag(
"mockS",
"s24"));
367 parameters->set(
"s_hat",
InputTag(
"mockS",
"s_hat"));
368 parameters->set(
"y_tot",
InputTag(
"mockS",
"y_tot"));
370 double s_13 =
SQ(100);
371 double s_24 =
SQ(200);
372 double s_hat =
SQ(500);
375 *pool->put<
double>({
"mockS",
"s13"}) = s_13;
376 *pool->put<
double>({
"mockS",
"s24"}) = s_24;
377 *pool->put<
double>({
"mockS",
"s_hat"}) = s_hat;
378 *pool->put<
double>({
"mockS",
"y_tot"}) = rap;
380 parameters->set(
"p3",
InputTag(
"input",
"particles", 0));
381 parameters->set(
"p4",
InputTag(
"input",
"particles", 2));
385 auto module = createModule(
"BlockE");
387 REQUIRE(module->work() == Module::Status::OK);
388 REQUIRE(solutions->size() == 2);
390 for (
const auto& solution: *solutions) {
391 REQUIRE(solution.valid ==
true);
393 LorentzVector test_p13 = input_particles->at(0) + solution.values.at(0);
394 LorentzVector test_p24 = input_particles->at(2) + solution.values.at(1);
395 LorentzVector test_pT = test_p13 + test_p24;
397 REQUIRE(test_p13.M2() == Approx(s_13));
398 REQUIRE(test_p24.M2() == Approx(s_24));
400 REQUIRE(test_pT.M2() == Approx(s_hat));
401 REQUIRE(test_pT.Rapidity() == Approx(rap));
402 REQUIRE(test_pT.Pt() == Approx(0));
404 REQUIRE(solution.values.at(0).M() / solution.values.at(0).E() == Approx(0).margin(0.000001));
405 REQUIRE(solution.values.at(1).M() / solution.values.at(1).E() == Approx(0).margin(0.000001));
413 double sqrt_s = 13000;
414 parameters->set(
"energy", sqrt_s);
416 parameters->set(
"s13",
InputTag(
"mockS",
"s13"));
417 parameters->set(
"s24",
InputTag(
"mockS",
"s24"));
418 parameters->set(
"q1",
InputTag(
"mockS",
"q1"));
419 parameters->set(
"q2",
InputTag(
"mockS",
"q2"));
421 double s_13 =
SQ(100);
422 double s_24 =
SQ(200);
426 *pool->put<
double>({
"mockS",
"s13"}) = s_13;
427 *pool->put<
double>({
"mockS",
"s24"}) = s_24;
428 *pool->put<
double>({
"mockS",
"q1"}) = q1;
429 *pool->put<
double>({
"mockS",
"q2"}) = q2;
431 parameters->set(
"p3",
InputTag(
"input",
"particles", 0));
432 parameters->set(
"p4",
InputTag(
"input",
"particles", 2));
436 auto module = createModule(
"BlockF");
438 REQUIRE(module->work() == Module::Status::OK);
439 REQUIRE(solutions->size() == 2);
441 for (
const auto& solution: *solutions) {
442 REQUIRE(solution.valid ==
true);
444 LorentzVector test_p13 = input_particles->at(0) + solution.values.at(0);
445 LorentzVector test_p24 = input_particles->at(2) + solution.values.at(1);
446 LorentzVector test_pT = test_p13 + test_p24;
448 REQUIRE(test_p13.M2() == Approx(s_13));
449 REQUIRE(test_p24.M2() == Approx(s_24));
451 REQUIRE(test_pT.E() == Approx(0.5 * (q1 + q2) * sqrt_s));
452 REQUIRE(test_pT.Pz() == Approx(0.5 * (q1 - q2) * sqrt_s));
453 REQUIRE(test_pT.Pt() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
455 REQUIRE(solution.values.at(0).M() / solution.values.at(0).E() == Approx(0).margin(0.000001));
456 REQUIRE(solution.values.at(1).M() / solution.values.at(1).E() == Approx(0).margin(0.000001));
464 double sqrt_s = 13000;
465 parameters->set(
"energy", sqrt_s);
467 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
468 parameters->set(
"s34",
InputTag(
"mockS",
"s34"));
470 double s_12 =
SQ(650);
471 double s_34 =
SQ(550);
473 *pool->put<
double>({
"mockS",
"s12"}) = s_12;
474 *pool->put<
double>({
"mockS",
"s34"}) = s_34;
476 parameters->set(
"p1",
InputTag(
"input",
"particles", 4));
477 parameters->set(
"p2",
InputTag(
"input",
"particles", 5));
478 parameters->set(
"p3",
InputTag(
"input",
"particles", 6));
479 parameters->set(
"p4",
InputTag(
"input",
"particles", 7));
483 auto module = createModule(
"BlockG");
485 REQUIRE(module->work() == Module::Status::OK);
486 REQUIRE(solutions->size() == 1);
488 for (
const auto& solution: *solutions) {
489 REQUIRE(solution.valid ==
true);
491 LorentzVector test_p12 = solution.values.at(0) + solution.values.at(1);
492 LorentzVector test_p34 = solution.values.at(2) + solution.values.at(3);
493 LorentzVector test_pT = test_p12 + test_p34;
495 REQUIRE(test_p12.M2() == Approx(s_12));
496 REQUIRE(test_p34.M2() == Approx(s_34));
498 REQUIRE(test_pT.Pt() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
500 REQUIRE(solution.values.at(0).M() / solution.values.at(0).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
501 REQUIRE(solution.values.at(0).Phi() == Approx(input_particles->at(4).Phi()));
502 REQUIRE(solution.values.at(0).Theta() == Approx(input_particles->at(4).Theta()));
504 REQUIRE(solution.values.at(1).M() / solution.values.at(1).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
505 REQUIRE(solution.values.at(1).Phi() == Approx(input_particles->at(5).Phi()));
506 REQUIRE(solution.values.at(1).Theta() == Approx(input_particles->at(5).Theta()));
508 REQUIRE(solution.values.at(2).M() / solution.values.at(2).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
509 REQUIRE(solution.values.at(2).Phi() == Approx(input_particles->at(6).Phi()));
510 REQUIRE(solution.values.at(2).Theta() == Approx(input_particles->at(6).Theta()));
512 REQUIRE(solution.values.at(3).M() / solution.values.at(3).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
513 REQUIRE(solution.values.at(3).Phi() == Approx(input_particles->at(7).Phi()));
514 REQUIRE(solution.values.at(3).Theta() == Approx(input_particles->at(7).Theta()));
519 SECTION(
"SecondaryBlockA") {
523 double sqrt_s = 13000;
524 parameters->set(
"energy", sqrt_s);
526 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
527 parameters->set(
"s123",
InputTag(
"mockS",
"s123"));
528 parameters->set(
"s1234",
InputTag(
"mockS",
"s1234"));
530 double s_12 =
SQ(75);
531 double s_123 =
SQ(150);
532 double s_1234 =
SQ(350);
534 *pool->put<
double>({
"mockS",
"s12"}) = s_12;
535 *pool->put<
double>({
"mockS",
"s123"}) = s_123;
536 *pool->put<
double>({
"mockS",
"s1234"}) = s_1234;
538 parameters->set(
"p2",
InputTag(
"input",
"particles", 0));
539 parameters->set(
"p3",
InputTag(
"input",
"particles", 2));
540 parameters->set(
"p4",
InputTag(
"input",
"particles", 1));
544 auto module = createModule(
"SecondaryBlockA");
546 REQUIRE(module->work() == Module::Status::OK);
547 REQUIRE(solutions->size() == 2);
549 for (
const auto& solution: *solutions) {
550 REQUIRE(solution.valid ==
true);
552 LorentzVector test_p12 = input_particles->at(0) + solution.values.at(0);
553 LorentzVector test_p123 = input_particles->at(2) + test_p12;
554 LorentzVector test_p1234 = input_particles->at(1) + test_p123;
556 REQUIRE(test_p12.M2() == Approx(s_12));
557 REQUIRE(test_p123.M2() == Approx(s_123));
558 REQUIRE(test_p1234.M2() == Approx(s_1234));
560 REQUIRE(solution.values.at(0).M() / solution.values.at(0).E() == Approx(0).margin(0.000001));
564 SECTION(
"SecondaryBlockB") {
568 double sqrt_s = 13000;
569 parameters->set(
"energy", sqrt_s);
571 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
572 parameters->set(
"s123",
InputTag(
"mockS",
"s123"));
574 double s_12 =
SQ(475.073);
575 double s_123 =
SQ(516.951);
577 *pool->put<
double>({
"mockS",
"s12"}) = s_12;
578 *pool->put<
double>({
"mockS",
"s123"}) = s_123;
580 parameters->set(
"p1",
InputTag(
"input",
"particles", 0));
581 parameters->set(
"p2",
InputTag(
"input",
"particles", 1));
582 parameters->set(
"p3",
InputTag(
"input",
"particles", 2));
586 auto module = createModule(
"SecondaryBlockB");
588 REQUIRE(module->work() == Module::Status::OK);
589 REQUIRE(solutions->size() == 1);
591 for (
const auto& solution: *solutions) {
592 REQUIRE(solution.valid ==
true);
594 LorentzVector test_p12 = input_particles->at(1) + solution.values.at(0);
595 LorentzVector test_p123 = input_particles->at(2) + test_p12;
597 REQUIRE(test_p12.M2() == Approx(s_12));
598 REQUIRE(test_p123.M2() == Approx(s_123));
600 REQUIRE(solution.values.at(0).M() == Approx(input_particles->at(0).M()));
601 REQUIRE(solution.values.at(0).Phi() == Approx(input_particles->at(0).Phi()));
605 SECTION(
"SecondaryBlockCD") {
609 double sqrt_s = 13000;
610 parameters->set(
"energy", sqrt_s);
612 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
613 double s_12 =
SQ(50);
614 *pool->put<
double>({
"mockS",
"s12"}) = s_12;
616 parameters->set(
"p1",
InputTag(
"input",
"particles", 0));
617 parameters->set(
"p2",
InputTag(
"input",
"particles", 2));
621 auto module = createModule(
"SecondaryBlockCD");
623 REQUIRE(module->work() == Module::Status::OK);
624 REQUIRE(solutions->size() == 1);
626 for (
const auto& solution: *solutions) {
627 REQUIRE(solution.valid ==
true);
629 LorentzVector test_p12 = input_particles->at(2) + solution.values.at(0);
631 REQUIRE(test_p12.M2() == Approx(s_12));
633 REQUIRE(solution.values.at(0).Phi() == Approx(input_particles->at(0).Phi()));
634 REQUIRE(solution.values.at(0).Theta() == Approx(input_particles->at(0).Theta()));
638 SECTION(
"SecondaryBlockE") {
642 double sqrt_s = 13000;
643 parameters->set(
"energy", sqrt_s);
645 parameters->set(
"s12",
InputTag(
"mockS",
"s12"));
646 parameters->set(
"s123",
InputTag(
"mockS",
"s123"));
648 double s_12 =
SQ(50);
649 double s_123 =
SQ(500);
651 *pool->put<
double>({
"mockS",
"s12"}) = s_12;
652 *pool->put<
double>({
"mockS",
"s123"}) = s_123;
654 parameters->set(
"p1",
InputTag(
"input",
"particles", 0));
655 parameters->set(
"p2",
InputTag(
"input",
"particles", 5));
656 parameters->set(
"p3",
InputTag(
"input",
"particles", 3));
660 auto module = createModule(
"SecondaryBlockE");
662 REQUIRE(module->work() == Module::Status::OK);
663 REQUIRE(solutions->size() == 2);
665 for (
const auto& solution: *solutions) {
666 REQUIRE(solution.valid ==
true);
668 LorentzVector test_p12 = solution.values.at(0) + solution.values.at(1);
669 LorentzVector test_p123 = input_particles->at(3) + test_p12;
671 REQUIRE(test_p12.M2() == Approx(s_12));
672 REQUIRE(test_p123.M2() == Approx(s_123));
674 REQUIRE(solution.values.at(0).M() == Approx(input_particles->at(0).M()));
675 REQUIRE(solution.values.at(0).Phi() == Approx(input_particles->at(0).Phi()));
676 REQUIRE(solution.values.at(0).Theta() == Approx(input_particles->at(0).Theta()));
678 REQUIRE(solution.values.at(1).M() / solution.values.at(1).E() == Approx(0).margin(std::numeric_limits<float>::epsilon()));
679 REQUIRE(solution.values.at(1).Phi() == Approx(input_particles->at(5).Phi()));
680 REQUIRE(solution.values.at(1).Theta() == Approx(input_particles->at(5).Theta()));
std::string name
Name of the module (user-defined from the configuration file)
virtual void create(const std::string &name, const momemta::any &value)
Add a new element to the ParameterSet.
std::shared_ptr< ParameterSet > parameters
Module's parameters, as parsed from the configuration file.
A class encapsulating a lua table.
A module declaration, defined from the configuration file.