Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-27 22:36:54

0001 // -*- C++ -*-
0002 //
0003 // Package:    Alignment/OfflineValidation
0004 // Class:      DiMuonVertexValidation
0005 //
0006 /**\class DiMuonVertexValidation DiMuonVertexValidation.cc Alignment/OfflineValidation/plugins/DiMuonVertexValidation.cc
0007 
0008  Description: Class to perform validation Tracker Alignment Validations by means of a PV and the SV constructed with a di-muon pair
0009 
0010 */
0011 //
0012 // Original Author:  Marco Musich
0013 //         Created:  Wed, 21 Apr 2021 09:06:25 GMT
0014 //
0015 //
0016 
0017 // system include files
0018 #include <memory>
0019 #include <utility>
0020 
0021 // user include files
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 // muons
0030 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0031 #include "DataFormats/MuonReco/interface/Muon.h"
0032 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0033 
0034 // utils
0035 #include "Alignment/OfflineValidation/interface/DiLeptonVertexHelpers.h"
0036 #include "DataFormats/Math/interface/deltaR.h"
0037 #include "TLorentzVector.h"
0038 
0039 // tracks
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 // vertices
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 // ROOT
0054 #include "TH1F.h"
0055 #include "TH2F.h"
0056 
0057 //#define LogDebug(X) std::cout << X <<
0058 
0059 //
0060 // class declaration
0061 //
0062 
0063 class DiMuonVertexValidation : public edm::one::EDAnalyzer<edm::one::SharedResources> {
0064 public:
0065   explicit DiMuonVertexValidation(const edm::ParameterSet&);
0066   ~DiMuonVertexValidation() override;
0067 
0068   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0069 
0070 private:
0071   void beginJob() override;
0072   void analyze(const edm::Event&, const edm::EventSetup&) override;
0073   void endJob() override;
0074 
0075   // ----------member data ---------------------------
0076   DiLeptonHelp::Counts myCounts;
0077 
0078   bool useReco_;
0079   std::vector<double> pTthresholds_;
0080   float maxSVdist_;
0081 
0082   // plot configurations
0083 
0084   edm::ParameterSet CosPhiConfiguration_;
0085   edm::ParameterSet CosPhi3DConfiguration_;
0086   edm::ParameterSet VtxProbConfiguration_;
0087   edm::ParameterSet VtxDistConfiguration_;
0088   edm::ParameterSet VtxDist3DConfiguration_;
0089   edm::ParameterSet VtxDistSigConfiguration_;
0090   edm::ParameterSet VtxDist3DSigConfiguration_;
0091   edm::ParameterSet DiMuMassConfiguration_;
0092 
0093   // control plots
0094 
0095   TH1F* hSVProb_;
0096   TH1F* hSVDist_;
0097   TH1F* hSVDistSig_;
0098   TH1F* hSVDist3D_;
0099   TH1F* hSVDist3DSig_;
0100 
0101   TH1F* hCosPhi_;
0102   TH1F* hCosPhi3D_;
0103   TH1F* hCosPhiInv_;
0104   TH1F* hCosPhiInv3D_;
0105 
0106   TH1F* hInvMass_;
0107   TH1F* hTrackInvMass_;
0108 
0109   TH1F* hCutFlow_;
0110 
0111   // 2D maps
0112 
0113   DiLeptonHelp::PlotsVsKinematics CosPhiPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0114   DiLeptonHelp::PlotsVsKinematics CosPhi3DPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0115   DiLeptonHelp::PlotsVsKinematics VtxProbPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0116   DiLeptonHelp::PlotsVsKinematics VtxDistPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0117   DiLeptonHelp::PlotsVsKinematics VtxDist3DPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0118   DiLeptonHelp::PlotsVsKinematics VtxDistSigPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0119   DiLeptonHelp::PlotsVsKinematics VtxDist3DSigPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0120   DiLeptonHelp::PlotsVsKinematics ZMassPlots = DiLeptonHelp::PlotsVsKinematics(DiLeptonHelp::MM);
0121 
0122   const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> ttbESToken_;
0123 
0124   edm::EDGetTokenT<reco::TrackCollection> tracksToken_;   //used to select what tracks to read from configuration file
0125   edm::EDGetTokenT<reco::VertexCollection> vertexToken_;  //used to select what vertices to read from configuration file
0126 
0127   // either on or the other!
0128   edm::EDGetTokenT<reco::MuonCollection> muonsToken_;  //used to select what tracks to read from configuration file
0129   edm::EDGetTokenT<reco::TrackCollection>
0130       alcaRecoToken_;  //used to select what muon tracks to read from configuration file
0131 };
0132 
0133 //
0134 // constants, enums and typedefs
0135 //
0136 
0137 static constexpr float cmToum = 10e4;
0138 static constexpr float mumass2 = 0.105658367 * 0.105658367;  //mu mass squared (GeV^2/c^4)
0139 
0140 //
0141 // static data member definitions
0142 //
0143 
0144 //
0145 // constructors and destructor
0146 //
0147 DiMuonVertexValidation::DiMuonVertexValidation(const edm::ParameterSet& iConfig)
0148     : useReco_(iConfig.getParameter<bool>("useReco")),
0149       pTthresholds_(iConfig.getParameter<std::vector<double>>("pTThresholds")),
0150       maxSVdist_(iConfig.getParameter<double>("maxSVdist")),
0151       CosPhiConfiguration_(iConfig.getParameter<edm::ParameterSet>("CosPhiConfig")),
0152       CosPhi3DConfiguration_(iConfig.getParameter<edm::ParameterSet>("CosPhi3DConfig")),
0153       VtxProbConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxProbConfig")),
0154       VtxDistConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDistConfig")),
0155       VtxDist3DConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDist3DConfig")),
0156       VtxDistSigConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDistSigConfig")),
0157       VtxDist3DSigConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDist3DSigConfig")),
0158       DiMuMassConfiguration_(iConfig.getParameter<edm::ParameterSet>("DiMuMassConfig")),
0159       ttbESToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))),
0160       tracksToken_(consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"))),
0161       vertexToken_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))) {
0162   if (useReco_) {
0163     muonsToken_ = mayConsume<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"));
0164   } else {
0165     alcaRecoToken_ = mayConsume<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("muonTracks"));
0166   }
0167 
0168   usesResource(TFileService::kSharedResource);
0169 
0170   // sort the vector of thresholds
0171   std::sort(pTthresholds_.begin(), pTthresholds_.end(), [](const double& lhs, const double& rhs) { return lhs > rhs; });
0172 
0173   edm::LogInfo("DiMuonVertexValidation") << __FUNCTION__;
0174   for (const auto& thr : pTthresholds_) {
0175     edm::LogInfo("DiMuonVertexValidation") << " Threshold: " << thr << " ";
0176   }
0177   edm::LogInfo("DiMuonVertexValidation") << "Max SV distance: " << maxSVdist_ << " ";
0178 }
0179 
0180 DiMuonVertexValidation::~DiMuonVertexValidation() = default;
0181 
0182 //
0183 // member functions
0184 //
0185 
0186 // ------------ method called for each event  ------------
0187 void DiMuonVertexValidation::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0188   using namespace edm;
0189 
0190   myCounts.eventsTotal++;
0191 
0192   // the di-muon tracks
0193   std::vector<const reco::Track*> myTracks;
0194 
0195   // if we have to start from scratch from RECO data-tier
0196   if (useReco_) {
0197     // select the good muons
0198     std::vector<const reco::Muon*> myGoodMuonVector;
0199     for (const auto& muon : iEvent.get(muonsToken_)) {
0200       const reco::TrackRef t = muon.innerTrack();
0201       if (!t.isNull()) {
0202         if (t->quality(reco::TrackBase::highPurity)) {
0203           if (t->chi2() / t->ndof() <= 2.5 && t->numberOfValidHits() >= 5 &&
0204               t->hitPattern().numberOfValidPixelHits() >= 2 && t->quality(reco::TrackBase::highPurity))
0205             myGoodMuonVector.emplace_back(&muon);
0206         }
0207       }
0208     }
0209 
0210     LogDebug("DiMuonVertexValidation") << "myGoodMuonVector size: " << myGoodMuonVector.size() << std::endl;
0211     std::sort(myGoodMuonVector.begin(), myGoodMuonVector.end(), [](const reco::Muon*& lhs, const reco::Muon*& rhs) {
0212       return lhs->pt() > rhs->pt();
0213     });
0214 
0215     // just check the ordering
0216     for (const auto& muon : myGoodMuonVector) {
0217       LogDebug("DiMuonVertexValidation") << "pT: " << muon->pt() << " ";
0218     }
0219     LogDebug("DiMuonVertexValidation") << std::endl;
0220 
0221     // reject if there's no Z
0222     if (myGoodMuonVector.size() < 2)
0223       return;
0224 
0225     myCounts.eventsAfterMult++;
0226 
0227     if ((myGoodMuonVector[0]->pt()) < pTthresholds_[0] || (myGoodMuonVector[1]->pt() < pTthresholds_[1]))
0228       return;
0229 
0230     myCounts.eventsAfterPt++;
0231     myCounts.eventsAfterEta++;
0232 
0233     if (myGoodMuonVector[0]->charge() * myGoodMuonVector[1]->charge() > 0)
0234       return;
0235 
0236     const auto& m1 = myGoodMuonVector[1]->p4();
0237     const auto& m0 = myGoodMuonVector[0]->p4();
0238     const auto& mother = m0 + m1;
0239 
0240     float invMass = mother.M();
0241     hInvMass_->Fill(invMass);
0242 
0243     // just copy the top two muons
0244     std::vector<const reco::Muon*> theZMuonVector;
0245     theZMuonVector.reserve(2);
0246     theZMuonVector.emplace_back(myGoodMuonVector[1]);
0247     theZMuonVector.emplace_back(myGoodMuonVector[0]);
0248 
0249     // do the matching of Z muons with inner tracks
0250     unsigned int i = 0;
0251     for (const auto& muon : theZMuonVector) {
0252       i++;
0253       float minD = 1000.;
0254       const reco::Track* theMatch = nullptr;
0255       for (const auto& track : iEvent.get(tracksToken_)) {
0256         float D = ::deltaR(muon->eta(), muon->phi(), track.eta(), track.phi());
0257         if (D < minD) {
0258           minD = D;
0259           theMatch = &track;
0260         }
0261       }
0262       LogDebug("DiMuonVertexValidation") << "pushing new track: " << i << std::endl;
0263       myTracks.emplace_back(theMatch);
0264     }
0265   } else {
0266     // we start directly with the pre-selected ALCARECO tracks
0267     for (const auto& muon : iEvent.get(alcaRecoToken_)) {
0268       myTracks.emplace_back(&muon);
0269     }
0270   }
0271 
0272   LogDebug("DiMuonVertexValidation") << "selected tracks: " << myTracks.size() << std::endl;
0273 
0274   const TransientTrackBuilder* theB = &iSetup.getData(ttbESToken_);
0275   TransientVertex aTransientVertex;
0276   std::vector<reco::TransientTrack> tks;
0277 
0278   if (myTracks.size() != 2)
0279     return;
0280 
0281   const auto& t1 = myTracks[1]->momentum();
0282   const auto& t0 = myTracks[0]->momentum();
0283   const auto& ditrack = t1 + t0;
0284 
0285   const auto& tplus = myTracks[0]->charge() > 0 ? myTracks[0] : myTracks[1];
0286   const auto& tminus = myTracks[0]->charge() < 0 ? myTracks[0] : myTracks[1];
0287 
0288   TLorentzVector p4_tplus(tplus->px(), tplus->py(), tplus->pz(), sqrt((tplus->p() * tplus->p()) + mumass2));
0289   TLorentzVector p4_tminus(tminus->px(), tminus->py(), tminus->pz(), sqrt((tminus->p() * tminus->p()) + mumass2));
0290 
0291   const auto& Zp4 = p4_tplus + p4_tminus;
0292   float track_invMass = Zp4.M();
0293   hTrackInvMass_->Fill(track_invMass);
0294 
0295   // creat the pair of TLorentVectors used to make the plos
0296   std::pair<TLorentzVector, TLorentzVector> tktk_p4 = std::make_pair(p4_tplus, p4_tminus);
0297 
0298   // fill the z->mm mass plots
0299   ZMassPlots.fillPlots(track_invMass, tktk_p4);
0300 
0301   math::XYZPoint ZpT(ditrack.x(), ditrack.y(), 0);
0302   math::XYZPoint Zp(ditrack.x(), ditrack.y(), ditrack.z());
0303 
0304   for (const auto& track : myTracks) {
0305     reco::TransientTrack trajectory = theB->build(track);
0306     tks.push_back(trajectory);
0307   }
0308 
0309   KalmanVertexFitter kalman(true);
0310   aTransientVertex = kalman.vertex(tks);
0311 
0312   double SVProb = TMath::Prob(aTransientVertex.totalChiSquared(), (int)aTransientVertex.degreesOfFreedom());
0313 
0314   LogDebug("DiMuonVertexValidation") << " vertex prob: " << SVProb << std::endl;
0315 
0316   hSVProb_->Fill(SVProb);
0317 
0318   if (!aTransientVertex.isValid())
0319     return;
0320 
0321   myCounts.eventsAfterVtx++;
0322 
0323   // fill the VtxProb plots
0324   VtxProbPlots.fillPlots(SVProb, tktk_p4);
0325 
0326   // get collection of reconstructed vertices from event
0327   edm::Handle<reco::VertexCollection> vertexHandle = iEvent.getHandle(vertexToken_);
0328 
0329   math::XYZPoint MainVertex(0, 0, 0);
0330   reco::Vertex TheMainVertex = vertexHandle.product()->front();
0331 
0332   if (vertexHandle.isValid()) {
0333     const reco::VertexCollection* vertices = vertexHandle.product();
0334     if ((*vertices).at(0).isValid()) {
0335       auto theMainVtx = (*vertices).at(0);
0336       MainVertex.SetXYZ(theMainVtx.position().x(), theMainVtx.position().y(), theMainVtx.position().z());
0337     }
0338   }
0339 
0340   const math::XYZPoint myVertex(
0341       aTransientVertex.position().x(), aTransientVertex.position().y(), aTransientVertex.position().z());
0342   const math::XYZPoint deltaVtx(
0343       MainVertex.x() - myVertex.x(), MainVertex.y() - myVertex.y(), MainVertex.z() - myVertex.z());
0344 
0345   if (TheMainVertex.isValid()) {
0346     // Z Vertex distance in the xy plane
0347 
0348     VertexDistanceXY vertTool;
0349     double distance = vertTool.distance(aTransientVertex, TheMainVertex).value();
0350     double dist_err = vertTool.distance(aTransientVertex, TheMainVertex).error();
0351 
0352     hSVDist_->Fill(distance * cmToum);
0353     hSVDistSig_->Fill(distance / dist_err);
0354 
0355     // fill the VtxDist plots
0356     VtxDistPlots.fillPlots(distance * cmToum, tktk_p4);
0357 
0358     // fill the VtxDisSig plots
0359     VtxDistSigPlots.fillPlots(distance / dist_err, tktk_p4);
0360 
0361     // Z Vertex distance in 3D
0362 
0363     VertexDistance3D vertTool3D;
0364     double distance3D = vertTool3D.distance(aTransientVertex, TheMainVertex).value();
0365     double dist3D_err = vertTool3D.distance(aTransientVertex, TheMainVertex).error();
0366 
0367     hSVDist3D_->Fill(distance3D * cmToum);
0368     hSVDist3DSig_->Fill(distance3D / dist3D_err);
0369 
0370     // fill the VtxDist3D plots
0371     VtxDist3DPlots.fillPlots(distance3D * cmToum, tktk_p4);
0372 
0373     // fill the VtxDisSig plots
0374     VtxDist3DSigPlots.fillPlots(distance3D / dist3D_err, tktk_p4);
0375 
0376     LogDebug("DiMuonVertexValidation") << "distance: " << distance << "+/-" << dist_err << std::endl;
0377     // cut on the PV - SV distance
0378     if (distance * cmToum < maxSVdist_) {
0379       myCounts.eventsAfterDist++;
0380 
0381       double cosphi = (ZpT.x() * deltaVtx.x() + ZpT.y() * deltaVtx.y()) /
0382                       (sqrt(ZpT.x() * ZpT.x() + ZpT.y() * ZpT.y()) *
0383                        sqrt(deltaVtx.x() * deltaVtx.x() + deltaVtx.y() * deltaVtx.y()));
0384 
0385       double cosphi3D = (Zp.x() * deltaVtx.x() + Zp.y() * deltaVtx.y() + Zp.z() * deltaVtx.z()) /
0386                         (sqrt(Zp.x() * Zp.x() + Zp.y() * Zp.y() + Zp.z() * Zp.z()) *
0387                          sqrt(deltaVtx.x() * deltaVtx.x() + deltaVtx.y() * deltaVtx.y() + deltaVtx.z() * deltaVtx.z()));
0388 
0389       LogDebug("DiMuonVertexValidation") << "cos(phi) = " << cosphi << std::endl;
0390 
0391       hCosPhi_->Fill(cosphi);
0392       hCosPhi3D_->Fill(cosphi3D);
0393 
0394       // fill the cosphi plots
0395       CosPhiPlots.fillPlots(cosphi, tktk_p4);
0396 
0397       // fill the VtxDisSig plots
0398       CosPhi3DPlots.fillPlots(cosphi3D, tktk_p4);
0399     }
0400   }
0401 }
0402 
0403 // ------------ method called once each job just before starting event loop  ------------
0404 void DiMuonVertexValidation::beginJob() {
0405   edm::Service<TFileService> fs;
0406 
0407   // clang-format off
0408   TH1F::SetDefaultSumw2(kTRUE);
0409   hSVProb_ = fs->make<TH1F>("VtxProb", ";ZV vertex probability;N(#mu#mu pairs)", 100, 0., 1.);
0410 
0411   hSVDist_ = fs->make<TH1F>("VtxDist", ";PV-ZV xy distance [#mum];N(#mu#mu pairs)", 100, 0., 300.);
0412   hSVDistSig_ = fs->make<TH1F>("VtxDistSig", ";PV-ZV xy distance signficance;N(#mu#mu pairs)", 100, 0., 5.);
0413 
0414   hSVDist3D_ = fs->make<TH1F>("VtxDist3D", ";PV-ZV 3D distance [#mum];N(#mu#mu pairs)", 100, 0., 300.);
0415   hSVDist3DSig_ = fs->make<TH1F>("VtxDist3DSig", ";PV-ZV 3D distance signficance;N(#mu#mu pairs)", 100, 0., 5.);
0416 
0417   hInvMass_ = fs->make<TH1F>("InvMass", ";M(#mu#mu) [GeV];N(#mu#mu pairs)", 70., 50., 120.);
0418   hTrackInvMass_ = fs->make<TH1F>("TkTkInvMass", ";M(tk,tk) [GeV];N(tk tk pairs)", 70., 50., 120.);
0419 
0420   hCosPhi_ = fs->make<TH1F>("CosPhi", ";cos(#phi_{xy});N(#mu#mu pairs)", 50, -1., 1.);
0421   hCosPhi3D_ = fs->make<TH1F>("CosPhi3D", ";cos(#phi_{3D});N(#mu#mu pairs)", 50, -1., 1.);
0422 
0423   hCosPhiInv_ = fs->make<TH1F>("CosPhiInv", ";inverted cos(#phi_{xy});N(#mu#mu pairs)", 50, -1., 1.);
0424   hCosPhiInv3D_ = fs->make<TH1F>("CosPhiInv3D", ";inverted cos(#phi_{3D});N(#mu#mu pairs)", 50, -1., 1.);
0425   // clang-format on
0426 
0427   // 2D Maps
0428 
0429   TFileDirectory dirCosPhi = fs->mkdir("CosPhiPlots");
0430   CosPhiPlots.bookFromPSet(dirCosPhi, CosPhiConfiguration_);
0431 
0432   TFileDirectory dirCosPhi3D = fs->mkdir("CosPhi3DPlots");
0433   CosPhi3DPlots.bookFromPSet(dirCosPhi3D, CosPhi3DConfiguration_);
0434 
0435   TFileDirectory dirVtxProb = fs->mkdir("VtxProbPlots");
0436   VtxProbPlots.bookFromPSet(dirVtxProb, VtxProbConfiguration_);
0437 
0438   TFileDirectory dirVtxDist = fs->mkdir("VtxDistPlots");
0439   VtxDistPlots.bookFromPSet(dirVtxDist, VtxDistConfiguration_);
0440 
0441   TFileDirectory dirVtxDist3D = fs->mkdir("VtxDist3DPlots");
0442   VtxDist3DPlots.bookFromPSet(dirVtxDist3D, VtxDist3DConfiguration_);
0443 
0444   TFileDirectory dirVtxDistSig = fs->mkdir("VtxDistSigPlots");
0445   VtxDistSigPlots.bookFromPSet(dirVtxDistSig, VtxDistSigConfiguration_);
0446 
0447   TFileDirectory dirVtxDist3DSig = fs->mkdir("VtxDist3DSigPlots");
0448   VtxDist3DSigPlots.bookFromPSet(dirVtxDist3DSig, VtxDist3DSigConfiguration_);
0449 
0450   TFileDirectory dirInvariantMass = fs->mkdir("InvariantMassPlots");
0451   ZMassPlots.bookFromPSet(dirInvariantMass, DiMuMassConfiguration_);
0452 
0453   // cut flow
0454 
0455   hCutFlow_ = fs->make<TH1F>("hCutFlow", "cut flow;cut step;events left", 6, -0.5, 5.5);
0456   std::string names[6] = {"Total", "Mult.", ">pT", "<eta", "hasVtx", "VtxDist"};
0457   for (unsigned int i = 0; i < 6; i++) {
0458     hCutFlow_->GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
0459   }
0460 
0461   myCounts.zeroAll();
0462 }
0463 
0464 // ------------ method called once each job just after ending the event loop  ------------
0465 void DiMuonVertexValidation::endJob() {
0466   myCounts.printCounts();
0467 
0468   hCutFlow_->SetBinContent(1, myCounts.eventsTotal);
0469   hCutFlow_->SetBinContent(2, myCounts.eventsAfterMult);
0470   hCutFlow_->SetBinContent(3, myCounts.eventsAfterPt);
0471   hCutFlow_->SetBinContent(4, myCounts.eventsAfterEta);
0472   hCutFlow_->SetBinContent(5, myCounts.eventsAfterVtx);
0473   hCutFlow_->SetBinContent(6, myCounts.eventsAfterDist);
0474 
0475   TH1F::SetDefaultSumw2(kTRUE);
0476   const unsigned int nBinsX = hCosPhi_->GetNbinsX();
0477   for (unsigned int i = 1; i <= nBinsX; i++) {
0478     //float binContent = hCosPhi_->GetBinContent(i);
0479     float invertedBinContent = hCosPhi_->GetBinContent(nBinsX + 1 - i);
0480     float invertedBinError = hCosPhi_->GetBinError(nBinsX + 1 - i);
0481     hCosPhiInv_->SetBinContent(i, invertedBinContent);
0482     hCosPhiInv_->SetBinError(i, invertedBinError);
0483 
0484     //float binContent3D = hCosPhi3D_->GetBinContent(i);
0485     float invertedBinContent3D = hCosPhi3D_->GetBinContent(nBinsX + 1 - i);
0486     float invertedBinError3D = hCosPhi3D_->GetBinError(nBinsX + 1 - i);
0487     hCosPhiInv3D_->SetBinContent(i, invertedBinContent3D);
0488     hCosPhiInv3D_->SetBinError(i, invertedBinError3D);
0489   }
0490 }
0491 
0492 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0493 void DiMuonVertexValidation::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0494   edm::ParameterSetDescription desc;
0495   desc.ifValue(edm::ParameterDescription<bool>("useReco", true, true),
0496                true >> edm::ParameterDescription<edm::InputTag>("muons", edm::InputTag("muons"), true) or
0497                    false >> edm::ParameterDescription<edm::InputTag>(
0498                                 "muonTracks", edm::InputTag("ALCARECOTkAlDiMuon"), true))
0499       ->setComment("If useReco is true need to specify the muon tracks, otherwise take the ALCARECO Inner tracks");
0500   //desc.add<bool>("useReco",true);
0501   //desc.add<edm::InputTag>("muons", edm::InputTag("muons"));
0502   //desc.add<edm::InputTag>("muonTracks", edm::InputTag("ALCARECOTkAlDiMuon"));
0503   desc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
0504   desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
0505   desc.add<std::vector<double>>("pTThresholds", {30., 10.});
0506   desc.add<double>("maxSVdist", 50.);
0507 
0508   {
0509     edm::ParameterSetDescription psDiMuMass;
0510     psDiMuMass.add<std::string>("name", "DiMuMass");
0511     psDiMuMass.add<std::string>("title", "M(#mu#mu)");
0512     psDiMuMass.add<std::string>("yUnits", "[GeV]");
0513     psDiMuMass.add<int>("NxBins", 24);
0514     psDiMuMass.add<int>("NyBins", 50);
0515     psDiMuMass.add<double>("ymin", 70.);
0516     psDiMuMass.add<double>("ymax", 120.);
0517     desc.add<edm::ParameterSetDescription>("DiMuMassConfig", psDiMuMass);
0518   }
0519   {
0520     edm::ParameterSetDescription psCosPhi;
0521     psCosPhi.add<std::string>("name", "CosPhi");
0522     psCosPhi.add<std::string>("title", "cos(#phi_{xy})");
0523     psCosPhi.add<std::string>("yUnits", "");
0524     psCosPhi.add<int>("NxBins", 50);
0525     psCosPhi.add<int>("NyBins", 50);
0526     psCosPhi.add<double>("ymin", -1.);
0527     psCosPhi.add<double>("ymax", 1.);
0528     desc.add<edm::ParameterSetDescription>("CosPhiConfig", psCosPhi);
0529   }
0530   {
0531     edm::ParameterSetDescription psCosPhi3D;
0532     psCosPhi3D.add<std::string>("name", "CosPhi3D");
0533     psCosPhi3D.add<std::string>("title", "cos(#phi_{3D})");
0534     psCosPhi3D.add<std::string>("yUnits", "");
0535     psCosPhi3D.add<int>("NxBins", 50);
0536     psCosPhi3D.add<int>("NyBins", 50);
0537     psCosPhi3D.add<double>("ymin", -1.);
0538     psCosPhi3D.add<double>("ymax", 1.);
0539     desc.add<edm::ParameterSetDescription>("CosPhi3DConfig", psCosPhi3D);
0540   }
0541   {
0542     edm::ParameterSetDescription psVtxProb;
0543     psVtxProb.add<std::string>("name", "VtxProb");
0544     psVtxProb.add<std::string>("title", "Prob(#chi^{2}_{SV})");
0545     psVtxProb.add<std::string>("yUnits", "");
0546     psVtxProb.add<int>("NxBins", 50);
0547     psVtxProb.add<int>("NyBins", 50);
0548     psVtxProb.add<double>("ymin", 0);
0549     psVtxProb.add<double>("ymax", 1.);
0550     desc.add<edm::ParameterSetDescription>("VtxProbConfig", psVtxProb);
0551   }
0552   {
0553     edm::ParameterSetDescription psVtxDist;
0554     psVtxDist.add<std::string>("name", "VtxDist");
0555     psVtxDist.add<std::string>("title", "d_{xy}(PV,SV)");
0556     psVtxDist.add<std::string>("yUnits", "[#mum]");
0557     psVtxDist.add<int>("NxBins", 50);
0558     psVtxDist.add<int>("NyBins", 100);
0559     psVtxDist.add<double>("ymin", 0);
0560     psVtxDist.add<double>("ymax", 300.);
0561     desc.add<edm::ParameterSetDescription>("VtxDistConfig", psVtxDist);
0562   }
0563   {
0564     edm::ParameterSetDescription psVtxDist3D;
0565     psVtxDist3D.add<std::string>("name", "VtxDist3D");
0566     psVtxDist3D.add<std::string>("title", "d_{3D}(PV,SV)");
0567     psVtxDist3D.add<std::string>("yUnits", "[#mum]");
0568     psVtxDist3D.add<int>("NxBins", 50);
0569     psVtxDist3D.add<int>("NyBins", 250);
0570     psVtxDist3D.add<double>("ymin", 0);
0571     psVtxDist3D.add<double>("ymax", 500.);
0572     desc.add<edm::ParameterSetDescription>("VtxDist3DConfig", psVtxDist3D);
0573   }
0574   {
0575     edm::ParameterSetDescription psVtxDistSig;
0576     psVtxDistSig.add<std::string>("name", "VtxDistSig");
0577     psVtxDistSig.add<std::string>("title", "d_{xy}(PV,SV)/#sigma_{dxy}(PV,SV)");
0578     psVtxDistSig.add<std::string>("yUnits", "");
0579     psVtxDistSig.add<int>("NxBins", 50);
0580     psVtxDistSig.add<int>("NyBins", 100);
0581     psVtxDistSig.add<double>("ymin", 0);
0582     psVtxDistSig.add<double>("ymax", 5.);
0583     desc.add<edm::ParameterSetDescription>("VtxDistSigConfig", psVtxDistSig);
0584   }
0585   {
0586     edm::ParameterSetDescription psVtxDist3DSig;
0587     psVtxDist3DSig.add<std::string>("name", "VtxDist3DSig");
0588     psVtxDist3DSig.add<std::string>("title", "d_{3D}(PV,SV)/#sigma_{d3D}(PV,SV)");
0589     psVtxDist3DSig.add<std::string>("yUnits", "");
0590     psVtxDist3DSig.add<int>("NxBins", 50);
0591     psVtxDist3DSig.add<int>("NyBins", 100);
0592     psVtxDist3DSig.add<double>("ymin", 0);
0593     psVtxDist3DSig.add<double>("ymax", 5.);
0594     desc.add<edm::ParameterSetDescription>("VtxDist3DSigConfig", psVtxDist3DSig);
0595   }
0596 
0597   descriptions.addWithDefaultLabel(desc);
0598 }
0599 
0600 //define this as a plug-in
0601 DEFINE_FWK_MODULE(DiMuonVertexValidation);