Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a Generic validation tool for dataset validation in the alignment all-in-one tool #47055

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Alignment/OfflineValidation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,11 @@ For details read [`README_JetHT.md`](https://github.com/cms-sw/cmssw/blob/master
## MTS validation
For details read [`README_MTS.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_MTS.md)

## Pixel BaryCenter
For details read [`README_MTS.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_PixBary.md)

## Generic validation (dataset validation)
For details read [`README_Generic.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_Generic.md)

## General info about IOV/run arguments
For details read [`README_IOV.md`](https://github.com/cms-sw/cmssw/blob/master/Alignment/OfflineValidation/README_IOV.md)
39 changes: 39 additions & 0 deletions Alignment/OfflineValidation/README_Generic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Generic Validation

## General info
```
validations:
Generic:
<step_type>:
<step_name>:
<options>
```

Generic validation runs in 2 possible types of steps:
- single (validation analysis by GenericV_cfg.py)
- (optional) merge (GenericVmerge macro)
Step name is and arbitrary string which will be used as a reference for consequent steps.
Merge job awill only start if all corresponding single jobs are done.
Merge jobs can run in parallel.

## Single Generic jobs
Single jobs can be specified per run (IoV as well). In case of MC, IoV is specified to arbitrary 1.

Variable | Default value | Explanation/Options
-------- | ------------- | --------------------
IOV | None | List of IOVs/runs defined by integer value. IOV 1 is reserved for MC.
Alignments | None | List of alignments. Will create separate directory for each.
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).
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`
maxevents | 1 | Maximum number of events before cmsRun terminates.
trackcollection | "generalTracks" | Track collection to be specified here, e.g. "ALCARECOTkAlMuonIsolated" or "ALCARECOTkAlMinBias" ...
tthrbuilder | "WithAngleAndTemplate" | Specify TTRH Builder

## Merge Generic job
Its name do not need to match single job name but option `singles` must list all single jobs to be merged.
Generic merged plot style can be adjusted from global plotting style.

Variable | Default value | Explanation/Options
-------- | ------------- | --------------------
singles | None | List of strings matching single job names to be merged in one plot.
customrighttitle | "" | Top right title. Reserved word "IOV" will be replaced for given IOV/run in the list.
1 change: 1 addition & 0 deletions Alignment/OfflineValidation/bin/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<bin name="SplitVmerge" file="SplitVmerge.cc,Options.cc" />
<bin name="Zmumumerge" file="Zmumumerge.cc,Options.cc" />
<bin name="DiMuonVmerge" file="DiMuonVmerge.cc,Options.cc" />
<bin name="GenericVmerge" file="GenericVmerge.cc,Options.cc" />
<bin name="MTSmerge" file="MTSmerge.cc,Options.cc" />
<bin name="haddws" file="haddws.C" />
<bin name="jetHtPlotter" file="jetHtPlotter.cc,JetHtPlotConfiguration.cc,Options.cc" />
73 changes: 73 additions & 0 deletions Alignment/OfflineValidation/bin/GenericVmerge.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <cstdlib>
#include <string>
#include <iostream>
#include <numeric>
#include <functional>

#include "exceptions.h"
#include "toolbox.h"
#include "Options.h"

#include "boost/filesystem.hpp"
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include "boost/optional.hpp"

#include "TString.h"
#include "TASImage.h"
#include "TGraph.h"

#include "Alignment/OfflineValidation/macros/loopAndPlot.C"
#include "Alignment/OfflineValidation/interface/TkAlStyle.h"

using namespace std;
using namespace AllInOneConfig;

namespace pt = boost::property_tree;

int merge(int argc, char* argv[]) {
// parse the command line

Options options;
options.helper(argc, argv);
options.parser(argc, argv);

//Read in AllInOne json config
pt::ptree main_tree;
pt::read_json(options.config, main_tree);

pt::ptree alignments = main_tree.get_child("alignments");
pt::ptree validation = main_tree.get_child("validation");

TString filesAndLabels;
for (const auto& childTree : alignments) {
// Print node name and its attributes
// std::cout << "Node: " << childTree.first << std::endl;
// for (const auto& attr : childTree.second) {
// std::cout << " Attribute: " << attr.first << " = " << attr.second.data() << std::endl;
// }

std::string file = childTree.second.get<string>("file");
std::cout << file << std::endl;
std::cout << childTree.second.get<string>("title") << std::endl;

// Check if the file contains "/eos/cms/" and add the prefix accordingly
std::string prefixToAdd = file.find("/eos/cms/") != std::string::npos ? "root://eoscms.cern.ch/" : "";
std::string toAdd = prefixToAdd + file + "/GenericValidation.root=" + childTree.second.get<string>("title") + ",";
filesAndLabels += toAdd;
}

if (filesAndLabels.Length() > 0) {
filesAndLabels.Remove(filesAndLabels.Length() - 1); // Remove the last character
}

std::cout << "filesAndLabels: " << filesAndLabels << std::endl;

loopAndPlot(filesAndLabels);

return EXIT_SUCCESS;
}

#ifndef DOXYGEN_SHOULD_SKIP_THIS
int main(int argc, char* argv[]) { return exceptions<merge>(argc, argv); }
#endif
113 changes: 109 additions & 4 deletions Alignment/OfflineValidation/plugins/GeneralPurposeVertexAnalyzer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,50 @@

using reco::TrackCollection;

namespace gpVertexAnalyzer {
void setBinLog(TAxis *axis) {
int bins = axis->GetNbins();
float from = axis->GetXmin();
float to = axis->GetXmax();
float width = (to - from) / bins;
std::vector<float> new_bins(bins + 1, 0);
for (int i = 0; i <= bins; i++) {
new_bins[i] = TMath::Power(10, from + i * width);
}
axis->Set(bins, new_bins.data());
}

void setBinLogX(TH1 *h) {
TAxis *axis = h->GetXaxis();
setBinLog(axis);
}

void setBinLogY(TH1 *h) {
TAxis *axis = h->GetYaxis();
setBinLog(axis);
}

template <typename... Args>
TProfile *makeProfileIfLog(const edm::Service<TFileService> &fs, bool logx, bool logy, Args &&...args) {
auto prof = fs->make<TProfile>(std::forward<Args>(args)...);
if (logx)
setBinLogX(prof);
if (logy)
setBinLogY(prof);
return prof;
}

template <typename... Args>
TH1D *makeTH1IfLog(const edm::Service<TFileService> &fs, bool logx, bool logy, Args &&...args) {
auto h1 = fs->make<TH1D>(std::forward<Args>(args)...);
if (logx)
setBinLogX(h1);
if (logy)
setBinLogY(h1);
return h1;
}
} // namespace gpVertexAnalyzer

class GeneralPurposeVertexAnalyzer : public edm::one::EDAnalyzer<edm::one::SharedResources> {
public:
explicit GeneralPurposeVertexAnalyzer(const edm::ParameterSet &);
Expand All @@ -73,9 +117,9 @@ class GeneralPurposeVertexAnalyzer : public edm::one::EDAnalyzer<edm::one::Share
struct IPMonitoring {
std::string varname_;
float pTcut_;
TH1D *IP_, *IPErr_;
TProfile *IPVsPhi_, *IPVsEta_;
TProfile *IPErrVsPhi_, *IPErrVsEta_;
TH1D *IP_, *IPErr_, *IPPull_;
TProfile *IPVsPhi_, *IPVsEta_, *IPVsPt_;
TProfile *IPErrVsPhi_, *IPErrVsEta_, *IPErrVsPt_;
TProfile2D *IPVsEtaVsPhi_, *IPErrVsEtaVsPhi_;

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

TH1D *sumpt, *ntracks, *weight, *chi2ndf, *chi2prob;
TH1D *trackpt, *sumpt, *ntracks, *weight, *chi2ndf, *chi2prob;
TH1D *dxy2;
TH1D *phi_pt1, *eta_pt1;
TH1D *phi_pt10, *eta_pt10;
Expand Down Expand Up @@ -157,6 +201,10 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
double EtaMin = config.getParameter<double>("EtaMin");
double EtaMax = config.getParameter<double>("EtaMax");

int PtBin = config.getParameter<int>("PtBin");
double PtMin = config.getParameter<double>("PtMin") * pTcut_;
double PtMax = config.getParameter<double>("PtMax") * pTcut_;

IP_ = fs->make<TH1D>(fmt::format("d{}_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} (#mum)", pTcut_, varname_).c_str(),
VarBin,
Expand All @@ -169,6 +217,13 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
0.,
(varname_.find("xy") != std::string::npos) ? 2000. : 10000.);

IPPull_ = fs->make<TH1D>(
fmt::format("d{}Pull_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}}/#sigma_{{d_{{{}}}}}", pTcut_, varname_, varname_).c_str(),
100,
-5.,
5.);

IPVsPhi_ =
fs->make<TProfile>(fmt::format("d{}VsPhi_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} VS track #phi", pTcut_, varname_).c_str(),
Expand All @@ -193,6 +248,21 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
IPVsEta_->SetXTitle("PV track (p_{T} > 1 GeV) #eta");
IPVsEta_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} (#mum)", pTcut_, varname_).c_str());

IPVsPt_ = gpVertexAnalyzer::makeProfileIfLog(
fs,
true, /* x-axis */
false, /* y-axis */
fmt::format("d{}VsPt_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} VS track p_{{T}}", pTcut_, varname_).c_str(),
PtBin,
log10(PtMin),
log10(PtMax),
VarMin,
VarMax,
"");
IPVsPt_->SetXTitle("PV track (p_{T} > 1 GeV) p_{T} [GeV]");
IPVsPt_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} (#mum)", pTcut_, varname_).c_str());

IPErrVsPhi_ =
fs->make<TProfile>(fmt::format("d{}ErrVsPhi_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} error VS track #phi", pTcut_, varname_).c_str(),
Expand All @@ -217,6 +287,21 @@ void GeneralPurposeVertexAnalyzer::IPMonitoring::bookIPMonitor(const edm::Parame
IPErrVsEta_->SetXTitle("PV track (p_{T} > 1 GeV) #eta");
IPErrVsEta_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} error (#mum)", pTcut_, varname_).c_str());

IPErrVsPt_ = gpVertexAnalyzer::makeProfileIfLog(
fs,
true, /* x-axis */
false, /* y-axis */
fmt::format("d{}ErrVsPt_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} error VS track p_{{T}}", pTcut_, varname_).c_str(),
PtBin,
log10(PtMin),
log10(PtMax),
VarMin,
VarMax,
"");
IPErrVsPt_->SetXTitle("PV track (p_{T} > 1 GeV) p_{T} [GeV]");
IPErrVsPt_->SetYTitle(fmt::format("PV tracks (p_{{T}} > {} GeV) d_{{{}}} error (#mum)", pTcut_, varname_).c_str());

IPVsEtaVsPhi_ = fs->make<TProfile2D>(
fmt::format("d{}VsEtaVsPhi_pt{}", varname_, pTcut_).c_str(),
fmt::format("PV tracks (p_{{T}} > {}) d_{{{}}} VS track #eta VS track #phi", pTcut_, varname_).c_str(),
Expand Down Expand Up @@ -294,6 +379,7 @@ GeneralPurposeVertexAnalyzer::GeneralPurposeVertexAnalyzer(const edm::ParameterS
bsBeamWidthX(nullptr),
bsBeamWidthY(nullptr),
bsType(nullptr),
trackpt(nullptr),
sumpt(nullptr),
ntracks(nullptr),
weight(nullptr),
Expand Down Expand Up @@ -411,6 +497,8 @@ void GeneralPurposeVertexAnalyzer::pvTracksPlots(const reco::Vertex &v) {
}

const float pt = t->pt();
trackpt->Fill(pt);

if (pt < 1.f) {
continue;
}
Expand All @@ -435,22 +523,28 @@ void GeneralPurposeVertexAnalyzer::pvTracksPlots(const reco::Vertex &v) {
phi_pt1->Fill(phi);
eta_pt1->Fill(eta);

// dxy pT>1

dxy_pt1.IP_->Fill(Dxy);
dxy_pt1.IPVsPhi_->Fill(phi, Dxy);
dxy_pt1.IPVsEta_->Fill(eta, Dxy);
dxy_pt1.IPVsEtaVsPhi_->Fill(eta, phi, Dxy);

dxy_pt1.IPErr_->Fill(DxyErr);
dxy_pt1.IPPull_->Fill(Dxy / DxyErr);
dxy_pt1.IPErrVsPhi_->Fill(phi, DxyErr);
dxy_pt1.IPErrVsEta_->Fill(eta, DxyErr);
dxy_pt1.IPErrVsEtaVsPhi_->Fill(eta, phi, DxyErr);

// dz pT>1

dz_pt1.IP_->Fill(Dz);
dz_pt1.IPVsPhi_->Fill(phi, Dz);
dz_pt1.IPVsEta_->Fill(eta, Dz);
dz_pt1.IPVsEtaVsPhi_->Fill(eta, phi, Dz);

dz_pt1.IPErr_->Fill(DzErr);
dz_pt1.IPPull_->Fill(Dz / DzErr);
dz_pt1.IPErrVsPhi_->Fill(phi, DzErr);
dz_pt1.IPErrVsEta_->Fill(eta, DzErr);
dz_pt1.IPErrVsEtaVsPhi_->Fill(eta, phi, DzErr);
Expand All @@ -459,22 +553,28 @@ void GeneralPurposeVertexAnalyzer::pvTracksPlots(const reco::Vertex &v) {
phi_pt10->Fill(phi);
eta_pt10->Fill(eta);

// dxy pT>10

dxy_pt10.IP_->Fill(Dxy);
dxy_pt10.IPVsPhi_->Fill(phi, Dxy);
dxy_pt10.IPVsEta_->Fill(eta, Dxy);
dxy_pt10.IPVsEtaVsPhi_->Fill(eta, phi, Dxy);

dxy_pt10.IPErr_->Fill(DxyErr);
dxy_pt10.IPPull_->Fill(Dxy / DxyErr);
dxy_pt10.IPErrVsPhi_->Fill(phi, DxyErr);
dxy_pt10.IPErrVsEta_->Fill(eta, DxyErr);
dxy_pt10.IPErrVsEtaVsPhi_->Fill(eta, phi, DxyErr);

// dz pT>10

dz_pt10.IP_->Fill(Dz);
dz_pt10.IPVsPhi_->Fill(phi, Dz);
dz_pt10.IPVsEta_->Fill(eta, Dz);
dz_pt10.IPVsEtaVsPhi_->Fill(eta, phi, Dz);

dz_pt10.IPErr_->Fill(DzErr);
dz_pt10.IPPull_->Fill(Dz / DzErr);
dz_pt10.IPErrVsPhi_->Fill(phi, DzErr);
dz_pt10.IPErrVsEta_->Fill(eta, DzErr);
dz_pt10.IPErrVsEtaVsPhi_->Fill(eta, phi, DzErr);
Expand Down Expand Up @@ -649,6 +749,8 @@ void GeneralPurposeVertexAnalyzer::beginJob() {

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

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

Expand Down
Loading