CMS 3D CMS Logo

HLTTriMuonIsolation.h
Go to the documentation of this file.
1 #ifndef HLTrigger_Muon_HLTTriMuonIsolation_h
2 #define HLTrigger_Muon_HLTTriMuonIsolation_h
3 
4 #include <iostream>
5 #include <string>
6 
13 
22 
23 
25  public:
26  explicit HLTTriMuonIsolation(const edm::ParameterSet& iConfig);
28  virtual void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
29  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
30 
31  private:
36 
42 
43  static bool ptComparer(const reco::RecoChargedCandidate & mu_1, const reco::RecoChargedCandidate & mu_2) { return mu_1.pt() > mu_2.pt(); }
44 
45  const double Muon1PtCut_ ;
46  const double Muon2PtCut_ ;
47  const double Muon3PtCut_ ;
48  const double TriMuonPtCut_ ;
49  const double TriMuonEtaCut_ ;
50  const double ChargedRelIsoCut_;
51  const double ChargedAbsIsoCut_;
52  const double IsoConeSize_ ;
53  const double MatchingConeSize_;
54  const double MinTriMuonMass_ ;
55  const double MaxTriMuonMass_ ;
56  const double MaxTriMuonRadius_;
57  const int TriMuonAbsCharge_;
58  const double MaxDZ_ ;
59  const bool EnableRelIso_ ;
60  const bool EnableAbsIso_ ;
61 };
62 
64  L3MuonsToken_ (consumes<reco::RecoChargedCandidateCollection> (iConfig.getParameter<edm::InputTag>("L3MuonsSrc" ))),
65  AllMuonsToken_ (consumes<reco::RecoChargedCandidateCollection> (iConfig.getParameter<edm::InputTag>("AllMuonsSrc" ))),
66  L3DiMuonsFilterToken_(consumes<trigger::TriggerFilterObjectWithRefs> (iConfig.getParameter<edm::InputTag>("L3DiMuonsFilterSrc"))),
67  IsoTracksToken_ (consumes<reco::TrackCollection> (iConfig.getParameter<edm::InputTag>("IsoTracksSrc" ))),
68  Muon1PtCut_ (iConfig.getParameter<double> ("Muon1PtCut" )) ,
69  Muon2PtCut_ (iConfig.getParameter<double> ("Muon2PtCut" )) ,
70  Muon3PtCut_ (iConfig.getParameter<double> ("Muon3PtCut" )) ,
71  TriMuonPtCut_ (iConfig.getParameter<double> ("TriMuonPtCut" )) ,
72  TriMuonEtaCut_ (iConfig.getParameter<double> ("TriMuonEtaCut" )) ,
73  ChargedRelIsoCut_ (iConfig.getParameter<double> ("ChargedRelIsoCut" )) ,
74  ChargedAbsIsoCut_ (iConfig.getParameter<double> ("ChargedAbsIsoCut" )) ,
75  IsoConeSize_ (iConfig.getParameter<double> ("IsoConeSize" )) ,
76  MatchingConeSize_ (iConfig.getParameter<double> ("MatchingConeSize" )) ,
77  MinTriMuonMass_ (iConfig.getParameter<double> ("MinTriMuonMass" )) ,
78  MaxTriMuonMass_ (iConfig.getParameter<double> ("MaxTriMuonMass" )) ,
79  MaxTriMuonRadius_ (iConfig.getParameter<double> ("MaxTriMuonRadius" )) ,
80  TriMuonAbsCharge_ (iConfig.getParameter<int> ("TriMuonAbsCharge" )) ,
81  MaxDZ_ (iConfig.getParameter<double> ("MaxDZ" )) ,
82  EnableRelIso_ (iConfig.getParameter<bool> ("EnableRelIso" )) ,
83  EnableAbsIso_ (iConfig.getParameter<bool> ("EnableAbsIso" ))
84 {
85  //register products
86  produces<reco::CompositeCandidateCollection>("Taus");
87  produces<reco::CompositeCandidateCollection>("SelectedTaus");
88 }
89 
91 
92 void
94 {
95  std::unique_ptr<reco::CompositeCandidateCollection> Taus (new reco::CompositeCandidateCollection);
96  std::unique_ptr<reco::CompositeCandidateCollection> SelectedTaus(new reco::CompositeCandidateCollection);
97 
98  // Get the L3 muon candidates
100  iEvent.getByToken(L3MuonsToken_, L3MuCands);
101 
102  // Get the L3 muon candidates that passed the filter
104  iEvent.getByToken(L3DiMuonsFilterToken_, L3DiMuonsFilterCands);
105 
106  std::vector<reco::RecoChargedCandidateRef> PassedL3Muons;
107  L3DiMuonsFilterCands->getObjects(trigger::TriggerMuon, PassedL3Muons);
108 
109  // Get the Trk + L3 muon candidates (after merging)
111  iEvent.getByToken(AllMuonsToken_, AllMuCands);
112 
113  // Get iso tracks
115  iEvent.getByToken(IsoTracksToken_, IsoTracks);
116 
117  if (AllMuCands->size() >= 3 && L3MuCands->size() >= 2){
118  // Create the 3-muon candidates
119  // loop over L3/Trk muons and create all combinations
120  auto AllMuCands_end = AllMuCands->end();
121  for (auto i = AllMuCands->begin(); i != AllMuCands_end-2; ++i) {
122  // check that muon_i passes the previous filter
123  bool passingPreviousFilter_1 = false;
124  for (const auto & imu : PassedL3Muons){
125  if (reco::deltaR2(i->momentum(), imu->momentum()) < (MatchingConeSize_*MatchingConeSize_)) passingPreviousFilter_1 = true;
126  }
127  for (auto j = i+1; j != AllMuCands_end-1; ++j) {
128  // check that muon_j passes the previous filter
129  bool passingPreviousFilter_2 = false;
130  for (const auto & jmu : PassedL3Muons){
131  if (reco::deltaR2(j->momentum(), jmu->momentum()) < (MatchingConeSize_*MatchingConeSize_)) passingPreviousFilter_2 = true;
132  }
133  // if, at this point, no muons passed the previous filter just skip to the next iteration
134  if (!(passingPreviousFilter_1 || passingPreviousFilter_2)) continue;
135  for (auto k = j+1; k != AllMuCands_end; ++k){
136  // check that muon_k passes the previous filter
137  bool passingPreviousFilter_3 = false;
138  for (const auto & kmu : PassedL3Muons){
139  if (reco::deltaR2(k->momentum(), kmu->momentum()) < (MatchingConeSize_*MatchingConeSize_)) passingPreviousFilter_3 = true;
140  }
141  // at least two muons must have passed the previous di-muon filter
142  if (!( (passingPreviousFilter_1 & passingPreviousFilter_2 ) ||
143  (passingPreviousFilter_1 & passingPreviousFilter_3 ) ||
144  (passingPreviousFilter_2 & passingPreviousFilter_3 ) )) continue;
145 
146  // Create a composite candidate to be a tau
148 
149  // sort the muons by pt and add them to the tau
151  daughters.reserve(3);
152 
153  daughters.push_back(*i);
154  daughters.push_back(*j);
155  daughters.push_back(*k);
156 
157  std::sort(daughters.begin(), daughters.end(), ptComparer);
158 
159  tau.addDaughter((daughters)[0], "Muon_1");
160  tau.addDaughter((daughters)[1], "Muon_2");
161  tau.addDaughter((daughters)[2], "Muon_3");
162 
163  // start building the tau
164  int charge = daughters[0].charge() + daughters[1].charge() + daughters[2].charge();
165  math::XYZTLorentzVectorD taup4 = daughters[0].p4() + daughters[1].p4() + daughters[2].p4() ;
166  int tauPdgId = charge > 0? 15 : -15;
167 
168  tau.setP4(taup4);
169  tau.setCharge(charge);
170  tau.setPdgId(tauPdgId);
171  tau.setVertex((daughters)[0].vertex()); // assign the leading muon vertex as tau vertex
172 
173  // the three muons must be close to each other in Z
174  if (std::abs(tau.daughter(0)->vz() - tau.vz()) > MaxDZ_) continue;
175  if (std::abs(tau.daughter(1)->vz() - tau.vz()) > MaxDZ_) continue;
176  if (std::abs(tau.daughter(2)->vz() - tau.vz()) > MaxDZ_) continue;
177 
178  // require muons to be collimated
179  bool collimated = true;
180  for (auto const &idau : daughters){
181  if (reco::deltaR2(tau.p4(), idau.p4()) > MaxTriMuonRadius_*MaxTriMuonRadius_) {
182  collimated = false;
183  break;
184  }
185  }
186 
187  if (!collimated) continue;
188 
189  // a good tau, at last
190  Taus->push_back(tau);
191  }
192  }
193  }
194 
195  // Loop over taus and further select
196  for (const auto & itau : *Taus){
197  if ( itau.pt() < TriMuonPtCut_ ) continue;
198  if ( itau.mass() < MinTriMuonMass_) continue;
199  if ( itau.mass() > MaxTriMuonMass_) continue;
200  if (std::abs(itau.eta()) > TriMuonEtaCut_ ) continue;
201  if (itau.daughter(0)->pt() < Muon1PtCut_ ) continue;
202  if (itau.daughter(1)->pt() < Muon2PtCut_ ) continue;
203  if (itau.daughter(2)->pt() < Muon3PtCut_ ) continue;
204  if ((std::abs(itau.charge()) != TriMuonAbsCharge_) & (TriMuonAbsCharge_ >= 0)) continue;
205  if (std::abs(itau.daughter(0)->vz() - itau.vz()) > MaxDZ_) continue;
206  if (std::abs(itau.daughter(1)->vz() - itau.vz()) > MaxDZ_) continue;
207  if (std::abs(itau.daughter(2)->vz() - itau.vz()) > MaxDZ_) continue;
208 
209  // remove the candidate pt from the iso sum
210  double sumPt = -itau.pt();
211 
212  // compute iso sum pT
213  for (const auto & itrk : *IsoTracks){
214  if (reco::deltaR2(itrk.momentum(), itau.p4()) > IsoConeSize_*IsoConeSize_) continue;
215  if (std::abs(itrk.vz() - itau.vz()) > MaxDZ_) continue;
216  sumPt += itrk.pt();
217  }
218 
219  // apply the isolation cut
220  if ((sumPt > (EnableAbsIso_ * ChargedAbsIsoCut_)) ||
221  (sumPt > (EnableRelIso_ * ChargedRelIsoCut_ * itau.pt()))) continue;
222 
223  SelectedTaus->push_back(itau);
224  }
225  }
226 
227  // finally put the vector of 3-muon candidates in the event
228  iEvent.put(std::move(Taus) , "Taus" );
229  iEvent.put(std::move(SelectedTaus), "SelectedTaus");
230 }
231 
232 void
234 {
236  desc.add<edm::InputTag>("L3MuonsSrc" , edm::InputTag("hltIterL3FromL2MuonCandidates" ));
237  desc.add<edm::InputTag>("AllMuonsSrc" , edm::InputTag("hltGlbTrkMuonCands" ));
238  desc.add<edm::InputTag>("L3DiMuonsFilterSrc", edm::InputTag("hltDiMuonForTau3MuDzFiltered0p3"));
239  desc.add<edm::InputTag>("IsoTracksSrc" , edm::InputTag("hltIter2L3FromL2MuonMerged" ));
240  desc.add<double>("Muon1PtCut" , 5. );
241  desc.add<double>("Muon2PtCut" , 3. );
242  desc.add<double>("Muon3PtCut" , 0. );
243  desc.add<double>("TriMuonPtCut" , 8. );
244  desc.add<double>("TriMuonEtaCut" , 2.5 );
245  desc.add<double>("ChargedAbsIsoCut", 3.0 );
246  desc.add<double>("ChargedRelIsoCut", 0.1 );
247  desc.add<double>("IsoConeSize" , 0.5 );
248  desc.add<double>("MatchingConeSize", 0.03 );
249  desc.add<double>("MinTriMuonMass" , 0.5 );
250  desc.add<double>("MaxTriMuonMass" , 2.8 );
251  desc.add<double>("MaxTriMuonRadius", 0.6 );
252  desc.add<int> ("TriMuonAbsCharge", -1 );
253  desc.add<double>("MaxDZ" , 0.3 );
254  desc.add<bool> ("EnableRelIso" , false);
255  desc.add<bool> ("EnableAbsIso" , true );
256  descriptions.add("hltTriMuonIsolationProducer",desc);
257 }
258 
259 #endif
virtual double pt() const final
transverse momentum
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
const edm::EDGetTokenT< reco::RecoChargedCandidateCollection > AllMuonsToken_
edm::Handle< reco::RecoChargedCandidateCollection > L3MuCands
edm::Handle< trigger::TriggerFilterObjectWithRefs > L3DiMuonsFilterCands
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
const double MaxTriMuonMass_
std::vector< CompositeCandidate > CompositeCandidateCollection
collection of Candidate objects
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
const double MinTriMuonMass_
virtual void setPdgId(int pdgId) final
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
virtual void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
static bool ptComparer(const reco::RecoChargedCandidate &mu_1, const reco::RecoChargedCandidate &mu_2)
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int iEvent
Definition: GenABIO.cc:230
const double ChargedAbsIsoCut_
const double MatchingConeSize_
virtual void setCharge(Charge q) final
set electric charge
Definition: LeafCandidate.h:93
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::Handle< reco::TrackCollection > IsoTracks
ParameterDescriptionBase * add(U const &iLabel, T const &value)
virtual double vz() const
z coordinate of vertex position
virtual void setVertex(const Point &vertex)
set vertex
void addDaughter(const Candidate &, const std::string &s="")
add a clone of the passed candidate as daughter
int k[5][pyjets_maxn]
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< RecoChargedCandidate > RecoChargedCandidateCollection
collectin of RecoChargedCandidate objects
virtual void setP4(const LorentzVector &p4) final
set 4-momentum
virtual const Candidate * daughter(size_type) const
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const double ChargedRelIsoCut_
const edm::EDGetTokenT< reco::RecoChargedCandidateCollection > L3MuonsToken_
edm::Handle< reco::RecoChargedCandidateCollection > AllMuCands
T1 deltaR2(T1 eta1, T2 phi1, T3 eta2, T4 phi2)
Definition: deltaR.h:36
fixed size matrix
HLT enums.
edm::Handle< reco::RecoChargedCandidateRef > PassedL3Muons
HLTTriMuonIsolation(const edm::ParameterSet &iConfig)
virtual double vz() const =0
z coordinate of vertex position
const double MaxTriMuonRadius_
virtual const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
def move(src, dest)
Definition: eostools.py:510
const edm::EDGetTokenT< reco::TrackCollection > IsoTracksToken_
const edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > L3DiMuonsFilterToken_