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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
#include "EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.h"
ScGMTRawToDigi::ScGMTRawToDigi(const edm::ParameterSet& iConfig) {
using namespace edm;
srcInputTag = iConfig.getParameter<InputTag>("srcInputTag");
skipInterm_ = iConfig.getParameter<bool>("skipInterm");
debug_ = iConfig.getUntrackedParameter<bool>("debug", false);
// initialize orbit buffer for BX 1->3564;
orbitBuffer_ = std::vector<std::vector<l1ScoutingRun3::Muon>>(3565);
for (auto& bxVec : orbitBuffer_) {
bxVec.reserve(8);
}
nMuonsOrbit_ = 0;
produces<l1ScoutingRun3::MuonOrbitCollection>("Muon").setBranchAlias("MuonOrbitCollection");
rawToken = consumes<SDSRawDataCollection>(srcInputTag);
}
ScGMTRawToDigi::~ScGMTRawToDigi() {}
void ScGMTRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
using namespace edm;
Handle<SDSRawDataCollection> ScoutingRawDataCollection;
iEvent.getByToken(rawToken, ScoutingRawDataCollection);
const FEDRawData& sourceRawData = ScoutingRawDataCollection->FEDData(SDSNumbering::GmtSDSID);
size_t orbitSize = sourceRawData.size();
std::unique_ptr<l1ScoutingRun3::MuonOrbitCollection> unpackedMuons(new l1ScoutingRun3::MuonOrbitCollection);
if ((sourceRawData.size() == 0) && debug_) {
std::cout << "No raw data for GMT FED\n";
}
// unpack current orbit and store data into the orbitBufferr
unpackOrbit(sourceRawData.data(), orbitSize);
// fill orbit collection and clear the Bx buffer vector
unpackedMuons->fillAndClear(orbitBuffer_, nMuonsOrbit_);
// store collection in the event
iEvent.put(std::move(unpackedMuons), "Muon");
}
void ScGMTRawToDigi::unpackOrbit(const unsigned char* buf, size_t len) {
using namespace l1ScoutingRun3;
// reset counters
nMuonsOrbit_ = 0;
size_t pos = 0;
while (pos < len) {
assert(pos + 4 <= len);
// get BX header
uint32_t header = *((uint32_t*)(buf + pos));
pos += 4;
// count mA and mB
uint32_t mAcount = (header & header_masks::mAcount) >> header_shifts::mAcount;
uint32_t mBcount = (header & header_masks::mBcount) >> header_shifts::mBcount;
// declare block to read
ugmt::block* bl = (ugmt::block*)(buf + pos);
pos += 4 + 4 + (mAcount + mBcount) * 12;
assert(pos <= len);
uint32_t orbit = bl->orbit & 0x7FFFFFFF;
uint32_t bx = bl->bx;
if (debug_) {
std::cout << "GMT Orbit " << orbit << ", BX -> " << bx << ", nMuons -> " << mAcount + mBcount << std::endl;
}
// Unpack muons for this BX
orbitBuffer_[bx].reserve(mAcount + mBcount);
for (unsigned int i = 0; i < mAcount + mBcount; i++) {
uint32_t interm = (bl->mu[i].extra >> ugmt::shiftsMuon::interm) & ugmt::masksMuon::interm;
if ((interm == 1) && (skipInterm_)) {
if (debug_) {
std::cout << " -> Excluding intermediate muon\n";
}
continue;
}
uint32_t index = (bl->mu[i].s >> ugmt::shiftsMuon::index) & ugmt::masksMuon::index;
uint32_t ietaextu = (bl->mu[i].f >> ugmt::shiftsMuon::etaext) & ugmt::masksMuon::etaextv;
int32_t ietaext;
if (((bl->mu[i].f >> ugmt::shiftsMuon::etaext) & ugmt::masksMuon::etaexts) != 0) {
ietaext = ietaextu -= 256;
} else {
ietaext = ietaextu;
}
// extract pt and quality and apply cut if required
int32_t iptuncon = (bl->mu[i].s >> ugmt::shiftsMuon::ptuncon) & ugmt::masksMuon::ptuncon;
int32_t ipt = (bl->mu[i].f >> ugmt::shiftsMuon::pt) & ugmt::masksMuon::pt;
if ((ipt - 1) < 0) {
continue;
}
uint32_t qual = (bl->mu[i].f >> ugmt::shiftsMuon::qual) & ugmt::masksMuon::qual;
// extract integer value for extrapolated phi
int32_t iphiext = ((bl->mu[i].f >> ugmt::shiftsMuon::phiext) & ugmt::masksMuon::phiext);
// extract integer value for extrapolated phi
int32_t idxy = ((bl->mu[i].s >> ugmt::shiftsMuon::dxy) & ugmt::masksMuon::dxy);
// extract iso bits and charge
uint32_t iso = (bl->mu[i].s >> ugmt::shiftsMuon::iso) & ugmt::masksMuon::iso;
int32_t chrg = 0;
if (((bl->mu[i].s >> ugmt::shiftsMuon::chrgv) & ugmt::masksMuon::chrgv) == 1)
chrg = ((bl->mu[i].s >> ugmt::shiftsMuon::chrg) & ugmt::masksMuon::chrg) == 1 ? -1 : 1;
// extract eta and phi at muon station
int32_t iphi = (bl->mu[i].s >> ugmt::shiftsMuon::phi) & ugmt::masksMuon::phi;
uint32_t ieta1 = (bl->mu[i].extra >> ugmt::shiftsMuon::eta1) & ugmt::masksMuon::eta;
uint32_t ieta2 = (bl->mu[i].extra >> ugmt::shiftsMuon::eta2) & ugmt::masksMuon::eta;
uint32_t ieta_u;
int32_t ieta;
// checking if raw eta should be taken from muon 1 or muon 2
if ((bl->mu[i].extra & 0x1) == 0) {
ieta_u = ieta1;
} else {
ieta_u = ieta2;
}
// two's complement
if (ieta_u > 256) {
ieta = ieta_u - 512;
} else {
ieta = ieta_u;
}
// increment muon counter
nMuonsOrbit_++;
l1ScoutingRun3::Muon muon(ipt, ieta, iphi, qual, chrg, chrg != 0, iso, index, ietaext, iphiext, iptuncon, idxy);
orbitBuffer_[bx].push_back(muon);
if (debug_) {
std::cout << "--- Muon " << i << " ---\n";
std::cout << " Raw f: 0x" << std::hex << bl->mu[i].f << std::dec << "\n";
std::cout << " Raw s: 0x" << std::hex << bl->mu[i].s << std::dec << "\n";
std::cout << " Raw extra: 0x" << std::hex << bl->mu[i].extra << std::dec << "\n";
printMuon(muon);
}
} // end of bx
} // end orbit while loop
}
void ScGMTRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("srcInputTag", edm::InputTag("rawDataCollector"));
desc.add<bool>("skipInterm", true);
desc.addUntracked<bool>("debug", false);
descriptions.add("ScGMTRawToDigi", desc);
}
DEFINE_FWK_MODULE(ScGMTRawToDigi);
|