00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.h>
00030 #include <L1Trigger/CSCCommonTrigger/interface/CSCTriggerGeometry.h>
00031 #include <DataFormats/MuonDetId/interface/CSCTriggerNumbering.h>
00032
00033 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00034
00035 #include <set>
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 const int CSCAnodeLCTProcessor::pattern_envelope[CSCConstants::NUM_ALCT_PATTERNS][NUM_PATTERN_WIRES] = {
00046
00047 { 0, 0, 0,
00048 1, 1,
00049 2,
00050 3, 3,
00051 4, 4, 4,
00052 5, 5, 5},
00053
00054
00055 {-2, -1, 0,
00056 -1, 0,
00057 0,
00058 0, 1,
00059 0, 1, 2,
00060 0, 1, 2},
00061
00062
00063 {2, 1, 0,
00064 1, 0,
00065 0,
00066 0, -1,
00067 0, -1, -2,
00068 0, -1, -2}
00069 };
00070
00071
00072 const int CSCAnodeLCTProcessor::time_weights[NUM_PATTERN_WIRES] =
00073
00074 { 0, 1, 1,
00075 1, 2,
00076 2,
00077 2, 1,
00078 2, 1, 0,
00079 1, 1, 0};
00080
00081
00082
00083
00084
00085
00086 const int CSCAnodeLCTProcessor::pattern_mask_slim[CSCConstants::NUM_ALCT_PATTERNS][NUM_PATTERN_WIRES] = {
00087
00088 {0, 0, 1,
00089 0, 1,
00090 1,
00091 1, 0,
00092 1, 0, 0,
00093 1, 0, 0},
00094
00095
00096 {0, 1, 0,
00097 1, 1,
00098 1,
00099 1, 0,
00100 0, 1, 0,
00101 0, 1, 0},
00102
00103
00104 {1, 1, 0,
00105 1, 1,
00106 1,
00107 1, 1,
00108 0, 1, 1,
00109 0, 0, 1}
00110 };
00111
00112
00113
00114 const int CSCAnodeLCTProcessor::pattern_mask_open[CSCConstants::NUM_ALCT_PATTERNS][NUM_PATTERN_WIRES] = {
00115
00116 {0, 0, 1,
00117 0, 1,
00118 1,
00119 1, 0,
00120 1, 0, 0,
00121 1, 0, 0},
00122
00123
00124 {1, 1, 1,
00125 1, 1,
00126 1,
00127 1, 1,
00128 1, 1, 1,
00129 1, 1, 1},
00130
00131
00132 {1, 1, 1,
00133 1, 1,
00134 1,
00135 1, 1,
00136 1, 1, 1,
00137 1, 1, 1}
00138 };
00139
00140
00141 const int CSCAnodeLCTProcessor::pattern_mask_r1[CSCConstants::NUM_ALCT_PATTERNS][NUM_PATTERN_WIRES] = {
00142
00143 {0, 0, 1,
00144 0, 1,
00145 1,
00146 1, 0,
00147 1, 0, 0,
00148 1, 0, 0},
00149
00150
00151 {0, 1, 1,
00152 1, 1,
00153 1,
00154 1, 0,
00155 1, 1, 0,
00156 1, 1, 0},
00157
00158
00159 {0, 1, 1,
00160 1, 1,
00161 1,
00162 1, 0,
00163 1, 1, 0,
00164 1, 1, 0}
00165 };
00166
00167
00168
00169
00170 const unsigned int CSCAnodeLCTProcessor::def_fifo_tbins = 16;
00171 const unsigned int CSCAnodeLCTProcessor::def_fifo_pretrig = 10;
00172 const unsigned int CSCAnodeLCTProcessor::def_drift_delay = 2;
00173 const unsigned int CSCAnodeLCTProcessor::def_nplanes_hit_pretrig = 2;
00174 const unsigned int CSCAnodeLCTProcessor::def_nplanes_hit_pattern = 4;
00175 const unsigned int CSCAnodeLCTProcessor::def_nplanes_hit_accel_pretrig = 2;
00176 const unsigned int CSCAnodeLCTProcessor::def_nplanes_hit_accel_pattern = 4;
00177 const unsigned int CSCAnodeLCTProcessor::def_trig_mode = 2;
00178 const unsigned int CSCAnodeLCTProcessor::def_accel_mode = 0;
00179 const unsigned int CSCAnodeLCTProcessor::def_l1a_window_width = 7;
00180
00181
00182
00183
00184
00185 CSCAnodeLCTProcessor::CSCAnodeLCTProcessor(unsigned endcap, unsigned station,
00186 unsigned sector, unsigned subsector,
00187 unsigned chamber,
00188 const edm::ParameterSet& conf,
00189 const edm::ParameterSet& comm) :
00190 theEndcap(endcap), theStation(station), theSector(sector),
00191 theSubsector(subsector), theTrigChamber(chamber) {
00192 static bool config_dumped = false;
00193
00194
00195 fifo_tbins = conf.getParameter<unsigned int>("alctFifoTbins");
00196 fifo_pretrig = conf.getParameter<unsigned int>("alctFifoPretrig");
00197 drift_delay = conf.getParameter<unsigned int>("alctDriftDelay");
00198 nplanes_hit_pretrig =
00199 conf.getParameter<unsigned int>("alctNplanesHitPretrig");
00200 nplanes_hit_pattern =
00201 conf.getParameter<unsigned int>("alctNplanesHitPattern");
00202 nplanes_hit_accel_pretrig =
00203 conf.getParameter<unsigned int>("alctNplanesHitAccelPretrig");
00204 nplanes_hit_accel_pattern =
00205 conf.getParameter<unsigned int>("alctNplanesHitAccelPattern");
00206 trig_mode = conf.getParameter<unsigned int>("alctTrigMode");
00207 accel_mode = conf.getParameter<unsigned int>("alctAccelMode");
00208 l1a_window_width = conf.getParameter<unsigned int>("alctL1aWindowWidth");
00209
00210 hit_persist = conf.getUntrackedParameter<unsigned int>("alctHitPersist", 6);
00211
00212
00213 infoV = conf.getUntrackedParameter<int>("verbosity", 0);
00214
00215
00216
00217 isMTCC = comm.getParameter<bool>("isMTCC");
00218
00219 isTMB07 = comm.getParameter<bool>("isTMB07");
00220
00221
00222 isSLHC = comm.getUntrackedParameter<bool>("isSLHC", false);
00223
00224
00225 disableME1a = comm.getUntrackedParameter<bool>("disableME1a", false);
00226
00227
00228 early_tbins = conf.getUntrackedParameter<int>("alctEarlyTbins",-1);
00229 int fpga_latency = 6;
00230 if (early_tbins<0) early_tbins = fifo_pretrig - fpga_latency;
00231
00232
00233 ghost_cancellation_bx_depth = conf.getUntrackedParameter<int>("alctGhostCancellationBxDepth", 4);
00234
00235
00236 ghost_cancellation_side_quality = conf.getUntrackedParameter<bool>("alctGhostCancellationSideQuality", false);
00237
00238
00239 pretrig_extra_deadtime = conf.getUntrackedParameter<unsigned int>("alctPretrigDeadtime", 4);
00240
00241
00242 narrow_mask_r1 = conf.getUntrackedParameter<bool>("alctNarrowMaskForR1", false);
00243
00244
00245 checkConfigParameters();
00246 if ((infoV > 0 || isSLHC) && !config_dumped) {
00247
00248 dumpConfigParams();
00249 config_dumped = true;
00250 if (isSLHC) std::cout<<"disableME1a = "<<disableME1a<<std::endl;
00251 }
00252
00253 numWireGroups = 0;
00254 MESelection = (theStation < 3) ? 0 : 1;
00255
00256 theRing = CSCTriggerNumbering::ringFromTriggerLabels(theStation, theTrigChamber);
00257
00258 theChamber = CSCTriggerNumbering::chamberFromTriggerLabels(theSector, theSubsector,
00259 theStation, theTrigChamber);
00260
00261
00262 isME11 = (theStation == 1 && theRing == 1);
00263
00264
00265 use_corrected_bx = false;
00266 if (isSLHC && isME11) {
00267 use_corrected_bx = conf.getUntrackedParameter<bool>("alctUseCorrectedBx", false);
00268 }
00269
00270
00271
00272
00273 loadPatternMask();
00274 }
00275
00276 CSCAnodeLCTProcessor::CSCAnodeLCTProcessor() :
00277 theEndcap(1), theStation(1), theSector(1),
00278 theSubsector(1), theTrigChamber(1) {
00279
00280 static bool config_dumped = false;
00281
00282
00283 setDefaultConfigParameters();
00284 infoV = 2;
00285 isMTCC = false;
00286 isTMB07 = true;
00287
00288 isSLHC = false;
00289 disableME1a = false;
00290
00291 early_tbins = 4;
00292
00293
00294 checkConfigParameters();
00295 if (!config_dumped) {
00296
00297 dumpConfigParams();
00298 config_dumped = true;
00299 }
00300
00301 numWireGroups = CSCConstants::MAX_NUM_WIRES;
00302 MESelection = (theStation < 3) ? 0 : 1;
00303
00304 theRing = CSCTriggerNumbering::ringFromTriggerLabels(theStation, theTrigChamber);
00305 theChamber = CSCTriggerNumbering::chamberFromTriggerLabels(theSector, theSubsector,
00306 theStation, theTrigChamber);
00307 isME11 = (theStation == 1 && theRing == 1);
00308
00309
00310 loadPatternMask();
00311 }
00312
00313
00314 void CSCAnodeLCTProcessor::loadPatternMask() {
00315
00316 for (int i_patt = 0; i_patt < CSCConstants::NUM_ALCT_PATTERNS; i_patt++) {
00317 for (int i_wire = 0; i_wire < NUM_PATTERN_WIRES; i_wire++) {
00318 if (isMTCC || isTMB07) {
00319 pattern_mask[i_patt][i_wire] = pattern_mask_open[i_patt][i_wire];
00320 if (narrow_mask_r1 && (theRing == 1 || theRing == 4))
00321 pattern_mask[i_patt][i_wire] = pattern_mask_r1[i_patt][i_wire];
00322 }
00323 else {
00324 pattern_mask[i_patt][i_wire] = pattern_mask_slim[i_patt][i_wire];
00325 }
00326 }
00327 }
00328 }
00329
00330
00331 void CSCAnodeLCTProcessor::setDefaultConfigParameters() {
00332
00333 fifo_tbins = def_fifo_tbins;
00334 fifo_pretrig = def_fifo_pretrig;
00335 drift_delay = def_drift_delay;
00336 nplanes_hit_pretrig = def_nplanes_hit_pretrig;
00337 nplanes_hit_pattern = def_nplanes_hit_pattern;
00338 nplanes_hit_accel_pretrig = def_nplanes_hit_accel_pretrig;
00339 nplanes_hit_accel_pattern = def_nplanes_hit_accel_pattern;
00340 trig_mode = def_trig_mode;
00341 accel_mode = def_accel_mode;
00342 l1a_window_width = def_l1a_window_width;
00343 }
00344
00345
00346 void CSCAnodeLCTProcessor::setConfigParameters(const CSCDBL1TPParameters* conf) {
00347 static bool config_dumped = false;
00348
00349 fifo_tbins = conf->alctFifoTbins();
00350 fifo_pretrig = conf->alctFifoPretrig();
00351 drift_delay = conf->alctDriftDelay();
00352 nplanes_hit_pretrig = conf->alctNplanesHitPretrig();
00353 nplanes_hit_pattern = conf->alctNplanesHitPattern();
00354 nplanes_hit_accel_pretrig = conf->alctNplanesHitAccelPretrig();
00355 nplanes_hit_accel_pattern = conf->alctNplanesHitAccelPattern();
00356 trig_mode = conf->alctTrigMode();
00357 accel_mode = conf->alctAccelMode();
00358 l1a_window_width = conf->alctL1aWindowWidth();
00359
00360
00361 checkConfigParameters();
00362 if (!config_dumped) {
00363
00364 dumpConfigParams();
00365 config_dumped = true;
00366 }
00367 }
00368
00369 void CSCAnodeLCTProcessor::checkConfigParameters() {
00370
00371
00372
00373 static const unsigned int max_fifo_tbins = 1 << 5;
00374 static const unsigned int max_fifo_pretrig = 1 << 5;
00375 static const unsigned int max_drift_delay = 1 << 2;
00376 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
00377 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
00378 static const unsigned int max_nplanes_hit_accel_pretrig = 1 << 3;
00379 static const unsigned int max_nplanes_hit_accel_pattern = 1 << 3;
00380 static const unsigned int max_trig_mode = 1 << 2;
00381 static const unsigned int max_accel_mode = 1 << 2;
00382 static const unsigned int max_l1a_window_width = MAX_ALCT_BINS;
00383
00384
00385 if (fifo_tbins >= max_fifo_tbins) {
00386 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00387 << "+++ Value of fifo_tbins, " << fifo_tbins
00388 << ", exceeds max allowed, " << max_fifo_tbins-1 << " +++\n"
00389 << "+++ Try to proceed with the default value, fifo_tbins="
00390 << def_fifo_tbins << " +++\n";
00391 fifo_tbins = def_fifo_tbins;
00392 }
00393 if (fifo_pretrig >= max_fifo_pretrig) {
00394 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00395 << "+++ Value of fifo_pretrig, " << fifo_pretrig
00396 << ", exceeds max allowed, " << max_fifo_pretrig-1 << " +++\n"
00397 << "+++ Try to proceed with the default value, fifo_pretrig="
00398 << def_fifo_pretrig << " +++\n";
00399 fifo_pretrig = def_fifo_pretrig;
00400 }
00401 if (drift_delay >= max_drift_delay) {
00402 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00403 << "+++ Value of drift_delay, " << drift_delay
00404 << ", exceeds max allowed, " << max_drift_delay-1 << " +++\n"
00405 << "+++ Try to proceed with the default value, drift_delay="
00406 << def_drift_delay << " +++\n";
00407 drift_delay = def_drift_delay;
00408 }
00409 if (nplanes_hit_pretrig >= max_nplanes_hit_pretrig) {
00410 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00411 << "+++ Value of nplanes_hit_pretrig, " << nplanes_hit_pretrig
00412 << ", exceeds max allowed, " << max_nplanes_hit_pretrig-1 << " +++\n"
00413 << "+++ Try to proceed with the default value, nplanes_hit_pretrig="
00414 << nplanes_hit_pretrig << " +++\n";
00415 nplanes_hit_pretrig = def_nplanes_hit_pretrig;
00416 }
00417 if (nplanes_hit_pattern >= max_nplanes_hit_pattern) {
00418 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00419 << "+++ Value of nplanes_hit_pattern, " << nplanes_hit_pattern
00420 << ", exceeds max allowed, " << max_nplanes_hit_pattern-1 << " +++\n"
00421 << "+++ Try to proceed with the default value, nplanes_hit_pattern="
00422 << nplanes_hit_pattern << " +++\n";
00423 nplanes_hit_pattern = def_nplanes_hit_pattern;
00424 }
00425 if (nplanes_hit_accel_pretrig >= max_nplanes_hit_accel_pretrig) {
00426 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00427 << "+++ Value of nplanes_hit_accel_pretrig, "
00428 << nplanes_hit_accel_pretrig << ", exceeds max allowed, "
00429 << max_nplanes_hit_accel_pretrig-1 << " +++\n"
00430 << "+++ Try to proceed with the default value, "
00431 << "nplanes_hit_accel_pretrig=" << nplanes_hit_accel_pretrig << " +++\n";
00432 nplanes_hit_accel_pretrig = def_nplanes_hit_accel_pretrig;
00433 }
00434 if (nplanes_hit_accel_pattern >= max_nplanes_hit_accel_pattern) {
00435 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00436 << "+++ Value of nplanes_hit_accel_pattern, "
00437 << nplanes_hit_accel_pattern << ", exceeds max allowed, "
00438 << max_nplanes_hit_accel_pattern-1 << " +++\n"
00439 << "+++ Try to proceed with the default value, "
00440 << "nplanes_hit_accel_pattern=" << nplanes_hit_accel_pattern << " +++\n";
00441 nplanes_hit_accel_pattern = def_nplanes_hit_accel_pattern;
00442 }
00443 if (trig_mode >= max_trig_mode) {
00444 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00445 << "+++ Value of trig_mode, " << trig_mode
00446 << ", exceeds max allowed, " << max_trig_mode-1 << " +++\n"
00447 << "+++ Try to proceed with the default value, trig_mode="
00448 << trig_mode << " +++\n";
00449 trig_mode = def_trig_mode;
00450 }
00451 if (accel_mode >= max_accel_mode) {
00452 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00453 << "+++ Value of accel_mode, " << accel_mode
00454 << ", exceeds max allowed, " << max_accel_mode-1 << " +++\n"
00455 << "+++ Try to proceed with the default value, accel_mode="
00456 << accel_mode << " +++\n";
00457 accel_mode = def_accel_mode;
00458 }
00459 if (l1a_window_width >= max_l1a_window_width) {
00460 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00461 << "+++ Value of l1a_window_width, " << l1a_window_width
00462 << ", exceeds max allowed, " << max_l1a_window_width-1 << " +++\n"
00463 << "+++ Try to proceed with the default value, l1a_window_width="
00464 << l1a_window_width << " +++\n";
00465 l1a_window_width = def_l1a_window_width;
00466 }
00467 }
00468
00469 void CSCAnodeLCTProcessor::clear() {
00470 for (int bx = 0; bx < MAX_ALCT_BINS; bx++) {
00471 bestALCT[bx].clear();
00472 secondALCT[bx].clear();
00473 }
00474 }
00475
00476 void CSCAnodeLCTProcessor::clear(const int wire, const int pattern) {
00477
00478 if (pattern == 0) quality[wire][0] = -999;
00479 else {
00480 quality[wire][1] = -999;
00481 quality[wire][2] = -999;
00482 }
00483 }
00484
00485 std::vector<CSCALCTDigi>
00486 CSCAnodeLCTProcessor::run(const CSCWireDigiCollection* wiredc) {
00487
00488
00489
00490
00491
00492 static bool config_dumped = false;
00493 if ((infoV > 0 || isSLHC) && !config_dumped) {
00494
00495 dumpConfigParams();
00496 config_dumped = true;
00497 }
00498
00499
00500
00501
00502 if (numWireGroups == 0) {
00503 CSCTriggerGeomManager* theGeom = CSCTriggerGeometry::get();
00504 CSCChamber* chamber = theGeom->chamber(theEndcap, theStation, theSector,
00505 theSubsector, theTrigChamber);
00506 if (chamber) {
00507 numWireGroups = chamber->layer(1)->geometry()->numberOfWireGroups();
00508 if (numWireGroups > CSCConstants::MAX_NUM_WIRES) {
00509 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
00510 << "+++ Number of wire groups, " << numWireGroups
00511 << " found in ME" << ((theEndcap == 1) ? "+" : "-")
00512 << theStation << "/" << theRing << "/" << theChamber
00513 << " (sector " << theSector << " subsector " << theSubsector
00514 << " trig id. " << theTrigChamber << ")"
00515 << " exceeds max expected, " << CSCConstants::MAX_NUM_WIRES
00516 << " +++\n"
00517 << "+++ CSC geometry looks garbled; no emulation possible +++\n";
00518 numWireGroups = -1;
00519 }
00520 }
00521 else {
00522 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
00523 << "+++ ME" << ((theEndcap == 1) ? "+" : "-")
00524 << theStation << "/" << theRing << "/" << theChamber
00525 << " (sector " << theSector << " subsector " << theSubsector
00526 << " trig id. " << theTrigChamber << ")"
00527 << " is not defined in current geometry! +++\n"
00528 << "+++ CSC geometry looks garbled; no emulation possible +++\n";
00529 numWireGroups = -1;
00530 }
00531 }
00532
00533 if (numWireGroups < 0) {
00534 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
00535 << "+++ ME" << ((theEndcap == 1) ? "+" : "-")
00536 << theStation << "/" << theRing << "/" << theChamber
00537 << " (sector " << theSector << " subsector " << theSubsector
00538 << " trig id. " << theTrigChamber << "):"
00539 << " numWireGroups = " << numWireGroups
00540 << "; ALCT emulation skipped! +++";
00541 std::vector<CSCALCTDigi> emptyV;
00542 return emptyV;
00543 }
00544
00545
00546 bool noDigis = getDigis(wiredc);
00547
00548 if (!noDigis) {
00549
00550 std::vector<int>
00551 wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES];
00552 readWireDigis(wire);
00553
00554
00555
00556
00557 const unsigned int min_layers =
00558 (nplanes_hit_accel_pattern == 0) ?
00559 nplanes_hit_pattern :
00560 ((nplanes_hit_pattern <= nplanes_hit_accel_pattern) ?
00561 nplanes_hit_pattern :
00562 nplanes_hit_accel_pattern
00563 );
00564
00565 unsigned int layersHit = 0;
00566 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00567 for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
00568 if (!wire[i_layer][i_wire].empty()) {layersHit++; break;}
00569 }
00570 }
00571 if (layersHit >= min_layers) run(wire);
00572 }
00573
00574
00575 std::vector<CSCALCTDigi> tmpV = getALCTs();
00576 return tmpV;
00577 }
00578
00579 void CSCAnodeLCTProcessor::run(const std::vector<int> wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]) {
00580
00581
00582
00583
00584
00585 bool trigger = false;
00586
00587
00588 bool chamber_empty = pulseExtension(wire);
00589
00590
00591
00592
00593 unsigned int stop_bx = fifo_tbins - drift_delay;
00594 if (!chamber_empty) {
00595 for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
00596 unsigned int start_bx = 0;
00597
00598 while (start_bx < stop_bx) {
00599 if (preTrigger(i_wire, start_bx)) {
00600 if (infoV > 2) showPatterns(i_wire);
00601 if (patternDetection(i_wire)) {
00602 trigger = true;
00603 break;
00604 }
00605 else {
00606
00607
00608
00609 start_bx = first_bx[i_wire] + drift_delay + pretrig_extra_deadtime;
00610 }
00611 }
00612 else {
00613 break;
00614 }
00615 }
00616 }
00617 }
00618
00619
00620 if (trigger) {
00621 if (isSLHC) ghostCancellationLogicSLHC();
00622 else ghostCancellationLogic();
00623 lctSearch();
00624 }
00625 }
00626
00627 bool CSCAnodeLCTProcessor::getDigis(const CSCWireDigiCollection* wiredc) {
00628
00629 bool noDigis = true;
00630
00631
00632 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00633 digiV[i_layer].clear();
00634
00635 CSCDetId detid(theEndcap, theStation, theRing, theChamber, i_layer+1);
00636 getDigis(wiredc, detid);
00637
00638
00639 if (isME11 && !disableME1a) {
00640 CSCDetId detid_me1a(theEndcap, theStation, 4, theChamber, i_layer+1);
00641 getDigis(wiredc, detid_me1a);
00642 }
00643
00644 if (!digiV[i_layer].empty()) {
00645 noDigis = false;
00646 if (infoV > 1) {
00647 LogTrace("CSCAnodeLCTProcessor")
00648 << "found " << digiV[i_layer].size()
00649 << " wire digi(s) in layer " << i_layer << " of ME"
00650 << ((theEndcap == 1) ? "+" : "-") << theStation << "/" << theRing
00651 << "/" << theChamber << " (trig. sector " << theSector
00652 << " subsector " << theSubsector << " id " << theTrigChamber << ")";
00653 for (std::vector<CSCWireDigi>::iterator pld = digiV[i_layer].begin();
00654 pld != digiV[i_layer].end(); pld++) {
00655 LogTrace("CSCAnodeLCTProcessor") << " " << (*pld);
00656 }
00657 }
00658 }
00659 }
00660
00661 return noDigis;
00662 }
00663
00664 void CSCAnodeLCTProcessor::getDigis(const CSCWireDigiCollection* wiredc,
00665 const CSCDetId& id) {
00666 const CSCWireDigiCollection::Range rwired = wiredc->get(id);
00667 for (CSCWireDigiCollection::const_iterator digiIt = rwired.first;
00668 digiIt != rwired.second; ++digiIt) {
00669 digiV[id.layer()-1].push_back(*digiIt);
00670 }
00671 }
00672
00673 void CSCAnodeLCTProcessor::readWireDigis(std::vector<int> wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]) {
00674
00675
00676
00677 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00678
00679
00680 for (std::vector<CSCWireDigi>::iterator pld = digiV[i_layer].begin();
00681 pld != digiV[i_layer].end(); pld++) {
00682 int i_wire = pld->getWireGroup()-1;
00683 std::vector<int> bx_times = pld->getTimeBinsOn();
00684
00685
00686 if (i_wire < 0 || i_wire >= numWireGroups) {
00687 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00688 << "+++ Found wire digi with wrong wire number = " << i_wire
00689 << " (max wires = " << numWireGroups << "); skipping it... +++\n";
00690 continue;
00691 }
00692
00693
00694
00695
00696
00697
00698
00699 int last_time = -999;
00700 if (bx_times.size() == fifo_tbins) {
00701 wire[i_layer][i_wire].push_back(0);
00702 wire[i_layer][i_wire].push_back(6);
00703 }
00704 else {
00705 for (unsigned int i = 0; i < bx_times.size(); i++) {
00706
00707 if (i > 0 && bx_times[i] == (bx_times[i-1]+1)) continue;
00708 if (bx_times[i] < static_cast<int>(fifo_tbins)) {
00709 if (infoV > 2) LogTrace("CSCAnodeLCTProcessor")
00710 << "Digi on layer " << i_layer << " wire " << i_wire
00711 << " at time " << bx_times[i];
00712
00713
00714
00715
00716 if (last_time < 0 || ((bx_times[i]-last_time) >= 6) ) {
00717 wire[i_layer][i_wire].push_back(bx_times[i]);
00718 last_time = bx_times[i];
00719 }
00720 }
00721 else {
00722 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
00723 << "+++ Skipping wire digi: wire = " << i_wire
00724 << " layer = " << i_layer << ", bx = " << bx_times[i] << " +++";
00725 }
00726 }
00727 }
00728 }
00729 }
00730 }
00731
00732 bool CSCAnodeLCTProcessor::pulseExtension(const std::vector<int> wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]){
00733
00734
00735
00736
00737
00738
00739 bool chamber_empty = true;
00740 int i_wire, i_layer, digi_num;
00741 static unsigned int bits_in_pulse = 8*sizeof(pulse[0][0]);
00742
00743 for (i_wire = 0; i_wire < numWireGroups; i_wire++) {
00744 for (i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00745 pulse[i_layer][i_wire] = 0;
00746 }
00747 first_bx[i_wire] = -999;
00748 first_bx_corrected[i_wire] = -999;
00749 for (int j = 0; j < 3; j++) quality[i_wire][j] = -999;
00750 }
00751
00752 for (i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++){
00753 digi_num = 0;
00754 for (i_wire = 0; i_wire < numWireGroups; i_wire++) {
00755 if (wire[i_layer][i_wire].size() > 0) {
00756 std::vector<int> bx_times = wire[i_layer][i_wire];
00757 for (unsigned int i = 0; i < bx_times.size(); i++) {
00758
00759 if (bx_times[i] < 0 || bx_times[i] + hit_persist >= bits_in_pulse) {
00760 if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeDigi")
00761 << "+++ BX time of wire digi (wire = " << i_wire
00762 << " layer = " << i_layer << ") bx = " << bx_times[i]
00763 << " is not within the range (0-" << bits_in_pulse
00764 << "] allowed for pulse extension. Skip this digi! +++\n";
00765 continue;
00766 }
00767
00768
00769 if (chamber_empty) chamber_empty = false;
00770
00771
00772 for (unsigned int bx = bx_times[i];
00773 bx < (bx_times[i] + hit_persist); bx++)
00774 pulse[i_layer][i_wire] = pulse[i_layer][i_wire] | (1 << bx);
00775
00776
00777 if (infoV > 1) {
00778 LogTrace("CSCAnodeLCTProcessor")
00779 << "Wire digi: layer " << i_layer
00780 << " digi #" << ++digi_num << " wire group " << i_wire
00781 << " time " << bx_times[i];
00782 if (infoV > 2) {
00783 std::ostringstream strstrm;
00784 for (int i = 1; i <= 32; i++) {
00785 strstrm << ((pulse[i_layer][i_wire]>>(32-i)) & 1);
00786 }
00787 LogTrace("CSCAnodeLCTProcessor") << " Pulse: " << strstrm.str();
00788 }
00789 }
00790 }
00791 }
00792 }
00793 }
00794
00795 if (infoV > 1 && !chamber_empty) {
00796 dumpDigis(wire);
00797 }
00798
00799 return chamber_empty;
00800 }
00801
00802 bool CSCAnodeLCTProcessor::preTrigger(const int key_wire, const int start_bx) {
00803
00804
00805
00806
00807 unsigned int layers_hit;
00808 bool hit_layer[CSCConstants::NUM_LAYERS];
00809 int this_layer, this_wire;
00810
00811
00812 const unsigned int nplanes_hit_pretrig_acc =
00813 (nplanes_hit_accel_pretrig != 0) ? nplanes_hit_accel_pretrig :
00814 nplanes_hit_pretrig;
00815 const unsigned int pretrig_thresh[CSCConstants::NUM_ALCT_PATTERNS] = {
00816 nplanes_hit_pretrig_acc, nplanes_hit_pretrig, nplanes_hit_pretrig
00817 };
00818
00819
00820
00821
00822
00823 unsigned int stop_bx = fifo_tbins - drift_delay;
00824 for (unsigned int bx_time = start_bx; bx_time < stop_bx; bx_time++) {
00825 for (int i_pattern = 0; i_pattern < CSCConstants::NUM_ALCT_PATTERNS; i_pattern++) {
00826 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
00827 hit_layer[i_layer] = false;
00828 layers_hit = 0;
00829
00830 for (int i_wire = 0; i_wire < NUM_PATTERN_WIRES; i_wire++){
00831 if (pattern_mask[i_pattern][i_wire] != 0){
00832 this_layer = pattern_envelope[0][i_wire];
00833 this_wire = pattern_envelope[1+MESelection][i_wire]+key_wire;
00834 if ((this_wire >= 0) && (this_wire < numWireGroups)){
00835
00836 if (((pulse[this_layer][this_wire] >> bx_time) & 1) == 1) {
00837
00838 if (hit_layer[this_layer] == false){
00839 hit_layer[this_layer] = true;
00840 layers_hit++;
00841 }
00842
00843
00844
00845 if (layers_hit >= pretrig_thresh[i_pattern]) {
00846 first_bx[key_wire] = bx_time;
00847 if (infoV > 1) {
00848 LogTrace("CSCAnodeLCTProcessor")
00849 << "Pretrigger was satisfied for wire: " << key_wire
00850 << " pattern: " << i_pattern
00851 << " bx_time: " << bx_time;
00852 }
00853 return true;
00854 }
00855 }
00856 }
00857 }
00858 }
00859 }
00860 }
00861
00862 return false;
00863 }
00864
00865 bool CSCAnodeLCTProcessor::patternDetection(const int key_wire) {
00866
00867
00868
00869
00870 bool trigger = false;
00871 bool hit_layer[CSCConstants::NUM_LAYERS];
00872 unsigned int temp_quality;
00873 int this_layer, this_wire, delta_wire;
00874
00875
00876 const unsigned int nplanes_hit_pattern_acc =
00877 (nplanes_hit_accel_pattern != 0) ? nplanes_hit_accel_pattern :
00878 nplanes_hit_pattern;
00879 const unsigned int pattern_thresh[CSCConstants::NUM_ALCT_PATTERNS] = {
00880 nplanes_hit_pattern_acc, nplanes_hit_pattern, nplanes_hit_pattern
00881 };
00882 const std::string ptn_label[] = {"Accelerator", "CollisionA", "CollisionB"};
00883
00884 for (int i_pattern = 0; i_pattern < CSCConstants::NUM_ALCT_PATTERNS; i_pattern++){
00885 temp_quality = 0;
00886 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
00887 hit_layer[i_layer] = false;
00888
00889 double num_pattern_hits=0., times_sum=0.;
00890 std::multiset<int> mset_for_median;
00891 mset_for_median.clear();
00892
00893 for (int i_wire = 0; i_wire < NUM_PATTERN_WIRES; i_wire++){
00894 if (pattern_mask[i_pattern][i_wire] != 0){
00895 this_layer = pattern_envelope[0][i_wire];
00896 delta_wire = pattern_envelope[1+MESelection][i_wire];
00897 this_wire = delta_wire + key_wire;
00898 if ((this_wire >= 0) && (this_wire < numWireGroups)){
00899
00900
00901
00902 if ( ( (pulse[this_layer][this_wire] >>
00903 (first_bx[key_wire] + drift_delay)) & 1) == 1) {
00904
00905
00906
00907 if (hit_layer[this_layer] == false){
00908 temp_quality++;
00909
00910 hit_layer[this_layer] = true;
00911 if (infoV > 1)
00912 LogTrace("CSCAnodeLCTProcessor")
00913 << "bx_time: " << first_bx[key_wire]
00914 << " pattern: " << i_pattern << " keywire: " << key_wire
00915 << " layer: " << this_layer
00916 << " quality: " << temp_quality;
00917 }
00918
00919
00920 if (abs(delta_wire)<2) {
00921
00922
00923 int first_bx_layer = first_bx[key_wire] + drift_delay;
00924 for (unsigned int dbx=0; dbx<hit_persist; dbx++) {
00925 if (((pulse[this_layer][this_wire] >> (first_bx_layer-1)) & 1) == 1) first_bx_layer--;
00926 else break;
00927 }
00928 times_sum += (double)first_bx_layer;
00929 num_pattern_hits += 1.;
00930 mset_for_median.insert(first_bx_layer);
00931 if (infoV > 2)
00932 LogTrace("CSCAnodeLCTProcessor")
00933 <<" 1st bx in layer: "<<first_bx_layer
00934 <<" sum bx: "<<times_sum
00935 <<" #pat. hits: "<<num_pattern_hits;
00936 }
00937 }
00938 }
00939 }
00940 }
00941
00942
00943 const int sz = mset_for_median.size();
00944 if (sz > 0) {
00945 std::multiset<int>::iterator im = mset_for_median.begin();
00946 if (sz > 1) std::advance(im,sz/2-1);
00947 if (sz == 1) first_bx_corrected[key_wire] = *im;
00948 else if ((sz % 2) == 1) first_bx_corrected[key_wire] = *(++im);
00949 else first_bx_corrected[key_wire] = ((*im) + (*(++im)))/2;
00950
00951 if (infoV > 1) {
00952 char bxs[300]="";
00953 for (im = mset_for_median.begin(); im != mset_for_median.end(); im++)
00954 sprintf(bxs,"%s %d", bxs, *im);
00955 LogTrace("CSCAnodeLCTProcessor")
00956 <<"bx="<<first_bx[key_wire]<<" bx_cor="<< first_bx_corrected[key_wire]<<" bxset="<<bxs;
00957 }
00958 }
00959
00960 if (temp_quality >= pattern_thresh[i_pattern]) {
00961 trigger = true;
00962
00963 if (!isTMB07) {
00964
00965
00966 temp_quality -= (pattern_thresh[i_pattern]-1);
00967 }
00968 else {
00969
00970
00971 if (temp_quality > 3) temp_quality -= 3;
00972 else temp_quality = 0;
00973 }
00974
00975 if (i_pattern == 0) {
00976
00977 quality[key_wire][0] = temp_quality;
00978 }
00979 else {
00980
00981 if (static_cast<int>(temp_quality) > quality[key_wire][1]) {
00982 quality[key_wire][1] = temp_quality;
00983 quality[key_wire][2] = i_pattern-1;
00984 }
00985 }
00986 if (infoV > 1) {
00987 LogTrace("CSCAnodeLCTProcessor")
00988 << "Pattern found; keywire: " << key_wire
00989 << " type: " << ptn_label[i_pattern]
00990 << " quality: " << temp_quality << "\n";
00991 }
00992 }
00993 }
00994 if (infoV > 1 && quality[key_wire][1] > 0) {
00995 if (quality[key_wire][2] == 0)
00996 LogTrace("CSCAnodeLCTProcessor")
00997 << "Collision Pattern A is chosen" << "\n";
00998 else if (quality[key_wire][2] == 1)
00999 LogTrace("CSCAnodeLCTProcessor")
01000 << "Collision Pattern B is chosen" << "\n";
01001 }
01002 return trigger;
01003 }
01004
01005 void CSCAnodeLCTProcessor::ghostCancellationLogic() {
01006
01007
01008
01009
01010
01011
01012
01013 int ghost_cleared[CSCConstants::MAX_NUM_WIRES][2];
01014
01015 for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
01016 for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
01017 ghost_cleared[key_wire][i_pattern] = 0;
01018
01019
01020 int qual_this = quality[key_wire][i_pattern];
01021 if (qual_this > 0) {
01022
01023
01024 int qual_prev = (key_wire > 0) ? quality[key_wire-1][i_pattern] : 0;
01025 if (qual_prev > 0) {
01026 int dt = first_bx[key_wire] - first_bx[key_wire-1];
01027
01028
01029
01030
01031
01032
01033 if (dt == 0) {
01034 if (qual_prev >= qual_this) ghost_cleared[key_wire][i_pattern] = 1;
01035 }
01036 else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
01037
01038
01039
01040
01042 if ((!ghost_cancellation_side_quality) ||
01043 (qual_prev > qual_this) )
01044 ghost_cleared[key_wire][i_pattern] = 1;
01045 }
01046 }
01047
01048
01049
01050 if (ghost_cleared[key_wire][i_pattern] == 1) {
01051 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01052 << ((i_pattern == 0) ? "Accelerator" : "Collision")
01053 << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
01054 << " by wire " << key_wire-1<<" q="<<qual_prev;
01055 continue;
01056 }
01057
01058 int qual_next =
01059 (key_wire < numWireGroups-1) ? quality[key_wire+1][i_pattern] : 0;
01060 if (qual_next > 0) {
01061 int dt = first_bx[key_wire] - first_bx[key_wire+1];
01062
01063 if (dt == 0) {
01064 if (qual_next > qual_this) ghost_cleared[key_wire][i_pattern] = 1;
01065 }
01066 else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
01067
01068
01069
01070
01072 if ((!ghost_cancellation_side_quality) ||
01073 (qual_next >= qual_this) )
01074 ghost_cleared[key_wire][i_pattern] = 1;
01075 }
01076 }
01077 if (ghost_cleared[key_wire][i_pattern] == 1) {
01078 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01079 << ((i_pattern == 0) ? "Accelerator" : "Collision")
01080 << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
01081 << " by wire " << key_wire+1<<" q="<<qual_next;
01082 continue;
01083 }
01084 }
01085 }
01086 }
01087
01088
01089
01090 for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
01091 for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
01092 if (ghost_cleared[key_wire][i_pattern] > 0) {
01093 clear(key_wire, i_pattern);
01094 }
01095 }
01096 }
01097 }
01098
01099
01100 void CSCAnodeLCTProcessor::ghostCancellationLogicSLHC() {
01101
01102
01103
01104
01105
01106
01107
01108
01109 int ghost_cleared[CSCConstants::MAX_NUM_WIRES][2];
01110
01111 for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
01112 for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
01113 ghost_cleared[key_wire][i_pattern] = 0;
01114
01115
01116 int qual_this = quality[key_wire][i_pattern];
01117 if (qual_this > 0) {
01118
01119
01120 int dt = -1;
01121 int qual_prev = (key_wire > 0) ? quality[key_wire-1][i_pattern] : 0;
01122 if (qual_prev > 0) {
01123 if (use_corrected_bx)
01124 dt = first_bx_corrected[key_wire] - first_bx_corrected[key_wire-1];
01125 else
01126 dt = first_bx[key_wire] - first_bx[key_wire-1];
01127
01128
01129
01130
01131
01132
01133 if (dt == 0) {
01134 if (qual_prev > qual_this) ghost_cleared[key_wire][i_pattern] = 1;
01135 }
01136 else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
01137
01138
01139
01140
01142 if ((!ghost_cancellation_side_quality) ||
01143 (qual_prev > qual_this) )
01144 ghost_cleared[key_wire][i_pattern] = 1;
01145 }
01146 }
01147
01148
01149
01150 if (ghost_cleared[key_wire][i_pattern] == 1) {
01151 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01152 << ((i_pattern == 0) ? "Accelerator" : "Collision")
01153 << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
01154 << " by wire " << key_wire-1<<" q="<<qual_prev<<" dt="<<dt;
01155 continue;
01156 }
01157
01158 dt = -1;
01159 int qual_next =
01160 (key_wire < numWireGroups-1) ? quality[key_wire+1][i_pattern] : 0;
01161 if (qual_next > 0) {
01162 if (use_corrected_bx)
01163 dt = first_bx_corrected[key_wire] - first_bx_corrected[key_wire+1];
01164 else
01165 dt = first_bx[key_wire] - first_bx[key_wire+1];
01166
01167 if (dt == 0) {
01168 if (qual_next >= qual_this) ghost_cleared[key_wire][i_pattern] = 1;
01169 }
01170 else if (dt > 0 && dt <= ghost_cancellation_bx_depth ) {
01171
01172
01173
01174
01176 if ((!ghost_cancellation_side_quality) ||
01177 (qual_next >= qual_this) )
01178 ghost_cleared[key_wire][i_pattern] = 1;
01179 }
01180 }
01181 if (ghost_cleared[key_wire][i_pattern] == 1) {
01182 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01183 << ((i_pattern == 0) ? "Accelerator" : "Collision")
01184 << " pattern ghost cancelled on key_wire " << key_wire <<" q="<<qual_this
01185 << " by wire " << key_wire+1<<" q="<<qual_next<<" dt="<<dt;
01186 continue;
01187 }
01188 }
01189 }
01190 }
01191
01192
01193
01194 for (int key_wire = 0; key_wire < numWireGroups; key_wire++) {
01195 for (int i_pattern = 0; i_pattern < 2; i_pattern++) {
01196 if (ghost_cleared[key_wire][i_pattern] > 0) {
01197 clear(key_wire, i_pattern);
01198 }
01199 }
01200 }
01201 }
01202
01203
01204 void CSCAnodeLCTProcessor::lctSearch() {
01205
01206
01207 std::vector<CSCALCTDigi> lct_list;
01208
01209 for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
01210
01211
01212 if (quality[i_wire][0] > 0 || quality[i_wire][1] > 0) {
01213 trigMode(i_wire);
01214
01215 int bx = first_bx[i_wire];
01216 int fbx = first_bx_corrected[i_wire];
01217 if (infoV>1) LogTrace("CSCAnodeLCTProcessor")<<" bx="<<bx<<" fbx="<<fbx;
01218 if (use_corrected_bx) {
01219 bx = fbx;
01220 fbx = first_bx[i_wire];
01221 }
01222 if (infoV>1) LogTrace("CSCAnodeLCTProcessor")<<" bx="<<bx<<" fbx="<<fbx;
01223
01224 if (quality[i_wire][0] > 0) {
01225 int qual = (quality[i_wire][0] & 0x03);
01226 CSCALCTDigi lct_info(1, qual, 1, 0, i_wire, bx);
01227 lct_info.setFullBX(fbx);
01228 lct_list.push_back(lct_info);
01229 }
01230
01231
01232 if (quality[i_wire][1] > 0) {
01233 int qual = (quality[i_wire][1] & 0x03);
01234 CSCALCTDigi lct_info(1, qual, 0, quality[i_wire][2], i_wire, bx);
01235
01236 lct_list.push_back(lct_info);
01237 if (infoV>1) LogTrace("CSCAnodeLCTProcessor")<<" got lct_info: "<<lct_info;
01238 }
01239
01240
01241 accelMode(i_wire);
01242 }
01243 }
01244
01245
01246
01247 std::vector<CSCALCTDigi> fourBest = bestTrackSelector(lct_list);
01248
01249 if (infoV > 0) {
01250 int n_alct_all=0, n_alct=0;
01251 for (std::vector <CSCALCTDigi>::const_iterator plct = lct_list.begin(); plct != lct_list.end(); plct++)
01252 if (plct->isValid() && plct->getBX()==6) n_alct_all++;
01253 for (std::vector <CSCALCTDigi>::const_iterator plct = fourBest.begin(); plct != fourBest.end(); plct++)
01254 if (plct->isValid() && plct->getBX()==6) n_alct++;
01255
01256 LogTrace("CSCAnodeLCTProcessor")<<"alct_count E:"<<theEndcap<<"S:"<<theStation<<"R:"<<theRing<<"C:"<<theChamber
01257 <<" all "<<n_alct_all<<" found "<<n_alct;
01258 }
01259
01260
01261
01262 for (std::vector<CSCALCTDigi>::const_iterator plct = fourBest.begin();
01263 plct != fourBest.end(); plct++) {
01264
01265 int bx = plct->getBX();
01266 if (bx >= MAX_ALCT_BINS) {
01267 if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeALCT")
01268 << "+++ Bx of ALCT candidate, " << bx << ", exceeds max allowed, "
01269 << MAX_ALCT_BINS-1 << "; skipping it... +++\n";
01270 continue;
01271 }
01272
01273 if (isBetterALCT(*plct, bestALCT[bx])) {
01274 if (isBetterALCT(bestALCT[bx], secondALCT[bx])) {
01275 secondALCT[bx] = bestALCT[bx];
01276 }
01277 bestALCT[bx] = *plct;
01278 }
01279 else if (isBetterALCT(*plct, secondALCT[bx])) {
01280 secondALCT[bx] = *plct;
01281 }
01282 }
01283
01284 if (!isTMB07) {
01285
01286 int first_bx = MAX_ALCT_BINS;
01287 for (int bx = 0; bx < MAX_ALCT_BINS; bx++) {
01288 if (bestALCT[bx].isValid()) {
01289 first_bx = bx;
01290 break;
01291 }
01292 }
01293 if (first_bx < MAX_ALCT_BINS) {
01294 for (int bx = first_bx + 1; bx < MAX_ALCT_BINS; bx++) {
01295 if (bestALCT[bx].isValid()) bestALCT[bx].clear();
01296 if (secondALCT[bx].isValid()) secondALCT[bx].clear();
01297 }
01298 }
01299 }
01300
01301 for (int bx = 0; bx < MAX_ALCT_BINS; bx++) {
01302 if (bestALCT[bx].isValid()) {
01303 bestALCT[bx].setTrknmb(1);
01304 if (infoV > 0) {
01305 LogDebug("CSCAnodeLCTProcessor")
01306 << "\n" << bestALCT[bx] << " fullBX = "<<bestALCT[bx].getFullBX()
01307 << " found in ME"
01308 << ((theEndcap == 1) ? "+" : "-")
01309 << theStation << "/" << theRing << "/" << theChamber
01310 << " (sector " << theSector << " subsector " << theSubsector
01311 << " trig id. " << theTrigChamber << ")" << "\n";
01312 }
01313 if (secondALCT[bx].isValid()) {
01314 secondALCT[bx].setTrknmb(2);
01315 if (infoV > 0) {
01316 LogDebug("CSCAnodeLCTProcessor")
01317 << secondALCT[bx] << " fullBX = "<<secondALCT[bx].getFullBX()
01318 << " found in ME"
01319 << ((theEndcap == 1) ? "+" : "-")
01320 << theStation << "/" << theRing << "/" << theChamber
01321 << " (sector " << theSector << " subsector " << theSubsector
01322 << " trig id. " << theTrigChamber << ")" << "\n";
01323 }
01324 }
01325 }
01326 }
01327 }
01328
01329 std::vector<CSCALCTDigi> CSCAnodeLCTProcessor::bestTrackSelector(
01330 const std::vector<CSCALCTDigi>& all_alcts) {
01331
01332
01333 CSCALCTDigi bestALCTs[MAX_ALCT_BINS][2], secondALCTs[MAX_ALCT_BINS][2];
01334
01335 if (infoV > 1) {
01336 LogTrace("CSCAnodeLCTProcessor") << all_alcts.size() <<
01337 " ALCTs at the input of best-track selector: ";
01338 for (std::vector <CSCALCTDigi>::const_iterator plct = all_alcts.begin();
01339 plct != all_alcts.end(); plct++) {
01340 if (!plct->isValid()) continue;
01341 LogTrace("CSCAnodeLCTProcessor") << (*plct);
01342 }
01343 }
01344
01345 CSCALCTDigi tA[MAX_ALCT_BINS][2], tB[MAX_ALCT_BINS][2];
01346 for (std::vector <CSCALCTDigi>::const_iterator plct = all_alcts.begin();
01347 plct != all_alcts.end(); plct++) {
01348 if (!plct->isValid()) continue;
01349
01350
01351
01352
01353
01354
01355
01356
01357 int bx = (*plct).getBX();
01358 int accel = (*plct).getAccelerator();
01359 int qual = (*plct).getQuality();
01360 int wire = (*plct).getKeyWG();
01361 bool vA = tA[bx][accel].isValid();
01362 bool vB = tB[bx][accel].isValid();
01363 int qA = tA[bx][accel].getQuality();
01364 int qB = tB[bx][accel].getQuality();
01365 int wA = tA[bx][accel].getKeyWG();
01366 int wB = tB[bx][accel].getKeyWG();
01367 if (!vA || qual > qA || (qual == qA && wire > wA)) {
01368 tA[bx][accel] = *plct;
01369 }
01370 if (!vB || qual > qB || (qual == qB && wire < wB)) {
01371 tB[bx][accel] = *plct;
01372 }
01373 }
01374
01375 for (int bx = 0; bx < MAX_ALCT_BINS; bx++) {
01376 for (int accel = 0; accel <= 1; accel++) {
01377
01378 if (tA[bx][accel].isValid()) {
01379 if (infoV > 2) {
01380 LogTrace("CSCAnodeLCTProcessor") << "tA: " << tA[bx][accel];
01381 LogTrace("CSCAnodeLCTProcessor") << "tB: " << tB[bx][accel];
01382 }
01383 bestALCTs[bx][accel] = tA[bx][accel];
01384
01385
01386 if (tA[bx][accel] != tB[bx][accel] &&
01387 tA[bx][accel].getQuality() == tB[bx][accel].getQuality()) {
01388 secondALCTs[bx][accel] = tB[bx][accel];
01389 }
01390 else {
01391
01392
01393
01394
01395 for (std::vector <CSCALCTDigi>::const_iterator plct =
01396 all_alcts.begin(); plct != all_alcts.end(); plct++) {
01397 if ((*plct).isValid() &&
01398 (*plct).getAccelerator() == accel && (*plct).getBX() == bx &&
01399 (*plct).getQuality() < bestALCTs[bx][accel].getQuality() &&
01400 (*plct).getQuality() >= secondALCTs[bx][accel].getQuality() &&
01401 (*plct).getKeyWG() >= secondALCTs[bx][accel].getKeyWG()) {
01402 secondALCTs[bx][accel] = *plct;
01403 }
01404 }
01405 }
01406 }
01407 }
01408 }
01409
01410
01411 std::vector<CSCALCTDigi> fourBest;
01412 for (int bx = 0; bx < MAX_ALCT_BINS; bx++) {
01413 for (int i = 0; i < 2; i++) {
01414 if (bestALCTs[bx][i].isValid()) fourBest.push_back(bestALCTs[bx][i]);
01415 }
01416 for (int i = 0; i < 2; i++) {
01417 if (secondALCTs[bx][i].isValid()) fourBest.push_back(secondALCTs[bx][i]);
01418 }
01419 }
01420
01421 if (infoV > 1) {
01422 LogTrace("CSCAnodeLCTProcessor") << fourBest.size() << " ALCTs selected: ";
01423 for (std::vector<CSCALCTDigi>::const_iterator plct = fourBest.begin();
01424 plct != fourBest.end(); plct++) {
01425 LogTrace("CSCAnodeLCTProcessor") << (*plct);
01426 }
01427 }
01428
01429 return fourBest;
01430 }
01431
01432 bool CSCAnodeLCTProcessor::isBetterALCT(const CSCALCTDigi& lhsALCT,
01433 const CSCALCTDigi& rhsALCT) {
01434
01435
01436
01437 bool returnValue = false;
01438
01439 if (lhsALCT.isValid() && !rhsALCT.isValid()) {return true;}
01440
01441
01442
01443 if (lhsALCT.getBX() < rhsALCT.getBX()) {returnValue = true;}
01444 if (lhsALCT.getBX() != rhsALCT.getBX()) {return returnValue;}
01445
01446
01447 int qual1 = lhsALCT.getQuality();
01448 int qual2 = rhsALCT.getQuality();
01449 if (qual1 > qual2) {returnValue = true;}
01450
01451
01452
01453 else if (qual1 == qual2 &&
01454 lhsALCT.getAccelerator() != rhsALCT.getAccelerator() &&
01455 quality[lhsALCT.getKeyWG()][1-lhsALCT.getAccelerator()] >
01456 quality[rhsALCT.getKeyWG()][1-rhsALCT.getAccelerator()])
01457 {returnValue = true;}
01458
01459 return returnValue;
01460 }
01461
01462 void CSCAnodeLCTProcessor::trigMode(const int key_wire) {
01463
01464
01465
01466 switch(trig_mode) {
01467 default:
01468 case 0:
01469
01470 break;
01471 case 1:
01472
01473 if (quality[key_wire][1] > 0) {
01474 quality[key_wire][1] = 0;
01475 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01476 << "trigMode(): collision track " << key_wire << " disabled" << "\n";
01477 }
01478 break;
01479 case 2:
01480
01481 if (quality[key_wire][0] > 0) {
01482 quality[key_wire][0] = 0;
01483 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01484 << "trigMode(): accelerator track " << key_wire << " disabled" << "\n";
01485 }
01486 break;
01487 case 3:
01488
01489
01490 if (quality[key_wire][0] > 0 && quality[key_wire][1] > 0) {
01491 quality[key_wire][1] = 0;
01492 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01493 << "trigMode(): collision track " << key_wire << " disabled" << "\n";
01494 }
01495 break;
01496 }
01497 }
01498
01499 void CSCAnodeLCTProcessor::accelMode(const int key_wire) {
01500
01501
01502
01503 int promotionBit = 1 << 2;
01504
01505 switch(accel_mode) {
01506 default:
01507 case 0:
01508
01509 if (quality[key_wire][0] > 0) {
01510 quality[key_wire][0] = 0;
01511 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01512 << "alctMode(): accelerator track " << key_wire << " ignored" << "\n";
01513 }
01514 break;
01515 case 1:
01516
01517 if (quality[key_wire][1] > 0) {
01518 quality[key_wire][1] += promotionBit;
01519 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01520 << "alctMode(): collision track " << key_wire << " promoted" << "\n";
01521 }
01522 break;
01523 case 2:
01524
01525 if (quality[key_wire][0] > 0) {
01526 quality[key_wire][0] += promotionBit;
01527 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01528 << "alctMode(): accelerator track " << key_wire << " promoted"<< "\n";
01529 }
01530 break;
01531 case 3:
01532
01533 if (quality[key_wire][1] > 0) {
01534 quality[key_wire][1] = 0;
01535 if (infoV > 1) LogTrace("CSCAnodeLCTProcessor")
01536 << "alctMode(): collision track " << key_wire << " ignored" << "\n";
01537 }
01538 break;
01539 }
01540 }
01541
01542
01543 void CSCAnodeLCTProcessor::dumpConfigParams() const {
01544 std::ostringstream strm;
01545 strm << "\n";
01546 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
01547 strm << "+ ALCT configuration parameters: +\n";
01548 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
01549 strm << " fifo_tbins [total number of time bins in DAQ readout] = "
01550 << fifo_tbins << "\n";
01551 strm << " fifo_pretrig [start time of anode raw hits in DAQ readout] = "
01552 << fifo_pretrig << "\n";
01553 strm << " drift_delay [drift delay after pre-trigger, in 25 ns bins] = "
01554 << drift_delay << "\n";
01555 strm << " nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = "
01556 << nplanes_hit_pretrig << "\n";
01557 strm << " nplanes_hit_pattern [min. number of layers hit for trigger] = "
01558 << nplanes_hit_pattern << "\n";
01559 strm << " nplanes_hit_accel_pretrig [min. number of layers hit for accel."
01560 << " pre-trig.] = " << nplanes_hit_accel_pretrig << "\n";
01561 strm << " nplanes_hit_accel_pattern [min. number of layers hit for accel."
01562 << " trigger] = " << nplanes_hit_accel_pattern << "\n";
01563 strm << " trig_mode [enabling/disabling collision/accelerator tracks] = "
01564 << trig_mode << "\n";
01565 strm << " accel_mode [preference to collision/accelerator tracks] = "
01566 << accel_mode << "\n";
01567 strm << " l1a_window_width [L1Accept window width, in 25 ns bins] = "
01568 << l1a_window_width << "\n";
01569 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
01570 LogDebug("CSCAnodeLCTProcessor") << strm.str();
01571
01572 }
01573
01574
01575 void CSCAnodeLCTProcessor::dumpDigis(const std::vector<int> wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]) const {
01576 LogDebug("CSCAnodeLCTProcessor")
01577 << "ME" << ((theEndcap == 1) ? "+" : "-")
01578 << theStation << "/" << theRing << "/" << theChamber
01579 << " nWiregroups " << numWireGroups;
01580
01581 std::ostringstream strstrm;
01582 for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
01583 if (i_wire%10 == 0) {
01584 if (i_wire < 100) strstrm << i_wire/10;
01585 else strstrm << (i_wire-100)/10;
01586 }
01587 else strstrm << " ";
01588 }
01589 strstrm << "\n";
01590 for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
01591 strstrm << i_wire%10;
01592 }
01593 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
01594 strstrm << "\n";
01595 for (int i_wire = 0; i_wire < numWireGroups; i_wire++) {
01596 if (wire[i_layer][i_wire].size() > 0) {
01597 std::vector<int> bx_times = wire[i_layer][i_wire];
01598 strstrm << std::hex << bx_times[0] << std::dec;
01599 }
01600 else {
01601 strstrm << ".";
01602 }
01603 }
01604 }
01605 LogTrace("CSCAnodeLCTProcessor") << strstrm.str();
01606 }
01607
01608
01609
01610 std::vector<CSCALCTDigi> CSCAnodeLCTProcessor::readoutALCTs() {
01611 std::vector<CSCALCTDigi> tmpV;
01612
01613
01614
01615
01616 static int lct_bins =
01617
01618 l1a_window_width;
01619 static int late_tbins = early_tbins + lct_bins;
01620
01621 static int ifois = 0;
01622 if (ifois == 0) {
01623
01624
01625
01626
01627
01628 if (infoV >= 0 && early_tbins < 0) {
01629 edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
01630 << "+++ fifo_pretrig = " << fifo_pretrig
01631 << "; in-time ALCTs are not getting read-out!!! +++" << "\n";
01632 }
01633
01634 if (late_tbins > MAX_ALCT_BINS-1) {
01635 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
01636 << "+++ Allowed range of time bins, [0-" << late_tbins
01637 << "] exceeds max allowed, " << MAX_ALCT_BINS-1 << " +++\n"
01638 << "+++ Set late_tbins to max allowed +++\n";
01639 late_tbins = MAX_ALCT_BINS-1;
01640 }
01641 ifois = 1;
01642 }
01643
01644
01645
01646 std::vector<CSCALCTDigi> all_alcts = getALCTs();
01647 for (std::vector <CSCALCTDigi>::const_iterator plct = all_alcts.begin();
01648 plct != all_alcts.end(); plct++) {
01649 if (!plct->isValid()) continue;
01650
01651 int bx = (*plct).getBX();
01652
01653 if (bx <= early_tbins) {
01654 if (infoV > 1) LogDebug("CSCAnodeLCTProcessor")
01655 << " Do not report ALCT on keywire " << plct->getKeyWG()
01656 << ": found at bx " << bx << ", whereas the earliest allowed bx is "
01657 << early_tbins+1;
01658 continue;
01659 }
01660
01661
01662 if (bx > late_tbins) {
01663 if (infoV > 1) LogDebug("CSCAnodeLCTProcessor")
01664 << " Do not report ALCT on keywire " << plct->getKeyWG()
01665 << ": found at bx " << bx << ", whereas the latest allowed bx is "
01666 << late_tbins;
01667 continue;
01668 }
01669
01670 tmpV.push_back(*plct);
01671 }
01672 return tmpV;
01673 }
01674
01675
01676 std::vector<CSCALCTDigi> CSCAnodeLCTProcessor::getALCTs() {
01677 std::vector<CSCALCTDigi> tmpV;
01678 for (int bx = 0; bx < MAX_ALCT_BINS; bx++) {
01679 if (bestALCT[bx].isValid()) tmpV.push_back(bestALCT[bx]);
01680 if (secondALCT[bx].isValid()) tmpV.push_back(secondALCT[bx]);
01681 }
01682 return tmpV;
01683 }
01684
01687
01688 void CSCAnodeLCTProcessor::showPatterns(const int key_wire) {
01689
01690 for (int i_pattern = 0; i_pattern < CSCConstants::NUM_ALCT_PATTERNS;
01691 i_pattern++) {
01692 std::ostringstream strstrm_header;
01693 LogTrace("CSCAnodeLCTProcessor")
01694 << "\n" << "Pattern: " << i_pattern << " Key wire: " << key_wire;
01695 for (int i = 1; i <= 32; i++) {
01696 strstrm_header << ((32-i)%10);
01697 }
01698 LogTrace("CSCAnodeLCTProcessor") << strstrm_header.str();
01699 for (int i_wire = 0; i_wire < NUM_PATTERN_WIRES; i_wire++) {
01700 if (pattern_mask[i_pattern][i_wire] != 0) {
01701 std::ostringstream strstrm_pulse;
01702 int this_layer = pattern_envelope[0][i_wire];
01703 int this_wire = pattern_envelope[1+MESelection][i_wire]+key_wire;
01704 if (this_wire >= 0 && this_wire < numWireGroups) {
01705 for (int i = 1; i <= 32; i++) {
01706 strstrm_pulse << ((pulse[this_layer][this_wire]>>(32-i)) & 1);
01707 }
01708 LogTrace("CSCAnodeLCTProcessor")
01709 << strstrm_pulse.str() << " on layer " << this_layer;
01710 }
01711 }
01712 }
01713 LogTrace("CSCAnodeLCTProcessor")
01714 << "-------------------------------------------";
01715 }
01716 }