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