Skip to content

Commit 7458137

Browse files
authored
Merge pull request #47055 from cms-trackeralign/mm_dev_add_general_tk_modules_in_all-in-one
Introduce a `Generic` validation tool for dataset validation in the alignment all-in-one tool
2 parents 04cdcf2 + b6031b0 commit 7458137

File tree

12 files changed

+609
-4
lines changed

12 files changed

+609
-4
lines changed

Alignment/OfflineValidation/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,11 @@ For details read [`README_JetHT.md`](https://github.com/cms-sw/cmssw/blob/master
117117
## MTS validation
118118
For details read [`README_MTS.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_MTS.md)
119119

120+
## Pixel BaryCenter
121+
For details read [`README_MTS.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_PixBary.md)
122+
123+
## Generic validation (dataset validation)
124+
For details read [`README_Generic.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_Generic.md)
125+
120126
## General info about IOV/run arguments
121127
For details read [`README_IOV.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_IOV.md)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Generic Validation
2+
3+
## General info
4+
```
5+
validations:
6+
Generic:
7+
<step_type>:
8+
<step_name>:
9+
<options>
10+
```
11+
12+
Generic validation runs in 2 possible types of steps:
13+
- single (validation analysis by GenericV_cfg.py)
14+
- (optional) merge (GenericVmerge macro)
15+
Step name is and arbitrary string which will be used as a reference for consequent steps.
16+
Merge job awill only start if all corresponding single jobs are done.
17+
Merge jobs can run in parallel.
18+
19+
## Single Generic jobs
20+
Single jobs can be specified per run (IoV as well). In case of MC, IoV is specified to arbitrary 1.
21+
22+
Variable | Default value | Explanation/Options
23+
-------- | ------------- | --------------------
24+
IOV | None | List of IOVs/runs defined by integer value. IOV 1 is reserved for MC.
25+
Alignments | None | List of alignments. Will create separate directory for each.
26+
dataset | See defaultInputFiles_cff.py | Path to txt file containing list of datasets to be used. If file is missing at EOS or is corrupted - job will eventually fail (most common issue).
27+
goodlumi | cms.untracked.VLuminosityBlockRange() | Path to json file containing lumi information about selected IoV - must contain list of runs under particular IoV with lumiblock info. Format: `IOV_Vali_{}.json`
28+
maxevents | 1 | Maximum number of events before cmsRun terminates.
29+
trackcollection | "generalTracks" | Track collection to be specified here, e.g. "ALCARECOTkAlMuonIsolated" or "ALCARECOTkAlMinBias" ...
30+
tthrbuilder | "WithAngleAndTemplate" | Specify TTRH Builder
31+
32+
## Merge Generic job
33+
Its name do not need to match single job name but option `singles` must list all single jobs to be merged.
34+
Generic merged plot style can be adjusted from global plotting style.
35+
36+
Variable | Default value | Explanation/Options
37+
-------- | ------------- | --------------------
38+
singles | None | List of strings matching single job names to be merged in one plot.
39+
customrighttitle | "" | Top right title. Reserved word "IOV" will be replaced for given IOV/run in the list.

Alignment/OfflineValidation/bin/BuildFile.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<bin name="SplitVmerge" file="SplitVmerge.cc,Options.cc" />
1919
<bin name="Zmumumerge" file="Zmumumerge.cc,Options.cc" />
2020
<bin name="DiMuonVmerge" file="DiMuonVmerge.cc,Options.cc" />
21+
<bin name="GenericVmerge" file="GenericVmerge.cc,Options.cc" />
2122
<bin name="MTSmerge" file="MTSmerge.cc,Options.cc" />
2223
<bin name="haddws" file="haddws.C" />
2324
<bin name="jetHtPlotter" file="jetHtPlotter.cc,JetHtPlotConfiguration.cc,Options.cc" />
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <cstdlib>
2+
#include <string>
3+
#include <iostream>
4+
#include <numeric>
5+
#include <functional>
6+
7+
#include "exceptions.h"
8+
#include "toolbox.h"
9+
#include "Options.h"
10+
11+
#include "boost/filesystem.hpp"
12+
#include "boost/property_tree/ptree.hpp"
13+
#include "boost/property_tree/json_parser.hpp"
14+
#include "boost/optional.hpp"
15+
16+
#include "TString.h"
17+
#include "TASImage.h"
18+
#include "TGraph.h"
19+
20+
#include "Alignment/OfflineValidation/macros/loopAndPlot.C"
21+
#include "Alignment/OfflineValidation/interface/TkAlStyle.h"
22+
23+
using namespace std;
24+
using namespace AllInOneConfig;
25+
26+
namespace pt = boost::property_tree;
27+
28+
int merge(int argc, char* argv[]) {
29+
// parse the command line
30+
31+
Options options;
32+
options.helper(argc, argv);
33+
options.parser(argc, argv);
34+
35+
//Read in AllInOne json config
36+
pt::ptree main_tree;
37+
pt::read_json(options.config, main_tree);
38+
39+
pt::ptree alignments = main_tree.get_child("alignments");
40+
pt::ptree validation = main_tree.get_child("validation");
41+
42+
TString filesAndLabels;
43+
for (const auto& childTree : alignments) {
44+
// Print node name and its attributes
45+
// std::cout << "Node: " << childTree.first << std::endl;
46+
// for (const auto& attr : childTree.second) {
47+
// std::cout << " Attribute: " << attr.first << " = " << attr.second.data() << std::endl;
48+
// }
49+
50+
std::string file = childTree.second.get<string>("file");
51+
std::cout << file << std::endl;
52+
std::cout << childTree.second.get<string>("title") << std::endl;
53+
54+
// Check if the file contains "/eos/cms/" and add the prefix accordingly
55+
std::string prefixToAdd = file.find("/eos/cms/") != std::string::npos ? "root://eoscms.cern.ch/" : "";
56+
std::string toAdd = prefixToAdd + file + "/GenericValidation.root=" + childTree.second.get<string>("title") + ",";
57+
filesAndLabels += toAdd;
58+
}
59+
60+
if (filesAndLabels.Length() > 0) {
61+
filesAndLabels.Remove(filesAndLabels.Length() - 1); // Remove the last character
62+
}
63+
64+
std::cout << "filesAndLabels: " << filesAndLabels << std::endl;
65+
66+
loopAndPlot(filesAndLabels);
67+
68+
return EXIT_SUCCESS;
69+
}
70+
71+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
72+
int main(int argc, char* argv[]) { return exceptions<merge>(argc, argv); }
73+
#endif

Alignment/OfflineValidation/plugins/GeneralPurposeVertexAnalyzer.cc

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,50 @@
5252

5353
using reco::TrackCollection;
5454

55+
namespace gpVertexAnalyzer {
56+
void setBinLog(TAxis *axis) {
57+
int bins = axis->GetNbins();
58+
float from = axis->GetXmin();
59+
float to = axis->GetXmax();
60+
float width = (to - from) / bins;
61+
std::vector<float> new_bins(bins + 1, 0);
62+
for (int i = 0; i <= bins; i++) {
63+
new_bins[i] = TMath::Power(10, from + i * width);
64+
}
65+
axis->Set(bins, new_bins.data());
66+
}
67+
68+
void setBinLogX(TH1 *h) {
69+
TAxis *axis = h->GetXaxis();
70+
setBinLog(axis);
71+
}
72+
73+
void setBinLogY(TH1 *h) {
74+
TAxis *axis = h->GetYaxis();
75+
setBinLog(axis);
76+
}
77+
78+
template <typename... Args>
79+
TProfile *makeProfileIfLog(const edm::Service<TFileService> &fs, bool logx, bool logy, Args &&...args) {
80+
auto prof = fs->make<TProfile>(std::forward<Args>(args)...);
81+
if (logx)
82+
setBinLogX(prof);
83+
if (logy)
84+
setBinLogY(prof);
85+
return prof;
86+
}
87+
88+
template <typename... Args>
89+
TH1D *makeTH1IfLog(const edm::Service<TFileService> &fs, bool logx, bool logy, Args &&...args) {
90+
auto h1 = fs->make<TH1D>(std::forward<Args>(args)...);
91+
if (logx)
92+
setBinLogX(h1);
93+
if (logy)
94+
setBinLogY(h1);
95+
return h1;
96+
}
97+
} // namespace gpVertexAnalyzer
98+
5599
class GeneralPurposeVertexAnalyzer : public edm::one::EDAnalyzer<edm::one::SharedResources> {
56100
public:
57101
explicit GeneralPurposeVertexAnalyzer(const edm::ParameterSet &);
@@ -73,9 +117,9 @@ class GeneralPurposeVertexAnalyzer : public edm::one::EDAnalyzer<edm::one::Share
73117
struct IPMonitoring {
74118
std::string varname_;
75119
float pTcut_;
76-
TH1D *IP_, *IPErr_;
77-
TProfile *IPVsPhi_, *IPVsEta_;
78-
TProfile *IPErrVsPhi_, *IPErrVsEta_;
120+
TH1D *IP_, *IPErr_, *IPPull_;
121+
TProfile *IPVsPhi_, *IPVsEta_, *IPVsPt_;
122+
TProfile *IPErrVsPhi_, *IPErrVsEta_, *IPErrVsPt_;
79123
TProfile2D *IPVsEtaVsPhi_, *IPErrVsEtaVsPhi_;
80124

81125
void bookIPMonitor(const edm::ParameterSet &, const edm::Service<TFileService> fs);
@@ -128,7 +172,7 @@ class GeneralPurposeVertexAnalyzer : public edm::one::EDAnalyzer<edm::one::Share
128172
TH1D *type[2];
129173
TH1D *bsX, *bsY, *bsZ, *bsSigmaZ, *bsDxdz, *bsDydz, *bsBeamWidthX, *bsBeamWidthY, *bsType;
130174

131-
TH1D *sumpt, *ntracks, *weight, *chi2ndf, *chi2prob;
175+
TH1D *trackpt, *sumpt, *ntracks, *weight, *chi2ndf, *chi2prob;
132176
TH1D *dxy2;
133177
TH1D *phi_pt1, *eta_pt1;
134178
TH1D *phi_pt10, *eta_pt10;
@@ -157,6 +201,10 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
157201
double EtaMin = config.getParameter<double>("EtaMin");
158202
double EtaMax = config.getParameter<double>("EtaMax");
159203

204+
int PtBin = config.getParameter<int>("PtBin");
205+
double PtMin = config.getParameter<double>("PtMin") * pTcut_;
206+
double PtMax = config.getParameter<double>("PtMax") * pTcut_;
207+
160208
IP_ = fs->make<TH1D>(fmt::format("d{}_pt{}", varname_, pTcut_).c_str(),
161209
fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} (#mum)", pTcut_, varname_).c_str(),
162210
VarBin,
@@ -169,6 +217,13 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
169217
0.,
170218
(varname_.find("xy") != std::string::npos) ? 2000. : 10000.);
171219

220+
IPPull_ = fs->make<TH1D>(
221+
fmt::format("d{}Pull_pt{}", varname_, pTcut_).c_str(),
222+
fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}}/#sigma_{{d_{{{}}}}}", pTcut_, varname_, varname_).c_str(),
223+
100,
224+
-5.,
225+
5.);
226+
172227
IPVsPhi_ =
173228
fs->make<TProfile>(fmt::format("d{}VsPhi_pt{}", varname_, pTcut_).c_str(),
174229
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} VS track #phi", pTcut_, varname_).c_str(),
@@ -193,6 +248,21 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
193248
IPVsEta_->SetXTitle("PV track (p_{T} > 1 GeV) #eta");
194249
IPVsEta_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} (#mum)", pTcut_, varname_).c_str());
195250

251+
IPVsPt_ = gpVertexAnalyzer::makeProfileIfLog(
252+
fs,
253+
true, /* x-axis */
254+
false, /* y-axis */
255+
fmt::format("d{}VsPt_pt{}", varname_, pTcut_).c_str(),
256+
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} VS track p_{{T}}", pTcut_, varname_).c_str(),
257+
PtBin,
258+
log10(PtMin),
259+
log10(PtMax),
260+
VarMin,
261+
VarMax,
262+
"");
263+
IPVsPt_->SetXTitle("PV track (p_{T} > 1 GeV) p_{T} [GeV]");
264+
IPVsPt_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} (#mum)", pTcut_, varname_).c_str());
265+
196266
IPErrVsPhi_ =
197267
fs->make<TProfile>(fmt::format("d{}ErrVsPhi_pt{}", varname_, pTcut_).c_str(),
198268
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} error VS track #phi", pTcut_, varname_).c_str(),
@@ -217,6 +287,21 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
217287
IPErrVsEta_->SetXTitle("PV track (p_{T} > 1 GeV) #eta");
218288
IPErrVsEta_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} error (#mum)", pTcut_, varname_).c_str());
219289

290+
IPErrVsPt_ = gpVertexAnalyzer::makeProfileIfLog(
291+
fs,
292+
true, /* x-axis */
293+
false, /* y-axis */
294+
fmt::format("d{}ErrVsPt_pt{}", varname_, pTcut_).c_str(),
295+
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} error VS track p_{{T}}", pTcut_, varname_).c_str(),
296+
PtBin,
297+
log10(PtMin),
298+
log10(PtMax),
299+
VarMin,
300+
VarMax,
301+
"");
302+
IPErrVsPt_->SetXTitle("PV track (p_{T} > 1 GeV) p_{T} [GeV]");
303+
IPErrVsPt_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} error (#mum)", pTcut_, varname_).c_str());
304+
220305
IPVsEtaVsPhi_ = fs->make<TProfile2D>(
221306
fmt::format("d{}VsEtaVsPhi_pt{}", varname_, pTcut_).c_str(),
222307
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} VS track #eta VS track #phi", pTcut_, varname_).c_str(),
@@ -294,6 +379,7 @@ GeneralPurposeVertexAnalyzer::GeneralPurposeVertexAnalyzer(const edm::ParameterS
294379
bsBeamWidthX(nullptr),
295380
bsBeamWidthY(nullptr),
296381
bsType(nullptr),
382+
trackpt(nullptr),
297383
sumpt(nullptr),
298384
ntracks(nullptr),
299385
weight(nullptr),
@@ -411,6 +497,8 @@ void GeneralPurposeVertexAnalyzer::pvTracksPlots(const reco::Vertex &v) {
411497
}
412498

413499
const float pt = t->pt();
500+
trackpt->Fill(pt);
501+
414502
if (pt < 1.f) {
415503
continue;
416504
}
@@ -435,22 +523,28 @@ void GeneralPurposeVertexAnalyzer::pvTracksPlots(const reco::Vertex &v) {
435523
phi_pt1->Fill(phi);
436524
eta_pt1->Fill(eta);
437525

526+
// dxy pT>1
527+
438528
dxy_pt1.IP_->Fill(Dxy);
439529
dxy_pt1.IPVsPhi_->Fill(phi, Dxy);
440530
dxy_pt1.IPVsEta_->Fill(eta, Dxy);
441531
dxy_pt1.IPVsEtaVsPhi_->Fill(eta, phi, Dxy);
442532

443533
dxy_pt1.IPErr_->Fill(DxyErr);
534+
dxy_pt1.IPPull_->Fill(Dxy / DxyErr);
444535
dxy_pt1.IPErrVsPhi_->Fill(phi, DxyErr);
445536
dxy_pt1.IPErrVsEta_->Fill(eta, DxyErr);
446537
dxy_pt1.IPErrVsEtaVsPhi_->Fill(eta, phi, DxyErr);
447538

539+
// dz pT>1
540+
448541
dz_pt1.IP_->Fill(Dz);
449542
dz_pt1.IPVsPhi_->Fill(phi, Dz);
450543
dz_pt1.IPVsEta_->Fill(eta, Dz);
451544
dz_pt1.IPVsEtaVsPhi_->Fill(eta, phi, Dz);
452545

453546
dz_pt1.IPErr_->Fill(DzErr);
547+
dz_pt1.IPPull_->Fill(Dz / DzErr);
454548
dz_pt1.IPErrVsPhi_->Fill(phi, DzErr);
455549
dz_pt1.IPErrVsEta_->Fill(eta, DzErr);
456550
dz_pt1.IPErrVsEtaVsPhi_->Fill(eta, phi, DzErr);
@@ -459,22 +553,28 @@ void GeneralPurposeVertexAnalyzer::pvTracksPlots(const reco::Vertex &v) {
459553
phi_pt10->Fill(phi);
460554
eta_pt10->Fill(eta);
461555

556+
// dxy pT>10
557+
462558
dxy_pt10.IP_->Fill(Dxy);
463559
dxy_pt10.IPVsPhi_->Fill(phi, Dxy);
464560
dxy_pt10.IPVsEta_->Fill(eta, Dxy);
465561
dxy_pt10.IPVsEtaVsPhi_->Fill(eta, phi, Dxy);
466562

467563
dxy_pt10.IPErr_->Fill(DxyErr);
564+
dxy_pt10.IPPull_->Fill(Dxy / DxyErr);
468565
dxy_pt10.IPErrVsPhi_->Fill(phi, DxyErr);
469566
dxy_pt10.IPErrVsEta_->Fill(eta, DxyErr);
470567
dxy_pt10.IPErrVsEtaVsPhi_->Fill(eta, phi, DxyErr);
471568

569+
// dz pT>10
570+
472571
dz_pt10.IP_->Fill(Dz);
473572
dz_pt10.IPVsPhi_->Fill(phi, Dz);
474573
dz_pt10.IPVsEta_->Fill(eta, Dz);
475574
dz_pt10.IPVsEtaVsPhi_->Fill(eta, phi, Dz);
476575

477576
dz_pt10.IPErr_->Fill(DzErr);
577+
dz_pt10.IPPull_->Fill(Dz / DzErr);
478578
dz_pt10.IPErrVsPhi_->Fill(phi, DzErr);
479579
dz_pt10.IPErrVsEta_->Fill(eta, DzErr);
480580
dz_pt10.IPErrVsEtaVsPhi_->Fill(eta, phi, DzErr);
@@ -649,6 +749,8 @@ void GeneralPurposeVertexAnalyzer::beginJob() {
649749

650750
dxy2 = book<TH1D>("dxyzoom", fmt::sprintf("%s d_{xy} (#mum)", s_1).c_str(), dxyBin_, dxyMin_ / 5., dxyMax_ / 5.);
651751

752+
trackpt = gpVertexAnalyzer::makeTH1IfLog(
753+
fs_, true, false, "pt_track", "PV tracks p_{T};PV tracks p_{T} [GeV];#tracks", 49, log10(1.), log10(50.));
652754
phi_pt1 =
653755
book<TH1D>("phi_pt1", fmt::sprintf("%s #phi; PV tracks #phi;#tracks", s_1).c_str(), phiBin_, phiMin_, phiMax_);
654756
eta_pt1 =
@@ -701,6 +803,9 @@ void GeneralPurposeVertexAnalyzer::fillDescriptions(edm::ConfigurationDescriptio
701803
desc.add<int>("EtaBin2D", 8);
702804
desc.add<double>("EtaMin", -2.7);
703805
desc.add<double>("EtaMax", 2.7);
806+
desc.add<int>("PtBin", 49);
807+
desc.add<double>("PtMin", 1.);
808+
desc.add<double>("PtMax", 50.);
704809
descriptions.addWithDefaultLabel(desc);
705810
}
706811

0 commit comments

Comments
 (0)