Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:49

0001 #include <iostream>
0002 
0003 #include "FWCore/Framework/interface/ESHandle.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 
0006 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0007 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
0008 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0009 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
0010 #include "DataFormats/Candidate/interface/Candidate.h"
0011 
0012 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0013 #include "DataFormats/TrackReco/interface/Track.h"
0014 
0015 #include "DataFormats/VertexReco/interface/Vertex.h"
0016 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0017 #include "DataFormats/Common/interface/RefToBase.h"
0018 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
0019 #include "DataFormats/HLTReco/interface/TriggerRefsCollections.h"
0020 
0021 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0022 
0023 #include "DataFormats/Math/interface/Error.h"
0024 #include "DataFormats/Math/interface/Point3D.h"
0025 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0026 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
0027 
0028 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0029 
0030 #include "HLTDisplacedmumumuFilter.h"
0031 #include "TMath.h"
0032 
0033 //
0034 // constructors and destructor
0035 //
0036 HLTDisplacedmumumuFilter::HLTDisplacedmumumuFilter(const edm::ParameterSet& iConfig)
0037     : HLTFilter(iConfig),
0038       fastAccept_(iConfig.getParameter<bool>("FastAccept")),
0039       minLxySignificance_(iConfig.getParameter<double>("MinLxySignificance")),
0040       maxLxySignificance_(iConfig.getParameter<double>("MaxLxySignificance")),
0041       maxNormalisedChi2_(iConfig.getParameter<double>("MaxNormalisedChi2")),
0042       minVtxProbability_(iConfig.getParameter<double>("MinVtxProbability")),
0043       minCosinePointingAngle_(iConfig.getParameter<double>("MinCosinePointingAngle")),
0044       DisplacedVertexTag_(iConfig.getParameter<edm::InputTag>("DisplacedVertexTag")),
0045       DisplacedVertexToken_(consumes<reco::VertexCollection>(DisplacedVertexTag_)),
0046       beamSpotTag_(iConfig.getParameter<edm::InputTag>("BeamSpotTag")),
0047       beamSpotToken_(consumes<reco::BeamSpot>(beamSpotTag_)),
0048       MuonTag_(iConfig.getParameter<edm::InputTag>("MuonTag")),
0049       MuonToken_(consumes<reco::RecoChargedCandidateCollection>(MuonTag_)) {}
0050 
0051 HLTDisplacedmumumuFilter::~HLTDisplacedmumumuFilter() = default;
0052 
0053 void HLTDisplacedmumumuFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0054   edm::ParameterSetDescription desc;
0055   makeHLTFilterDescription(desc);
0056   desc.add<bool>("FastAccept", false);
0057   desc.add<double>("MinLxySignificance", 0.0);
0058   desc.add<double>("MaxLxySignificance", 0.0);
0059   desc.add<double>("MaxNormalisedChi2", 10.0);
0060   desc.add<double>("MinVtxProbability", 0.0);
0061   desc.add<double>("MinCosinePointingAngle", -2.0);
0062   desc.add<edm::InputTag>("DisplacedVertexTag", edm::InputTag("hltDisplacedmumumuVtx"));
0063   desc.add<edm::InputTag>("BeamSpotTag", edm::InputTag("hltOnlineBeamSpot"));
0064   desc.add<edm::InputTag>("MuonTag", edm::InputTag("hltL3MuonCandidates"));
0065   descriptions.add("hltDisplacedmumumuFilter", desc);
0066 }
0067 
0068 // ------------ method called once each job just before starting event loop  ------------
0069 void HLTDisplacedmumumuFilter::beginJob() {}
0070 
0071 // ------------ method called once each job just after ending the event loop  ------------
0072 void HLTDisplacedmumumuFilter::endJob() {}
0073 
0074 // ------------ method called on each new Event  ------------
0075 bool HLTDisplacedmumumuFilter::hltFilter(edm::Event& iEvent,
0076                                          const edm::EventSetup& iSetup,
0077                                          trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0078   // get beam spot
0079   reco::BeamSpot vertexBeamSpot;
0080   edm::Handle<reco::BeamSpot> recoBeamSpotHandle;
0081   iEvent.getByToken(beamSpotToken_, recoBeamSpotHandle);
0082   vertexBeamSpot = *recoBeamSpotHandle;
0083 
0084   // get displaced vertices
0085   reco::VertexCollection displacedVertexColl;
0086   edm::Handle<reco::VertexCollection> displacedVertexCollHandle;
0087   bool foundVertexColl = iEvent.getByToken(DisplacedVertexToken_, displacedVertexCollHandle);
0088   if (foundVertexColl)
0089     displacedVertexColl = *displacedVertexCollHandle;
0090 
0091   // get muon collection
0092   edm::Handle<reco::RecoChargedCandidateCollection> mucands;
0093   iEvent.getByToken(MuonToken_, mucands);
0094 
0095   // All HLT filters must create and fill an HLT filter object,
0096   // recording any reconstructed physics objects satisfying (or not)
0097   // this HLT filter, and place it in the Event.
0098 
0099   // Ref to Candidate object to be recorded in filter object
0100   reco::RecoChargedCandidateRef ref1;
0101   reco::RecoChargedCandidateRef ref2;
0102   reco::RecoChargedCandidateRef ref3;
0103 
0104   if (saveTags())
0105     filterproduct.addCollectionTag(MuonTag_);
0106 
0107   bool triggered = false;
0108 
0109   // loop over vertex collection
0110   for (const auto& displacedVertex : displacedVertexColl) {
0111     // check if the vertex actually consists of exactly two muon tracks, throw exception if not
0112     if (displacedVertex.tracksSize() != 3)
0113       throw cms::Exception("BadLogic") << "HLTDisplacedmumumuFilter: ERROR: the Jpsi vertex must have exactly three "
0114                                           "muons by definition. It now has n muons = "
0115                                        << displacedVertex.tracksSize() << std::endl;
0116 
0117     float normChi2 = displacedVertex.normalizedChi2();
0118     if (normChi2 > maxNormalisedChi2_)
0119       continue;
0120 
0121     double vtxProb = 0.0;
0122     if ((displacedVertex.chi2() >= 0.0) && (displacedVertex.ndof() > 0))
0123       vtxProb = TMath::Prob(displacedVertex.chi2(), displacedVertex.ndof());
0124     if (vtxProb < minVtxProbability_)
0125       continue;
0126 
0127     // get the two muons from the vertex
0128     auto trackIt = displacedVertex.tracks_begin();
0129     reco::TrackRef vertextkRef1 = (*trackIt).castTo<reco::TrackRef>();
0130     // the second one
0131     trackIt++;
0132     reco::TrackRef vertextkRef2 = (*trackIt).castTo<reco::TrackRef>();
0133     // the second one
0134     trackIt++;
0135     reco::TrackRef vertextkRef3 = (*trackIt).castTo<reco::TrackRef>();
0136 
0137     reco::RecoChargedCandidateCollection::const_iterator cand1;
0138     reco::RecoChargedCandidateCollection::const_iterator cand2;
0139     reco::RecoChargedCandidateCollection::const_iterator cand3;
0140 
0141     // first find these two tracks in the muon collection
0142     int iFoundRefs = 0;
0143     for (auto cand = mucands->begin(); cand != mucands->end(); cand++) {
0144       reco::TrackRef tkRef = cand->get<reco::TrackRef>();
0145       if (tkRef == vertextkRef1) {
0146         cand1 = cand;
0147         iFoundRefs++;
0148       }
0149       if (tkRef == vertextkRef2) {
0150         cand2 = cand;
0151         iFoundRefs++;
0152       }
0153       if (tkRef == vertextkRef3) {
0154         cand3 = cand;
0155         iFoundRefs++;
0156       }
0157     }
0158     if (iFoundRefs < 3)
0159       throw cms::Exception("BadLogic") << "HLTDisplacedmumumuFilter: ERROR: the muons matched with the Jpsi vertex "
0160                                           "tracks should be at least three by definition."
0161                                        << std::endl;
0162 
0163     // calculate two-track transverse momentum
0164     math::XYZVector pperp(cand1->px() + cand2->px() + cand3->px(), cand1->py() + cand2->py() + cand3->py(), 0.);
0165 
0166     const reco::Vertex::Point& vpoint = displacedVertex.position();
0167     //translate to global point, should be improved
0168     GlobalPoint secondaryVertex(vpoint.x(), vpoint.y(), vpoint.z());
0169 
0170     reco::Vertex::Error verr = displacedVertex.error();
0171     // translate to global error, should be improved
0172     GlobalError err(verr.At(0, 0), verr.At(1, 0), verr.At(1, 1), verr.At(2, 0), verr.At(2, 1), verr.At(2, 2));
0173 
0174     GlobalPoint displacementFromBeamspot(-1 * ((vertexBeamSpot.x0() - secondaryVertex.x()) +
0175                                                (secondaryVertex.z() - vertexBeamSpot.z0()) * vertexBeamSpot.dxdz()),
0176                                          -1 * ((vertexBeamSpot.y0() - secondaryVertex.y()) +
0177                                                (secondaryVertex.z() - vertexBeamSpot.z0()) * vertexBeamSpot.dydz()),
0178                                          0);
0179 
0180     float lxy = displacementFromBeamspot.perp();
0181     float lxyerr = sqrt(err.rerr(displacementFromBeamspot));
0182 
0183     //calculate the angle between the decay length and the mumumu momentum
0184     reco::Vertex::Point vperp(displacementFromBeamspot.x(), displacementFromBeamspot.y(), 0.);
0185 
0186     float cosAlpha = vperp.Dot(pperp) / (vperp.R() * pperp.R());
0187 
0188     // check thresholds
0189     if (cosAlpha < minCosinePointingAngle_)
0190       continue;
0191     if (minLxySignificance_ > 0. && lxy / lxyerr < minLxySignificance_)
0192       continue;
0193     if (maxLxySignificance_ > 0. && lxy / lxyerr > maxLxySignificance_)
0194       continue;
0195     triggered = true;
0196 
0197     // now add the muons that passed to the filter object
0198 
0199     ref1 = reco::RecoChargedCandidateRef(
0200         edm::Ref<reco::RecoChargedCandidateCollection>(mucands, distance(mucands->begin(), cand1)));
0201     filterproduct.addObject(trigger::TriggerMuon, ref1);
0202 
0203     ref2 = reco::RecoChargedCandidateRef(
0204         edm::Ref<reco::RecoChargedCandidateCollection>(mucands, distance(mucands->begin(), cand2)));
0205     filterproduct.addObject(trigger::TriggerMuon, ref2);
0206 
0207     ref3 = reco::RecoChargedCandidateRef(
0208         edm::Ref<reco::RecoChargedCandidateCollection>(mucands, distance(mucands->begin(), cand3)));
0209     filterproduct.addObject(trigger::TriggerMuon, ref3);
0210   }
0211 
0212   LogDebug("HLTDisplacedMumumuFilter") << " >>>>> Result of HLTDisplacedMumumuFilter is " << triggered << std::endl;
0213 
0214   return triggered;
0215 }