1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
//-------------------------------------------------
//
/** \class HLTL1MuonNoL2Selector
*
* HLTL1MuonNoL2Selector:
* Simple selector to output a subset of L1 muon collection
* with no L2 link.
*
* based on RecoMuon/L2MuonSeedGenerator
*
*
* \author S. Folgueras
*/
//
//--------------------------------------------------
// Class Header
#include "HLTL1MuonNoL2Selector.h"
// Framework
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
using namespace std;
using namespace edm;
using namespace l1t;
// constructors
HLTL1MuonNoL2Selector::HLTL1MuonNoL2Selector(const edm::ParameterSet& iConfig)
: theL1Source_(iConfig.getParameter<InputTag>("InputObjects")),
theL1MinPt_(iConfig.getParameter<double>("L1MinPt")),
theL1MaxEta_(iConfig.getParameter<double>("L1MaxEta")),
theL1MinQuality_(iConfig.getParameter<unsigned int>("L1MinQuality")),
centralBxOnly_(iConfig.getParameter<bool>("CentralBxOnly")),
theL2CandTag_(iConfig.getParameter<edm::InputTag>("L2CandTag")),
theL2CandToken_(consumes<reco::RecoChargedCandidateCollection>(theL2CandTag_)),
seedMapTag_(iConfig.getParameter<InputTag>("SeedMapTag")),
seedMapToken_(consumes<SeedMap>(seedMapTag_)) {
muCollToken_ = consumes<MuonBxCollection>(theL1Source_);
produces<MuonBxCollection>();
}
// destructor
HLTL1MuonNoL2Selector::~HLTL1MuonNoL2Selector() = default;
void HLTL1MuonNoL2Selector::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("InputObjects", edm::InputTag(""));
desc.add<edm::InputTag>("L2CandTag", edm::InputTag("hltL2MuonCandidates"));
desc.add<edm::InputTag>("SeedMapTag", edm::InputTag("hltL2Muons"));
desc.add<double>("L1MinPt", -1.);
desc.add<double>("L1MaxEta", 5.0);
desc.add<unsigned int>("L1MinQuality", 0);
// # OBSOLETE - these parameters are ignored, they are left only not to break old configurations
// they will not be printed in the generated cfi.py file
desc.addOptionalNode(edm::ParameterDescription<edm::InputTag>("L1CandTag", edm::InputTag(""), false), false)
->setComment("This parameter is obsolete and will be ignored.");
desc.add<bool>("CentralBxOnly", true);
descriptions.add("hltL1MuonNoL2Selector", desc);
}
void HLTL1MuonNoL2Selector::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
using namespace std;
using namespace reco;
using namespace trigger;
const std::string metname = "Muon|RecoMuon|HLTL1MuonNoL2Selector";
unique_ptr<MuonBxCollection> output(new MuonBxCollection());
// Get hold of L2 trks
edm::Handle<RecoChargedCandidateCollection> L2cands;
iEvent.getByToken(theL2CandToken_, L2cands);
// Muon particles
edm::Handle<MuonBxCollection> muColl;
iEvent.getByToken(muCollToken_, muColl);
LogTrace(metname) << "Number of muons " << muColl->size() << endl;
edm::Handle<SeedMap> seedMapHandle;
iEvent.getByToken(seedMapToken_, seedMapHandle);
for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
if (centralBxOnly_ && (ibx != 0))
continue;
for (auto it = muColl->begin(ibx); it != muColl->end(ibx); it++) {
l1t::MuonRef l1muon(muColl, distance(muColl->begin(muColl->getFirstBX()), it));
unsigned int quality = it->hwQual();
float pt = it->pt();
float eta = it->eta();
if (pt < theL1MinPt_ || std::abs(eta) > theL1MaxEta_ || quality <= theL1MinQuality_)
continue;
// Loop over L2's to find whether the L1 fired this L2.
bool isTriggeredByL1 = false;
for (auto const& cand : *L2cands) {
TrackRef l2muon = cand.get<TrackRef>();
const edm::RefVector<L2MuonTrajectorySeedCollection>& seeds =
(*seedMapHandle)[l2muon->seedRef().castTo<edm::Ref<L2MuonTrajectorySeedCollection> >()];
for (auto const& seed : seeds) {
// Check if the L2 was seeded by a triggered L1, in such case skip the loop.
if (seed->l1tParticle() == l1muon) {
isTriggeredByL1 = true;
break;
}
}
if (isTriggeredByL1)
break; // if I found a L2 I do not need to loop on the rest.
}
// Once we loop on all L2 decide:
if (!isTriggeredByL1) {
output->push_back(ibx, *it);
}
}
} // loop over L1
iEvent.put(std::move(output));
}
// declare this class as a framework plugin
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(HLTL1MuonNoL2Selector);
|