CMS 3D CMS Logo

OMTFinputMaker.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <vector>
3 #include <iostream>
4 #include <algorithm>
5 
10 
17 
21  : myAngleConverter(std::make_unique<AngleConverter>(iC, getDuringEvent)) {}
24 void OMTFinputMaker::initialize(const edm::EventSetup &es, const OMTFConfiguration *omtfConfig) {
25  myAngleConverter->checkAndUpdateGeometry(es, omtfConfig->nPhiBins());
26 
27  myOmtfConfig = omtfConfig;
28 }
34 bool OMTFinputMaker::acceptDigi(uint32_t rawId, unsigned int iProcessor, l1t::tftype type) {
35  unsigned int aMin = myOmtfConfig->getBarrelMin()[iProcessor];
36  unsigned int aMax = myOmtfConfig->getBarrelMax()[iProcessor];
37  unsigned int aSector = 99;
38 
40  DetId detId(rawId);
41  if (detId.det() != DetId::Muon)
42  edm::LogError("Critical OMTFinputMaker") << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
43  switch (detId.subdetId()) {
44  case MuonSubdetId::RPC: {
45  RPCDetId aId(rawId);
46 
48  if (type == l1t::tftype::omtf_pos &&
49  (aId.region() < 0 || (aId.region() == 0 && aId.ring() != 2) || (aId.region() == 0 && aId.station() == 4) ||
50  (aId.region() == 0 && aId.station() == 2 && aId.layer() == 2 && aId.roll() == 1) ||
51  (aId.region() == 0 && aId.station() == 3 && aId.roll() == 1) || (aId.region() == 1 && aId.station() == 4) ||
53  (aId.region() == 1 && aId.station() > 0 && aId.ring() < 3)))
54  return false;
55 
56  if (type == l1t::tftype::omtf_neg &&
57  (aId.region() > 0 || (aId.region() == 0 && aId.ring() != -2) || (aId.region() == 0 && aId.station() == 4) ||
58  (aId.region() == 0 && aId.station() == 2 && aId.layer() == 2 && aId.roll() == 1) ||
59  (aId.region() == 0 && aId.station() == 3 && aId.roll() == 1) || (aId.region() == -1 && aId.station() == 4) ||
60  //RPC RE1/2 temporarily not used (aId.region()==1 && aId.station()==1 && aId.ring()<2) ||
61  (aId.region() == -1 && aId.station() > 0 && aId.ring() < 3)))
62  return false;
63 
64  if (type == l1t::tftype::bmtf && aId.region() != 0)
65  return false;
66 
67  if (type == l1t::tftype::emtf_pos && (aId.region() <= 0 || (aId.station() == 1 && aId.ring() == 3)))
68  return false;
69  if (type == l1t::tftype::emtf_neg && (aId.region() >= 0 || (aId.station() == 1 && aId.ring() == 3)))
70  return false;
72  if (aId.region() == 0)
73  aSector = aId.sector();
74  if (aId.region() != 0) {
75  aSector = (aId.sector() - 1) * 6 + aId.subsector();
76  aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
77  aMax = myOmtfConfig->getEndcap10DegMax()[iProcessor];
78  }
79 
80  break;
81  }
82  case MuonSubdetId::DT: {
84 
85  if (type == l1t::tftype::omtf_pos && dt.wheel() != 2)
86  return false;
87  if (type == l1t::tftype::omtf_neg && dt.wheel() != -2)
88  return false;
90  return false;
91 
92  aSector = dt.sector();
93  break;
94  }
95  case MuonSubdetId::CSC: {
97  if (type == l1t::tftype::omtf_pos && (csc.endcap() == 2 || csc.ring() == 1 || csc.station() == 4))
98  return false;
99  if (type == l1t::tftype::omtf_neg && (csc.endcap() == 1 || csc.ring() == 1 || csc.station() == 4))
100  return false;
101 
102  if (type == l1t::tftype::emtf_pos && (csc.endcap() == 2 || (csc.station() == 1 && csc.ring() == 3)))
103  return false;
104  if (type == l1t::tftype::emtf_neg && (csc.endcap() == 1 || (csc.station() == 1 && csc.ring() == 3)))
105  return false;
106 
107  aSector = csc.chamber();
108  aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
109  aMax = myOmtfConfig->getEndcap10DegMax()[iProcessor];
110 
111  if ((type == l1t::tftype::emtf_pos || type == l1t::tftype::emtf_neg) && csc.station() > 1 && csc.ring() == 1) {
112  aMin = myOmtfConfig->getEndcap20DegMin()[iProcessor];
113  aMax = myOmtfConfig->getEndcap20DegMax()[iProcessor];
114  }
115  break;
116  }
117  }
118 
119  if (aMax > aMin && aSector >= aMin && aSector <= aMax)
120  return true;
121  if (aMax < aMin && (aSector >= aMin || aSector <= aMax))
122  return true;
123 
124  return false;
125 }
128 unsigned int OMTFinputMaker::getInputNumber(unsigned int rawId, unsigned int iProcessor, l1t::tftype type) {
129  unsigned int iInput = 99;
130  unsigned int aSector = 99;
131  int aMin = myOmtfConfig->getBarrelMin()[iProcessor];
132  int iRoll = 1;
133  int nInputsPerSector = 2;
134 
135  DetId detId(rawId);
136  if (detId.det() != DetId::Muon)
137  edm::LogError("Critical OMTFinputMaker") << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
138  switch (detId.subdetId()) {
139  case MuonSubdetId::RPC: {
140  RPCDetId rpc(rawId);
141  if (rpc.region() == 0) {
142  nInputsPerSector = 4;
143  aSector = rpc.sector();
146  if (iProcessor == 5 && aSector < 3)
147  aMin = -1;
148  //Use division into rolls
149  iRoll = rpc.roll();
152  if (rpc.station() == 2 && rpc.layer() == 2 && rpc.roll() == 2)
153  iRoll = 1;
155  if (rpc.station() == 3) {
156  iRoll = 1;
157  nInputsPerSector = 2;
158  }
160  if (type == l1t::tftype::bmtf)
161  iRoll = 1;
162  }
163  if (rpc.region() != 0) {
164  aSector = (rpc.sector() - 1) * 6 + rpc.subsector();
165  aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
168  if (iProcessor == 5 && aSector < 5)
169  aMin = -4;
170  }
171  break;
172  }
173  case MuonSubdetId::DT: {
175  aSector = dt.sector();
178  if (iProcessor == 5 && aSector < 3)
179  aMin = -1;
180  break;
181  }
182  case MuonSubdetId::CSC: {
183  CSCDetId csc(rawId);
184  aSector = csc.chamber();
185  aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
188  if (iProcessor == 5 && aSector < 5)
189  aMin = -4;
193  if ((type == l1t::tftype::emtf_pos || type == l1t::tftype::emtf_neg) && csc.station() > 1 && csc.ring() == 1) {
194  aMin = myOmtfConfig->getEndcap20DegMin()[iProcessor];
195  if (iProcessor == 5 && aSector < 3)
196  aMin = -2;
197  }
198  break;
199  }
200  }
201 
203  iInput = (aSector - aMin) * nInputsPerSector;
205  iInput += iRoll - 1;
206 
207  return iInput;
208 }
212  const L1MuDTChambThContainer *dtThDigis,
213  unsigned int iProcessor,
215  int bxTrg) {
217  if (!dtPhDigis)
218  return result;
219 
220  for (const auto &digiIt : *dtPhDigis->getContainer()) {
221  DTChamberId detid(digiIt.whNum(), digiIt.stNum(), digiIt.scNum() + 1);
222 
224  if (!acceptDigi(detid.rawId(), iProcessor, type))
225  continue;
226 
231  // FIXME (MK): at least Ts2Tag selection is not correct! Check it
232  // if (digiIt.bxNum()!= 0 || digiIt.BxCnt()!= 0 || digiIt.Ts2Tag()!= 0 || digiIt.code()<4) continue;
233 
234  if (digiIt.bxNum() != bxTrg)
235  continue;
236 
237  if (myOmtfConfig->fwVersion() <= 4) {
238  if (digiIt.code() != 4 && digiIt.code() != 5 && digiIt.code() != 6)
239  continue;
240  } else {
241  if (digiIt.code() != 2 && digiIt.code() != 3 && digiIt.code() != 4 && digiIt.code() != 5 && digiIt.code() != 6)
242  continue;
243  }
244 
245  unsigned int hwNumber = myOmtfConfig->getLayerNumber(detid.rawId());
246  if (myOmtfConfig->getHwToLogicLayer().find(hwNumber) == myOmtfConfig->getHwToLogicLayer().end())
247  continue;
248 
249  auto iter = myOmtfConfig->getHwToLogicLayer().find(hwNumber);
250  unsigned int iLayer = iter->second;
251  int iPhi = myAngleConverter->getProcessorPhi(iProcessor, type, digiIt);
252  int iEta = myAngleConverter->getGlobalEta(detid.rawId(), digiIt, dtThDigis);
253  unsigned int iInput = getInputNumber(detid.rawId(), iProcessor, type);
254  bool allowOverwrite = false;
255  result.addLayerHit(iLayer, iInput, iPhi, iEta, allowOverwrite);
256  result.addLayerHit(iLayer + 1, iInput, digiIt.phiB(), iEta, allowOverwrite);
257  }
258 
259  return result;
260 }
264  unsigned int iProcessor,
266  int bxTrg) {
268  if (!cscDigis)
269  return result;
270 
271  auto chamber = cscDigis->begin();
272  auto chend = cscDigis->end();
273  for (; chamber != chend; ++chamber) {
274  unsigned int rawid = (*chamber).first;
276  if (!acceptDigi(rawid, iProcessor, type))
277  continue;
278  auto digi = (*chamber).second.first;
279  auto dend = (*chamber).second.second;
280  for (; digi != dend; ++digi) {
282  if (digi->getBX() - CSCConstants::LCT_CENTRAL_BX != bxTrg)
283  continue;
284 
285  unsigned int hwNumber = myOmtfConfig->getLayerNumber(rawid);
286  if (myOmtfConfig->getHwToLogicLayer().find(hwNumber) == myOmtfConfig->getHwToLogicLayer().end())
287  continue;
288 
289  unsigned int iLayer = myOmtfConfig->getHwToLogicLayer().at(hwNumber);
290  int iPhi = myAngleConverter->getProcessorPhi(iProcessor, type, CSCDetId(rawid), *digi);
291  int iEta = myAngleConverter->getGlobalEta(rawid, *digi);
295  //if(abs(iEta)>1.26/2.61*240) continue;
296  //if (abs(iEta) > 115) continue;
297  unsigned int iInput = getInputNumber(rawid, iProcessor, type);
298  // std::cout <<" ADDING CSC hit, proc: "<<iProcessor<<" iPhi : " << iPhi <<" iEta: "<< iEta << std::endl;
299  bool allowOverwrite = false;
300  result.addLayerHit(iLayer, iInput, iPhi, iEta, allowOverwrite);
301  }
302  }
303  return result;
304 }
307 bool rpcPrimitiveCmp(const RPCDigi &a, const RPCDigi &b) { return a.strip() < b.strip(); };
311  unsigned int iProcessor,
313  int bxTrg) {
315  if (!rpcDigis)
316  return result;
317  std::stringstream str;
318 
319  // std::cout <<" RPC HITS, processor : " << iProcessor << std::endl;
320 
321  const RPCDigiCollection &rpcDigiCollection = *rpcDigis;
322  for (auto rollDigis : rpcDigiCollection) {
323  RPCDetId roll = rollDigis.first;
324  unsigned int rawid = roll.rawId();
325  if (!acceptDigi(rawid, iProcessor, type))
326  continue;
330  // for (auto tdigi = rollDigis.second.first; tdigi != rollDigis.second.second; tdigi++) { std::cout << "RPC DIGIS: " << roll.rawId()<< " "<<roll<<" digi: " << tdigi->strip() <<" bx: " << tdigi->bx() << std::endl; }
331  std::vector<RPCDigi> digisCopy;
332  // std::copy_if(rollDigis.second.first, rollDigis.second.second, std::back_inserter(digisCopy), [](const RPCDigi & aDigi){return (aDigi.bx()==0);} );
333  for (auto pDigi = rollDigis.second.first; pDigi != rollDigis.second.second; pDigi++) {
334  if (pDigi->bx() == bxTrg)
335  digisCopy.push_back(*pDigi);
336  }
337  std::sort(digisCopy.begin(), digisCopy.end(), rpcPrimitiveCmp);
338  typedef std::pair<unsigned int, unsigned int> Cluster;
339  std::vector<Cluster> clusters;
340  for (auto &digi : digisCopy) {
341  if (clusters.empty())
342  clusters.push_back(Cluster(digi.strip(), digi.strip()));
343  else if (digi.strip() - clusters.back().second == 1)
344  clusters.back().second = digi.strip();
345  else if (digi.strip() - clusters.back().second > 1)
346  clusters.push_back(Cluster(digi.strip(), digi.strip()));
347  }
348 
349  for (auto &cluster : clusters) {
350  // int iPhiHalfStrip1 = myAngleConverter->getProcessorPhi(iProcessor, type, roll, cluster.first);
351  // int iPhiHalfStrip2 = myAngleConverter->getProcessorPhi(iProcessor, type, roll, cluster.second);
352  int iPhi = myAngleConverter->getProcessorPhi(iProcessor, type, roll, cluster.first, cluster.second);
353  int cSize = abs(int(cluster.first) - int(cluster.second)) + 1;
354  // std::cout << " HStrip_1: " << iPhiHalfStrip1 <<" HStrip_2: "<<iPhiHalfStrip2<<" iPhi: " << iPhi << " cluster: ["<< cluster.first << ", "<< cluster.second <<"]"<< std::endl;
355  if (cSize > 3)
356  continue;
357  int iEta = myAngleConverter->getGlobalEta(rawid, cluster.first);
358  unsigned int hwNumber = myOmtfConfig->getLayerNumber(rawid);
359  unsigned int iLayer = myOmtfConfig->getHwToLogicLayer().at(hwNumber);
360  unsigned int iInput = getInputNumber(rawid, iProcessor, type);
361  // std::cout <<"ADDING HIT: iLayer = " << iLayer << " iInput: " << iInput << " iPhi: " << iPhi << std::endl;
362  if (iLayer == 17 && (iInput == 0 || iInput == 1))
363  continue; // FIXME (MK) there is no RPC link for that input, because it is taken by DAQ link
364  bool outres = result.addLayerHit(iLayer, iInput, iPhi, iEta);
365  // if (cSize>2) flag |= 2;
366  // if (!outres) flag |= 1;
367 
368  str << " RPC halfDigi "
369  << " begin: " << cluster.first << " end: " << cluster.second << " iPhi: " << iPhi << " iEta: " << iEta
370  << " hwNumber: " << hwNumber << " iInput: " << iInput << " iLayer: " << iLayer << " out: " << outres
371  << std::endl;
372  }
373  }
374 
375  edm::LogInfo("OMTFInputMaker") << str.str();
376  return result;
377 }
381  const L1MuDTChambThContainer *dtThDigis,
382  const CSCCorrelatedLCTDigiCollection *cscDigis,
383  const RPCDigiCollection *rpcDigis,
384  unsigned int iProcessor,
386  int bx) {
388  result += processDT(dtPhDigis, dtThDigis, iProcessor, type, bx);
389  result += processCSC(cscDigis, iProcessor, type, bx);
390  result += processRPC(rpcDigis, iProcessor, type, bx);
391  return result;
392 }
int sector() const
Sector id: the group of chambers at same phi (and increasing r)
Definition: RPCDetId.h:81
float dt
Definition: AMPTWrapper.h:136
const std::vector< unsigned int > & getEndcap20DegMin() const
OMTFinput buildInputForProcessor(const L1MuDTChambPhContainer *dtPhDigis, const L1MuDTChambThContainer *dtThDigis, const CSCCorrelatedLCTDigiCollection *cscDigis, const RPCDigiCollection *rpcDigis, unsigned int iProcessor, l1t::tftype type=l1t::tftype::omtf_pos, int bx=0)
Method translating trigger digis into input matrix with global phi coordinates.
const std::vector< unsigned int > & getEndcap20DegMax() const
const std::vector< unsigned int > & getBarrelMin() const
OMTFinput processRPC(const RPCDigiCollection *rpcDigis, unsigned int iProcessor, l1t::tftype type, int bx)
const std::vector< unsigned int > & getBarrelMax() const
int ring() const
Definition: RPCDetId.h:59
void initialize(const edm::EventSetup &, const OMTFConfiguration *)
const OMTFConfiguration * myOmtfConfig
unsigned int fwVersion() const
unsigned int nPhiBins() const
OMTFinput processCSC(const CSCCorrelatedLCTDigiCollection *cscDigis, unsigned int iProcessor, l1t::tftype type, int bx)
bool rpcPrimitiveCmp(const RPCDigi &a, const RPCDigi &b)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int roll() const
Definition: RPCDetId.h:92
int subsector() const
SubSector id : some sectors are divided along the phi direction in subsectors (from 1 to 4 in Barrel...
Definition: RPCDetId.h:88
Definition: L1Track.h:19
Log< level::Info, false > LogInfo
Definition: DetId.h:17
bool acceptDigi(uint32_t rawId, unsigned int iProcessor, l1t::tftype type)
Phi_Container const * getContainer() const
std::unique_ptr< AngleConverter > myAngleConverter
unsigned int getInputNumber(unsigned int rawId, unsigned int iProcessor, l1t::tftype type)
static constexpr int RPC
Definition: MuonSubdetId.h:13
double b
Definition: hdecay.h:120
int station() const
Definition: RPCDetId.h:78
int region() const
Region id: 0 for Barrel, +/-1 For +/- Endcap.
Definition: RPCDetId.h:53
const std::vector< unsigned int > & getEndcap10DegMin() const
const std::map< int, int > & getHwToLogicLayer() const
const std::vector< unsigned int > & getEndcap10DegMax() const
double a
Definition: hdecay.h:121
int layer() const
Definition: RPCDetId.h:85
static constexpr int DT
Definition: MuonSubdetId.h:11
#define str(s)
static constexpr int CSC
Definition: MuonSubdetId.h:12
OMTFinput processDT(const L1MuDTChambPhContainer *dtPhDigis, const L1MuDTChambThContainer *dtThDigis, unsigned int iProcessor, l1t::tftype type, int bx)
uint32_t getLayerNumber(uint32_t rawId) const
OMTFinputMaker(edm::ConsumesCollector &, bool getDuringEvent=true)