CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCMotherboardME3141RPC.cc
Go to the documentation of this file.
8 #include "boost/container/flat_set.hpp"
9 
11 { 0,2.421},{ 1,2.415},{ 2,2.406},{ 3,2.397},{ 4,2.388},{ 5,2.379},{ 6,2.371},{ 7,2.362},
12 { 8,2.353},{ 9,2.345},{10,2.336},{11,2.328},{12,2.319},{13,2.311},{14,2.303},{15,2.295},
13 {16,2.287},{17,2.279},{18,2.271},{19,2.263},{20,2.255},{21,2.248},{22,2.240},{23,2.232},
14 {24,2.225},{25,2.217},{26,2.210},{27,2.203},{28,2.195},{29,2.188},{30,2.181},{31,2.174},
15 {32,2.169},{33,2.157},{34,2.151},{35,2.142},{36,2.134},{37,2.126},{38,2.118},{39,2.110},
16 {40,2.102},{41,2.094},{42,2.087},{43,2.079},{44,2.071},{45,2.064},{46,2.056},{47,2.049},
17 {48,2.041},{49,2.034},{50,2.027},{51,2.019},{52,2.012},{53,2.005},{54,1.998},{55,1.991},
18 {56,1.984},{57,1.977},{58,1.970},{59,1.964},{60,1.957},{61,1.950},{62,1.944},{63,1.937},
19 {64,1.932},{65,1.922},{66,1.917},{67,1.911},{68,1.905},{69,1.898},{70,1.892},{71,1.886},
20 {72,1.880},{73,1.874},{74,1.868},{75,1.861},{76,1.855},{77,1.850},{78,1.844},{79,1.838},
21 {80,1.832},{81,1.826},{82,1.820},{83,1.815},{84,1.809},{85,1.803},{86,1.798},{87,1.792},
22 {88,1.787},{89,1.781},{90,1.776},{91,1.770},{92,1.765},{93,1.759},{94,1.754},{95,1.749},
23 };
24 
26 { 0,2.447},{ 1,2.441},{ 2,2.432},{ 3,2.423},{ 4,2.414},{ 5,2.405},{ 6,2.396},{ 7,2.388},
27 { 8,2.379},{ 9,2.371},{10,2.362},{11,2.354},{12,2.345},{13,2.337},{14,2.329},{15,2.321},
28 {16,2.313},{17,2.305},{18,2.297},{19,2.289},{20,2.281},{21,2.273},{22,2.266},{23,2.258},
29 {24,2.251},{25,2.243},{26,2.236},{27,2.228},{28,2.221},{29,2.214},{30,2.207},{31,2.200},
30 {32,2.195},{33,2.183},{34,2.176},{35,2.168},{36,2.160},{37,2.152},{38,2.144},{39,2.136},
31 {40,2.128},{41,2.120},{42,2.112},{43,2.104},{44,2.097},{45,2.089},{46,2.082},{47,2.074},
32 {48,2.067},{49,2.059},{50,2.052},{51,2.045},{52,2.038},{53,2.031},{54,2.023},{55,2.016},
33 {56,2.009},{57,2.003},{58,1.996},{59,1.989},{60,1.982},{61,1.975},{62,1.969},{63,1.962},
34 {64,1.957},{65,1.948},{66,1.943},{67,1.936},{68,1.930},{69,1.924},{70,1.917},{71,1.911},
35 {72,1.905},{73,1.899},{74,1.893},{75,1.887},{76,1.881},{77,1.875},{78,1.869},{79,1.863},
36 {80,1.857},{81,1.851},{82,1.845},{83,1.840},{84,1.834},{85,1.828},{86,1.823},{87,1.817},
37 {88,1.811},{89,1.806},{90,1.800},{91,1.795},{92,1.790},{93,1.784},{94,1.779},{95,1.774},
38 };
39 
41 { 0,2.399},{ 1,2.394},{ 2,2.386},{ 3,2.378},{ 4,2.370},{ 5,2.362},{ 6,2.354},{ 7,2.346},
42 { 8,2.339},{ 9,2.331},{10,2.323},{11,2.316},{12,2.308},{13,2.301},{14,2.293},{15,2.286},
43 {16,2.279},{17,2.272},{18,2.264},{19,2.257},{20,2.250},{21,2.243},{22,2.236},{23,2.229},
44 {24,2.223},{25,2.216},{26,2.209},{27,2.202},{28,2.196},{29,2.189},{30,2.183},{31,2.176},
45 {32,2.172},{33,2.161},{34,2.157},{35,2.150},{36,2.144},{37,2.138},{38,2.132},{39,2.126},
46 {40,2.119},{41,2.113},{42,2.107},{43,2.101},{44,2.095},{45,2.089},{46,2.083},{47,2.078},
47 {48,2.072},{49,2.066},{50,2.060},{51,2.055},{52,2.049},{53,2.043},{54,2.038},{55,2.032},
48 {56,2.027},{57,2.021},{58,2.016},{59,2.010},{60,2.005},{61,1.999},{62,1.994},{63,1.989},
49 {64,1.985},{65,1.977},{66,1.973},{67,1.968},{68,1.963},{69,1.958},{70,1.953},{71,1.947},
50 {72,1.942},{73,1.937},{74,1.932},{75,1.928},{76,1.923},{77,1.918},{78,1.913},{79,1.908},
51 {80,1.903},{81,1.898},{82,1.894},{83,1.889},{84,1.884},{85,1.879},{86,1.875},{87,1.870},
52 {88,1.866},{89,1.861},{90,1.856},{91,1.852},{92,1.847},{93,1.843},{94,1.838},{95,1.834},
53 };
54 
56 { 0,2.423},{ 1,2.418},{ 2,2.410},{ 3,2.402},{ 4,2.394},{ 5,2.386},{ 6,2.378},{ 7,2.370},
57 { 8,2.362},{ 9,2.355},{10,2.347},{11,2.339},{12,2.332},{13,2.324},{14,2.317},{15,2.310},
58 {16,2.302},{17,2.295},{18,2.288},{19,2.281},{20,2.274},{21,2.267},{22,2.260},{23,2.253},
59 {24,2.246},{25,2.239},{26,2.233},{27,2.226},{28,2.219},{29,2.213},{30,2.206},{31,2.199},
60 {32,2.195},{33,2.185},{34,2.180},{35,2.174},{36,2.168},{37,2.161},{38,2.155},{39,2.149},
61 {40,2.143},{41,2.137},{42,2.131},{43,2.125},{44,2.119},{45,2.113},{46,2.107},{47,2.101},
62 {48,2.095},{49,2.089},{50,2.084},{51,2.078},{52,2.072},{53,2.067},{54,2.061},{55,2.055},
63 {56,2.050},{57,2.044},{58,2.039},{59,2.033},{60,2.028},{61,2.023},{62,2.017},{63,2.012},
64 {64,2.008},{65,2.000},{66,1.996},{67,1.991},{68,1.986},{69,1.981},{70,1.976},{71,1.971},
65 {72,1.966},{73,1.961},{74,1.956},{75,1.951},{76,1.946},{77,1.941},{78,1.936},{79,1.931},
66 {80,1.926},{81,1.921},{82,1.917},{83,1.912},{84,1.907},{85,1.902},{86,1.898},{87,1.893},
67 {88,1.889},{89,1.884},{90,1.879},{91,1.875},{92,1.870},{93,1.866},{94,1.861},{95,1.857},
68 };
69 
70 // LUT with bending angles of the GEM-CSC high efficiency patterns (98%)
71 // 1st index: pt value = {5,10,15,20,30,40}
72 // 2nd index: bending angle for odd numbered chambers
73 // 3rd index: bending angle for even numbered chambers
75  {3., 0.02203511, 0.00930056},
76  {5., 0.02203511, 0.00930056},
77  {7 , 0.0182579 , 0.00790009},
78  {10., 0.01066000, 0.00483286},
79  {15., 0.00722795, 0.00363230},
80  {20., 0.00562598, 0.00304878},
81  {30., 0.00416544, 0.00253782},
82  {40., 0.00342827, 0.00230833} };
83 
85  {3., 0.02203511, 0.00930056},
86  {5., 0.02203511, 0.00930056},
87  {7 , 0.0182579 , 0.00790009},
88  {10., 0.01066000, 0.00483286},
89  {15., 0.00722795, 0.00363230},
90  {20., 0.00562598, 0.00304878},
91  {30., 0.00416544, 0.00253782},
92  {40., 0.00342827, 0.00230833} };
93 
95  unsigned sector, unsigned subsector,
96  unsigned chamber,
97  const edm::ParameterSet& conf) :
98  CSCMotherboard(endcap, station, sector, subsector, chamber, conf)
99 {
100  const edm::ParameterSet commonParams(conf.getParameter<edm::ParameterSet>("commonParam"));
101  runME3141ILT_ = commonParams.getParameter<bool>("runME3141ILT");
102 
103  if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError")
104  << "+++ Upgrade CSCMotherboardME3141RPC constructed while isSLHC is not set! +++\n";
105 
106  const edm::ParameterSet me3141tmbParams(conf.getParameter<edm::ParameterSet>("me3141tmbSLHCRPC"));
107 
108  // whether to not reuse CLCTs that were used by previous matching ALCTs
109  // in ALCT-to-CLCT algorithm
110  drop_used_clcts = me3141tmbParams.getParameter<bool>("tmbDropUsedClcts");
111 
112  match_earliest_clct_me3141_only = me3141tmbParams.getParameter<bool>("matchEarliestClctME3141Only");
113 
114  tmb_cross_bx_algo = me3141tmbParams.getParameter<unsigned int>("tmbCrossBxAlgorithm");
115 
116  // maximum lcts per BX in ME2
117  max_me3141_lcts = me3141tmbParams.getParameter<unsigned int>("maxME3141LCTs");
118 
120  for (unsigned int m=2; m<match_trig_window_size; m+=2)
121  {
122  pref[m-1] = pref[0] - m/2;
123  pref[m] = pref[0] + m/2;
124  }
125 
126  //----------------------------------------------------------------------------------------//
127 
128  // R P C - C S C I N T E G R A T E D L O C A L A L G O R I T H M
129 
130  //----------------------------------------------------------------------------------------//
131 
133  do_rpc_matching = me3141tmbParams.getParameter<bool>("doRpcMatching");
134 
136  rpc_match_delta_phi_odd = me3141tmbParams.getParameter<double>("rpcMatchDeltaPhiOdd");
137  rpc_match_delta_phi_even = me3141tmbParams.getParameter<double>("rpcMatchDeltaPhiEven");
138  rpc_match_delta_eta = me3141tmbParams.getParameter<double>("rpcMatchDeltaEta");
139 
141  rpc_match_delta_bx = me3141tmbParams.getParameter<int>("rpcMatchDeltaBX");
142 
144  rpc_match_min_eta = me3141tmbParams.getParameter<double>("rpcMatchMinEta");
145 
147  rpc_clear_nomatch_lcts = me3141tmbParams.getParameter<bool>("rpcClearNomatchLCTs");
148 
149  // debug
150  debug_luts_ = me3141tmbParams.getParameter<bool>("debugLUTs");
151  debug_rpc_matching_ = me3141tmbParams.getParameter<bool>("debugMatching");
152 
153  // deltas used to match to RPC digis
154  maxDeltaBXRPC_ = me3141tmbParams.getParameter<int>("maxDeltaBXRPC");
155  maxDeltaStripRPCOdd_ = me3141tmbParams.getParameter<int>("maxDeltaStripRPCOdd");
156  maxDeltaStripRPCEven_ = me3141tmbParams.getParameter<int>("maxDeltaStripRPCEven");
157  maxDeltaWg_ = me3141tmbParams.getParameter<int>("maxDeltaWg");
158 
159  // use "old" or "new" dataformat for integrated LCTs?
160  useOldLCTDataFormat_ = me3141tmbParams.getParameter<bool>("useOldLCTDataFormat");
161 
162  // drop low quality stubs if they don't have RPCs
163  dropLowQualityCLCTsNoRPCs_ = me3141tmbParams.getParameter<bool>("dropLowQualityCLCTsNoRPCs");
164 
165  // build LCT from CLCT and RPC
166  buildLCTfromALCTandRPC_ = me3141tmbParams.getParameter<bool>("buildLCTfromALCTandRPC");
167  buildLCTfromCLCTandRPC_ = me3141tmbParams.getParameter<bool>("buildLCTfromCLCTandRPC");
168  buildLCTfromLowQstubandRPC_ = me3141tmbParams.getParameter<bool>("buildLCTfromLowQstubandRPC");
169 
170  // promote ALCT-RPC pattern
171  promoteALCTRPCpattern_ = me3141tmbParams.getParameter<bool>("promoteALCTRPCpattern");
172 
173  // promote ALCT-CLCT-RPC quality
174  promoteALCTRPCquality_ = me3141tmbParams.getParameter<bool>("promoteALCTRPCquality");
175  promoteCLCTRPCquality_ = me3141tmbParams.getParameter<bool>("promoteCLCTRPCquality");
176 }
177 
179 {
180 }
181 
183 {
185 
186  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
187  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
188  for (int i=0;i<2;i++)
189  allLCTs[bx][mbx][i].clear();
190 
191  rpcRollToEtaLimits_.clear();
192  cscWgToRpcRoll_.clear();
193  rpcStripToCscHs_.clear();
194  cscHsToRpcStrip_.clear();
195  rpcDigis_.clear();
196 }
197 
198 void
200  const CSCComparatorDigiCollection* compdc,
201  const RPCDigiCollection* rpcDigis)
202 {
203  clear();
204 
205  if (!( alct and clct and runME3141ILT_))
206  {
207  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
208  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
209  return;
210  }
211 
212  alctV = alct->run(wiredc); // run anodeLCT
213  clctV = clct->run(compdc); // run cathodeLCT
214 
215  bool rpcGeometryAvailable(false);
216  if (rpc_g != nullptr) {
217  if (infoV >= 0) edm::LogInfo("L1CSCTPEmulatorSetupInfo")
218  << "+++ run() called for RPC-CSC integrated trigger! +++ \n";
219  rpcGeometryAvailable = true;
220  }
221  const bool hasCorrectRPCGeometry((not rpcGeometryAvailable) or (rpcGeometryAvailable and not hasRE31andRE41()));
222 
223  // retrieve CSCChamber geometry
225  const CSCChamber* cscChamber(geo_manager->chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber));
226  const CSCDetId csc_id(cscChamber->id());
227 
228  // trigger geometry
229  const CSCLayer* keyLayer(cscChamber->layer(3));
230  const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
231  const int region((theEndcap == 1) ? 1: -1);
232  const bool isEven(csc_id.chamber()%2==0);
233  const int csc_trig_sect(CSCTriggerNumbering::triggerSectorFromLabels(csc_id));
234  const int csc_trig_id( CSCTriggerNumbering::triggerCscIdFromLabels(csc_id));
235  const int csc_trig_chid((3*(csc_trig_sect-1)+csc_trig_id)%18 +1);
236  const int rpc_trig_sect((csc_trig_chid-1)/3+1);
237  const int rpc_trig_subsect((csc_trig_chid-1)%3+1);
238  const RPCDetId rpc_id(region,1,theStation,rpc_trig_sect,1,rpc_trig_subsect,0);
239  const RPCChamber* rpcChamber(rpc_g->chamber(rpc_id));
240 
241  if (runME3141ILT_){
242 
243  // check for RE3/1-RE4/1 geometry
244  if (hasCorrectRPCGeometry) {
245  if (infoV >= 0) edm::LogInfo("L1CSCTPEmulatorSetupError")
246  << "+++ run() called for RPC-CSC integrated trigger without valid RPC geometry! +++ \n";
247  return;
248  }
249 
250  // LUT<roll,<etaMin,etaMax> >
252 
253  if (debug_luts_){
254  std::cout << "RPC det " <<rpc_id<<" CSC det "<< csc_id << std::endl;
255  if (rpcRollToEtaLimits_.size()) {
256  for(auto p : rpcRollToEtaLimits_) {
257  std::cout << "roll "<< p.first << " min eta " << (p.second).first << " max eta " << (p.second).second << std::endl;
258  }
259  }
260  }
261 
262  // loop on all wiregroups to create a LUT <WG,roll>
263  const int numberOfWG(keyLayerGeometry->numberOfWireGroups());
264  for (int i = 0; i< numberOfWG; ++i){
265  auto eta(theStation==3 ?
266  (isEven ? lut_wg_me31_eta_even[i][1] : lut_wg_me31_eta_odd[i][1]) :
267  (isEven ? lut_wg_me41_eta_even[i][1] : lut_wg_me41_eta_odd[i][1]));
269  }
270  if (debug_luts_){
271  for(auto p : cscWgToRpcRoll_) {
272  auto eta(theStation==3 ?
273  (isEven ? lut_wg_me31_eta_even[p.first][1] : lut_wg_me31_eta_odd[p.first][1]) :
274  (isEven ? lut_wg_me41_eta_even[p.first][1] : lut_wg_me41_eta_odd[p.first][1]));
275 
276  std::cout << "WG "<< p.first << " RPC roll " << p.second << " "
277  << rpcRollToEtaLimits_[p.second].first << " "
278  << rpcRollToEtaLimits_[p.second].second << " " << eta << std::endl;
279  }
280  }
281 
282  // pick any roll
283  auto randRoll(rpcChamber->roll(2));
284 
285  auto nStrips(keyLayerGeometry->numberOfStrips());
286  for (float i = 0; i< nStrips; i = i+0.5){
287  const LocalPoint lpCSC(keyLayerGeometry->topology()->localPosition(i));
288  const GlobalPoint gp(keyLayer->toGlobal(lpCSC));
289  const LocalPoint lpRPC(randRoll->toLocal(gp));
290  const int HS(i/0.5);
291  const bool edge(HS < 5 or HS > 155);
292  const float strip(edge ? -99 : randRoll->strip(lpRPC));
293  // HS are wrapped-around
294  cscHsToRpcStrip_[HS] = std::make_pair(std::floor(strip),std::ceil(strip));
295  }
296  if (debug_luts_){
297  std::cout << "detId " << csc_id << std::endl;
298  std::cout << "CSCHSToRPCStrip LUT in" << std::endl;
299  for(auto p : cscHsToRpcStrip_) {
300  std::cout << "CSC HS "<< p.first << " RPC Strip low " << (p.second).first << " RPC Strip high " << (p.second).second << std::endl;
301  }
302  }
303 
304  const int nRPCStrips(randRoll->nstrips());
305  for (int i = 0; i< nRPCStrips; ++i){
306  const LocalPoint lpRPC(randRoll->centreOfStrip(i));
307  const GlobalPoint gp(randRoll->toGlobal(lpRPC));
308  const LocalPoint lpCSC(keyLayer->toLocal(gp));
309  const float strip(keyLayerGeometry->strip(lpCSC));
310  // HS are wrapped-around
311  rpcStripToCscHs_[i] = (int) (strip - 0.25)/0.5;
312  }
313  if (debug_luts_){
314  std::cout << "detId " << csc_id << std::endl;
315  std::cout << "RPCStripToCSCHs LUT" << std::endl;
316  for(auto p : rpcStripToCscHs_) {
317  std::cout << "RPC Strip "<< p.first << " CSC HS: " << p.second << std::endl;
318  }
319  }
320  //select correct scenarios, even or odd
322 
323  rpcDigis_.clear();
324  retrieveRPCDigis(rpcDigis, rpc_id.rawId());
325  }
326 
327  const bool hasRPCDigis(rpcDigis_.size()!=0);
328 
329  int used_clct_mask[20];
330  for (int c=0;c<20;++c) used_clct_mask[c]=0;
331 
332  // ALCT centric matching
333  for (int bx_alct = 0; bx_alct < CSCAnodeLCTProcessor::MAX_ALCT_BINS; bx_alct++)
334  {
335  if (alct->bestALCT[bx_alct].isValid())
336  {
337  const int bx_clct_start(bx_alct - match_trig_window_size/2);
338  const int bx_clct_stop(bx_alct + match_trig_window_size/2);
339  if (debug_rpc_matching_){
340  std::cout << "========================================================================" << std::endl;
341  std::cout << "ALCT-CLCT matching in ME" << theStation << "/1 chamber: " << csc_id << std::endl;
342  std::cout << "------------------------------------------------------------------------" << std::endl;
343  std::cout << "+++ Best ALCT Details: ";
344  alct->bestALCT[bx_alct].print();
345  std::cout << "+++ Second ALCT Details: ";
346  alct->secondALCT[bx_alct].print();
347  std::cout << "------------------------------------------------------------------------" << std::endl;
348  std::cout << "RPC Chamber " << rpc_id << std::endl;
349  printRPCTriggerDigis(bx_clct_start, bx_clct_stop);
350 
351  std::cout << "------------------------------------------------------------------------" << std::endl;
352  std::cout << "Attempt ALCT-CLCT matching in ME" << theStation << "/1 in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl;
353  }
354 
355  // low quality ALCT
356  const bool lowQualityALCT(alct->bestALCT[bx_alct].getQuality() == 0);
357 
358  // ALCT-to-CLCT
359  int nSuccesFulMatches = 0;
360  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) {
361  if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
362  if (drop_used_clcts and used_clct_mask[bx_clct]) continue;
363  if (clct->bestCLCT[bx_clct].isValid()) {
364 
365  // pick the digi that corresponds
366  auto matchingDigis(matchingRPCDigis(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], rpcDigis_[bx_alct], false));
367 
368  // clct quality
369  const int quality(clct->bestCLCT[bx_clct].getQuality());
370  // low quality ALCT or CLCT
371  const bool lowQuality(quality<4 or lowQualityALCT);
372 
373  if (runME3141ILT_ and dropLowQualityCLCTsNoRPCs_ and lowQuality and hasRPCDigis){
374  int nFound(matchingDigis.size());
375  const bool clctInEdge(clct->bestCLCT[bx_clct].getKeyStrip() < 5 or clct->bestCLCT[bx_clct].getKeyStrip() > 155);
376  if (clctInEdge){
377  if (debug_rpc_matching_) std::cout << "\tInfo: low quality ALCT or CLCT in CSC chamber edge, don't care about RPC digis" << std::endl;
378  }
379  else {
380  if (nFound != 0){
381  if (debug_rpc_matching_) std::cout << "\tInfo: low quality ALCT or CLCT with " << nFound << " matching RPC trigger digis" << std::endl;
382  }
383  else {
384  if (debug_rpc_matching_) std::cout << "\tWarning: low quality ALCT or CLCT without matching RPC trigger digi" << std::endl;
385  continue;
386  }
387  }
388  }
389 
390  int mbx = bx_clct-bx_clct_start;
391  correlateLCTsRPC(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
392  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
393  allLCTs[bx_alct][mbx][0], allLCTs[bx_alct][mbx][1], matchingDigis);
394  ++nSuccesFulMatches;
395  if (debug_rpc_matching_) {
396  // if (infoV > 1) LogTrace("CSCMotherboard")
397  std::cout
398  << "Successful ALCT-CLCT match: bx_clct = " << bx_clct
399  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
400  << "]; bx_alct = " << bx_alct << std::endl;
401  std::cout << "+++ Best CLCT Details: ";
402  clct->bestCLCT[bx_clct].print();
403  std::cout << "+++ Second CLCT Details: ";
404  clct->secondCLCT[bx_clct].print();
405  }
406  if (allLCTs[bx_alct][mbx][0].isValid()) {
407  used_clct_mask[bx_clct] += 1;
409  }
410  }
411  }
412  // ALCT-RPC digi matching
413  int nSuccesFulRPCMatches = 0;
414  if (runME3141ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandRPC_){
415  if (debug_rpc_matching_) std::cout << "++No valid ALCT-CLCT matches in ME"<<theStation<<"1" << std::endl;
416  for (int bx_rpc = bx_clct_start; bx_rpc <= bx_clct_stop; bx_rpc++) {
417  if (lowQualityALCT and !buildLCTfromLowQstubandRPC_) continue; // build lct from low-Q ALCTs and rpc if para is set true
418  if (not hasRPCDigis) continue;
419 
420  // find the best matching copad - first one
421  auto digis(matchingRPCDigis(alct->bestALCT[bx_alct], rpcDigis_[bx_rpc], true));
422  if (debug_rpc_matching_) std::cout << "\t++Number of matching RPC Digis in BX " << bx_alct << " : "<< digis.size() << std::endl;
423  if (digis.size()==0) continue;
424 
425  correlateLCTsRPC(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
426  *(digis.at(0)).second, allLCTs[bx_alct][0][0], allLCTs[bx_alct][0][1]);
427  if (allLCTs[bx_alct][0][0].isValid()) {
428  ++nSuccesFulRPCMatches;
430  }
431  if (debug_rpc_matching_) {
432  std::cout << "Successful ALCT-RPC digi match in ME"<<theStation<<"1: bx_alct = " << bx_alct << std::endl << std::endl;
433  std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
434  }
435  }
436  }
437  }
438  else{
439  auto digis(rpcDigis_[bx_alct]);
440  if (runME3141ILT_ and digis.size() and buildLCTfromCLCTandRPC_) {
441  //const int bx_clct_start(bx_alct - match_trig_window_size/2);
442  //const int bx_clct_stop(bx_alct + match_trig_window_size/2);
443  // RPC-to-CLCT
444  int nSuccesFulMatches = 0;
445  // for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
446  // {
447  // if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
448  if (drop_used_clcts and used_clct_mask[bx_alct]) continue;
449  if (clct->bestCLCT[bx_alct].isValid())
450  {
451  if (debug_rpc_matching_){
452  std::cout << "========================================================================" << std::endl;
453  std::cout << "RPC-CLCT matching in ME" << theStation << "/1 chamber: " << cscChamber->id() << " in bx: "<<bx_alct<< std::endl;
454  std::cout << "------------------------------------------------------------------------" << std::endl;
455  }
456  const int quality(clct->bestCLCT[bx_alct].getQuality());
457  // we also use low-Q stubs for the time being
458  if (quality < 4 and !buildLCTfromLowQstubandRPC_) continue;
459 
460  ++nSuccesFulMatches;
461 
462  int mbx = std::abs(clct->bestCLCT[bx_alct].getBX()-bx_alct);
463  int bx_rpc = lct_central_bx;
464  correlateLCTsRPC(clct->bestCLCT[bx_alct], clct->secondCLCT[bx_alct], *(digis[0].second), RPCDetId(digis[0].first).roll(),
465  allLCTs[bx_rpc][mbx][0], allLCTs[bx_rpc][mbx][1]);
466  if (debug_rpc_matching_) {
467  // if (infoV > 1) LogTrace("CSCMotherboard")
468  std::cout << "Successful RPC-CLCT match in ME"<<theStation<<"/1: bx_alct = " << bx_alct
469  << std::endl;
470  std::cout << "+++ Best CLCT Details: ";
471  clct->bestCLCT[bx_alct].print();
472  std::cout << "+++ Second CLCT Details: ";
473  clct->secondCLCT[bx_alct].print();
474  }
475  if (allLCTs[bx_rpc][mbx][0].isValid()) {
476  used_clct_mask[bx_alct] += 1;
478  }
479  }
480  }
481  }
482  }
483 
484  // possibly use some discrimination from GEMs
485  if (rpcGeometryAvailable and runME3141ILT_ and do_rpc_matching) {
486  auto mex1(theStation == 3 ? ME31 : ME41);
487  matchRPCDigis(mex1);
488  }
489 
490  // reduction of nLCTs per each BX
491  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
492  {
493  // counting
494  unsigned int n=0;
495  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
496  for (int i=0;i<2;i++)
497  {
498  int cbx = bx + mbx - match_trig_window_size/2;
499  if (allLCTs[bx][mbx][i].isValid())
500  {
501  ++n;
502  if (infoV > 0) LogDebug("CSCMotherboard")
503  << "LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs[bx][mbx][i]<<std::endl;
504  }
505  }
506 
507  // some simple cross-bx sorting algorithms
508  if (tmb_cross_bx_algo == 1 and (n>2))
509  {
510  n=0;
511  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
512  for (int i=0;i<2;i++)
513  {
514  if (allLCTs[bx][pref[mbx]][i].isValid())
515  {
516  n++;
517  if (n>2) allLCTs[bx][pref[mbx]][i].clear();
518  }
519  }
520 
521  n=0;
522  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
523  for (int i=0;i<2;i++)
524  {
525  int cbx = bx + mbx - match_trig_window_size/2;
526  if (allLCTs[bx][mbx][i].isValid())
527  {
528  n++;
529  if (infoV > 0) LogDebug("CSCMotherboard")
530  << "LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs[bx][mbx][i]<<std::cout;
531  }
532  }
533  if (infoV > 0 and n>0) LogDebug("CSCMotherboard")
534  <<"bx "<<bx<<" nnLCT:"<<n<<" "<<n<<std::endl;
535  } // x-bx sorting
536  }
537 
538  bool first = true;
539  unsigned int n=0;
540  for (auto p : readoutLCTs()) {
541  if (debug_rpc_matching_ and first){
542  std::cout << "========================================================================" << std::endl;
543  std::cout << "Counting the final LCTs" << std::endl;
544  std::cout << "========================================================================" << std::endl;
545  first = false;
546  std::cout << "tmb_cross_bx_algo: " << tmb_cross_bx_algo << std::endl;
547  }
548  n++;
550  std::cout << "LCT "<<n<<" " << p <<std::endl;
551  }
552 }
553 
554 // check that the RE31 and RE41 chambers are really there
556 {
557  // just pick two random chambers
558  auto aRE31(rpc_g->chamber(RPCDetId(1,1,3,2,1,1,0)));
559  auto aRE41(rpc_g->chamber(RPCDetId(-1,1,4,3,1,2,0)));
560  return aRE31 and aRE41;
561 }
562 
563 
564 std::map<int,std::pair<double,double> > CSCMotherboardME3141RPC::createRPCRollLUT(RPCDetId id)
565 {
566  std::map<int,std::pair<double,double> > result;
567 
568  auto chamber(rpc_g->chamber(id));
569  if (chamber==nullptr) return result;
570 
571  for(int i = 1; i<= chamber->nrolls(); ++i){
572  auto roll(chamber->roll(i));
573  if (roll==nullptr) continue;
574 
575  const float half_striplength(roll->specs()->specificTopology().stripLength()/2.);
576  const LocalPoint lp_top(0., half_striplength, 0.);
577  const LocalPoint lp_bottom(0., -half_striplength, 0.);
578  const GlobalPoint gp_top(roll->toGlobal(lp_top));
579  const GlobalPoint gp_bottom(roll->toGlobal(lp_bottom));
580  //result[i] = std::make_pair(floorf(gp_top.eta() * 100) / 100, ceilf(gp_bottom.eta() * 100) / 100);
581  result[i] = std::make_pair(std::abs(gp_top.eta()), std::abs(gp_bottom.eta()));
582  }
583  return result;
584 }
585 
586 
588 {
589  int result = -99;
590  for(auto p : rpcRollToEtaLimits_) {
591  const float minEta((p.second).first);
592  const float maxEta((p.second).second);
593  if (minEta <= eta and eta <= maxEta) {
594  result = p.first;
595  break;
596  }
597  }
598  return result;
599 }
600 
601 
603 {
604  auto chamber(rpc_g->chamber(RPCDetId(id)));
605  for (auto roll : chamber->rolls()) {
606  RPCDetId roll_id(roll->id());
607  auto digis_in_det = rpcDigis->get(roll_id);
608  for (auto digi = digis_in_det.first; digi != digis_in_det.second; ++digi) {
609  auto id_digi = std::make_pair(roll_id(), &(*digi));
610  const int bx_shifted(lct_central_bx + digi->bx());
611  for (int bx = bx_shifted - maxDeltaBXRPC_;bx <= bx_shifted + maxDeltaBXRPC_; ++bx) {
612  rpcDigis_[bx].push_back(id_digi);
613  }
614  }
615  }
616 }
617 
618 
619 void CSCMotherboardME3141RPC::printRPCTriggerDigis(int bx_start, int bx_stop)
620 {
621  std::cout << "------------------------------------------------------------------------" << std::endl;
622  bool first = true;
623  for (int bx = bx_start; bx <= bx_stop; bx++) {
624  std::vector<std::pair<unsigned int, const RPCDigi*> > in_strips = rpcDigis_[bx];
625  if (first) {
626  std::cout << "* RPC trigger digis: " << std::endl;
627  }
628  first = false;
629  std::cout << "N(digis) BX " << bx << " : " << in_strips.size() << std::endl;
630  if (rpcDigis_.size()!=0){
631  for (auto digi : in_strips){
632  auto roll_id(RPCDetId(digi.first));
633  std::cout << "\tdetId " << digi.first << " " << roll_id << ", digi = " << digi.second->strip() << ", BX = " << digi.second->bx() + 6 << std::endl;
634  }
635  }
636  else
637  break;
638  }
639 }
640 
641 
644 {
646 
647  const int lowStrip(cscHsToRpcStrip_[clct.getKeyStrip()].first);
648  const int highStrip(cscHsToRpcStrip_[clct.getKeyStrip()].second);
649  const bool debug(false);
650  if (debug) std::cout << "lowStrip " << lowStrip << " highStrip " << highStrip << " delta strip " << maxDeltaStripRPC_ <<std::endl;
651  for (auto p: digis){
652  auto strip((p.second)->strip());
653  if (debug) std::cout << "strip " << strip << std::endl;
654  if (std::abs(lowStrip - strip) <= maxDeltaStripRPC_ or std::abs(strip - highStrip) <= maxDeltaStripRPC_){
655  if (debug) std::cout << "++Matches! " << std::endl;
656  result.push_back(p);
657  if (first) return result;
658  }
659  }
660  return result;
661 }
662 
663 
666 {
668 
669  int Wg = alct.getKeyWG();
670  std::vector<int> Rolls;
671  Rolls.push_back(cscWgToRpcRoll_[Wg]);
673  Rolls.push_back(cscWgToRpcRoll_[Wg-maxDeltaWg_]);
674  if ((unsigned int)(Wg+maxDeltaWg_)<cscWgToRpcRoll_.size() && cscWgToRpcRoll_[Wg] != cscWgToRpcRoll_[Wg+maxDeltaWg_])
675  Rolls.push_back(cscWgToRpcRoll_[Wg+maxDeltaWg_]);
676 
677  const bool debug(false);
678  if (debug) std::cout << "ALCT keyWG " << alct.getKeyWG() << std::endl;
679  for (auto alctRoll : Rolls)
680  {
681  if (debug) std::cout << " roll " << alctRoll << std::endl;
682  for (auto p: digis){
683  auto digiRoll(RPCDetId(p.first).roll());
684  if (debug) std::cout << "Candidate ALCT: " << digiRoll << std::endl;
685  if (alctRoll != digiRoll) continue;
686  if (debug) std::cout << "++Matches! " << std::endl;
687  result.push_back(p);
688  if (first) return result;
689  }
690  }
691  return result;
692 }
693 
694 
697 {
699 
700  // Fetch all (!) digis matching to ALCTs and CLCTs
701  auto digisClct(matchingRPCDigis(clct, digis, false));
702  auto digisAlct(matchingRPCDigis(alct, digis, false));
703 
704  const bool debug(false);
705  if (debug) std::cout << "-----------------------------------------------------------------------"<<std::endl;
706  // Check if the digis overlap
707  for (auto p : digisAlct){
708  if (debug) std::cout<< "Candidate RPC digis for ALCT: " << p.first << " " << *(p.second) << std::endl;
709  for (auto q: digisClct){
710  if (debug) std::cout<< "++Candidate RPC digis for CLCT: " << q.first << " " << *(q.second) << std::endl;
711  // look for exactly the same digis
712  if (p.first != q.first) continue;
713  // if (not RPCDigi(*(p.second))==*(q.second)) continue;
714  if (debug) std::cout << "++Matches! " << std::endl;
715  result.push_back(p);
716  if (first) return result;
717  }
718  }
719  if (debug) std::cout << "-----------------------------------------------------------------------"<<std::endl;
720  return result;
721 }
722 
723 unsigned int CSCMotherboardME3141RPC::findQualityRPC(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, bool hasRPC)
724 {
725 
726  /*
727  Same LCT quality definition as standard LCTs
728  a4 and c4 takes RPCs into account!!!
729  */
730 
731  unsigned int quality = 0;
732 
733  if (!isTMB07) {
734  bool isDistrip = (cLCT.getStripType() == 0);
735 
736  if (aLCT.isValid() && !(cLCT.isValid())) { // no CLCT
737  if (aLCT.getAccelerator()) {quality = 1;}
738  else {quality = 3;}
739  }
740  else if (!(aLCT.isValid()) && cLCT.isValid()) { // no ALCT
741  if (isDistrip) {quality = 4;}
742  else {quality = 5;}
743  }
744  else if (aLCT.isValid() && cLCT.isValid()) { // both ALCT and CLCT
745  if (aLCT.getAccelerator()) {quality = 2;} // accelerator muon
746  else { // collision muon
747  // CLCT quality is, in fact, the number of layers hit, so subtract 3
748  // to get quality analogous to ALCT one.
749  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
750  if (sumQual < 1 || sumQual > 6) {
751  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
752  << "+++ findQuality: sumQual = " << sumQual << "+++ \n";
753  }
754  if (isDistrip) { // distrip pattern
755  if (sumQual == 2) {quality = 6;}
756  else if (sumQual == 3) {quality = 7;}
757  else if (sumQual == 4) {quality = 8;}
758  else if (sumQual == 5) {quality = 9;}
759  else if (sumQual == 6) {quality = 10;}
760  }
761  else { // halfstrip pattern
762  if (sumQual == 2) {quality = 11;}
763  else if (sumQual == 3) {quality = 12;}
764  else if (sumQual == 4) {quality = 13;}
765  else if (sumQual == 5) {quality = 14;}
766  else if (sumQual == 6) {quality = 15;}
767  }
768  }
769  }
770  }
771 #ifdef OLD
772  else {
773  // Temporary definition, used until July 2008.
774  // First if statement is fictitious, just to help the CSC TF emulator
775  // handle such cases (one needs to make sure they will be accounted for
776  // in the new quality definition.
777  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
778  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
779  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
780  else quality = 0; // both absent; should never happen.
781  }
782  else {
783  // Sum of ALCT and CLCT quality bits. CLCT quality is, in fact, the
784  // number of layers hit, so subtract 3 to put it to the same footing as
785  // the ALCT quality.
786  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
787  if (sumQual < 1 || sumQual > 6) {
788  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
789  << "+++ findQuality: Unexpected sumQual = " << sumQual << "+++\n";
790  }
791 
792  // LCT quality is basically the sum of ALCT and CLCT qualities, but split
793  // in two groups depending on the CLCT pattern id (higher quality for
794  // straighter patterns).
795  int offset = 0;
796  if (cLCT.getPattern() <= 7) offset = 4;
797  else offset = 9;
798  quality = offset + sumQual;
799  }
800  }
801 #endif
802  else {
803  // 2008 definition.
804  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
805  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
806  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
807  else quality = 0; // both absent; should never happen.
808  }
809  else {
810  const int pattern(cLCT.getPattern());
811  if (pattern == 1) quality = 3; // layer-trigger in CLCT
812  else {
813  // ALCT quality is the number of layers hit minus 3.
814  // CLCT quality is the number of layers hit.
815  int n_rpc = 0;
816  if (hasRPC) n_rpc = 1;
817  const bool a4((aLCT.getQuality() >= 1 and aLCT.getQuality() != 4) or
818  (aLCT.getQuality() == 4 and n_rpc >=1));
819  const bool c4((cLCT.getQuality() >= 4) or (cLCT.getQuality() >= 3 and n_rpc>=1));
820  // quality = 4; "reserved for low-quality muons in future"
821  if (!a4 && !c4) quality = 5; // marginal anode and cathode
822  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
823  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
824  else if ( a4 && c4) {
825  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
826  else {
827  // quality = 9; "reserved for HQ muons with future patterns
828  // quality = 10; "reserved for HQ muons with future patterns
829  if (pattern == 2 || pattern == 3) quality = 11;
830  else if (pattern == 4 || pattern == 5) quality = 12;
831  else if (pattern == 6 || pattern == 7) quality = 13;
832  else if (pattern == 8 || pattern == 9) quality = 14;
833  else if (pattern == 10) quality = 15;
834  else {
835  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
836  << "+++ findQuality: Unexpected CLCT pattern id = "
837  << pattern << "+++\n";
838  }
839  }
840  }
841  }
842  }
843  }
844  return quality;
845 }
846 
847 
849  CSCCLCTDigi secondCLCT,
850  RPCDigi rpcDigi, int roll,
851  CSCCorrelatedLCTDigi& lct1,
852  CSCCorrelatedLCTDigi& lct2)
853 {
854  bool cathodeBestValid = bestCLCT.isValid();
855  bool cathodeSecondValid = secondCLCT.isValid();
856 
857  if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT;
858  if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT;
859 
860  if ((clct_trig_enable and bestCLCT.isValid()) or
861  (match_trig_enable and bestCLCT.isValid()))
862  {
863  lct1 = constructLCTsRPC(bestCLCT, rpcDigi, roll, useOldLCTDataFormat_);
864  lct1.setTrknmb(1);
865  }
866 
867  if ((clct_trig_enable and secondCLCT.isValid()) or
868  (match_trig_enable and secondCLCT.isValid() and secondCLCT != bestCLCT))
869  {
870  lct2 = constructLCTsRPC(secondCLCT, rpcDigi, roll, useOldLCTDataFormat_);
871  lct2.setTrknmb(2);
872  }
873 }
874 
875 
877  CSCALCTDigi secondALCT,
878  RPCDigi rpcDigi,
879  CSCCorrelatedLCTDigi& lct1,
880  CSCCorrelatedLCTDigi& lct2)
881 {
882  bool anodeBestValid = bestALCT.isValid();
883  bool anodeSecondValid = secondALCT.isValid();
884 
885  if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT;
886  if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT;
887 
888  if ((alct_trig_enable and bestALCT.isValid()) or
889  (match_trig_enable and bestALCT.isValid()))
890  {
891  lct1 = constructLCTsRPC(bestALCT, rpcDigi, useOldLCTDataFormat_);
892  lct1.setTrknmb(1);
893  }
894 
895  if ((alct_trig_enable and secondALCT.isValid()) or
896  (match_trig_enable and secondALCT.isValid() and secondALCT != bestALCT))
897  {
898  lct2 = constructLCTsRPC(secondALCT, rpcDigi, useOldLCTDataFormat_);
899  lct2.setTrknmb(2);
900  }
901 }
902 
903 
905  CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT,
907  const RPCDigisBX& digis)
908 {
909  bool anodeBestValid = bestALCT.isValid();
910  bool anodeSecondValid = secondALCT.isValid();
911  bool cathodeBestValid = bestCLCT.isValid();
912  bool cathodeSecondValid = secondCLCT.isValid();
913 
914  if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT;
915  if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT;
916  if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT;
917  if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT;
918 
919  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
920  // parameters.
921  if ((alct_trig_enable and bestALCT.isValid()) or
922  (clct_trig_enable and bestCLCT.isValid()) or
923  (match_trig_enable and bestALCT.isValid() and bestCLCT.isValid())){
924  lct1 = constructLCTsRPC(bestALCT, bestCLCT, digis);
925  lct1.setTrknmb(1);
926  }
927 
928  if (((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) and
929  ((alct_trig_enable and secondALCT.isValid()) or
930  (clct_trig_enable and secondCLCT.isValid()) or
931  (match_trig_enable and secondALCT.isValid() and secondCLCT.isValid()))){
932  lct2 = constructLCTsRPC(secondALCT, secondCLCT, digis);
933  lct2.setTrknmb(2);
934  }
935 }
936 
938 {
939  // CLCT pattern number
940  unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType());
941 
942  // LCT quality number
943  unsigned int quality = findQualityRPC(aLCT, cLCT, digis.size()!=0);
944 
945  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
946  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
947  if (digis.size()!=0) bx = lct_central_bx + digis[0].second->bx(); // fix this!!!
948 
949  // construct correlated LCT; temporarily assign track number of 0.
950  int trknmb = 0;
951  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
952  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
953  bx, 0, 0, 0, theTrigChamber);
954  return thisLCT;
955 }
956 
957 
959  const RPCDigi& rpc, int roll,
960  bool oldDataFormat)
961 {
962  if (oldDataFormat){
963  // CLCT pattern number - for the time being, do not include RPCs in the pattern
964  unsigned int pattern = encodePattern(clct.getPattern(), clct.getStripType());
965 
966  // LCT quality number - dummy quality
967  unsigned int quality = promoteCLCTRPCquality_ ? 14 : 11;
968 
969  // Bunch crossing: pick RPC bx
970  int bx = rpc.bx() + lct_central_bx;
971 
972  // pick a random WG in the roll range
973  int wg(4);
974 
975  // construct correlated LCT; temporarily assign track number of 0.
976  return CSCCorrelatedLCTDigi(0, 1, quality, wg, clct.getKeyStrip(), pattern, clct.getBend(), bx, 0, 0, 0, theTrigChamber);
977  }
978  else {
979  // CLCT pattern number - no pattern
980  unsigned int pattern = 0;//encodePatternRPC(clct.getPattern(), clct.getStripType());
981 
982  // LCT quality number - dummy quality
983  unsigned int quality = 5;//findQualityRPC(alct, gem);
984 
985  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
986  int bx = rpc.bx() + lct_central_bx;;
987 
988  // ALCT WG
989  int wg(0);
990 
991  // construct correlated LCT; temporarily assign track number of 0.
992  return CSCCorrelatedLCTDigi(0, 1, quality, wg, 0, pattern, 0, bx, 0, 0, 0, theTrigChamber);
993  }
994 }
995 
996 
998  const RPCDigi& rpc,
999  bool oldDataFormat)
1000 {
1001  if (oldDataFormat){
1002  // CLCT pattern number - set it to a highest value
1003  // hack to get LCTs in the CSCTF
1004  unsigned int pattern = promoteALCTRPCpattern_ ? 10 : 0;
1005 
1006  // LCT quality number - set it to a very high value
1007  // hack to get LCTs in the CSCTF
1008  unsigned int quality = promoteALCTRPCquality_ ? 14 : 11;
1009 
1010  // Bunch crossing
1011  int bx = rpc.bx() + lct_central_bx;
1012 
1013  // get keyStrip from LUT
1014  int keyStrip = rpcStripToCscHs_[rpc.strip()];
1015 
1016  // get wiregroup from ALCT
1017  int wg = alct.getKeyWG();
1018 
1019  // construct correlated LCT; temporarily assign track number of 0.
1020  return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber);
1021  }
1022  else {
1023  // CLCT pattern number - no pattern
1024  unsigned int pattern = 0;
1025 
1026  // LCT quality number
1027  unsigned int quality = 1;
1028 
1029  // Bunch crossing
1030  int bx = rpc.bx() + lct_central_bx;
1031 
1032  // get keyStrip from LUT
1033  int keyStrip = rpcStripToCscHs_[rpc.strip()];
1034  // get wiregroup from ALCT
1035  int wg = alct.getKeyWG();
1036 
1037  // construct correlated LCT; temporarily assign track number of 0.
1038  return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber);
1039  }
1040 }
1041 
1042 
1043 //readout LCTs
1044 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME3141RPC::readoutLCTs()
1045 {
1046  return getLCTs();
1047 }
1048 
1049 //getLCTs when we use different sort algorithm
1050 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME3141RPC::getLCTs()
1051 {
1052  std::vector<CSCCorrelatedLCTDigi> result;
1053  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
1054  std::vector<CSCCorrelatedLCTDigi> tmpV;
1055  if (tmb_cross_bx_algo == 3) {
1056  tmpV = sortLCTsByQuality(bx);
1057  result.insert(result.end(), tmpV.begin(), tmpV.end());
1058  }
1059  else {
1060  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) {
1061  for (int i=0;i<2;i++) {
1062  if (allLCTs[bx][mbx][i].isValid()) {
1063  result.push_back(allLCTs[bx][mbx][i]);
1064  }
1065  }
1066  }
1067  }
1068  }
1069  return result;
1070 }
1071 
1072 //sort LCTs by Quality in each BX
1073 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME3141RPC::sortLCTsByQuality(int bx)
1074 {
1075  std::vector<CSCCorrelatedLCTDigi> LCTs;
1076  LCTs.clear();
1077  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1078  for (int i=0;i<2;i++)
1079  if (allLCTs[bx][mbx][i].isValid())
1080  LCTs.push_back(allLCTs[bx][mbx][i]);
1081 
1082  // return sorted vector with 2 highest quality LCTs
1083  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByQuality);
1084  if (LCTs.size()> max_me3141_lcts) LCTs.erase(LCTs.begin()+max_me3141_lcts, LCTs.end());
1085  return LCTs;
1086 }
1087 
1088 
1090 {
1091  /*
1092  using namespace std;
1093 
1094  // check if we have any LCTs at all
1095  int nlct = 0;
1096  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
1097  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1098  for (int i=0;i<2;i++)
1099  {
1100  CSCCorrelatedLCTDigi& lct = allLCTs[bx][mbx][i];
1101  if (lct.isValid()) nlct++;
1102  }
1103  if (nlct == 0) return;
1104 
1105  // retrieve CSCChamber geometry
1106  CSCTriggerGeomManager* geo_manager = CSCTriggerGeometry::get();
1107  CSCChamber* cscChamber = geo_manager->chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber);
1108  const CSCDetId csc_id(cscChamber->id());
1109  const int chamber(csc_id.chamber());
1110  const bool is_odd(chamber%2==1);
1111 
1112 
1113  if (debug_rpc_dphi) std::cout<<"++++++++ matchRPCPads "<< csc_id <<" +++++++++ "<<std::endl;
1114 
1115  // check if there are any pads
1116  if (rpcDigis_.empty()) {
1117  if (debug_rpc_dphi) std::cout<<"igotnopads"<<std::endl;
1118  return;
1119  }
1120 
1121  // walk over BXs
1122  for (int bx = 0; bx < MAX_LCT_BINS; ++bx)
1123  {
1124  auto in_digis = rpcDigis_.find(bx);
1125 
1126  // walk over potential LCTs in this BX
1127  for (unsigned int mbx = 0; mbx < match_trig_window_size; ++mbx)
1128  for (int i=0; i<2; ++i)
1129  {
1130  CSCCorrelatedLCTDigi& lct = allLCTs[bx][mbx][i];
1131  if (!lct.isValid() or fabs(lct.getGEMDPhi()) < 0.000001) continue;
1132  if (debug_rpc_dphi) std::cout<<"LCTbefore "<<bx<<" "<<mbx<<" "<<i<<" "<<lct;
1133 
1134  // use -99 as default value whe we don't know if there could have been a gem match
1135  lct.setGEMDPhi(-99.);
1136 
1137  // "strip" here is actually a half-strip in geometry's terms
1138  // note that LCT::getStrip() starts from 0
1139  float fractional_strip = 0.5 * (lct.getStrip() + 1) - 0.25;
1140  auto layer_geo = cscChamber->layer(CSCConstants::KEY_CLCT_LAYER)->geometry();
1141  // LCT::getKeyWG() also starts from 0
1142  float wire = layer_geo->middleWireOfGroup(lct.getKeyWG() + 1);
1143 
1144  LocalPoint csc_intersect = layer_geo->intersectionOfStripAndWire(fractional_strip, wire);
1145  GlobalPoint csc_gp = csc_g->idToDet(csc_id)->surface().toGlobal(csc_intersect);
1146 
1147  // is LCT located in the high efficiency RPC eta range?
1148  bool rpc_fid = ( std::abs(csc_gp.eta()) >= rpc_match_min_eta );
1149 
1150  if (debug_rpc_dphi) std::cout<<" lct eta "<<csc_gp.eta()<<" phi "<<csc_gp.phi()<<std::endl;
1151 
1152  if (!rpc_fid)
1153  {
1154  if (debug_rpc_dphi) std::cout<<" -- lct pass no rpc req"<<std::endl;
1155  continue;
1156  }
1157  // use 100 ad default value when within gem fiducial region
1158  lct.setGEMDPhi(100.);
1159 
1160  if (in_digis == rpcDigis_.end()) // has no potential RPC hits with similar BX -> zap it
1161  {
1162  if (rpc_clear_nomatch_lcts) lct.clear();
1163  if (debug_rpc_dphi) std::cout<<" -- no rpc"<<std::endl;
1164  continue;
1165  }
1166  if (debug_rpc_dphi) std::cout<<" -- rpc possible"<<std::endl;
1167  // use 99 ad default value when we expect there to be a gem match
1168  lct.setGEMDPhi(99.);
1169 
1170  // to consider a GEM digi as "matched" it has to be
1171  // within specified delta_eta and delta_phi ranges
1172  // and if there are multiple ones, only the min|delta_phi| is considered as matched
1173  bool rpc_matched = false;
1174  //int rpc_bx = 99;
1175  float min_dphi = 99.;
1176  for (auto& id_digi: in_digis->second)
1177  {
1178  RPCDetId rpc_id(id_digi.first);
1179  LocalPoint rpc_lp = rpc_g->roll(rpc_id)->centreOfStrip(id_digi.second->strip());
1180  GlobalPoint rpc_gp = rpc_g->idToDet(rpc_id)->surface().toGlobal(rpc_lp);
1181  float dphi = deltaPhi(csc_gp.phi(), rpc_gp.phi());
1182  float deta = csc_gp.eta() - rpc_gp.eta();
1183  if (debug_rpc_dphi) std::cout<<" rpc with dphi "<< std::abs(dphi) <<" deta "<< std::abs(deta) <<std::endl;
1184 
1185  if( ( std::abs(deta) <= rpc_match_delta_eta ) and // within delta_eta
1186  ( ( is_odd and std::abs(dphi) <= rpc_match_delta_phi_odd ) or
1187  ( !is_odd and std::abs(dphi) <= rpc_match_delta_phi_even ) ) and // within delta_phi
1188  ( std::abs(dphi) < std::abs(min_dphi) ) // minimal delta phi
1189  )
1190  {
1191  rpc_matched = true;
1192  min_dphi = dphi;
1193  //rpc_bx = id_digi.second->bx();
1194  }
1195  }
1196  if (rpc_matched)
1197  {
1198  if (debug_rpc_dphi) std::cout<<" GOT MATCHED RPC!"<<std::endl;
1199  lct.setGEMDPhi(min_dphi);
1200  // assing the bit value
1201  int oddEven = int(not is_odd) + 1;
1202  auto lut_pt_vs_dphi_rpccsc(st == ME31 ? lut_pt_vs_dphi_rpccsc_me31 : lut_pt_vs_dphi_rpccsc_me41);
1203  int numberOfBendAngles(sizeof lut_pt_vs_dphi_rpccsc / sizeof *lut_pt_vs_dphi_rpccsc);
1204 
1205  int iFound = 0;
1206  if (abs(min_dphi) < lut_pt_vs_dphi_rpccsc[numberOfBendAngles-1][oddEven]) iFound = numberOfBendAngles;
1207  else {
1208  for (int i=0; i< numberOfBendAngles-1; ++i) {
1209  if (debug_rpc_dphi) std::cout<<"is_odd "<<is_odd <<" min_dphi "<<abs(min_dphi)<<" bend angle lib "<<i<<" "<<lut_pt_vs_dphi_rpccsc[i][oddEven]<< std::endl;
1210  if (abs(min_dphi) < lut_pt_vs_dphi_rpccsc[i][oddEven] and abs(min_dphi) > lut_pt_vs_dphi_rpccsc[i+1][oddEven])
1211  iFound = i+1;
1212  }
1213  }
1214  lct.setGEMDPhiBits(iFound);
1215  if (debug_rpc_dphi) std::cout<<"found bend angle "<<abs(min_dphi)<<" "<<lct.getGEMDPhiBits()<<" "<<lut_pt_vs_dphi_rpccsc[iFound][oddEven]<<" "<<iFound << std::endl;
1216  }
1217  else
1218  {
1219  if (debug_rpc_dphi) std::cout<<" no rpc match";
1220  if (rpc_clear_nomatch_lcts)
1221  {
1222  lct.clear();
1223  if (debug_rpc_dphi) std::cout<<" - cleared lct";
1224  }
1225  if (debug_rpc_dphi) std::cout<<std::endl;
1226  }
1227  if (debug_rpc_dphi) std::cout<<"LCTafter "<<bx<<" "<<mbx<<" "<<i<<" "<<lct;
1228  }
1229  }
1230 
1231  // final count
1232  int nlct_after = 0;
1233  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
1234  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1235  for (int i=0;i<2;i++)
1236  {
1237  if (allLCTs[bx][mbx][i].isValid()) nlct_after++;
1238  }
1239  if (debug_rpc_dphi) std::cout<<"before "<<nlct<<" after "<<nlct_after<<std::endl;
1240  */
1241 }
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:33
const unsigned theSector
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
static const double lut_wg_me41_eta_odd[96][2]
std::map< int, int > cscWgToRpcRoll_
CSCMotherboardME3141RPC(unsigned endcap, unsigned station, unsigned sector, unsigned subsector, unsigned chamber, const edm::ParameterSet &conf)
std::map< int, int > rpcStripToCscHs_
unsigned int clct_trig_enable
CSCChamber * chamber(unsigned endcap, unsigned station, unsigned sector, unsigned subsector, unsigned tcscid) const
Return the CSCChamber for a corresponding endcap/station/sector/subsector/trigger cscid...
std::vector< CSCCLCTDigi > clctV
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool rpc_clear_nomatch_lcts
whether to throw out RPC-fiducial LCTs that have no rpc match
unsigned int match_trig_window_size
int bx() const
Definition: RPCDigi.cc:47
const unsigned theTrigChamber
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
const unsigned theEndcap
double maxEta
std::vector< CSCCorrelatedLCTDigi > readoutLCTs()
std::vector< CSCCorrelatedLCTDigi > sortLCTsByQuality(int bx)
int getStripType() const
return striptype
Definition: CSCCLCTDigi.h:39
int rpc_match_delta_bx
delta BX for RPC pads matching
int getBend() const
return bend
Definition: CSCCLCTDigi.h:42
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
U second(std::pair< T, U > const &p)
const RPCChamber * chamber(RPCDetId id) const
Definition: RPCGeometry.cc:71
void printRPCTriggerDigis(int minBX, int maxBx)
int strip() const
Definition: RPCDigi.cc:45
const unsigned theStation
static CSCTriggerGeomManager * get()
std::map< int, std::pair< double, double > > createRPCRollLUT(RPCDetId id)
std::map< int, std::pair< int, int > > cscHsToRpcStrip_
const unsigned theSubsector
tuple result
Definition: query.py:137
int getBX() const
return BX
Definition: CSCCLCTDigi.h:51
static const double lut_wg_me41_eta_even[96][2]
unsigned int encodePattern(const int ptn, const int highPt)
static const double lut_pt_vs_dphi_rpccsc_me41[8][3]
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:30
unsigned int match_trig_enable
static const double lut_wg_me31_eta_odd[96][2]
static int triggerCscIdFromLabels(int station, int ring, int chamber)
static const double lut_pt_vs_dphi_rpccsc_me31[8][3]
tuple conf
Definition: dbtoconf.py:185
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:48
std::map< int, std::pair< double, double > > rpcRollToEtaLimits_
double rpc_match_delta_phi_odd
RPC matching dphi and deta.
int getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:33
#define debug
Definition: HDRShower.cc:19
CSCCorrelatedLCTDigi allLCTs[MAX_LCT_BINS][15][2]
int getAccelerator() const
Definition: CSCALCTDigi.h:37
static int triggerSectorFromLabels(int station, int ring, int chamber)
int getPattern() const
return pattern
Definition: CSCCLCTDigi.h:36
RPCDigisBX matchingRPCDigis(const CSCCLCTDigi &cLCT, const RPCDigisBX &digis=RPCDigisBX(), bool first=true)
unsigned int alct_trig_enable
std::vector< RPCDigiBX > RPCDigisBX
std::unique_ptr< CSCAnodeLCTProcessor > alct
void matchRPCDigis(enum MEX1Station st)
void correlateLCTsRPC(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, CSCCorrelatedLCTDigi &lct1, CSCCorrelatedLCTDigi &lct2, const RPCDigisBX &digis=RPCDigisBX())
bool do_rpc_matching
Do RPC matching?
std::unique_ptr< CSCCathodeLCTProcessor > clct
std::vector< CSCALCTDigi > alctV
tuple cout
Definition: gather_cfg.py:121
double rpc_match_min_eta
min eta of LCT for which we require RPC match (we don&#39;t throw out LCTs below this min eta) ...
int getKeyStrip() const
Definition: CSCCLCTDigi.h:65
std::vector< CSCCorrelatedLCTDigi > getLCTs()
void setTrknmb(const uint16_t number)
Set track number (1,2) after sorting LCTs.
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc, const RPCDigiCollection *rpcDigis)
void retrieveRPCDigis(const RPCDigiCollection *digis, unsigned id)
unsigned int findQualityRPC(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT, bool hasRPC)
int getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:45
CSCCorrelatedLCTDigi constructLCTsRPC(const CSCALCTDigi &alct, const CSCCLCTDigi &clct, const RPCDigisBX &digis=RPCDigisBX())
static bool sortByQuality(const CSCCorrelatedLCTDigi &, const CSCCorrelatedLCTDigi &)
static const double lut_wg_me31_eta_even[96][2]