phaseSpaceGenerationTests.cc
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2017 Universite catholique de Louvain (UCL), Belgium
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <momemta/ConfigurationReader.h>
20 #include <momemta/MoMEMta.h>
21 #include <momemta/Types.h>
22 #include <momemta/Utils.h>
23 
24 #include "phaseSpaceGenerationTests.h"
25 
26 #include <chrono>
27 #include <exception>
28 
29 using namespace std::chrono;
30 using namespace momemta;
31 
32 void PSGenerationTestManager::registerTest(PSGenerationTest test, char mainBlock, char secondaryBlock/*='\0'*/) {
33  assert(test.particle_names.size() == test.particle_masses.size());
34 
35  if (secondaryBlock == '\0')
36  mainBlocks.emplace(mainBlock, test);
37  else
38  secondaryBlocks.emplace(std::make_pair(mainBlock, secondaryBlock), test);
39 }
40 
41 void PSGenerationTestManager::parseArgs(int argc, char** argv) {
42  if (argc <= 1) {
43  printHelpMessage();
44  throw std::invalid_argument("Expected at least one argument!");
45  }
46 
47  for (int i = 1; i < argc; i++) {
48  std::string arg(argv[i]);
49 
50  if (arg == "-h" || arg == "--help") {
51  printHelpMessage();
52  break;
53  }
54 
55  if (arg.length() == 1)
56  runTest(arg[0]);
57  else if (arg.length() == 2)
58  runTest(arg[0], arg[1]);
59  else {
60  printHelpMessage();
61  throw std::invalid_argument("Each argument has to be one or two characters!");
62  }
63  }
64 }
65 
66 void PSGenerationTestManager::printHelpMessage() {
67  LOG(info) << "Usage: X[Y] [X[Y] ...]";
68  LOG(info) << "\t where X and Y are characters indicating which main [optionally in combination with a secondary] block is requested.";
69  LOG(info) << "Available block combinations:";
70  LOG(info) << "\tMain Blocks:";
71  for (auto it: mainBlocks)
72  LOG(info) << "\t\t" << it.first;
73  LOG(info) << "\tMain Blocks with Secondary Blocks:";
74  for (auto it: secondaryBlocks)
75  LOG(info) << "\t\t" << it.first.first << " (main) combined with " << it.first.second << " (secondary)";
76 }
77 
78 void PSGenerationTestManager::runTest(char mainBlock, char secondaryBlock/*='\0'*/) {
79  if (secondaryBlock == '\0') {
80  LOG(debug) << "Attempting to run test for Main Block " << mainBlock;
81  auto it = mainBlocks.find(mainBlock);
82  if (it == mainBlocks.end()) {
83  printHelpMessage();
84  throw std::invalid_argument("Could not find test for main block!");
85  }
86  runTest(it->second);
87  } else {
88  LOG(debug) << "Attempting to run test for combination of Main Block " << mainBlock << " and Secondary Block " << secondaryBlock;
89  auto it = secondaryBlocks.find(std::make_pair(mainBlock, secondaryBlock));
90  if (it == secondaryBlocks.end()) {
91  printHelpMessage();
92  throw std::invalid_argument("Could not find test for main and secondary block combination!");
93  }
94  runTest(it->second);
95  }
96 }
97 
98 void PSGenerationTestManager::runTest(PSGenerationTest &test) {
99  ConfigurationReader configuration(test.lua_file);
100  MoMEMta weight(configuration.freeze());
101 
102  std::vector<Particle> particles;
103  for (std::size_t i = 0; i < test.particle_names.size(); i++)
104  particles.push_back(Particle(test.particle_names[i], getRandom4Vector(100, test.particle_masses[i]), 0));
105 
106  auto start_time = system_clock::now();
107  std::vector<std::pair<double, double>> weights = weight.computeWeights(particles);
108  auto end_time = system_clock::now();
109 
110  LOG(info) << "Result: " << weights.back().first << " +- " << weights.back().second;
111  LOG(info) << "Target value: " << test.target_value;
112  LOG(info) << "Ratio: " << std::fixed << std::setprecision(4) << weights.back().first / test.target_value << " +- " << weights.back().second / test.target_value;
113 
114  LOG(info) << "Weight computed in " << std::chrono::duration_cast<milliseconds>(end_time - start_time).count() << "ms";
115 }
A lua configuration file parser.
A MoMEMta instance.
Definition: MoMEMta.h:44
Definition: Graph.h:21
Describe a reco particle. Used as input of MoMEMta::computeWeights.
Definition: Particle.h:30