CMS 3D CMS Logo

DMRtrends.cc
Go to the documentation of this file.
1 #include <cstdlib>
2 #include <string>
3 #include <tuple>
4 #include <iostream>
5 #include <numeric>
6 #include <functional>
7 #include <unistd.h>
8 
9 #include "TFile.h"
10 #include "TGraph.h"
11 #include "TH1.h"
12 
13 #include "exceptions.h"
14 #include "toolbox.h"
15 #include "Options.h"
16 
18 #include "boost/filesystem.hpp"
19 #include "boost/algorithm/string.hpp"
20 #include "boost/property_tree/ptree.hpp"
21 #include "boost/property_tree/json_parser.hpp"
22 #include "boost/optional.hpp"
23 
24 #include "TString.h"
25 #include "TColor.h"
26 
29 
30 using namespace std;
31 using namespace AllInOneConfig;
32 namespace fs = boost::filesystem;
33 namespace bc = boost::container;
34 
35 static const char *bold = "\e[1m", *normal = "\e[0m";
36 static const float defaultConvertScale = 1000.;
37 static const int startRun2016 = 272930;
38 static const int endRun2018 = 325175;
39 
40 namespace pt = boost::property_tree;
41 
42 int trends(int argc, char *argv[]) {
43  // parse the command line
44 
46  options.helper(argc, argv);
47  options.parser(argc, argv);
48 
49  //Read in AllInOne json config
50  pt::ptree main_tree;
51  pt::read_json(options.config, main_tree);
52 
53  pt::ptree alignments = main_tree.get_child("alignments");
54  pt::ptree validation = main_tree.get_child("validation");
55  pt::ptree style = main_tree.get_child("style");
56 
57  //Read all configure variables and set default for missing keys
58  string outputdir = main_tree.get<string>("output");
59  bool FORCE = validation.count("FORCE") ? validation.get<bool>("FORCE") : false;
60  string year = validation.count("year") ? validation.get<string>("year") : "Run2";
61  TString lumiInputFile = style.get_child("trends").count("lumiInputFile")
62  ? style.get_child("trends").get<string>("lumiInputFile")
63  : "Alignment/OfflineValidation/data/lumiPerRun_Run2.txt";
64  fs::path lumiFile = lumiInputFile.Data();
65  edm::FileInPath fip = edm::FileInPath(lumiFile.string());
66  fs::path pathToLumiFile = "";
67  if (!fs::exists(lumiFile)) {
68  pathToLumiFile = fip.fullPath();
69  } else {
70  pathToLumiFile = lumiFile;
71  }
72  if (!fs::exists(pathToLumiFile)) {
73  cout << "ERROR: lumi-per-run file (" << lumiFile.string().data() << ") not found!" << endl
74  << "Please check!" << endl;
75  exit(EXIT_FAILURE);
76  } else {
77  cout << "Found lumi-per-run file: " << pathToLumiFile.string().data() << endl;
78  }
79  if (!lumiInputFile.Contains(year)) {
80  cout << "ERROR: lumi-per-run file must contain (" << year.data() << ")!" << endl << "Please check!" << endl;
81  exit(EXIT_FAILURE);
82  }
83 
84  string lumiAxisType = "recorded";
85  if (lumiInputFile.Contains("delivered"))
86  lumiAxisType = "delivered";
87 
88  std::cout << Form("NOTE: using %s luminosity!", lumiAxisType.data()) << std::endl;
89 
90  vector<int> IOVlist;
91  vector<string> inputFiles;
92  for (auto const &childTree : validation.get_child("IOV")) {
93  int iov = childTree.second.get_value<int>();
94  IOVlist.push_back(iov);
95  TString mergeFile = validation.get<string>("mergeFile");
96  string input = Form("%s/OfflineValidationSummary.root", mergeFile.ReplaceAll("{}", to_string(iov)).Data());
97  inputFiles.push_back(input);
98  }
99 
100  string labels_to_add = "";
101  if (validation.count("labels")) {
102  for (auto const &label : validation.get_child("labels")) {
103  labels_to_add += "_";
104  labels_to_add += label.second.get_value<string>();
105  }
106  }
107 
108  fs::path pname = Form("%s/DMRtrends%s.root", outputdir.data(), labels_to_add.data());
109 
110  vector<TString> structures{"BPIX", "BPIX_y", "FPIX", "FPIX_y", "TIB", "TID", "TOB", "TEC"};
111 
112  map<TString, int> nlayers{{"BPIX", 4}, {"FPIX", 3}, {"TIB", 4}, {"TID", 3}, {"TOB", 6}, {"TEC", 9}};
113  if (year == "2016")
114  nlayers = {{"BPIX", 3}, {"FPIX", 2}, {"TIB", 4}, {"TID", 3}, {"TOB", 6}, {"TEC", 9}};
115 
116  PrepareDMRTrends prepareTrends(pname.c_str(), alignments);
117  if (validation.count("Variables")) {
118  for (auto const &Variable : validation.get_child("Variables")) {
119  prepareTrends.compileDMRTrends(
120  IOVlist, Variable.second.get_value<string>(), inputFiles, structures, nlayers, FORCE);
121  }
122  } else
123  prepareTrends.compileDMRTrends(IOVlist, "median", inputFiles, structures, nlayers, FORCE);
124 
125  assert(fs::exists(pname));
126 
127  float convertUnit = style.get_child("trends").count("convertUnit")
128  ? style.get_child("trends").get<float>("convertUnit")
130  int firstRun = validation.count("firstRun") ? validation.get<int>("firstRun") : startRun2016;
131  int lastRun = validation.count("lastRun") ? validation.get<int>("lastRun") : endRun2018;
132 
133  const Run2Lumi GetLumi(pathToLumiFile.string().data(), firstRun, lastRun, convertUnit);
134 
135  auto f = TFile::Open(pname.c_str());
136 
137  for (auto const &Variable : validation.get_child("Variables")) {
138  vector<tuple<TString, TString, float, float>> DMRs{{"mu", "#mu [#mum]", -6, 6},
139  {"sigma", "#sigma_{#mu} [#mum]", -15, 15},
140  {"muplus", "#mu outward [#mum]", -6, 6},
141  {"sigmaplus", "#sigma_{#mu outward} [#mum]", -15, 15},
142  {"muminus", "#mu inward [#mum]", -6, 6},
143  {"sigmaminus", "#sigma_{#mu inward} [#mum]", -15, 15},
144  {"deltamu", "#Delta#mu [#mum]", -15, 15},
145  {"sigmadeltamu", "#sigma_{#Delta#mu} [#mum]", -15, 15},
146  {"musigma", "#mu [#mum]", -6, 6},
147  {"muplussigmaplus", "#mu outward [#mum]", -15, 15},
148  {"muminussigmaminus", "#mu inward [#mum]", -15, 15},
149  {"deltamusigmadeltamu", "#Delta#mu [#mum]", -15, 15}};
150 
151  if (Variable.second.get_value<string>() == "DrmsNR") {
152  DMRs = {{"mu", "RMS(x'_{pred}-x'_{hit} /#sigma)", -1.2, 1.2},
153  {"sigma", "#sigma_{RMS(x'_{pred}-x'_{hit} /#sigma)}", -6, 6},
154  {"muplus", "RMS(x'_{pred}-x'_{hit} /#sigma) outward", -1.2, 1.2},
155  {"sigmaplus", "#sigma_{#mu outward}", -6, 6},
156  {"muminus", "RMS(x'_{pred}-x'_{hit} /#sigma) inward", -1.2, 1.2},
157  {"sigmaminus", "#sigma_{RMS(x'_{pred}-x'_{hit} /#sigma) inward}", -6, 6},
158  {"deltamu", "#DeltaRMS(x'_{pred}-x'_{hit} /#sigma)", -0.15, 0.15},
159  {"sigmadeltamu", "#sigma_{#DeltaRMS(x'_{pred}-x'_{hit} /#sigma)}", -6, 6},
160  {"musigma", "RMS(x'_{pred}-x'_{hit} /#sigma)", -1.2, 1.2},
161  {"muplussigmaplus", "RMS(x'_{pred}-x'_{hit} /#sigma) outward", -1.2, 1.2},
162  {"muminussigmaminus", "RMS(x'_{pred}-x'_{hit} /#sigma) inward", -1.2, 1.2},
163  {"deltamusigmadeltamu", "#DeltaRMS(x'_{pred}-x'_{hit} /#sigma)", -0.15, 0.15}};
164  }
165 
166  for (const auto &structure : structures) {
167  TString structname = structure;
168  structname.ReplaceAll("_y", "");
169  size_t layersnumber = nlayers.at(structname);
170  for (Size_t layer = 0; layer <= layersnumber; layer++) {
171  TString structtitle = "";
172  if (structure.Contains("PIX") && !(structure.Contains("_y")))
173  structtitle = structure + " (x)";
174  else if (structure.Contains("_y")) {
175  TString substring(structure(0, 4));
176  structtitle = substring + " (y)";
177  } else
178  structtitle = structure;
179  if (layer != 0) {
180  if (structure == "TID" || structure == "TEC" || structure == "FPIX" || structure == "FPIX_y")
181  structtitle += " disc ";
182  else
183  structtitle += " layer ";
184  structtitle += layer;
185  }
186 
187  TString structandlayer = structure;
188  if (layer != 0) {
189  if (structure == "TID" || structure == "TEC")
190  structandlayer += "_disc";
191  else
192  structandlayer += "_layer";
193  structandlayer += layer;
194  }
195 
196  for (auto &DMR : DMRs) {
197  auto name = get<0>(DMR), ytitle = get<1>(DMR);
198 
199  if (name.Contains("plus") || name.Contains("minus") || name.Contains("delta")) {
200  if (structname == "TEC" || structname == "TID")
201  continue; //Lorentz drift cannot appear in TEC and TID. These structures are skipped when looking at outward and inward pointing modules.
202  }
203 
204  cout << bold << name << normal << endl;
205 
206  float ymin = get<2>(DMR), ymax = get<3>(DMR);
207  Trend trend(Form("%s_%s_%s", Variable.second.get_value<string>().data(), structandlayer.Data(), name.Data()),
208  outputdir.data(),
209  ytitle,
210  ytitle,
211  ymin,
212  ymax,
213  style,
214  GetLumi,
215  lumiAxisType.data());
216  trend.lgd.SetHeader(structtitle);
217 
218  for (auto const &alignment : alignments) {
219  bool fullRange = true;
220  if (style.get_child("trends").count("earlyStops")) {
221  for (auto const &earlyStop : style.get_child("trends.earlyStops")) {
222  if (earlyStop.second.get_value<string>() == alignment.first)
223  fullRange = false;
224  }
225  }
226 
227  TString gtitle = alignment.second.get<string>("title");
228  TString gname = Form("%s_%s_%s_%s",
229  Variable.second.get_value<string>().data(),
230  gtitle.Data(),
231  structandlayer.Data(),
232  name.Data());
233  gname.ReplaceAll(" ", "_");
234  auto g = Get<TGraphErrors>(gname);
235  assert(g != nullptr);
236  g->SetTitle(gtitle); // for the legend
237  g->SetMarkerSize(0.6);
238  int color = alignment.second.get<int>("color");
239  int style = floor(alignment.second.get<double>("style") / 100.);
240  g->SetFillColorAlpha(color, 0.2);
241  g->SetMarkerColor(color);
242  g->SetMarkerStyle(style);
243  g->SetLineColor(kWhite);
244  trend(g, "P2", "pf", fullRange);
245  }
246  }
247  }
248  }
249  }
250 
251  f->Close();
252  cout << bold << "Done" << normal << endl;
253 
254  return EXIT_SUCCESS;
255 }
256 
257 #ifndef DOXYGEN_SHOULD_SKIP_THIS
258 int main(int argc, char *argv[]) { return exceptions<trends>(argc, argv); }
259 #endif
static const char * normal
Definition: DMRtrends.cc:35
void compileDMRTrends(std::vector< int > IOVlist, TString Variable, std::vector< std::string > inputFiles, std::vector< TString > structures, const std::map< TString, int > nlayers, bool FORCE=false)
std::string fullPath() const
Definition: FileInPath.cc:161
Definition: Trend.h:22
std::string to_string(const V &value)
Definition: OMSAccess.h:71
assert(be >=bs)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
constexpr std::array< uint8_t, layerIndexSize > layer
static std::string const input
Definition: EdmProvDump.cc:50
char const * label
Definition: Trend.h:78
int trends(int argc, char *argv[])
Definition: DMRtrends.cc:42
Definition: style.py:1
double f[11][100]
def DMR(config, validationDir)
Definition: DMR.py:4
static const float defaultConvertScale
Definition: DMRtrends.cc:36
static const int endRun2018
Definition: DMRtrends.cc:38
static const char * bold
Definition: DMRtrends.cc:35
static const int startRun2016
Definition: DMRtrends.cc:37
firstRun
Definition: dataset.py:940
TLegend lgd
Definition: Trend.h:88
Definition: DMR.py:1
int main(int argc, char *argv[])
Definition: DMRtrends.cc:258
def exit(msg="")