Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackSummary.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TrackSummary.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
11 #include <algorithm>
12 #include <array>
13 #include <bitset>
14 #include <cmath>
15 #include <exception>
16 #include <iostream>
17 #include <limits>
18 #include <optional>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 
23 #include <TApplication.h>
24 #include <boost/program_options.hpp>
25 #include <nlohmann/json.hpp>
26 
27 #define BOOST_AVAILABLE 1
28 #if ((BOOST_VERSION / 100) % 1000) <= 71
29 // Boost <=1.71 and lower do not have progress_display.hpp as a replacement yet
30 #include <boost/progress.hpp>
31 
33 #else
34 // Boost >=1.72 can use this as a replacement
35 #include <boost/timer/progress_display.hpp>
36 
38 #endif
39 
40 #define NLOHMANN_AVAILABLE 1
41 #include "trackSummaryAnalysis.C"
42 
43 using namespace boost::program_options;
44 
47 
48 int main(int argc, char** argv) {
49  std::cout << "*** ACTS Perigee parameters and Track summary plotting "
50  << std::endl;
51 
52  try {
53  options_description description("*** Usage:");
54 
55  // Add the program options
56  auto ao = description.add_options();
57  ao("help,h", "Display this help message");
58  ao("silent,s", bool_switch(), "Silent mode (without X-window/display).");
59  ao("events,n", value<unsigned long>()->default_value(0),
60  "(Optionally) limit number of events to be processed.");
61  ao("peak-events,p", value<unsigned long>()->default_value(0),
62  "(Optionally) limit number of events for the range peaking.");
63  ao("input,i", value<std::vector<std::string>>()->required(),
64  "Input ROOT file(s) containing the input TTree.");
65  ao("tree,t", value<std::string>()->default_value("tracksummary"),
66  "Input TTree/TChain name.");
67  ao("output,o", value<std::string>()->default_value(""),
68  "Output ROOT file with histograms");
69  ao("hist-bins", value<unsigned int>()->default_value(61),
70  "Number of bins for the residual/pull histograms");
71  ao("pull-range", value<float>()->default_value(5.),
72  "Number of sigmas for the pull range.");
73  ao("eta-bins", value<unsigned int>()->default_value(10),
74  "Number of bins in eta.");
75  ao("eta-range",
76  value<Interval>()->value_name("MIN:MAX")->default_value({-3.0, 3.0}),
77  "Range for the eta bins.");
78  ao("phi-bins", value<unsigned int>()->default_value(10),
79  "Number of bins in phi.");
80  ao("phi-range",
81  value<Interval>()->value_name("MIN:MAX")->default_value({-M_PI, M_PI}),
82  "Range for the phi bins.");
83  ao("pt-borders", value<VariableReals>()->required(),
84  "Transverse momentum borders.");
85  ao("config-output", value<std::string>()->default_value(""),
86  "(Optional) output histogram configuration json file.");
87  ao("config-input", value<std::string>()->default_value(""),
88  "(Optional) input histogram configuration json file.");
89  // Define all parameters (overwrites individual parameters)
90  ao("all", bool_switch(),
91  "Process all residual/pull and auxiliary parameters");
92  // Define the parameters for the residual/pull analysis
93  std::vector<std::string> resPullPars = {"d0", "z0", "phi0", "theta0",
94  "qop", "time", "pt"};
95  for (const auto& rp : resPullPars) {
96  ao(rp.c_str(), bool_switch(),
97  (std::string("Residual/pulls for ") + rp).c_str());
98  }
99  // Define the auxiliary track information
100  std::vector<std::string> auxPars = {"chi2ndf", "measurements", "holes",
101  "outliers", "shared"};
102  for (const auto& aux : auxPars) {
103  ao(aux.c_str(), bool_switch(),
104  (std::string("Auxiliary information for ") + aux).c_str());
105  }
106 
107  // Set up the variables map
108  variables_map vm;
109  store(command_line_parser(argc, argv).options(description).run(), vm);
110 
111  if (vm.count("help") != 0u) {
112  std::cout << description;
113  return 1;
114  }
115 
116  notify(vm);
117 
118  // Events
119  unsigned long nEntries = vm["events"].as<unsigned long>();
120  unsigned long nPeakEntries = vm["peak-events"].as<unsigned long>();
121 
122  // Parse the parameters
123  auto iFiles = vm["input"].as<std::vector<std::string>>();
124  auto iTree = vm["tree"].as<std::string>();
125  auto oFile = vm["output"].as<std::string>();
126 
127  // Configuration JSON files
128  auto configInput = vm["config-input"].as<std::string>();
129  auto configOutput = vm["config-output"].as<std::string>();
130 
131  float pullRange = vm["pull-range"].as<float>();
132  unsigned int nHistBins = vm["hist-bins"].as<unsigned int>();
133  unsigned int nEtaBins = vm["eta-bins"].as<unsigned int>();
134 
135  auto etaInterval = vm["eta-range"].as<Interval>();
136  std::array<float, 2> etaRange = {
137  static_cast<float>(etaInterval.lower.value_or(-3)),
138  static_cast<float>(etaInterval.upper.value_or(3.))};
139 
140  unsigned int nPhiBins = vm["phi-bins"].as<unsigned int>();
141  auto phiInterval = vm["phi-range"].as<Interval>();
142  std::array<float, 2> phiRange = {
143  static_cast<float>(phiInterval.lower.value_or(-M_PI)),
144  static_cast<float>(phiInterval.upper.value_or(M_PI))};
145 
146  auto ptBorders = vm["pt-borders"].as<VariableReals>().values;
147  if (ptBorders.empty()) {
148  ptBorders = {0., std::numeric_limits<double>::infinity()};
149  }
150 
151  TApplication* tApp =
152  vm["silent"].as<bool>()
153  ? nullptr
154  : new TApplication("TrackSummary", nullptr, nullptr);
155 
156  std::bitset<7> residualPulls;
157  std::bitset<5> auxiliaries;
158  if (vm["all"].as<bool>()) {
159  residualPulls = std::bitset<7>{"1111111"};
160  auxiliaries = std::bitset<5>{"11111"};
161  } else {
162  // Set the bit for the chosen parameters(s)
163  for (unsigned int iresp = 0; iresp < resPullPars.size(); ++iresp) {
164  if (vm[resPullPars[iresp]].as<bool>()) {
165  residualPulls.set(iresp);
166  }
167  }
168  // Set the bit for the chosen auxiliaries
169  for (unsigned int iaux = 0; iaux < auxPars.size(); ++iaux) {
170  if (vm[auxPars[iaux]].as<bool>()) {
171  auxiliaries.set(iaux);
172  }
173  }
174  }
175 
176  // Run the actual resolution estimation
177  switch (trackSummaryAnalysis(
178  iFiles, iTree, oFile, configInput, configOutput, nEntries, nPeakEntries,
179  pullRange, nHistBins, nPhiBins, phiRange, nEtaBins, etaRange, ptBorders,
180  residualPulls, auxiliaries)) {
181  case -1: {
182  std::cout << "*** Input file could not be opened, check name/path."
183  << std::endl;
184  } break;
185  case -2: {
186  std::cout << "*** Input tree could not be found, check name."
187  << std::endl;
188  } break;
189  default: {
190  std::cout << "*** Successful run." << std::endl;
191  };
192  }
193 
194  if (tApp != nullptr) {
195  tApp->Run();
196  }
197 
198  } catch (std::exception& e) {
199  std::cerr << e.what() << "\n";
200  }
201 
202  std::cout << "*** Done." << std::endl;
203  return 1;
204 }