CMS 3D CMS Logo

RPCTechnicalTrigger.cc
Go to the documentation of this file.
1 // $Id:
2 
3 //-----------------------------------------------------------------------------
4 // Implementation file for class : RPCTechnicalTrigger
5 //
6 // 2008-10-15 : Andres Osorio
7 //-----------------------------------------------------------------------------
8 
9 //=============================================================================
10 // Standard constructor, initializes variables
11 //=============================================================================
12 
13 // Include files
14 
15 // local
20 
23 
24 //=============================================================================
25 // Standard constructor, initializes variables
26 //=============================================================================
27 
28 namespace {
29  //...........................................................................
30  //For the pointing Logic: declare here the first sector of each quadrant
31  //
32  constexpr std::array<int, 10> s_quadrants = {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
33 
34  //The wheelTtu is addressed using -2, -1, 0, 1, 2
35  constexpr unsigned int kWheelOffset = 2;
36  constexpr std::array<int, 5> wheelTtu = {{3, 3, 2, 1, 1}};
37 } // namespace
38 
40  : m_verbosity{iConfig.getUntrackedParameter<int>("Verbosity", 0)},
41  m_useEventSetup{iConfig.getUntrackedParameter<int>("UseEventSetup", 0)},
42  m_ttBits{iConfig.getParameter<std::vector<unsigned>>("BitNumbers")},
43  m_ttNames{iConfig.getParameter<std::vector<std::string>>("BitNames")},
44  m_rpcDigiLabel{iConfig.getParameter<edm::InputTag>("RPCDigiLabel")},
45  m_rpcDigiToken{consumes<RPCDigiCollection>(m_rpcDigiLabel)},
46  m_useRPCSimLink{iConfig.getUntrackedParameter<int>("UseRPCSimLink", 0)},
47  m_rpcGeometryToken(esConsumes<RPCGeometry, MuonGeometryRecord>()) {
48  std::string configFile = iConfig.getParameter<std::string>("ConfigFile");
49 
50  edm::FileInPath f1("L1Trigger/RPCTechnicalTrigger/data/" + configFile);
51  m_configFile = f1.fullPath();
52 
53  if (m_verbosity) {
54  LogTrace("RPCTechnicalTrigger") << m_rpcDigiLabel << '\n' << std::endl;
55 
56  LogTrace("RPCTechnicalTrigger") << "\nConfiguration file used for UseEventSetup = 0 \n"
57  << m_configFile << '\n'
58  << std::endl;
59  }
60 
61  //...........................................................................
62  //... There are three Technical Trigger Units Boards: 1 can handle 2 Wheels
63  //... n_Wheels sets the number of wheels attached to board with index boardIndex
64 
65  constexpr std::array<int, 3> boardIndex = {{1, 2, 3}};
66  constexpr std::array<int, 3> nWheels = {{2, 1, 2}};
67 
68  m_ttu[0] = TTUEmulator(boardIndex[0], nWheels[0]);
69  m_ttu[1] = TTUEmulator(boardIndex[1], nWheels[1]);
70  m_ttu[2] = TTUEmulator(boardIndex[2], nWheels[2]);
71 
72  //... This is second line that delivers in parallel a second trigger
73  m_ttuRbcLine[0] = TTUEmulator(boardIndex[0], nWheels[0]);
74  m_ttuRbcLine[1] = TTUEmulator(boardIndex[1], nWheels[1]);
75  m_ttuRbcLine[2] = TTUEmulator(boardIndex[2], nWheels[2]);
76 
77  //...........................................................................
78 
79  m_hasConfig = false;
80  produces<L1GtTechnicalTriggerRecord>();
81  consumes<edm::DetSetVector<RPCDigiSimLink>>(edm::InputTag("simMuonRPCDigis", "RPCDigiSimLink", ""));
82  if (m_useEventSetup >= 1) {
83  m_pRBCSpecsToken = esConsumes<RBCBoardSpecs, RBCBoardSpecsRcd, edm::Transition::BeginRun>();
84  m_pTTUSpecsToken = esConsumes<TTUBoardSpecs, TTUBoardSpecsRcd, edm::Transition::BeginRun>();
85  }
86 }
87 
89 
90 //=============================================================================
92  bool status(false);
93 
95 
97 
98  std::unique_ptr<L1GtTechnicalTriggerRecord> output(new L1GtTechnicalTriggerRecord());
99 
100  //. Set up RPC geometry
102 
103  std::unique_ptr<ProcessInputSignal> signal;
104  if (m_useRPCSimLink == 0) {
105  iEvent.getByToken(m_rpcDigiToken, pIn);
106  if (!pIn.isValid()) {
107  edm::LogError("RPCTechnicalTrigger") << "can't find RPCDigiCollection with label: " << m_rpcDigiLabel << '\n';
108  iEvent.put(std::move(output));
109  return;
110  }
111 
112  signal = std::make_unique<RBCProcessRPCDigis>(rpcGeometry, pIn);
113 
114  } else {
115  iEvent.getByLabel("simMuonRPCDigis", "RPCDigiSimLink", simIn);
116 
117  if (!simIn.isValid()) {
118  edm::LogError("RPCTechnicalTrigger") << "can't find RPCDigiCollection with label: " << m_rpcDigiLabel << '\n';
119  iEvent.put(std::move(output));
120  return;
121  }
122  signal = std::make_unique<RBCProcessRPCSimDigis>(rpcGeometry, simIn);
123  }
124 
125  LogDebug("RPCTechnicalTrigger") << "signal object created" << '\n';
126 
127  if (!m_hasConfig) {
128  edm::LogError("RPCTechnicalTrigger") << "cannot read hardware configuration \n";
129  iEvent.put(std::move(output));
130  return;
131  }
132 
133  status = signal->next();
134 
135  if (!status) {
136  iEvent.put(std::move(output));
137  return;
138  }
139 
140  auto* input = signal->retrievedata();
141 
142  std::vector<L1GtTechnicalTrigger> ttVec(m_ttBits.size());
143 
144  //. distribute data to different TTU emulator instances and process it
145  std::bitset<5> triggerbits;
146 
147  std::vector<std::unique_ptr<TTUResults>> serializedInfoLine1;
148  std::vector<std::unique_ptr<TTUResults>> serializedInfoLine2;
149 
150  for (int k = 0; k < kMaxTtuBoards; ++k) {
151  m_ttu[k].processTtu(input);
152 
153  //work out Pointing Logic to Tracker
154  for (auto firstSector : s_quadrants)
155  m_ttuRbcLine[k].processTtu(input, firstSector);
156 
157  //...for trigger 1
158  for (auto const& out : m_ttu[k].m_triggerBxVec)
159  serializedInfoLine1.emplace_back(std::make_unique<TTUResults>(k, out.m_bx, out.m_trigger[0], out.m_trigger[1]));
160  m_ttu[k].clearTriggerResponse();
161 
162  //...for trigger 2
163  for (auto const& out : m_ttuRbcLine[k].m_triggerBxVec)
164  serializedInfoLine2.push_back(
165  std::make_unique<TTUResults>(k, out.m_bx, out.m_trigger[0], out.m_trigger[1], out.m_wedge));
166 
167  m_ttuRbcLine[k].clearTriggerResponse();
168  }
169 
170  //.. write results to technical trigger bits
171  int bx(0);
172  int infoSize(0);
173 
174  infoSize = serializedInfoLine1.size();
175 
176  auto sortByBx = [](auto& iLHS, auto& iRHS) { return iLHS->m_bx < iRHS->m_bx; };
177  std::sort(serializedInfoLine1.begin(), serializedInfoLine1.end(), sortByBx);
178 
179  if (m_verbosity) {
180  for (auto& ttu : serializedInfoLine1) {
181  if (abs(ttu->m_bx) <= 1)
182  std::cout << "RPCTechnicalTrigger> " << ttu->m_ttuidx << '\t' << ttu->m_bx << '\t' << ttu->m_trigWheel1 << '\t'
183  << ttu->m_trigWheel2 << '\n';
184  }
185  }
186 
187  bool has_bx0 = false;
188 
189  for (int k = 0; k < infoSize; k += kMaxTtuBoards) {
190  bx = serializedInfoLine1[k]->m_bx;
191 
192  if (bx == 0) {
193  triggerbits.set(0, serializedInfoLine1[k]->m_trigWheel2);
194  triggerbits.set(1, serializedInfoLine1[k]->m_trigWheel1);
195  triggerbits.set(2, serializedInfoLine1[k + 1]->m_trigWheel1);
196  triggerbits.set(3, serializedInfoLine1[k + 2]->m_trigWheel1);
197  triggerbits.set(4, serializedInfoLine1[k + 2]->m_trigWheel2);
198 
199  bool five_wheels_OR = triggerbits.any();
200 
201  ttVec.at(0) = L1GtTechnicalTrigger(
202  m_ttNames.at(0), m_ttBits.at(0), bx, five_wheels_OR); // bit 24 = Or 5 wheels in TTU mode
203  ttVec.at(2) = L1GtTechnicalTrigger(m_ttNames.at(2), m_ttBits.at(2), bx, triggerbits[0]); // bit 26
204  ttVec.at(3) = L1GtTechnicalTrigger(m_ttNames.at(3), m_ttBits.at(3), bx, triggerbits[1]); // bit 27
205  ttVec.at(4) = L1GtTechnicalTrigger(m_ttNames.at(4), m_ttBits.at(4), bx, triggerbits[2]); // bit 28
206  ttVec.at(5) = L1GtTechnicalTrigger(m_ttNames.at(5), m_ttBits.at(5), bx, triggerbits[3]); // bit 29
207  ttVec.at(6) = L1GtTechnicalTrigger(m_ttNames.at(6), m_ttBits.at(6), bx, triggerbits[4]); // bit 30
208 
209  triggerbits.reset();
210 
211  has_bx0 = true;
212 
213  break;
214 
215  } else
216  continue;
217  }
218 
219  infoSize = serializedInfoLine2.size();
220 
221  std::sort(serializedInfoLine2.begin(), serializedInfoLine2.end(), sortByBx);
222 
223  if (m_verbosity) {
224  for (auto& ttu : serializedInfoLine2) {
225  if (abs(ttu->m_bx) <= 1)
226  std::cout << "RPCTechnicalTrigger> " << ttu->m_ttuidx << '\t' << ttu->m_bx << '\t' << ttu->m_trigWheel1 << '\t'
227  << ttu->m_trigWheel2 << '\t' << ttu->m_wedge << '\n';
228  }
229  }
230 
231  auto ttuResultsByQuadrant = convertToMap(serializedInfoLine2);
232 
233  std::bitset<8> triggerCoincidence;
234  triggerCoincidence.reset();
235 
236  // searchCoincidence( W-2 , W0 )
237  bool result = searchCoincidence(-2, 0, ttuResultsByQuadrant);
238  triggerCoincidence.set(0, result);
239 
240  // searchCoincidence( W-2 , W+1 )
241  result = searchCoincidence(-2, 1, ttuResultsByQuadrant);
242  triggerCoincidence.set(1, result);
243 
244  // searchCoincidence( W-1 , W0 )
245  result = searchCoincidence(-1, 0, ttuResultsByQuadrant);
246  triggerCoincidence.set(2, result);
247 
248  // searchCoincidence( W-1 , W+1 )
249  result = searchCoincidence(-1, 1, ttuResultsByQuadrant);
250  triggerCoincidence.set(3, result);
251 
252  // searchCoincidence( W-1 , W+2 )
253  result = searchCoincidence(-1, 2, ttuResultsByQuadrant);
254  triggerCoincidence.set(4, result);
255 
256  // searchCoincidence( W0 , W0 )
257  result = searchCoincidence(0, 0, ttuResultsByQuadrant);
258  triggerCoincidence.set(5, result);
259 
260  // searchCoincidence( W+1 , W0 )
261  result = searchCoincidence(1, 0, ttuResultsByQuadrant);
262  triggerCoincidence.set(6, result);
263 
264  // searchCoincidence( W+2 , W0 )
265  result = searchCoincidence(2, 0, ttuResultsByQuadrant);
266  triggerCoincidence.set(7, result);
267 
268  bool five_wheels_OR = triggerCoincidence.any();
269 
270  if (m_verbosity)
271  std::cout << "RPCTechnicalTrigger> pointing trigger: " << five_wheels_OR << '\n';
272 
273  ttVec.at(1) =
274  L1GtTechnicalTrigger(m_ttNames.at(1), m_ttBits.at(1), bx, five_wheels_OR); // bit 25 = Or 5 wheels in RBC mode
275 
276  triggerCoincidence.reset();
277 
278  //...check that data appeared at bx=0
279 
280  if (!has_bx0) {
281  iEvent.put(std::move(output));
282  LogDebug("RPCTechnicalTrigger") << "RPCTechnicalTrigger> end of event loop" << std::endl;
283  return;
284  }
285 
286  output->setGtTechnicalTrigger(ttVec);
287  iEvent.put(std::move(output));
288 
289  //.... all done
290 
291  LogDebug("RPCTechnicalTrigger") << "RPCTechnicalTrigger> end of event loop" << std::endl;
292 }
293 // ------------ method called once each job just before starting event loop ------------
294 void RPCTechnicalTrigger::beginRun(edm::Run const& iRun, const edm::EventSetup& evtSetup) {
295  LogDebug("RPCTechnicalTrigger") << "RPCTechnicalTrigger::beginRun> starts" << std::endl;
296 
297  //.. Get Board Specifications (hardware configuration)
298 
299  if (m_useEventSetup >= 1) {
301 
303 
304  if (!pRBCSpecs.isValid() || !pTTUSpecs.isValid()) {
305  edm::LogError("RPCTechnicalTrigger") << "can't find RBC/TTU BoardSpecsRcd" << '\n';
306  m_hasConfig = false;
307  } else {
308  m_rbcspecs = pRBCSpecs.product();
309  m_ttuspecs = pTTUSpecs.product();
310  m_hasConfig = true;
311  }
312 
313  } else {
314  // read hardware configuration from file
315  m_readConfig = std::make_unique<TTUConfigurator>(m_configFile);
316 
317  if (m_readConfig->m_hasConfig) {
318  m_readConfig->process();
319  m_rbcspecs = m_readConfig->getRbcSpecs();
320  m_ttuspecs = m_readConfig->getTtuSpecs();
321  m_hasConfig = true;
322  }
323 
324  else
325  m_hasConfig = false;
326  }
327 
328  if (m_hasConfig) {
329  //... Initialize all
330 
331  for (int k = 0; k < kMaxTtuBoards; ++k) {
332  m_ttu[k].SetLineId(1);
333  m_ttuRbcLine[k].SetLineId(2);
334 
335  m_ttu[k].setSpecifications(m_ttuspecs, m_rbcspecs);
336  m_ttuRbcLine[k].setSpecifications(m_ttuspecs, m_rbcspecs);
337 
338  m_ttu[k].initialise();
339  m_ttuRbcLine[k].initialise();
340  }
341  }
342 }
343 
344 //
345 std::map<int, RPCTechnicalTrigger::TTUResults*> RPCTechnicalTrigger::convertToMap(
346  const std::vector<std::unique_ptr<TTUResults>>& ttuResults) const {
347  std::map<int, TTUResults*> returnValue;
348  auto itr = ttuResults.begin();
349 
350  while (itr != ttuResults.end()) {
351  if ((*itr)->m_bx != 0) {
352  ++itr;
353  continue;
354  }
355 
356  int key(0);
357  key = 1000 * ((*itr)->m_ttuidx + 1) + 1 * (*itr)->m_wedge;
358  returnValue[key] = itr->get();
359  ++itr;
360  }
361 
362  return returnValue;
363 }
364 
365 //...RBC pointing logic to tracker bit 25: hardwired
367  int wheel2,
368  std::map<int, TTUResults*> const& ttuResultsByQuadrant) const {
369  std::map<int, TTUResults*>::const_iterator itr;
370  bool topRight(false);
371  bool botLeft(false);
372 
373  int indxW1 = wheelTtu[wheel1 + kWheelOffset];
374  int indxW2 = wheelTtu[wheel2 + kWheelOffset];
375 
376  int k(0);
377  int key(0);
378  bool finalTrigger(false);
379  int maxTopQuadrants = 4;
380 
381  //work out Pointing Logic to Tracker
382 
383  for (auto firstSector : s_quadrants) {
384  key = 1000 * (indxW1) + firstSector;
385 
386  itr = ttuResultsByQuadrant.find(key);
387  if (itr != ttuResultsByQuadrant.end())
388  topRight = (*itr).second->getTriggerForWheel(wheel1);
389 
390  //std::cout << "W1: " << wheel1 << " " << "sec: " << firstSector << " dec: " << topRight << '\n';
391 
392  key = 1000 * (indxW2) + firstSector + 5;
393 
394  itr = ttuResultsByQuadrant.find(key);
395 
396  if (itr != ttuResultsByQuadrant.end())
397  botLeft = (*itr).second->getTriggerForWheel(wheel2);
398 
399  //std::cout << "W2: " << wheel2 << " " << "sec: " << firstSector + 5 << " dec: " << botLeft << '\n';
400 
401  finalTrigger |= (topRight && botLeft);
402 
403  ++k;
404 
405  if (k > maxTopQuadrants)
406  break;
407  }
408 
409  //Try the opposite now
410 
411  k = 0;
412 
413  for (auto firstSector : s_quadrants) {
414  key = 1000 * (indxW2) + firstSector;
415 
416  itr = ttuResultsByQuadrant.find(key);
417  if (itr != ttuResultsByQuadrant.end())
418  topRight = (*itr).second->getTriggerForWheel(wheel1);
419 
420  //std::cout << "W1: " << wheel1 << " " << "sec: " << firstSector << " dec: " << topRight << '\n';
421 
422  key = 1000 * (indxW1) + firstSector + 5;
423 
424  itr = ttuResultsByQuadrant.find(key);
425 
426  if (itr != ttuResultsByQuadrant.end())
427  botLeft = (*itr).second->getTriggerForWheel(wheel2);
428 
429  //std::cout << "W2: " << wheel2 << " " << "sec: " << firstSector + 5 << " dec: " << botLeft << '\n';
430 
431  finalTrigger |= (topRight && botLeft);
432 
433  ++k;
434 
435  if (k > maxTopQuadrants)
436  break;
437  }
438 
439  return finalTrigger;
440 }
441 
442 // ------------ method called once each job just after ending the event loop ------------
443 
445  LogDebug("RPCTechnicalTrigger") << "RPCTechnicalTrigger::Printing TTU emulators info>" << std::endl;
446 
447  for (int k = 0; k < kMaxTtuBoards; ++k) {
448  m_ttu[k].printinfo();
449  m_ttuRbcLine[k].printinfo();
450  }
451 }
452 
453 //define this as a plug-in
void beginRun(edm::Run const &, const edm::EventSetup &) final
std::unique_ptr< TTUConfigurator > m_readConfig
const edm::InputTag m_rpcDigiLabel
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::map< int, TTUResults * > convertToMap(const std::vector< std::unique_ptr< TTUResults >> &) const
Log< level::Error, false > LogError
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:47
static constexpr int kMaxTtuBoards
T getUntrackedParameter(std::string const &, T const &) const
int iEvent
Definition: GenABIO.cc:224
T const * product() const
Definition: ESHandle.h:86
edm::ESGetToken< RPCGeometry, MuonGeometryRecord > m_rpcGeometryToken
RPCTechnicalTrigger(const edm::ParameterSet &)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:151
bool isValid() const
Definition: ESHandle.h:44
const TTUBoardSpecs * m_ttuspecs
bool searchCoincidence(int, int, std::map< int, TTUResults *> const &ttuResultsByQuandrant) const
std::array< TTUEmulator, kMaxTtuBoards > m_ttu
bool isValid() const
Definition: HandleBase.h:70
const edm::EDGetTokenT< RPCDigiCollection > m_rpcDigiToken
const std::vector< unsigned > m_ttBits
const RBCBoardSpecs * m_rbcspecs
edm::ESGetToken< RBCBoardSpecs, RBCBoardSpecsRcd > m_pRBCSpecsToken
const std::vector< std::string > m_ttNames
edm::ESGetToken< TTUBoardSpecs, TTUBoardSpecsRcd > m_pTTUSpecsToken
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
std::array< TTUEmulator, kMaxTtuBoards > m_ttuRbcLine
#define LogDebug(id)
void produce(edm::Event &, const edm::EventSetup &) override