CMS 3D CMS Logo

MicroGMTCancelOutUnit.cc
Go to the documentation of this file.
1 #include "../interface/MicroGMTCancelOutUnit.h"
4 
5 namespace l1t {
7 {
8 }
9 
11 {
12 
13 }
14 
15 void
17  int fwVersion = microGMTParamsHelper->fwVersion();
26 
35 }
36 
37 void
39 {
40  std::vector<std::shared_ptr<GMTInternalMuon>> coll1;
41  coll1.reserve(3);
42  std::vector<std::shared_ptr<GMTInternalMuon>> coll2;
43  coll2.reserve(3);
44  int maxWedges = 6;
45  if (trackFinder == bmtf) {
46  maxWedges = 12;
47  }
48  for (int currentWedge = 0; currentWedge < maxWedges; ++currentWedge) {
49  for (const auto &mu : wedges.at(currentWedge)) {
50  coll1.push_back(mu);
51  }
52  // handle wrap around: max "wedge" has to be compared to first "wedge"
53  int neighbourWedge = (currentWedge + 1) % maxWedges;
54  for (const auto &mu : wedges.at(neighbourWedge)) {
55  coll2.push_back(mu);
56  }
57  if (mode == cancelmode::coordinate) {
58  getCoordinateCancelBits(coll2, coll1); // in case of a tie coll1 muon wins
59  } else {
60  getTrackAddrCancelBits(coll1, coll2);
61  }
62 
63  coll1.clear();
64  coll2.clear();
65  }
66 }
67 
68 void
70 {
71  // overlap sector collection
72  std::vector<std::shared_ptr<GMTInternalMuon>> coll1;
73  coll1.reserve(3);
74  // barrel wedge collection with 4 wedges
75  std::vector<std::shared_ptr<GMTInternalMuon>> coll2;
76  coll2.reserve(12);
77 
78  for (int currentSector = 0; currentSector < 6; ++currentSector) {
79  for (const auto &omtfMuon : omtfSectors.at(currentSector)) {
80  coll1.push_back(omtfMuon);
81  }
82  // BMTF | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 0 |
83  // OMTF | 0 | 1 | 2 | 3 | 4 | 5 |
84  // cancel OMTF sector x with corresponding BMTF wedge + the two on either side;
85  // e.g. OMTF 0 with BMTF 0, 1, 2, 3, OMTF 2 with BMTF 4, 5, 6, 7 etc.
86  for (int i = 0; i < 4; ++i) {
87  int currentWedge = (currentSector * 2 + i) % 12;
88  for (const auto &bmtfMuon : bmtfWedges.at(currentWedge)) {
89  coll2.push_back(bmtfMuon);
90  }
91  }
92  if (mode == cancelmode::coordinate) {
93  getCoordinateCancelBits(coll1, coll2);
94  } else {
95  getTrackAddrCancelBits(coll1, coll2);
96  }
97  coll1.clear();
98  coll2.clear();
99  }
100 }
101 
102 void
104 {
105  // overlap sector collection
106  std::vector<std::shared_ptr<GMTInternalMuon>> coll1;
107  coll1.reserve(3);
108  // endcap sector collection with 3 sectors
109  std::vector<std::shared_ptr<GMTInternalMuon>> coll2;
110  coll2.reserve(9);
111 
112  for (int curOmtfSector = 0; curOmtfSector < 6; ++curOmtfSector) {
113  for (const auto &omtfMuon : omtfSectors.at(curOmtfSector)) {
114  coll1.push_back(omtfMuon);
115  }
116  // OMTF | 0 | 1 | 2 | 3 | 4 | 5 |
117  // EMTF | 0 | 1 | 2 | 3 | 4 | 5 |
118  // cancel OMTF sector x with corresponding EMTF sector + the ones on either side;
119  // e.g. OMTF 1 with EMTF 0, 1, 2; OMTF 0 with EMTF 5, 0, 1 etc.
120  for (int i = 0; i < 3; ++i) {
121  // handling the wrap around: adding 5 because 0 has to be compared to 5
122  int curEmtfSector = ((curOmtfSector + 5) + i) % 6;
123  for (const auto &emtfMuon : emtfSectors.at(curEmtfSector)) {
124  coll2.push_back(emtfMuon);
125  }
126  }
127  if (mode == cancelmode::coordinate) {
128  getCoordinateCancelBits(coll1, coll2);
129  } else {
130  getTrackAddrCancelBits(coll1, coll2);
131  }
132  coll1.clear();
133  coll2.clear();
134  }
135 }
136 
137 void
138 MicroGMTCancelOutUnit::getCoordinateCancelBits(std::vector<std::shared_ptr<GMTInternalMuon>>& coll1, std::vector<std::shared_ptr<GMTInternalMuon>>& coll2)
139 {
140  if (coll1.empty() || coll2.empty()) {
141  return;
142  }
143  tftype coll1TfType = (*coll1.begin())->trackFinderType();
144  tftype coll2TfType = (*coll2.begin())->trackFinderType();
145  if (coll2TfType != tftype::bmtf && coll1TfType % 2 != coll2TfType % 2) {
146  edm::LogError("Detector side mismatch") << "Overlap-Endcap cancel out between positive and negative detector side attempted. Check eta assignment. OMTF candidate: TF type: " << coll1TfType << ", hwEta: " << (*coll1.begin())->hwEta() << ". EMTF candidate: TF type: " << coll2TfType << ", hwEta: " << (*coll2.begin())->hwEta() << ". TF type even: pos. side; odd: neg. side." << std::endl;
147  return;
148  }
149 
150  MicroGMTMatchQualLUT* matchLUT = m_lutDict.at(coll1TfType+coll2TfType*10).get();
151 
152  for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) {
153  int etaFine1 = (*mu_w1)->hwHF();
154  // for EMTF muons set eta fine bit to true since hwHF is the halo bit
155  if (coll1TfType == tftype::emtf_pos || coll1TfType == tftype::emtf_neg) {
156  etaFine1 = 1;
157  }
158  for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) {
159  int etaFine2 = (*mu_w2)->hwHF();
160  // for EMTF muons set eta fine bit to true since hwHF is the halo bit
161  if (coll2TfType == tftype::emtf_pos || coll2TfType == tftype::emtf_neg) {
162  etaFine2 = 1;
163  }
164  // both muons must have the eta fine bit set in order to use the eta fine part of the LUT
165  int etaFine = (int)(etaFine1 > 0 && etaFine2 > 0);
166 
167  // The LUT for cancellation takes reduced width phi and eta, we need the LSBs
168  int dPhiMask = (1 << matchLUT->getDeltaPhiWidth()) - 1;
169  int dEtaMask = (1 << matchLUT->getDeltaEtaWidth()) - 1;
170 
171  int dPhi = (*mu_w1)->hwGlobalPhi() - (*mu_w2)->hwGlobalPhi();
172  dPhi = std::abs(dPhi);
173  if (dPhi > 338) dPhi -= 576; // shifts dPhi to [-pi, pi) in integer scale
174  dPhi = std::abs(dPhi);
175  int dEta = std::abs((*mu_w1)->hwEta() - (*mu_w2)->hwEta());
176  // check first if the delta is within the LSBs that the LUT takes, otherwise the distance
177  // is greater than what we want to cancel -> e.g. 31(int) is max => 31*0.01 = 0.31 (rad)
178  // LUT takes 5 LSB for dEta and 3 LSB for dPhi
179  if (dEta <= dEtaMask && dPhi <= dPhiMask) {
180  int match = matchLUT->lookup(etaFine, dEta & dEtaMask, dPhi & dPhiMask);
181  if (match == 1) {
182  if((*mu_w1)->hwQual() > (*mu_w2)->hwQual()) {
183  (*mu_w2)->setHwCancelBit(1);
184  } else {
185  (*mu_w1)->setHwCancelBit(1);
186  }
187  }
188  }
189  }
190  }
191 }
192 
193 void
194 MicroGMTCancelOutUnit::getTrackAddrCancelBits(std::vector<std::shared_ptr<GMTInternalMuon>>& coll1, std::vector<std::shared_ptr<GMTInternalMuon>>& coll2)
195 {
196  if (coll1.empty() || coll2.empty()) {
197  return;
198  }
199  // Address based cancel out for BMTF
200  if ((*coll1.begin())->trackFinderType() == tftype::bmtf && (*coll2.begin())->trackFinderType() == tftype::bmtf) {
201  for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) {
202  std::map<int, int> trkAddr_w1 = (*mu_w1)->origin().trackAddress();
203  int wheelNum_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelNum];
204  int wheelSide_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelSide];
205  std::vector<int> stations_w1;
206  stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat1]);
207  stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat2]);
208  stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat3]);
209  stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat4]);
210  //std::cout << "Track address 1: wheelSide (1 == negative side): " << wheelSide_w1 << ", wheelNum: " << wheelNum_w1 << ", stations1234: 0x" << hex << stations_w1[0] << stations_w1[1] << stations_w1[2] << stations_w1[3] << dec << std::endl;
211 
212  for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) {
213  std::map<int, int> trkAddr_w2 = (*mu_w2)->origin().trackAddress();
214  int wheelNum_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelNum];
215  int wheelSide_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelSide];
216  std::vector<int> stations_w2;
217  stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat1]);
218  stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat2]);
219  stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat3]);
220  stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat4]);
221  //std::cout << "Track address 2: wheelSide (1 == negative side): " << wheelSide_w2 << ", wheelNum: " << wheelNum_w2 << ", stations1234: 0x" << hex << stations_w2[0] << stations_w2[1] << stations_w2[2] << stations_w2[3] << dec << std::endl;
222 
223  int nMatchedStations = 0;
224  // search for duplicates in stations 2-4
225  for (int i = 1; i < 4; ++i) {
226  if (wheelSide_w1 == wheelSide_w2) { // both tracks are on the same detector side
227  if (wheelNum_w1 == wheelNum_w2) { // both tracks have the same reference wheel
228  if ((stations_w1[i] == 0x0 && stations_w2[i] == 0x2) ||
229  (stations_w1[i] == 0x1 && stations_w2[i] == 0x3) ||
230  (stations_w1[i] == 0x4 && stations_w2[i] == 0x0) ||
231  (stations_w1[i] == 0x5 && stations_w2[i] == 0x1) ||
232  (stations_w1[i] == 0x8 && stations_w2[i] == 0xA) ||
233  (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) ||
234  (stations_w1[i] == 0xC && stations_w2[i] == 0x8) ||
235  (stations_w1[i] == 0xD && stations_w2[i] == 0x9))
236  {
237  ++nMatchedStations;
238  }
239  } else if (wheelNum_w1 == wheelNum_w2 - 1) { // track 2 is one wheel higher than track 1
240  if ((stations_w1[i] == 0x0 && stations_w2[i] == 0xA) ||
241  (stations_w1[i] == 0x1 && stations_w2[i] == 0xB) ||
242  (stations_w1[i] == 0x4 && stations_w2[i] == 0x8) ||
243  (stations_w1[i] == 0x5 && stations_w2[i] == 0x9))
244  {
245  ++nMatchedStations;
246  }
247  } else if (wheelNum_w1 == wheelNum_w2 + 1) { // track 2 is one wheel lower than track 1
248  if ((stations_w1[i] == 0x8 && stations_w2[i] == 0x2) ||
249  (stations_w1[i] == 0x9 && stations_w2[i] == 0x3) ||
250  (stations_w1[i] == 0xC && stations_w2[i] == 0x0) ||
251  (stations_w1[i] == 0xD && stations_w2[i] == 0x1))
252  {
253  ++nMatchedStations;
254  }
255  }
256  } else {
257  if (wheelNum_w1 == 0 && wheelNum_w2 == 0) { // both tracks are on either side of the central wheel (+0 and -0)
258  if ((stations_w1[i] == 0x8 && stations_w2[i] == 0xA) ||
259  (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) ||
260  (stations_w1[i] == 0xC && stations_w2[i] == 0x8) ||
261  (stations_w1[i] == 0xD && stations_w2[i] == 0x9))
262  {
263  ++nMatchedStations;
264  }
265  }
266  }
267  }
268  //std::cout << "Shared hits found: " << nMatchedStations << std::endl;
269  if (nMatchedStations > 0) {
270  if ((*mu_w1)->origin().hwQual() >= (*mu_w2)->origin().hwQual()) {
271  (*mu_w2)->setHwCancelBit(1);
272  } else {
273  (*mu_w1)->setHwCancelBit(1);
274  }
275  }
276  }
277  }
278  // Address based cancel out for EMTF
279  } else if (((*coll1.begin())->trackFinderType() == tftype::emtf_pos && (*coll2.begin())->trackFinderType() == tftype::emtf_pos)
280  || ((*coll1.begin())->trackFinderType() == tftype::emtf_neg && (*coll2.begin())->trackFinderType() == tftype::emtf_neg)) {
281  for (auto mu_s1 = coll1.begin(); mu_s1 != coll1.end(); ++mu_s1) {
282  std::map<int, int> trkAddr_s1 = (*mu_s1)->origin().trackAddress();
283  int me1_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME1Ch];
284  int me2_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME2Ch];
285  int me3_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME3Ch];
286  int me4_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME4Ch];
287  if (me1_ch_s1 + me2_ch_s1 + me3_ch_s1 + me4_ch_s1 == 0) {
288  continue;
289  }
290  int me1_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME1Seg];
291  int me2_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME2Seg];
292  int me3_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME3Seg];
293  int me4_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME4Seg];
294  for (auto mu_s2 = coll2.begin(); mu_s2 != coll2.end(); ++mu_s2) {
295  std::map<int, int> trkAddr_s2 = (*mu_s2)->origin().trackAddress();
296  int me1_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME1Ch];
297  int me2_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME2Ch];
298  int me3_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME3Ch];
299  int me4_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME4Ch];
300  if (me1_ch_s2 + me2_ch_s2 + me3_ch_s2 + me4_ch_s2 == 0) {
301  continue;
302  }
303  int me1_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME1Seg];
304  int me2_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME2Seg];
305  int me3_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME3Seg];
306  int me4_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME4Seg];
307 
308  int nMatchedStations = 0;
309  if (me1_ch_s2 != 0 && me1_ch_s1 == me1_ch_s2+3 && me1_seg_s1 == me1_seg_s2) {
310  ++nMatchedStations;
311  }
312  if (me2_ch_s2 != 0 && me2_ch_s1 == me2_ch_s2+2 && me2_seg_s1 == me2_seg_s2) {
313  ++nMatchedStations;
314  }
315  if (me3_ch_s2 != 0 && me3_ch_s1 == me3_ch_s2+2 && me3_seg_s1 == me3_seg_s2) {
316  ++nMatchedStations;
317  }
318  if (me4_ch_s2 != 0 && me4_ch_s1 == me4_ch_s2+2 && me4_seg_s1 == me4_seg_s2) {
319  ++nMatchedStations;
320  }
321 
322  //std::cout << "Shared hits found: " << nMatchedStations << std::endl;
323  if (nMatchedStations > 0) {
324  if ((*mu_s1)->origin().hwQual() >= (*mu_s2)->origin().hwQual()) {
325  (*mu_s2)->setHwCancelBit(1);
326  } else {
327  (*mu_s1)->setHwCancelBit(1);
328  }
329  }
330  }
331  }
332  } else {
333  edm::LogError("Cancel out not implemented") << "Address based cancel out is currently only implemented for the barrel track finder.";
334  }
335 }
336 
337 } // namespace l1t
void setCancelOutBitsOverlapEndcap(GMTInternalWedges &, GMTInternalWedges &, cancelmode)
Cancel-out between overlap and endcap track finders.
void initialise(L1TMuonGlobalParamsHelper *)
Initialisation from ES record.
void setCancelOutBitsOverlapBarrel(GMTInternalWedges &, GMTInternalWedges &, cancelmode)
Cancel-out between overlap and barrel track finders.
void getTrackAddrCancelBits(std::vector< std::shared_ptr< GMTInternalMuon >> &, std::vector< std::shared_ptr< GMTInternalMuon >> &)
Compares all muons from coll1 with all muons from coll2 and sets the cancel-bits based on track addre...
std::shared_ptr< MicroGMTMatchQualLUT > m_ovlNegSingleMatchQualLUT
delete x;
Definition: CaloConfig.h:22
void getCoordinateCancelBits(std::vector< std::shared_ptr< GMTInternalMuon >> &, std::vector< std::shared_ptr< GMTInternalMuon >> &)
Compares all muons from coll1 with all muons from coll2 and sets the cancel-bits based on eta/phi coo...
std::shared_ptr< MicroGMTMatchQualLUT > m_foPosMatchQualLUT
std::shared_ptr< MicroGMTMatchQualLUT > m_fwdNegSingleMatchQualLUT
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::shared_ptr< MicroGMTMatchQualLUT > m_fwdPosSingleMatchQualLUT
std::shared_ptr< MicroGMTMatchQualLUT > m_boPosMatchQualLUT
const int mu
Definition: Constants.h:22
virtual int lookup(int etaFine, int dEta, int dPhi) const =0
void setCancelOutBits(GMTInternalWedges &, tftype, cancelmode)
Cancel out between sectors/wedges in one track finder.
std::shared_ptr< MicroGMTMatchQualLUT > m_boNegMatchQualLUT
std::shared_ptr< MicroGMTMatchQualLUT > m_ovlPosSingleMatchQualLUT
std::shared_ptr< MicroGMTMatchQualLUT > m_foNegMatchQualLUT
static ReturnType create(const std::string &filename, const double maxDR, const double fEta, const double fEtaCoarse, const double fPhi, cancel_t cancelType, const int fwVersion)
std::map< int, std::vector< std::shared_ptr< GMTInternalMuon > > > GMTInternalWedges
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
std::map< int, std::shared_ptr< MicroGMTMatchQualLUT > > m_lutDict