@@ -70,12 +70,14 @@ class DiMuonVertexValidation : public edm::one::EDAnalyzer<edm::one::SharedResou
7070private:
7171 void beginJob () override ;
7272 void analyze (const edm::Event&, const edm::EventSetup&) override ;
73+ const reco::Vertex* findClosestVertex (const TransientVertex aTransVtx, const reco::VertexCollection* vertices) const ;
7374 void endJob () override ;
7475
7576 // ----------member data ---------------------------
7677 DiLeptonHelp::Counts myCounts;
7778
78- bool useReco_;
79+ const bool useReco_;
80+ const bool useClosestVertex_;
7981 std::vector<double > pTthresholds_;
8082 float maxSVdist_;
8183
@@ -146,6 +148,7 @@ static constexpr float mumass2 = 0.105658367 * 0.105658367; //mu mass squared (
146148//
147149DiMuonVertexValidation::DiMuonVertexValidation (const edm::ParameterSet& iConfig)
148150 : useReco_(iConfig.getParameter<bool >(" useReco" )),
151+ useClosestVertex_(iConfig.getParameter<bool >(" useClosestVertex" )),
149152 pTthresholds_(iConfig.getParameter<std::vector<double >>(" pTThresholds" )),
150153 maxSVdist_(iConfig.getParameter<double >(" maxSVdist" )),
151154 CosPhiConfiguration_(iConfig.getParameter<edm::ParameterSet>(" CosPhiConfig" )),
@@ -269,6 +272,14 @@ void DiMuonVertexValidation::analyze(const edm::Event& iEvent, const edm::EventS
269272 }
270273 }
271274
275+ #ifdef EDM_ML_DEBUG
276+ for (const auto & track : myTracks) {
277+ edm::LogVerbatim (" DiMuonVertexValidation" ) << __PRETTY_FUNCTION__ << " pT: " << track->pt () << " GeV"
278+ << " , pT error: " << track->ptError () << " GeV"
279+ << " , eta: " << track->eta () << " , phi: " << track->phi () << std::endl;
280+ }
281+ #endif
282+
272283 LogDebug (" DiMuonVertexValidation" ) << " selected tracks: " << myTracks.size () << std::endl;
273284
274285 const TransientTrackBuilder* theB = &iSetup.getData (ttbESToken_);
@@ -288,6 +299,17 @@ void DiMuonVertexValidation::analyze(const edm::Event& iEvent, const edm::EventS
288299 TLorentzVector p4_tplus (tplus->px (), tplus->py (), tplus->pz (), sqrt ((tplus->p () * tplus->p ()) + mumass2));
289300 TLorentzVector p4_tminus (tminus->px (), tminus->py (), tminus->pz (), sqrt ((tminus->p () * tminus->p ()) + mumass2));
290301
302+ #ifdef EDM_ML_DEBUG
303+ // Define a lambda function to convert TLorentzVector to a string
304+ auto tLorentzVectorToString = [](const TLorentzVector& vector) {
305+ return std::to_string (vector.Px ()) + " " + std::to_string (vector.Py ()) + " " + std::to_string (vector.Pz ()) + " " +
306+ std::to_string (vector.E ());
307+ };
308+
309+ edm::LogVerbatim (" DiMuonVertexValidation" ) << " mu+" << tLorentzVectorToString (p4_tplus) << std::endl;
310+ edm::LogVerbatim (" DiMuonVertexValidation" ) << " mu-" << tLorentzVectorToString (p4_tminus) << std::endl;
311+ #endif
312+
291313 const auto & Zp4 = p4_tplus + p4_tminus;
292314 float track_invMass = Zp4.M ();
293315 hTrackInvMass_->Fill (track_invMass);
@@ -323,25 +345,41 @@ void DiMuonVertexValidation::analyze(const edm::Event& iEvent, const edm::EventS
323345 // fill the VtxProb plots
324346 VtxProbPlots.fillPlots (SVProb, tktk_p4);
325347
348+ math::XYZPoint MainVertex (0 , 0 , 0 );
349+ const reco::Vertex* theClosestVertex = nullptr ;
326350 // get collection of reconstructed vertices from event
327351 edm::Handle<reco::VertexCollection> vertexHandle = iEvent.getHandle (vertexToken_);
328-
329- math::XYZPoint MainVertex (0 , 0 , 0 );
330- reco::Vertex TheMainVertex = vertexHandle.product ()->front ();
331-
332352 if (vertexHandle.isValid ()) {
333353 const reco::VertexCollection* vertices = vertexHandle.product ();
334- if ((* vertices). at ( 0 ). isValid ()) {
335- auto theMainVtx = (*vertices). at ( 0 );
336- MainVertex. SetXYZ (theMainVtx. position (). x (), theMainVtx. position (). y (), theMainVtx. position (). z ()) ;
337- }
354+ theClosestVertex = this -> findClosestVertex (aTransientVertex, vertices);
355+ } else {
356+ edm::LogWarning ( " DiMuonVertexMonitor " ) << " invalid vertex collection encountered Skipping event! " ;
357+ return ;
338358 }
339359
360+ reco::Vertex TheMainVertex;
361+ if (!useClosestVertex_ || theClosestVertex == nullptr ) {
362+ // if the closest vertex is not available, or explicitly not chosen
363+ TheMainVertex = vertexHandle.product ()->front ();
364+ } else {
365+ TheMainVertex = *theClosestVertex;
366+ }
367+
368+ MainVertex.SetXYZ (TheMainVertex.position ().x (), TheMainVertex.position ().y (), TheMainVertex.position ().z ());
340369 const math::XYZPoint myVertex (
341370 aTransientVertex.position ().x (), aTransientVertex.position ().y (), aTransientVertex.position ().z ());
342371 const math::XYZPoint deltaVtx (
343372 MainVertex.x () - myVertex.x (), MainVertex.y () - myVertex.y (), MainVertex.z () - myVertex.z ());
344373
374+ #ifdef EDM_ML_DEBUG
375+ edm::LogVerbatim (" DiMuonVertexValidation" )
376+ << " mm vertex position:" << aTransientVertex.position ().x () << " ," << aTransientVertex.position ().y () << " ,"
377+ << aTransientVertex.position ().z ();
378+
379+ edm::LogVerbatim (" DiMuonVertexValidation" ) << " main vertex position:" << TheMainVertex.position ().x () << " ,"
380+ << TheMainVertex.position ().y () << " ," << TheMainVertex.position ().z ();
381+ #endif
382+
345383 if (TheMainVertex.isValid ()) {
346384 // Z Vertex distance in the xy plane
347385
@@ -391,6 +429,11 @@ void DiMuonVertexValidation::analyze(const edm::Event& iEvent, const edm::EventS
391429 hCosPhi_->Fill (cosphi);
392430 hCosPhi3D_->Fill (cosphi3D);
393431
432+ #ifdef EDM_ML_DEBUG
433+ edm::LogVerbatim (" DiMuonVertexValidation" )
434+ << " distance " << distance * cmToum << " cosphi3D:" << cosphi3D << std::endl;
435+ #endif
436+
394437 // fill the cosphi plots
395438 CosPhiPlots.fillPlots (cosphi, tktk_p4);
396439
@@ -489,6 +532,35 @@ void DiMuonVertexValidation::endJob() {
489532 }
490533}
491534
535+ // compute the closest vertex to di-lepton ------------------------------------
536+ const reco::Vertex* DiMuonVertexValidation::findClosestVertex (const TransientVertex aTransVtx,
537+ const reco::VertexCollection* vertices) const {
538+ reco::Vertex* defaultVtx = nullptr ;
539+
540+ if (!aTransVtx.isValid ())
541+ return defaultVtx;
542+
543+ // find the closest vertex to the secondary vertex in 3D
544+ VertexDistance3D vertTool3D;
545+ float minD = 9999 .;
546+ int closestVtxIndex = 0 ;
547+ int counter = 0 ;
548+ for (const auto & vtx : *vertices) {
549+ double dist3D = vertTool3D.distance (aTransVtx, vtx).value ();
550+ if (dist3D < minD) {
551+ minD = dist3D;
552+ closestVtxIndex = counter;
553+ }
554+ counter++;
555+ }
556+
557+ if ((*vertices).at (closestVtxIndex).isValid ()) {
558+ return &(vertices->at (closestVtxIndex));
559+ } else {
560+ return defaultVtx;
561+ }
562+ }
563+
492564// ------------ method fills 'descriptions' with the allowed parameters for the module ------------
493565void DiMuonVertexValidation::fillDescriptions (edm::ConfigurationDescriptions& descriptions) {
494566 edm::ParameterSetDescription desc;
@@ -503,6 +575,7 @@ void DiMuonVertexValidation::fillDescriptions(edm::ConfigurationDescriptions& de
503575 desc.add <edm::InputTag>(" tracks" , edm::InputTag (" generalTracks" ));
504576 desc.add <edm::InputTag>(" vertices" , edm::InputTag (" offlinePrimaryVertices" ));
505577 desc.add <std::vector<double >>(" pTThresholds" , {30 ., 10 .});
578+ desc.add <bool >(" useClosestVertex" , true );
506579 desc.add <double >(" maxSVdist" , 50 .);
507580
508581 {
0 commit comments