Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialComposition.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialComposition.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 <cstddef>
13 #include <exception>
14 #include <filesystem>
15 #include <fstream>
16 #include <iostream>
17 #include <sstream>
18 #include <string>
19 #include <vector>
20 
21 #include <TApplication.h>
22 #include <boost/program_options.hpp>
23 #include <nlohmann/json.hpp>
24 
25 #define BOOST_AVAILABLE 1
26 #if ((BOOST_VERSION / 100) % 1000) <= 71
27 // Boost <=1.71 and lower do not have progress_display.hpp as a replacement yet
28 #include <boost/progress.hpp>
29 
31 #else
32 // Boost >=1.72 can use this as a replacement
33 #include <boost/timer/progress_display.hpp>
34 
36 #endif
37 
38 #include "materialComposition.C"
39 
40 using namespace boost::program_options;
42 
43 int main(int argc, char** argv) {
44  std::cout << "*** Material Composition plotting " << std::endl;
45 
46  try {
47  options_description description("*** Usage:");
48 
49  // Add the program options
50  auto ao = description.add_options();
51  ao("help,h", "Display this help message");
52  ao("silent,s", bool_switch(), "Silent mode (without X-window/display).");
53  ao("input,i", value<std::string>()->default_value(""),
54  "Input ROOT file containing the input TTree.");
55  ao("tree,t", value<std::string>()->default_value("material-tracks"),
56  "Input TTree name.");
57  ao("output,o", value<std::string>()->default_value(""),
58  "Output ROOT file with histograms");
59  ao("bins,b", value<unsigned int>()->default_value(60),
60  "Number of bins in eta/phi");
61  ao("eta,e", value<float>()->default_value(4.), "Eta range.");
62  ao("sub-names", value<std::vector<std::string>>()->multitoken(),
63  "Subdetector names.");
64  ao("sub-rmin", value<VariableReals>(), "Minimal radial restrictions.");
65  ao("sub-rmax", value<VariableReals>(), "Maximal radial restrictions.");
66  ao("sub-zmin", value<VariableReals>(), "Minimal z radial restrictions");
67  ao("sub-zmax", value<VariableReals>(), "Maximal z radial restrictions.");
68  ao("config,c", value<std::string>(), "Configuration file (json).");
69 
70  // Set up the variables map
71  variables_map vm;
72  store(command_line_parser(argc, argv).options(description).run(), vm);
73  notify(vm);
74 
75  if (vm.count("help") != 0u) {
76  std::cout << description;
77  }
78 
79  // Parse the parameters
80  auto iFile = vm["input"].as<std::string>();
81  auto iTree = vm["tree"].as<std::string>();
82  auto oFile = vm["output"].as<std::string>();
83 
84  // Bins & eta range
85  unsigned int bins = vm["bins"].as<unsigned int>();
86  float eta = vm["eta"].as<float>();
87 
88  // Subdetector configurations
89  std::vector<Region> dRegion = {};
90 
91  if (vm.count("config") > 0) {
92  std::filesystem::path config = vm["config"].as<std::string>();
93  std::cout << "Reading region configuration from JSON: " << config
94  << std::endl;
95 
96  if (!std::filesystem::exists(config)) {
97  std::cerr << "Configuration file does not exist." << std::endl;
98  return 1;
99  }
100 
101  std::ifstream ifs(config.string().c_str());
102  nlohmann::ordered_json j = nlohmann::ordered_json::parse(ifs);
103 
104  for (const auto& [key, regions] : j.items()) {
105  dRegion.push_back(Region{key, {}});
106  auto& reg = dRegion.back();
107  std::cout << "Region(" << key << ")" << std::endl;
108  for (const auto& region : regions) {
109  float rmin = region["rmin"].template get<float>();
110  float rmax = region["rmax"].template get<float>();
111  float zmin = region["zmin"].template get<float>();
112  float zmax = region["zmax"].template get<float>();
113 
114  reg.boxes.push_back({rmin, rmax, zmin, zmax});
115  std::cout << "* " << key << " r/z: " << rmin << "/" << rmax << " "
116  << zmin << "/" << zmax << std::endl;
117  }
118  }
119  } else {
120  auto snames = vm["sub-names"].as<std::vector<std::string>>();
121  auto rmins = vm["sub-rmin"].as<VariableReals>().values;
122  auto rmaxs = vm["sub-rmax"].as<VariableReals>().values;
123  auto zmins = vm["sub-zmin"].as<VariableReals>().values;
124  auto zmaxs = vm["sub-zmax"].as<VariableReals>().values;
125 
126  size_t subs = snames.size();
127 
128  if (subs != rmins.size() or subs != rmaxs.size() or
129  subs != zmins.size() or subs != zmaxs.size()) {
130  std::cerr << "Configuration problem." << std::endl;
131  return 1;
132  }
133 
134  // Create the regions
135  for (unsigned int is = 0; is < subs; ++is) {
136  dRegion.push_back(Region{
137  snames[is],
138  {{static_cast<float>(rmins[is]), static_cast<float>(rmaxs[is]),
139  static_cast<float>(zmins[is]), static_cast<float>(zmaxs[is])}}});
140  }
141  }
142 
143  TApplication* tApp =
144  vm["silent"].as<bool>()
145  ? nullptr
146  : new TApplication("ResidualAndPulls", nullptr, nullptr);
147 
148  materialComposition(iFile, iTree, oFile, bins, eta, dRegion);
149 
150  if (tApp != nullptr) {
151  tApp->Run();
152  }
153 
154  } catch (std::exception& e) {
155  std::cerr << e.what() << "\n";
156  }
157 
158  std::cout << "*** Done." << std::endl;
159  return 0;
160 }