File indexing completed on 2024-04-12 23:01:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <memory>
0019 #include <utility>
0020
0021
0022 #include "FWCore/Framework/interface/Frameworkfwd.h"
0023 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0024 #include "FWCore/Framework/interface/Event.h"
0025 #include "FWCore/Framework/interface/MakerMacros.h"
0026 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0027 #include "FWCore/Utilities/interface/InputTag.h"
0028
0029
0030 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0031 #include "DataFormats/MuonReco/interface/Muon.h"
0032 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0033
0034
0035 #include "Alignment/OfflineValidation/interface/DiLeptonVertexHelpers.h"
0036 #include "DataFormats/Math/interface/deltaR.h"
0037 #include "TLorentzVector.h"
0038
0039
0040 #include "DataFormats/TrackReco/interface/Track.h"
0041 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0042 #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
0043 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h"
0044 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0045 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0046
0047
0048 #include "RecoVertex/VertexTools/interface/VertexDistanceXY.h"
0049 #include "RecoVertex/VertexTools/interface/VertexDistance3D.h"
0050 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0051 #include "FWCore/ServiceRegistry/interface/Service.h"
0052
0053
0054 #include "TrackingTools/IPTools/interface/IPTools.h"
0055
0056
0057 #include "TH1F.h"
0058 #include "TH2F.h"
0059
0060
0061
0062
0063
0064
0065
0066 class DiMuonVertexValidation : public edm::one::EDAnalyzer<edm::one::SharedResources> {
0067 public:
0068 explicit DiMuonVertexValidation(const edm::ParameterSet&);
0069 ~DiMuonVertexValidation() override;
0070
0071 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0072
0073 private:
0074 void beginJob() override;
0075 void analyze(const edm::Event&, const edm::EventSetup&) override;
0076 const reco::Vertex* findClosestVertex(const TransientVertex aTransVtx, const reco::VertexCollection* vertices) const;
0077 void endJob() override;
0078
0079
0080 DiLeptonHelp::Counts myCounts;
0081
0082 const std::string motherName_;
0083 const bool useReco_;
0084 const bool useClosestVertex_;
0085 std::pair<float, float> massLimits_;
0086 std::vector<double> pTthresholds_;
0087 const float maxSVdist_;
0088
0089
0090 const edm::ParameterSet CosPhiConfiguration_;
0091 const edm::ParameterSet CosPhi3DConfiguration_;
0092 const edm::ParameterSet VtxProbConfiguration_;
0093 const edm::ParameterSet VtxDistConfiguration_;
0094 const edm::ParameterSet VtxDist3DConfiguration_;
0095 const edm::ParameterSet VtxDistSigConfiguration_;
0096 const edm::ParameterSet VtxDist3DSigConfiguration_;
0097 const edm::ParameterSet DiMuMassConfiguration_;
0098
0099
0100 TH1F* hSVProb_;
0101 TH1F* hSVChi2_;
0102 TH1F* hSVNormChi2_;
0103
0104 TH1F* hSVDist_;
0105 TH1F* hSVDistErr_;
0106 TH1F* hSVDistSig_;
0107 TH1F* hSVCompatibility_;
0108
0109 TH1F* hSVDist3D_;
0110 TH1F* hSVDist3DErr_;
0111 TH1F* hSVDist3DSig_;
0112 TH1F* hSVCompatibility3D_;
0113
0114 TH1F* hCosPhi_;
0115 TH1F* hCosPhi3D_;
0116 TH1F* hCosPhiInv_;
0117 TH1F* hCosPhiInv3D_;
0118 TH1F* hCosPhiUnbalance_;
0119 TH1F* hCosPhi3DUnbalance_;
0120
0121 TH1F* hInvMass_;
0122 TH1F* hTrackInvMass_;
0123
0124 TH1F* hCutFlow_;
0125
0126
0127 TH1F* hdxy_;
0128 TH1F* hdz_;
0129 TH1F* hdxyErr_;
0130 TH1F* hdzErr_;
0131 TH1F* hIP2d_;
0132 TH1F* hIP3d_;
0133 TH1F* hIP2dsig_;
0134 TH1F* hIP3dsig_;
0135
0136
0137
0138 DiLeptonHelp::PlotsVsKinematics CosPhiPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0139 DiLeptonHelp::PlotsVsKinematics CosPhi3DPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0140 DiLeptonHelp::PlotsVsKinematics VtxProbPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0141 DiLeptonHelp::PlotsVsKinematics VtxDistPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0142 DiLeptonHelp::PlotsVsKinematics VtxDist3DPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0143 DiLeptonHelp::PlotsVsKinematics VtxDistSigPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0144 DiLeptonHelp::PlotsVsKinematics VtxDist3DSigPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0145 DiLeptonHelp::PlotsVsKinematics ZMassPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0146
0147
0148 DiLeptonHelp::PlotsVsDiLeptonRegion CosPhi3DInEtaBins = DiLeptonHelp::PlotsVsDiLeptonRegion(1.5);
0149 DiLeptonHelp::PlotsVsDiLeptonRegion InvMassInEtaBins = DiLeptonHelp::PlotsVsDiLeptonRegion(1.5);
0150
0151 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> ttbESToken_;
0152
0153
0154 edm::EDGetTokenT<reco::TrackCollection> tracksToken_;
0155
0156 const edm::EDGetTokenT<reco::VertexCollection> vertexToken_;
0157
0158
0159 edm::EDGetTokenT<reco::MuonCollection> muonsToken_;
0160 edm::EDGetTokenT<reco::TrackCollection> alcaRecoToken_;
0161 };
0162
0163
0164
0165
0166
0167 static constexpr float cmToum = 10e4;
0168 static constexpr float mumass2 = 0.105658367 * 0.105658367;
0169
0170
0171
0172
0173
0174
0175
0176
0177 DiMuonVertexValidation::DiMuonVertexValidation(const edm::ParameterSet& iConfig)
0178 : motherName_(iConfig.getParameter<std::string>("decayMotherName")),
0179 useReco_(iConfig.getParameter<bool>("useReco")),
0180 useClosestVertex_(iConfig.getParameter<bool>("useClosestVertex")),
0181 pTthresholds_(iConfig.getParameter<std::vector<double>>("pTThresholds")),
0182 maxSVdist_(iConfig.getParameter<double>("maxSVdist")),
0183 CosPhiConfiguration_(iConfig.getParameter<edm::ParameterSet>("CosPhiConfig")),
0184 CosPhi3DConfiguration_(iConfig.getParameter<edm::ParameterSet>("CosPhi3DConfig")),
0185 VtxProbConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxProbConfig")),
0186 VtxDistConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDistConfig")),
0187 VtxDist3DConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDist3DConfig")),
0188 VtxDistSigConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDistSigConfig")),
0189 VtxDist3DSigConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDist3DSigConfig")),
0190 DiMuMassConfiguration_(iConfig.getParameter<edm::ParameterSet>("DiMuMassConfig")),
0191 ttbESToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))),
0192 vertexToken_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))) {
0193 if (useReco_) {
0194 tracksToken_ = consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"));
0195 muonsToken_ = consumes<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"));
0196 } else {
0197 alcaRecoToken_ = consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("muonTracks"));
0198 }
0199
0200 usesResource(TFileService::kSharedResource);
0201
0202
0203 std::sort(pTthresholds_.begin(), pTthresholds_.end(), [](const double& lhs, const double& rhs) { return lhs > rhs; });
0204
0205 edm::LogInfo("DiMuonVertexValidation") << __FUNCTION__;
0206 for (const auto& thr : pTthresholds_) {
0207 edm::LogInfo("DiMuonVertexValidation") << " Threshold: " << thr << " ";
0208 }
0209 edm::LogInfo("DiMuonVertexValidation") << "Max SV distance: " << maxSVdist_ << " ";
0210
0211
0212 if (motherName_.find('Z') != std::string::npos) {
0213 massLimits_ = std::make_pair(50., 120);
0214 } else if (motherName_.find("J/#psi") != std::string::npos) {
0215 massLimits_ = std::make_pair(2.7, 3.4);
0216 } else if (motherName_.find("#Upsilon") != std::string::npos) {
0217 massLimits_ = std::make_pair(8.9, 9.9);
0218 } else {
0219 edm::LogError("DiMuonVertexValidation") << " unrecognized decay mother particle: " << motherName_
0220 << " setting the default for the Z->mm (50.,120.)" << std::endl;
0221 massLimits_ = std::make_pair(50., 120);
0222 }
0223 }
0224
0225 DiMuonVertexValidation::~DiMuonVertexValidation() = default;
0226
0227
0228
0229
0230
0231
0232 void DiMuonVertexValidation::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0233 using namespace edm;
0234
0235 myCounts.eventsTotal++;
0236
0237
0238 std::vector<const reco::Track*> myTracks;
0239
0240
0241 if (useReco_) {
0242
0243 std::vector<const reco::Muon*> myGoodMuonVector;
0244 for (const auto& muon : iEvent.get(muonsToken_)) {
0245 const reco::TrackRef t = muon.innerTrack();
0246 if (!t.isNull()) {
0247 if (t->quality(reco::TrackBase::highPurity)) {
0248 if (t->chi2() / t->ndof() <= 2.5 && t->numberOfValidHits() >= 5 &&
0249 t->hitPattern().numberOfValidPixelHits() >= 2 && t->quality(reco::TrackBase::highPurity))
0250 myGoodMuonVector.emplace_back(&muon);
0251 }
0252 }
0253 }
0254
0255 LogDebug("DiMuonVertexValidation") << "myGoodMuonVector size: " << myGoodMuonVector.size() << std::endl;
0256 std::sort(myGoodMuonVector.begin(), myGoodMuonVector.end(), [](const reco::Muon*& lhs, const reco::Muon*& rhs) {
0257 return lhs->pt() > rhs->pt();
0258 });
0259
0260
0261 for (const auto& muon : myGoodMuonVector) {
0262 LogDebug("DiMuonVertexValidation") << "pT: " << muon->pt() << " ";
0263 }
0264 LogDebug("DiMuonVertexValidation") << std::endl;
0265
0266
0267 if (myGoodMuonVector.size() < 2)
0268 return;
0269
0270 myCounts.eventsAfterMult++;
0271
0272 if ((myGoodMuonVector[0]->pt()) < pTthresholds_[0] || (myGoodMuonVector[1]->pt() < pTthresholds_[1]))
0273 return;
0274
0275 myCounts.eventsAfterPt++;
0276 myCounts.eventsAfterEta++;
0277
0278 if (myGoodMuonVector[0]->charge() * myGoodMuonVector[1]->charge() > 0)
0279 return;
0280
0281 const auto& m1 = myGoodMuonVector[1]->p4();
0282 const auto& m0 = myGoodMuonVector[0]->p4();
0283 const auto& mother = m0 + m1;
0284
0285 float invMass = mother.M();
0286 hInvMass_->Fill(invMass);
0287
0288
0289 std::vector<const reco::Muon*> theZMuonVector;
0290 theZMuonVector.reserve(2);
0291 theZMuonVector.emplace_back(myGoodMuonVector[1]);
0292 theZMuonVector.emplace_back(myGoodMuonVector[0]);
0293
0294
0295 unsigned int i = 0;
0296 for (const auto& muon : theZMuonVector) {
0297 i++;
0298 float minD = 1000.;
0299 const reco::Track* theMatch = nullptr;
0300 for (const auto& track : iEvent.get(tracksToken_)) {
0301 float D = ::deltaR(muon->eta(), muon->phi(), track.eta(), track.phi());
0302 if (D < minD) {
0303 minD = D;
0304 theMatch = &track;
0305 }
0306 }
0307 LogDebug("DiMuonVertexValidation") << "pushing new track: " << i << std::endl;
0308 myTracks.emplace_back(theMatch);
0309 }
0310 } else {
0311
0312 for (const auto& muon : iEvent.get(alcaRecoToken_)) {
0313 myTracks.emplace_back(&muon);
0314 }
0315 }
0316
0317 #ifdef EDM_ML_DEBUG
0318 for (const auto& track : myTracks) {
0319 edm::LogVerbatim("DiMuonVertexValidation") << __PRETTY_FUNCTION__ << " pT: " << track->pt() << " GeV"
0320 << " , pT error: " << track->ptError() << " GeV"
0321 << " , eta: " << track->eta() << " , phi: " << track->phi() << std::endl;
0322 }
0323 #endif
0324
0325 LogDebug("DiMuonVertexValidation") << "selected tracks: " << myTracks.size() << std::endl;
0326
0327 const TransientTrackBuilder* theB = &iSetup.getData(ttbESToken_);
0328 TransientVertex aTransientVertex;
0329 std::vector<reco::TransientTrack> tks;
0330
0331 if (myTracks.size() != 2)
0332 return;
0333
0334 const auto& t1 = myTracks[1]->momentum();
0335 const auto& t0 = myTracks[0]->momentum();
0336 const auto& ditrack = t1 + t0;
0337
0338 const auto& tplus = myTracks[0]->charge() > 0 ? myTracks[0] : myTracks[1];
0339 const auto& tminus = myTracks[0]->charge() < 0 ? myTracks[0] : myTracks[1];
0340
0341 TLorentzVector p4_tplus(tplus->px(), tplus->py(), tplus->pz(), sqrt((tplus->p() * tplus->p()) + mumass2));
0342 TLorentzVector p4_tminus(tminus->px(), tminus->py(), tminus->pz(), sqrt((tminus->p() * tminus->p()) + mumass2));
0343
0344 #ifdef EDM_ML_DEBUG
0345
0346 auto tLorentzVectorToString = [](const TLorentzVector& vector) {
0347 return std::to_string(vector.Px()) + " " + std::to_string(vector.Py()) + " " + std::to_string(vector.Pz()) + " " +
0348 std::to_string(vector.E());
0349 };
0350
0351 edm::LogVerbatim("DiMuonVertexValidation") << "mu+" << tLorentzVectorToString(p4_tplus) << std::endl;
0352 edm::LogVerbatim("DiMuonVertexValidation") << "mu-" << tLorentzVectorToString(p4_tminus) << std::endl;
0353 #endif
0354
0355 const auto& Zp4 = p4_tplus + p4_tminus;
0356 float track_invMass = Zp4.M();
0357 hTrackInvMass_->Fill(track_invMass);
0358
0359
0360 std::pair<TLorentzVector, TLorentzVector> tktk_p4 = std::make_pair(p4_tplus, p4_tminus);
0361
0362
0363 ZMassPlots.fillPlots(track_invMass, tktk_p4);
0364 InvMassInEtaBins.fillTH1Plots(track_invMass, tktk_p4);
0365
0366 math::XYZPoint ZpT(ditrack.x(), ditrack.y(), 0);
0367 math::XYZPoint Zp(ditrack.x(), ditrack.y(), ditrack.z());
0368
0369 for (const auto& track : myTracks) {
0370 reco::TransientTrack trajectory = theB->build(track);
0371 tks.push_back(trajectory);
0372 }
0373
0374 KalmanVertexFitter kalman(true);
0375 aTransientVertex = kalman.vertex(tks);
0376
0377 double SVProb = TMath::Prob(aTransientVertex.totalChiSquared(), (int)aTransientVertex.degreesOfFreedom());
0378
0379 LogDebug("DiMuonVertexValidation") << " vertex prob: " << SVProb << std::endl;
0380
0381 hSVProb_->Fill(SVProb);
0382 hSVChi2_->Fill(aTransientVertex.totalChiSquared());
0383 hSVNormChi2_->Fill(aTransientVertex.totalChiSquared() / (int)aTransientVertex.degreesOfFreedom());
0384
0385 LogDebug("DiMuonVertexValidation") << " vertex norm chi2: "
0386 << (aTransientVertex.totalChiSquared() / (int)aTransientVertex.degreesOfFreedom())
0387 << std::endl;
0388
0389 if (!aTransientVertex.isValid())
0390 return;
0391
0392 myCounts.eventsAfterVtx++;
0393
0394
0395 VtxProbPlots.fillPlots(SVProb, tktk_p4);
0396
0397 math::XYZPoint mainVtxPos(0, 0, 0);
0398 const reco::Vertex* theClosestVertex = nullptr;
0399
0400 edm::Handle<reco::VertexCollection> vertexHandle = iEvent.getHandle(vertexToken_);
0401 if (vertexHandle.isValid()) {
0402 const reco::VertexCollection* vertices = vertexHandle.product();
0403 theClosestVertex = this->findClosestVertex(aTransientVertex, vertices);
0404 } else {
0405 edm::LogWarning("DiMuonVertexMonitor") << "invalid vertex collection encountered Skipping event!";
0406 return;
0407 }
0408
0409 reco::Vertex theMainVertex;
0410 if (!useClosestVertex_ || theClosestVertex == nullptr) {
0411
0412 theMainVertex = vertexHandle.product()->front();
0413 } else {
0414 theMainVertex = *theClosestVertex;
0415 }
0416
0417 mainVtxPos.SetXYZ(theMainVertex.position().x(), theMainVertex.position().y(), theMainVertex.position().z());
0418 const math::XYZPoint myVertex(
0419 aTransientVertex.position().x(), aTransientVertex.position().y(), aTransientVertex.position().z());
0420 const math::XYZPoint deltaVtx(
0421 mainVtxPos.x() - myVertex.x(), mainVtxPos.y() - myVertex.y(), mainVtxPos.z() - myVertex.z());
0422
0423 #ifdef EDM_ML_DEBUG
0424 edm::LogVerbatim("DiMuonVertexValidation")
0425 << "mm vertex position:" << aTransientVertex.position().x() << "," << aTransientVertex.position().y() << ","
0426 << aTransientVertex.position().z();
0427
0428 edm::LogVerbatim("DiMuonVertexValidation") << "main vertex position:" << theMainVertex.position().x() << ","
0429 << theMainVertex.position().y() << "," << theMainVertex.position().z();
0430 #endif
0431
0432 if (theMainVertex.isValid()) {
0433
0434 for (const auto& track : myTracks) {
0435 hdxy_->Fill(track->dxy(mainVtxPos) * cmToum);
0436 hdz_->Fill(track->dz(mainVtxPos) * cmToum);
0437 hdxyErr_->Fill(track->dxyError() * cmToum);
0438 hdzErr_->Fill(track->dzError() * cmToum);
0439
0440 const auto& ttrk = theB->build(track);
0441 Global3DVector dir(track->px(), track->py(), track->pz());
0442 const auto& ip2d = IPTools::signedTransverseImpactParameter(ttrk, dir, theMainVertex);
0443 const auto& ip3d = IPTools::signedImpactParameter3D(ttrk, dir, theMainVertex);
0444
0445 hIP2d_->Fill(ip2d.second.value() * cmToum);
0446 hIP3d_->Fill(ip3d.second.value() * cmToum);
0447 hIP2dsig_->Fill(ip2d.second.significance());
0448 hIP3dsig_->Fill(ip3d.second.significance());
0449 }
0450
0451 LogDebug("DiMuonVertexValidation") << " after filling the IP histograms " << std::endl;
0452
0453
0454 VertexDistanceXY vertTool;
0455 double distance = vertTool.distance(aTransientVertex, theMainVertex).value();
0456 double dist_err = vertTool.distance(aTransientVertex, theMainVertex).error();
0457 float compatibility = 0.;
0458
0459 try {
0460 compatibility = vertTool.compatibility(aTransientVertex, theMainVertex);
0461 } catch (cms::Exception& er) {
0462 LogTrace("DiMuonVertexValidation") << "caught std::exception " << er.what() << std::endl;
0463 }
0464
0465 hSVCompatibility_->Fill(compatibility);
0466 hSVDist_->Fill(distance * cmToum);
0467 hSVDistErr_->Fill(dist_err * cmToum);
0468 hSVDistSig_->Fill(distance / dist_err);
0469
0470
0471 VtxDistPlots.fillPlots(distance * cmToum, tktk_p4);
0472
0473
0474 VtxDistSigPlots.fillPlots(distance / dist_err, tktk_p4);
0475
0476
0477
0478 VertexDistance3D vertTool3D;
0479 double distance3D = vertTool3D.distance(aTransientVertex, theMainVertex).value();
0480 double dist3D_err = vertTool3D.distance(aTransientVertex, theMainVertex).error();
0481 float compatibility3D = 0.;
0482
0483 try {
0484 compatibility3D = vertTool3D.compatibility(aTransientVertex, theMainVertex);
0485 } catch (cms::Exception& er) {
0486 LogTrace("DiMuonVertexMonitor") << "caught std::exception " << er.what() << std::endl;
0487 }
0488
0489 hSVCompatibility3D_->Fill(compatibility3D);
0490 hSVDist3D_->Fill(distance3D * cmToum);
0491 hSVDist3DErr_->Fill(dist3D_err * cmToum);
0492 hSVDist3DSig_->Fill(distance3D / dist3D_err);
0493
0494
0495 VtxDist3DPlots.fillPlots(distance3D * cmToum, tktk_p4);
0496
0497
0498 VtxDist3DSigPlots.fillPlots(distance3D / dist3D_err, tktk_p4);
0499
0500 LogDebug("DiMuonVertexValidation") << "distance: " << distance << "+/-" << dist_err << std::endl;
0501
0502 if (distance * cmToum < maxSVdist_) {
0503 myCounts.eventsAfterDist++;
0504
0505 double cosphi = (ZpT.x() * deltaVtx.x() + ZpT.y() * deltaVtx.y()) /
0506 (sqrt(ZpT.x() * ZpT.x() + ZpT.y() * ZpT.y()) *
0507 sqrt(deltaVtx.x() * deltaVtx.x() + deltaVtx.y() * deltaVtx.y()));
0508
0509 double cosphi3D = (Zp.x() * deltaVtx.x() + Zp.y() * deltaVtx.y() + Zp.z() * deltaVtx.z()) /
0510 (sqrt(Zp.x() * Zp.x() + Zp.y() * Zp.y() + Zp.z() * Zp.z()) *
0511 sqrt(deltaVtx.x() * deltaVtx.x() + deltaVtx.y() * deltaVtx.y() + deltaVtx.z() * deltaVtx.z()));
0512
0513 LogDebug("DiMuonVertexValidation") << "cos(phi) = " << cosphi << std::endl;
0514
0515 hCosPhi_->Fill(cosphi);
0516 hCosPhi3D_->Fill(cosphi3D);
0517
0518 #ifdef EDM_ML_DEBUG
0519 edm::LogVerbatim("DiMuonVertexValidation")
0520 << "distance " << distance * cmToum << " cosphi3D:" << cosphi3D << std::endl;
0521 #endif
0522
0523
0524 hCosPhiUnbalance_->Fill(cosphi, 1.);
0525 hCosPhiUnbalance_->Fill(-cosphi, -1.);
0526 hCosPhi3DUnbalance_->Fill(cosphi3D, 1.);
0527 hCosPhi3DUnbalance_->Fill(-cosphi3D, -1.);
0528
0529
0530 CosPhiPlots.fillPlots(cosphi, tktk_p4);
0531
0532
0533 CosPhi3DPlots.fillPlots(cosphi3D, tktk_p4);
0534
0535
0536 CosPhi3DInEtaBins.fillTH1Plots(cosphi3D, tktk_p4);
0537 }
0538 }
0539 }
0540
0541
0542 void DiMuonVertexValidation::beginJob() {
0543 edm::Service<TFileService> fs;
0544
0545
0546 TH1F::SetDefaultSumw2(kTRUE);
0547 hSVProb_ = fs->make<TH1F>("VtxProb", ";#mu^{+}#mu^{-} vertex probability;N(#mu#mu pairs)", 100, 0., 1.);
0548
0549 auto extractRangeValues = [](const edm::ParameterSet& PSetConfiguration_) -> std::pair<double, double> {
0550 double min = PSetConfiguration_.getParameter<double>("ymin");
0551 double max = PSetConfiguration_.getParameter<double>("ymax");
0552 return {min, max};
0553 };
0554
0555 std::string ts = fmt::sprintf(";%s vertex probability;N(#mu#mu pairs)", motherName_);
0556 std::string ps = "N(#mu#mu pairs)";
0557 ts = fmt::sprintf("#chi^{2} of the %s vertex; #chi^{2} of the %s vertex; %s", motherName_, motherName_, ps);
0558 hSVChi2_ = fs->make<TH1F>("VtxChi2", ts.c_str(), 200, 0., 200.);
0559
0560 ts = fmt::sprintf("#chi^{2}/ndf of the %s vertex; #chi^{2}/ndf of %s vertex; %s", motherName_, motherName_, ps);
0561 hSVNormChi2_ = fs->make<TH1F>("VtxNormChi2", ts.c_str(), 100, 0., 20.);
0562
0563
0564 const auto& svDistRng = extractRangeValues(VtxDistConfiguration_);
0565 hSVDist_ = fs->make<TH1F>("VtxDist", ";PV-#mu^{+}#mu^{-} vertex xy distance [#mum];N(#mu#mu pairs)", 100, svDistRng.first, svDistRng.second);
0566
0567 std::string histTit = motherName_ + " #rightarrow #mu^{+}#mu^{-}";
0568 ts = fmt::sprintf("%s;PV-%sV xy distance error [#mum];%s", histTit, motherName_, ps);
0569 hSVDistErr_ = fs->make<TH1F>("VtxDistErr", ts.c_str(), 100, 0., 1000.);
0570
0571
0572 const auto& svDistSigRng = extractRangeValues(VtxDistSigConfiguration_);
0573 hSVDistSig_ = fs->make<TH1F>("VtxDistSig", ";PV-#mu^{+}#mu^{-} vertex xy distance signficance;N(#mu#mu pairs)", 100, svDistSigRng.first, svDistSigRng.second);
0574
0575
0576 const auto& svDist3DRng = extractRangeValues(VtxDist3DConfiguration_);
0577 hSVDist3D_ = fs->make<TH1F>("VtxDist3D", ";PV-#mu^{+}#mu^{-} vertex 3D distance [#mum];N(#mu#mu pairs)", 100, svDist3DRng.first, svDist3DRng.second);
0578
0579 ts = fmt::sprintf("%s;PV-%sV 3D distance error [#mum];%s", histTit, motherName_, ps);
0580 hSVDist3DErr_ = fs->make<TH1F>("VtxDist3DErr", ts.c_str(), 100, 0., 1000.);
0581
0582
0583 const auto& svDist3DSigRng = extractRangeValues(VtxDist3DSigConfiguration_);
0584 hSVDist3DSig_ = fs->make<TH1F>("VtxDist3DSig", ";PV-#mu^{+}#mu^{-} vertex 3D distance signficance;N(#mu#mu pairs)", 100, svDist3DSigRng.first, svDist3DSigRng.second);
0585
0586 ts = fmt::sprintf("compatibility of %s vertex; compatibility of %s vertex; %s", motherName_, motherName_, ps);
0587 hSVCompatibility_ = fs->make<TH1F>("VtxCompatibility", ts.c_str(), 100, 0., 100.);
0588
0589 ts = fmt::sprintf("3D compatibility of %s vertex;3D compatibility of %s vertex; %s", motherName_, motherName_, ps);
0590 hSVCompatibility3D_ = fs->make<TH1F>("VtxCompatibility3D", ts.c_str(), 100, 0., 100.);
0591
0592
0593 const auto& massRng = extractRangeValues(DiMuMassConfiguration_);
0594 hInvMass_ = fs->make<TH1F>("InvMass", ";M(#mu#mu) [GeV];N(#mu#mu pairs)", 70., massRng.first, massRng.second);
0595 hTrackInvMass_ = fs->make<TH1F>("TkTkInvMass", ";M(tk,tk) [GeV];N(tk tk pairs)", 70., massRng.first, massRng.second);
0596
0597 hCosPhi_ = fs->make<TH1F>("CosPhi", ";cos(#phi_{xy});N(#mu#mu pairs)", 50, -1., 1.);
0598 hCosPhi3D_ = fs->make<TH1F>("CosPhi3D", ";cos(#phi_{3D});N(#mu#mu pairs)", 50, -1., 1.);
0599
0600 hCosPhiInv_ = fs->make<TH1F>("CosPhiInv", ";inverted cos(#phi_{xy});N(#mu#mu pairs)", 50, -1., 1.);
0601 hCosPhiInv3D_ = fs->make<TH1F>("CosPhiInv3D", ";inverted cos(#phi_{3D});N(#mu#mu pairs)", 50, -1., 1.);
0602
0603 hCosPhiUnbalance_ = fs->make<TH1F>("CosPhiUnbalance", fmt::sprintf("%s;cos(#phi_{xy}) unbalance;#Delta%s", histTit, ps).c_str(), 50, -1.,1.);
0604 hCosPhi3DUnbalance_ = fs->make<TH1F>("CosPhi3DUnbalance", fmt::sprintf("%s;cos(#phi_{3D}) unbalance;#Delta%s", histTit, ps).c_str(), 50, -1., 1.);
0605
0606 hdxy_ = fs->make<TH1F>("dxy", fmt::sprintf("%s;muon track d_{xy}(PV) [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
0607 hdz_ = fs->make<TH1F>("dz", fmt::sprintf("%s;muon track d_{z}(PV) [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
0608 hdxyErr_ = fs->make<TH1F>("dxyErr", fmt::sprintf("%s;muon track err_{dxy} [#mum];muon tracks", histTit).c_str(), 250, 0., 500.);
0609 hdzErr_ = fs->make<TH1F>("dzErr", fmt::sprintf("%s;muon track err_{dz} [#mum];muon tracks", histTit).c_str(), 250, 0., 500.);
0610 hIP2d_ = fs->make<TH1F>("IP2d", fmt::sprintf("%s;muon track IP_{2D} [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
0611 hIP3d_ = fs->make<TH1F>("IP3d", fmt::sprintf("%s;muon track IP_{3D} [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
0612 hIP2dsig_ = fs->make<TH1F>("IP2Dsig", fmt::sprintf("%s;muon track IP_{2D} significance;muon tracks", histTit).c_str(), 100, 0., 5.);
0613 hIP3dsig_ = fs->make<TH1F>("IP3Dsig", fmt::sprintf("%s;muon track IP_{3D} significance;muon tracks", histTit).c_str(), 100, 0., 5.);
0614
0615
0616
0617
0618 TFileDirectory dirCosPhi = fs->mkdir("CosPhiPlots");
0619 CosPhiPlots.bookFromPSet(dirCosPhi, CosPhiConfiguration_);
0620
0621 TFileDirectory dirCosPhi3D = fs->mkdir("CosPhi3DPlots");
0622 CosPhi3DPlots.bookFromPSet(dirCosPhi3D, CosPhi3DConfiguration_);
0623
0624 TFileDirectory dirVtxProb = fs->mkdir("VtxProbPlots");
0625 VtxProbPlots.bookFromPSet(dirVtxProb, VtxProbConfiguration_);
0626
0627 TFileDirectory dirVtxDist = fs->mkdir("VtxDistPlots");
0628 VtxDistPlots.bookFromPSet(dirVtxDist, VtxDistConfiguration_);
0629
0630 TFileDirectory dirVtxDist3D = fs->mkdir("VtxDist3DPlots");
0631 VtxDist3DPlots.bookFromPSet(dirVtxDist3D, VtxDist3DConfiguration_);
0632
0633 TFileDirectory dirVtxDistSig = fs->mkdir("VtxDistSigPlots");
0634 VtxDistSigPlots.bookFromPSet(dirVtxDistSig, VtxDistSigConfiguration_);
0635
0636 TFileDirectory dirVtxDist3DSig = fs->mkdir("VtxDist3DSigPlots");
0637 VtxDist3DSigPlots.bookFromPSet(dirVtxDist3DSig, VtxDist3DSigConfiguration_);
0638
0639 TFileDirectory dirInvariantMass = fs->mkdir("InvariantMassPlots");
0640 ZMassPlots.bookFromPSet(dirInvariantMass, DiMuMassConfiguration_);
0641
0642
0643 TFileDirectory dirCosphi3DEta = fs->mkdir("CosPhi3DInEtaBins");
0644 CosPhi3DInEtaBins.bookSet(dirCosphi3DEta, hCosPhi3D_);
0645
0646
0647 TFileDirectory dirResMassEta = fs->mkdir("TkTkMassInEtaBins");
0648 InvMassInEtaBins.bookSet(dirResMassEta, hTrackInvMass_);
0649
0650
0651
0652 hCutFlow_ = fs->make<TH1F>("hCutFlow", "cut flow;cut step;events left", 6, -0.5, 5.5);
0653 std::string names[6] = {"Total", "Mult.", ">pT", "<eta", "hasVtx", "VtxDist"};
0654 for (unsigned int i = 0; i < 6; i++) {
0655 hCutFlow_->GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
0656 }
0657
0658 myCounts.zeroAll();
0659 }
0660
0661
0662 void DiMuonVertexValidation::endJob() {
0663 myCounts.printCounts();
0664
0665 hCutFlow_->SetBinContent(1, myCounts.eventsTotal);
0666 hCutFlow_->SetBinContent(2, myCounts.eventsAfterMult);
0667 hCutFlow_->SetBinContent(3, myCounts.eventsAfterPt);
0668 hCutFlow_->SetBinContent(4, myCounts.eventsAfterEta);
0669 hCutFlow_->SetBinContent(5, myCounts.eventsAfterVtx);
0670 hCutFlow_->SetBinContent(6, myCounts.eventsAfterDist);
0671
0672 TH1F::SetDefaultSumw2(kTRUE);
0673 const unsigned int nBinsX = hCosPhi_->GetNbinsX();
0674 for (unsigned int i = 1; i <= nBinsX; i++) {
0675
0676 float invertedBinContent = hCosPhi_->GetBinContent(nBinsX + 1 - i);
0677 float invertedBinError = hCosPhi_->GetBinError(nBinsX + 1 - i);
0678 hCosPhiInv_->SetBinContent(i, invertedBinContent);
0679 hCosPhiInv_->SetBinError(i, invertedBinError);
0680
0681
0682 float invertedBinContent3D = hCosPhi3D_->GetBinContent(nBinsX + 1 - i);
0683 float invertedBinError3D = hCosPhi3D_->GetBinError(nBinsX + 1 - i);
0684 hCosPhiInv3D_->SetBinContent(i, invertedBinContent3D);
0685 hCosPhiInv3D_->SetBinError(i, invertedBinError3D);
0686 }
0687 }
0688
0689
0690 const reco::Vertex* DiMuonVertexValidation::findClosestVertex(const TransientVertex aTransVtx,
0691 const reco::VertexCollection* vertices) const {
0692 reco::Vertex* defaultVtx = nullptr;
0693
0694 if (!aTransVtx.isValid())
0695 return defaultVtx;
0696
0697
0698 VertexDistance3D vertTool3D;
0699 float minD = 9999.;
0700 int closestVtxIndex = 0;
0701 int counter = 0;
0702 for (const auto& vtx : *vertices) {
0703 double dist3D = vertTool3D.distance(aTransVtx, vtx).value();
0704 if (dist3D < minD) {
0705 minD = dist3D;
0706 closestVtxIndex = counter;
0707 }
0708 counter++;
0709 }
0710
0711 if ((*vertices).at(closestVtxIndex).isValid()) {
0712 return &(vertices->at(closestVtxIndex));
0713 } else {
0714 return defaultVtx;
0715 }
0716 }
0717
0718
0719 void DiMuonVertexValidation::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0720 edm::ParameterSetDescription desc;
0721 desc.ifValue(edm::ParameterDescription<bool>("useReco", true, true),
0722 true >> edm::ParameterDescription<edm::InputTag>("muons", edm::InputTag("muons"), true) or
0723 false >> edm::ParameterDescription<edm::InputTag>(
0724 "muonTracks", edm::InputTag("ALCARECOTkAlDiMuon"), true))
0725 ->setComment("If useReco is true need to specify the muon tracks, otherwise take the ALCARECO Inner tracks");
0726
0727
0728
0729 desc.add<std::string>("decayMotherName", "Z");
0730 desc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
0731 desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
0732 desc.add<std::vector<double>>("pTThresholds", {30., 10.});
0733 desc.add<bool>("useClosestVertex", true);
0734 desc.add<double>("maxSVdist", 50.);
0735
0736 {
0737 edm::ParameterSetDescription psDiMuMass;
0738 psDiMuMass.add<std::string>("name", "DiMuMass");
0739 psDiMuMass.add<std::string>("title", "M(#mu#mu)");
0740 psDiMuMass.add<std::string>("yUnits", "[GeV]");
0741 psDiMuMass.add<int>("NxBins", 24);
0742 psDiMuMass.add<int>("NyBins", 50);
0743 psDiMuMass.add<double>("ymin", 70.);
0744 psDiMuMass.add<double>("ymax", 120.);
0745 desc.add<edm::ParameterSetDescription>("DiMuMassConfig", psDiMuMass);
0746 }
0747 {
0748 edm::ParameterSetDescription psCosPhi;
0749 psCosPhi.add<std::string>("name", "CosPhi");
0750 psCosPhi.add<std::string>("title", "cos(#phi_{xy})");
0751 psCosPhi.add<std::string>("yUnits", "");
0752 psCosPhi.add<int>("NxBins", 50);
0753 psCosPhi.add<int>("NyBins", 50);
0754 psCosPhi.add<double>("ymin", -1.);
0755 psCosPhi.add<double>("ymax", 1.);
0756 desc.add<edm::ParameterSetDescription>("CosPhiConfig", psCosPhi);
0757 }
0758 {
0759 edm::ParameterSetDescription psCosPhi3D;
0760 psCosPhi3D.add<std::string>("name", "CosPhi3D");
0761 psCosPhi3D.add<std::string>("title", "cos(#phi_{3D})");
0762 psCosPhi3D.add<std::string>("yUnits", "");
0763 psCosPhi3D.add<int>("NxBins", 50);
0764 psCosPhi3D.add<int>("NyBins", 50);
0765 psCosPhi3D.add<double>("ymin", -1.);
0766 psCosPhi3D.add<double>("ymax", 1.);
0767 desc.add<edm::ParameterSetDescription>("CosPhi3DConfig", psCosPhi3D);
0768 }
0769 {
0770 edm::ParameterSetDescription psVtxProb;
0771 psVtxProb.add<std::string>("name", "VtxProb");
0772 psVtxProb.add<std::string>("title", "Prob(#chi^{2}_{SV})");
0773 psVtxProb.add<std::string>("yUnits", "");
0774 psVtxProb.add<int>("NxBins", 50);
0775 psVtxProb.add<int>("NyBins", 50);
0776 psVtxProb.add<double>("ymin", 0);
0777 psVtxProb.add<double>("ymax", 1.);
0778 desc.add<edm::ParameterSetDescription>("VtxProbConfig", psVtxProb);
0779 }
0780 {
0781 edm::ParameterSetDescription psVtxDist;
0782 psVtxDist.add<std::string>("name", "VtxDist");
0783 psVtxDist.add<std::string>("title", "d_{xy}(PV,SV)");
0784 psVtxDist.add<std::string>("yUnits", "[#mum]");
0785 psVtxDist.add<int>("NxBins", 50);
0786 psVtxDist.add<int>("NyBins", 100);
0787 psVtxDist.add<double>("ymin", 0);
0788 psVtxDist.add<double>("ymax", 300.);
0789 desc.add<edm::ParameterSetDescription>("VtxDistConfig", psVtxDist);
0790 }
0791 {
0792 edm::ParameterSetDescription psVtxDist3D;
0793 psVtxDist3D.add<std::string>("name", "VtxDist3D");
0794 psVtxDist3D.add<std::string>("title", "d_{3D}(PV,SV)");
0795 psVtxDist3D.add<std::string>("yUnits", "[#mum]");
0796 psVtxDist3D.add<int>("NxBins", 50);
0797 psVtxDist3D.add<int>("NyBins", 250);
0798 psVtxDist3D.add<double>("ymin", 0);
0799 psVtxDist3D.add<double>("ymax", 500.);
0800 desc.add<edm::ParameterSetDescription>("VtxDist3DConfig", psVtxDist3D);
0801 }
0802 {
0803 edm::ParameterSetDescription psVtxDistSig;
0804 psVtxDistSig.add<std::string>("name", "VtxDistSig");
0805 psVtxDistSig.add<std::string>("title", "d_{xy}(PV,SV)/#sigma_{dxy}(PV,SV)");
0806 psVtxDistSig.add<std::string>("yUnits", "");
0807 psVtxDistSig.add<int>("NxBins", 50);
0808 psVtxDistSig.add<int>("NyBins", 100);
0809 psVtxDistSig.add<double>("ymin", 0);
0810 psVtxDistSig.add<double>("ymax", 5.);
0811 desc.add<edm::ParameterSetDescription>("VtxDistSigConfig", psVtxDistSig);
0812 }
0813 {
0814 edm::ParameterSetDescription psVtxDist3DSig;
0815 psVtxDist3DSig.add<std::string>("name", "VtxDist3DSig");
0816 psVtxDist3DSig.add<std::string>("title", "d_{3D}(PV,SV)/#sigma_{d3D}(PV,SV)");
0817 psVtxDist3DSig.add<std::string>("yUnits", "");
0818 psVtxDist3DSig.add<int>("NxBins", 50);
0819 psVtxDist3DSig.add<int>("NyBins", 100);
0820 psVtxDist3DSig.add<double>("ymin", 0);
0821 psVtxDist3DSig.add<double>("ymax", 5.);
0822 desc.add<edm::ParameterSetDescription>("VtxDist3DSigConfig", psVtxDist3DSig);
0823 }
0824
0825 descriptions.addWithDefaultLabel(desc);
0826 }
0827
0828
0829 DEFINE_FWK_MODULE(DiMuonVertexValidation);