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/CSCCathodeLCTProcessor.h>
00030 #include <L1Trigger/CSCCommonTrigger/interface/CSCTriggerGeometry.h>
00031 #include <DataFormats/MuonDetId/interface/CSCTriggerNumbering.h>
00032
00033 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00034 #include <algorithm>
00035 #include <iomanip>
00036 #include <iostream>
00037
00038
00039
00040
00041
00042
00043
00044 const int CSCCathodeLCTProcessor::pre_hit_pattern[2][NUM_PATTERN_STRIPS] = {
00045 { 999, 0, 0, 0, 999,
00046 999, 1, 1, 1, 999,
00047 999, 2, 2, 2, 999,
00048 3,
00049 999, 4, 4, 4, 999,
00050 999, 5, 5, 5, 999},
00051
00052 { 999, -1, 0, 1, 999,
00053 999, -1, 0, 1, 999,
00054 999, -1, 0, 1, 999,
00055 0,
00056 999, -1, 0, 1, 999,
00057 999, -1, 0, 1, 999}
00058 };
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 const int CSCCathodeLCTProcessor::pattern[CSCConstants::NUM_CLCT_PATTERNS_PRE_TMB07][NUM_PATTERN_STRIPS+1] = {
00069 { 999, 999, 999, 999, 999,
00070 999, 999, 999, 999, 999,
00071 999, 999, 999, 999, 999,
00072 999,
00073 999, 999, 999, 999, 999,
00074 999, 999, 999, 999, 999, 0},
00075
00076 { 999, 999, 999, 0, 999,
00077 999, 999, 999, 1, 999,
00078 999, 999, 2, 2, 999,
00079 3,
00080 999, 4, 4, 999, 999,
00081 999, 5, 999, 999, 999, 1},
00082
00083 { 999, 0, 999, 999, 999,
00084 999, 1, 999, 999, 999,
00085 999, 2, 2, 999, 999,
00086 3,
00087 999, 999, 4, 4, 999,
00088 999, 999, 999, 5, 999, 0},
00089
00090 { 999, 999, 0, 999, 999,
00091 999, 999, 1, 999, 999,
00092 999, 999, 2, 999, 999,
00093 3,
00094 999, 4, 999, 999, 999,
00095 999, 5, 999, 999, 999, 1},
00096
00097 { 999, 999, 0, 999, 999,
00098 999, 999, 1, 999, 999,
00099 999, 999, 2, 999, 999,
00100 3,
00101 999, 999, 999, 4, 999,
00102 999, 999, 999, 5, 999, 0},
00103
00104 { 999, 999, 999, 0, 999,
00105 999, 999, 999, 1, 999,
00106 999, 999, 2, 2, 999,
00107 3,
00108 999, 999, 4, 999, 999,
00109 999, 999, 5, 999, 999, 1},
00110
00111 { 999, 0, 999, 999, 999,
00112 999, 1, 999, 999, 999,
00113 999, 2, 2, 999, 999,
00114 3,
00115 999, 999, 4, 999, 999,
00116 999, 999, 5, 999, 999, 0},
00117
00118 { 999, 999, 0, 999, 999,
00119 999, 999, 1, 999, 999,
00120 999, 999, 2, 999, 999,
00121 3,
00122 999, 999, 4, 999, 999,
00123 999, 999, 5, 999, 999, 1}
00124 };
00125
00126
00127
00128
00129
00130 const int CSCCathodeLCTProcessor::pattern2007_offset[NUM_PATTERN_HALFSTRIPS] =
00131 { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
00132 -2, -1, 0, 1, 2,
00133 0,
00134 -2, -1, 0, 1, 2,
00135 -4, -3, -2, -1, 0, 1, 2, 3, 4,
00136 -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
00137
00138 const int CSCCathodeLCTProcessor::pattern2007[CSCConstants::NUM_CLCT_PATTERNS][NUM_PATTERN_HALFSTRIPS+1] = {
00139 { 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,
00140 999, 999, 999, 999, 999,
00141 999,
00142 999, 999, 999, 999, 999,
00143 999, 999, 999, 999, 999, 999, 999, 999, 999,
00144 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, -1},
00145
00146 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00147 1, 1, 1, 1, 1,
00148 2,
00149 3, 3, 3, 3, 3,
00150 4, 4, 4, 4, 4, 4, 4, 4, 4,
00151 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1},
00152
00153 { 999, 999, 999, 999, 999, 999, 999, 999, 0, 0, 0,
00154 999, 999, 999, 1, 1,
00155 2,
00156 3, 3, 3, 999, 999,
00157 4, 4, 4, 999, 999, 999, 999, 999, 999,
00158 5, 5, 5, 999, 999, 999, 999, 999, 999, 999, 999, 0},
00159
00160 { 0, 0, 0, 999, 999, 999, 999, 999, 999, 999, 999,
00161 1, 1, 999, 999, 999,
00162 2,
00163 999, 999, 3, 3, 3,
00164 999, 999, 999, 999, 999, 999, 4, 4, 4,
00165 999, 999, 999, 999, 999, 999, 999, 999, 5, 5, 5, 1},
00166
00167 { 999, 999, 999, 999, 999, 999, 999, 0, 0, 0, 999,
00168 999, 999, 999, 1, 1,
00169 2,
00170 3, 3, 999, 999, 999,
00171 4, 4, 4, 999, 999, 999, 999, 999, 999,
00172 999, 5, 5, 5, 999, 999, 999, 999, 999, 999, 999, 0},
00173
00174 { 999, 0, 0, 0, 999, 999, 999, 999, 999, 999, 999,
00175 1, 1, 999, 999, 999,
00176 2,
00177 999, 999, 999, 3, 3,
00178 999, 999, 999, 999, 999, 999, 4, 4, 4,
00179 999, 999, 999, 999, 999, 999, 999, 5, 5, 5, 999, 1},
00180
00181 { 999, 999, 999, 999, 999, 999, 0, 0, 0, 999, 999,
00182 999, 999, 1, 1, 999,
00183 2,
00184 999, 3, 3, 999, 999,
00185 999, 999, 4, 4, 999, 999, 999, 999, 999,
00186 999, 999, 5, 5, 5, 999, 999, 999, 999, 999, 999, 0},
00187
00188 { 999, 999, 0, 0, 0, 999, 999, 999, 999, 999, 999,
00189 999, 1, 1, 999, 999,
00190 2,
00191 999, 999, 3, 3, 999,
00192 999, 999, 999, 999, 999, 4, 4, 999, 999,
00193 999, 999, 999, 999, 999, 999, 5, 5, 5, 999, 999, 1},
00194
00195 { 999, 999, 999, 999, 999, 0, 0, 0, 999, 999, 999,
00196 999, 999, 1, 1, 999,
00197 2,
00198 999, 3, 3, 999, 999,
00199 999, 999, 4, 4, 4, 999, 999, 999, 999,
00200 999, 999, 999, 5, 5, 5, 999, 999, 999, 999, 999, 0},
00201
00202 { 999, 999, 999, 0, 0, 0, 999, 999, 999, 999, 999,
00203 999, 1, 1, 999, 999,
00204 2,
00205 999, 999, 3, 3, 999,
00206 999, 999, 999, 999, 4, 4, 4, 999, 999,
00207 999, 999, 999, 999, 999, 5, 5, 5, 999, 999, 999, 1},
00208
00209 { 999, 999, 999, 999, 0, 0, 0, 999, 999, 999, 999,
00210 999, 999, 1, 999, 999,
00211 2,
00212 999, 999, 3, 999, 999,
00213 999, 999, 999, 4, 4, 4, 999, 999, 999,
00214 999, 999, 999, 999, 5, 5, 5, 999, 999, 999, 999, 0}
00215
00216 };
00217
00218
00219 const unsigned int CSCCathodeLCTProcessor::def_fifo_tbins = 12;
00220 const unsigned int CSCCathodeLCTProcessor::def_fifo_pretrig = 7;
00221 const unsigned int CSCCathodeLCTProcessor::def_hit_persist = 6;
00222 const unsigned int CSCCathodeLCTProcessor::def_drift_delay = 2;
00223 const unsigned int CSCCathodeLCTProcessor::def_nplanes_hit_pretrig = 2;
00224 const unsigned int CSCCathodeLCTProcessor::def_nplanes_hit_pattern = 4;
00225 const unsigned int CSCCathodeLCTProcessor::def_pid_thresh_pretrig = 2;
00226 const unsigned int CSCCathodeLCTProcessor::def_min_separation = 10;
00227
00228
00229 const int CSCCathodeLCTProcessor::cfeb_strips[2] = { 8, 32};
00230
00231
00232
00233
00234
00235 CSCCathodeLCTProcessor::CSCCathodeLCTProcessor(unsigned endcap,
00236 unsigned station,
00237 unsigned sector,
00238 unsigned subsector,
00239 unsigned chamber,
00240 const edm::ParameterSet& conf,
00241 const edm::ParameterSet& comm) :
00242 theEndcap(endcap), theStation(station), theSector(sector),
00243 theSubsector(subsector), theTrigChamber(chamber) {
00244 static bool config_dumped = false;
00245
00246
00247 fifo_tbins = conf.getParameter<unsigned int>("clctFifoTbins");
00248 hit_persist = conf.getParameter<unsigned int>("clctHitPersist");
00249 drift_delay = conf.getParameter<unsigned int>("clctDriftDelay");
00250 nplanes_hit_pretrig =
00251 conf.getParameter<unsigned int>("clctNplanesHitPretrig");
00252 nplanes_hit_pattern =
00253 conf.getParameter<unsigned int>("clctNplanesHitPattern");
00254
00255
00256 fifo_pretrig = conf.getParameter<unsigned int>("clctFifoPretrig");
00257
00258
00259
00260 isMTCC = comm.getParameter<bool>("isMTCC");
00261
00262
00263 isTMB07 = comm.getParameter<bool>("isTMB07");
00264 if (isTMB07) {
00265 pid_thresh_pretrig =
00266 conf.getParameter<unsigned int>("clctPidThreshPretrig");
00267 min_separation =
00268 conf.getParameter<unsigned int>("clctMinSeparation");
00269 }
00270
00271
00272 infoV = conf.getUntrackedParameter<int>("verbosity", 0);
00273
00274
00275 checkConfigParameters();
00276 if (infoV > 0 && !config_dumped) {
00277 dumpConfigParams();
00278 config_dumped = true;
00279 }
00280
00281 numStrips = 0;
00282
00283 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00284 if ((i_layer+1)%2 == 0) stagger[i_layer] = 0;
00285 else stagger[i_layer] = 1;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 }
00302
00303 CSCCathodeLCTProcessor::CSCCathodeLCTProcessor() :
00304 theEndcap(1), theStation(1), theSector(1),
00305 theSubsector(1), theTrigChamber(1) {
00306
00307 static bool config_dumped = false;
00308
00309
00310 setDefaultConfigParameters();
00311 infoV = 2;
00312 isMTCC = false;
00313 isTMB07 = true;
00314
00315
00316 checkConfigParameters();
00317 if (!config_dumped) {
00318 dumpConfigParams();
00319 config_dumped = true;
00320 }
00321
00322 numStrips = CSCConstants::MAX_NUM_STRIPS;
00323
00324 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00325 if ((i_layer+1)%2 == 0) stagger[i_layer] = 0;
00326 else stagger[i_layer] = 1;
00327 }
00328 }
00329
00330 void CSCCathodeLCTProcessor::setDefaultConfigParameters() {
00331
00332 fifo_tbins = def_fifo_tbins;
00333 fifo_pretrig = def_fifo_pretrig;
00334 hit_persist = def_hit_persist;
00335 drift_delay = def_drift_delay;
00336 nplanes_hit_pretrig = def_nplanes_hit_pretrig;
00337 nplanes_hit_pattern = def_nplanes_hit_pattern;
00338
00339 isMTCC = false;
00340
00341
00342 isTMB07 = true;
00343 if (isTMB07) {
00344 pid_thresh_pretrig = def_pid_thresh_pretrig;
00345 min_separation = def_min_separation;
00346 }
00347 }
00348
00349
00350 void CSCCathodeLCTProcessor::setConfigParameters(const CSCDBL1TPParameters* conf) {
00351 static bool config_dumped = false;
00352
00353 fifo_tbins = conf->clctFifoTbins();
00354 fifo_pretrig = conf->clctFifoPretrig();
00355 hit_persist = conf->clctHitPersist();
00356 drift_delay = conf->clctDriftDelay();
00357 nplanes_hit_pretrig = conf->clctNplanesHitPretrig();
00358 nplanes_hit_pattern = conf->clctNplanesHitPattern();
00359
00360
00361 if (isTMB07) {
00362 pid_thresh_pretrig = conf->clctPidThreshPretrig();
00363 min_separation = conf->clctMinSeparation();
00364 }
00365
00366
00367 checkConfigParameters();
00368 if (!config_dumped) {
00369 dumpConfigParams();
00370 config_dumped = true;
00371 }
00372 }
00373
00374 void CSCCathodeLCTProcessor::checkConfigParameters() {
00375
00376
00377
00378 static const unsigned int max_fifo_tbins = 1 << 5;
00379 static const unsigned int max_fifo_pretrig = 1 << 5;
00380 static const unsigned int max_hit_persist = 1 << 4;
00381 static const unsigned int max_drift_delay = 1 << 2;
00382 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
00383 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
00384 static const unsigned int max_pid_thresh_pretrig = 1 << 4;
00385 static const unsigned int max_min_separation = CSCConstants::NUM_HALF_STRIPS;
00386
00387
00388 if (fifo_tbins >= max_fifo_tbins) {
00389 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00390 << "+++ Value of fifo_tbins, " << fifo_tbins
00391 << ", exceeds max allowed, " << max_fifo_tbins-1 << " +++\n"
00392 << "+++ Try to proceed with the default value, fifo_tbins="
00393 << def_fifo_tbins << " +++\n";
00394 fifo_tbins = def_fifo_tbins;
00395 }
00396 if (fifo_pretrig >= max_fifo_pretrig) {
00397 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00398 << "+++ Value of fifo_pretrig, " << fifo_pretrig
00399 << ", exceeds max allowed, " << max_fifo_pretrig-1 << " +++\n"
00400 << "+++ Try to proceed with the default value, fifo_pretrig="
00401 << def_fifo_pretrig << " +++\n";
00402 fifo_pretrig = def_fifo_pretrig;
00403 }
00404 if (hit_persist >= max_hit_persist) {
00405 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00406 << "+++ Value of hit_persist, " << hit_persist
00407 << ", exceeds max allowed, " << max_hit_persist-1 << " +++\n"
00408 << "+++ Try to proceed with the default value, hit_persist="
00409 << def_hit_persist << " +++\n";
00410 hit_persist = def_hit_persist;
00411 }
00412 if (drift_delay >= max_drift_delay) {
00413 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00414 << "+++ Value of drift_delay, " << drift_delay
00415 << ", exceeds max allowed, " << max_drift_delay-1 << " +++\n"
00416 << "+++ Try to proceed with the default value, drift_delay="
00417 << def_drift_delay << " +++\n";
00418 drift_delay = def_drift_delay;
00419 }
00420 if (nplanes_hit_pretrig >= max_nplanes_hit_pretrig) {
00421 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00422 << "+++ Value of nplanes_hit_pretrig, " << nplanes_hit_pretrig
00423 << ", exceeds max allowed, " << max_nplanes_hit_pretrig-1 << " +++\n"
00424 << "+++ Try to proceed with the default value, nplanes_hit_pretrig="
00425 << def_nplanes_hit_pretrig << " +++\n";
00426 nplanes_hit_pretrig = def_nplanes_hit_pretrig;
00427 }
00428 if (nplanes_hit_pattern >= max_nplanes_hit_pattern) {
00429 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00430 << "+++ Value of nplanes_hit_pattern, " << nplanes_hit_pattern
00431 << ", exceeds max allowed, " << max_nplanes_hit_pattern-1 << " +++\n"
00432 << "+++ Try to proceed with the default value, nplanes_hit_pattern="
00433 << def_nplanes_hit_pattern << " +++\n";
00434 nplanes_hit_pattern = def_nplanes_hit_pattern;
00435 }
00436
00437 if (isTMB07) {
00438 if (pid_thresh_pretrig >= max_pid_thresh_pretrig) {
00439 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00440 << "+++ Value of pid_thresh_pretrig, " << pid_thresh_pretrig
00441 << ", exceeds max allowed, " << max_pid_thresh_pretrig-1 << " +++\n"
00442 << "+++ Try to proceed with the default value, pid_thresh_pretrig="
00443 << def_pid_thresh_pretrig << " +++\n";
00444 pid_thresh_pretrig = def_pid_thresh_pretrig;
00445 }
00446 if (min_separation >= max_min_separation) {
00447 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00448 << "+++ Value of min_separation, " << min_separation
00449 << ", exceeds max allowed, " << max_min_separation-1 << " +++\n"
00450 << "+++ Try to proceed with the default value, min_separation="
00451 << def_min_separation << " +++\n";
00452 min_separation = def_min_separation;
00453 }
00454 }
00455 }
00456
00457 void CSCCathodeLCTProcessor::clear() {
00458 thePreTriggerBXs.clear();
00459 for (int bx = 0; bx < MAX_CLCT_BINS; bx++) {
00460 bestCLCT[bx].clear();
00461 secondCLCT[bx].clear();
00462 }
00463 }
00464
00465 std::vector<CSCCLCTDigi>
00466 CSCCathodeLCTProcessor::run(const CSCComparatorDigiCollection* compdc) {
00467
00468
00469
00470
00471
00472
00473
00474
00475 if (numStrips == 0) {
00476 CSCTriggerGeomManager* theGeom = CSCTriggerGeometry::get();
00477 CSCChamber* theChamber = theGeom->chamber(theEndcap, theStation, theSector,
00478 theSubsector, theTrigChamber);
00479 if (theChamber) {
00480 numStrips = theChamber->layer(1)->geometry()->numberOfStrips();
00481
00482
00483
00484
00485
00486 if (theStation == 1 &&
00487 CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00488 theTrigChamber) == 1) {
00489 numStrips = 80;
00490 }
00491
00492 if (numStrips > CSCConstants::MAX_NUM_STRIPS) {
00493 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
00494 << "+++ Number of strips, " << numStrips
00495 << " found in ME" << ((theEndcap == 1) ? "+" : "-")
00496 << theStation << "/"
00497 << CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00498 theTrigChamber) << "/"
00499 << CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
00500 theSubsector, theStation, theTrigChamber)
00501 << " (sector " << theSector << " subsector " << theSubsector
00502 << " trig id. " << theTrigChamber << ")"
00503 << " exceeds max expected, " << CSCConstants::MAX_NUM_STRIPS
00504 << " +++\n"
00505 << "+++ CSC geometry looks garbled; no emulation possible +++\n";
00506 numStrips = -1;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00522 stagger[i_layer] =
00523 (theChamber->layer(i_layer+1)->geometry()->stagger() + 1) / 2;
00524 }
00525 }
00526 else {
00527 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00528 << " ME" << ((theEndcap == 1) ? "+" : "-") << theStation << "/"
00529 << CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00530 theTrigChamber) << "/"
00531 << CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
00532 theSubsector, theStation, theTrigChamber)
00533 << " (sector " << theSector << " subsector " << theSubsector
00534 << " trig id. " << theTrigChamber << ")"
00535 << " is not defined in current geometry! +++\n"
00536 << "+++ CSC geometry looks garbled; no emulation possible +++\n";
00537 numStrips = -1;
00538 }
00539 }
00540
00541 if (numStrips < 0) {
00542 if (infoV >= 0) edm::LogError("L1CSCTPEmulatorConfigError")
00543 << " ME" << ((theEndcap == 1) ? "+" : "-") << theStation << "/"
00544 << CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00545 theTrigChamber) << "/"
00546 << CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
00547 theSubsector, theStation, theTrigChamber)
00548 << " (sector " << theSector << " subsector " << theSubsector
00549 << " trig id. " << theTrigChamber << "):"
00550 << " numStrips = " << numStrips << "; CLCT emulation skipped! +++";
00551 std::vector<CSCCLCTDigi> emptyV;
00552 return emptyV;
00553 }
00554
00555
00556 bool noDigis = getDigis(compdc);
00557
00558 if (!noDigis) {
00559
00560 std::vector<int>
00561 halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
00562 std::vector<int>
00563 distrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
00564 if (isTMB07) {
00565 readComparatorDigis(halfstrip);
00566 }
00567 else {
00568 readComparatorDigis(halfstrip, distrip);
00569 }
00570
00571
00572
00573
00574
00575
00576
00577 unsigned int layersHit = 0;
00578 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00579 for (int i_hstrip = 0; i_hstrip < CSCConstants::NUM_HALF_STRIPS;
00580 i_hstrip++) {
00581 if (!halfstrip[i_layer][i_hstrip].empty()) {layersHit++; break;}
00582 }
00583 }
00584 if (layersHit >= nplanes_hit_pattern) run(halfstrip, distrip);
00585 }
00586
00587
00588 std::vector<CSCCLCTDigi> tmpV = getCLCTs();
00589 return tmpV;
00590 }
00591
00592 void CSCCathodeLCTProcessor::run(
00593 const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
00594 const std::vector<int> distrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
00595
00596
00597
00598
00599
00600 std::vector<CSCCLCTDigi> LCTlist;
00601
00602 if (isTMB07) {
00603 LCTlist = findLCTs(halfstrip);
00604 }
00605 else if (isMTCC) {
00606 LCTlist = findLCTs(halfstrip, distrip);
00607 }
00608 else {
00609 std::vector<CSCCLCTDigi> halfStripLCTs = findLCTs(halfstrip, 1);
00610 std::vector<CSCCLCTDigi> diStripLCTs = findLCTs(distrip, 0);
00611
00612 for (unsigned int i = 0; i < halfStripLCTs.size(); i++)
00613 LCTlist.push_back(halfStripLCTs[i]);
00614 for (unsigned int i = 0; i < diStripLCTs.size(); i++)
00615 LCTlist.push_back(diStripLCTs[i]);
00616 }
00617
00618
00619 if (LCTlist.size() > 1)
00620 sort(LCTlist.begin(), LCTlist.end(), std::greater<CSCCLCTDigi>());
00621
00622
00623 for (std::vector<CSCCLCTDigi>::const_iterator plct = LCTlist.begin();
00624 plct != LCTlist.end(); plct++) {
00625 int bx = plct->getBX();
00626 if (bx >= MAX_CLCT_BINS) {
00627 if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeCLCT")
00628 << "+++ Bx of CLCT candidate, " << bx << ", exceeds max allowed, "
00629 << MAX_CLCT_BINS-1 << "; skipping it... +++\n";
00630 continue;
00631 }
00632
00633 if (!bestCLCT[bx].isValid()) bestCLCT[bx] = *plct;
00634 else if (!secondCLCT[bx].isValid()) {
00635
00636
00637
00638
00639 if (!isMTCC && !isTMB07 && *plct == bestCLCT[bx]) continue;
00640 secondCLCT[bx] = *plct;
00641 }
00642 }
00643
00644 for (int bx = 0; bx < MAX_CLCT_BINS; bx++) {
00645 if (bestCLCT[bx].isValid()) {
00646 bestCLCT[bx].setTrknmb(1);
00647 if (infoV > 0) LogDebug("CSCCathodeLCTProcessor")
00648 << bestCLCT[bx] << " found in ME" << ((theEndcap == 1) ? "+" : "-")
00649 << theStation << "/"
00650 << CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00651 theTrigChamber) << "/"
00652 << CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
00653 theSubsector, theStation, theTrigChamber)
00654 << " (sector " << theSector << " subsector " << theSubsector
00655 << " trig id. " << theTrigChamber << ")" << "\n";
00656 }
00657 if (secondCLCT[bx].isValid()) {
00658 secondCLCT[bx].setTrknmb(2);
00659 if (infoV > 0) LogDebug("CSCCathodeLCTProcessor")
00660 << secondCLCT[bx] << " found in ME" << ((theEndcap == 1) ? "+" : "-")
00661 << theStation << "/"
00662 << CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00663 theTrigChamber) << "/"
00664 << CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
00665 theSubsector, theStation, theTrigChamber)
00666 << " (sector " << theSector << " subsector " << theSubsector
00667 << " trig id. " << theTrigChamber << ")" << "\n";
00668 }
00669 }
00670
00671
00672 }
00673
00674 bool CSCCathodeLCTProcessor::getDigis(const CSCComparatorDigiCollection* compdc) {
00675 bool noDigis = true;
00676 int theRing = CSCTriggerNumbering::ringFromTriggerLabels(theStation,
00677 theTrigChamber);
00678 int theChamber = CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
00679 theSubsector, theStation, theTrigChamber);
00680
00681
00682 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00683 digiV[i_layer].clear();
00684
00685 CSCDetId detid(theEndcap, theStation, theRing, theChamber, i_layer+1);
00686 getDigis(compdc, detid);
00687
00688
00689 if (theStation == 1 && theRing == 1) {
00690 CSCDetId detid_me1a(theEndcap, theStation, 4, theChamber, i_layer+1);
00691 getDigis(compdc, detid_me1a);
00692 }
00693
00694 if (!digiV[i_layer].empty()) {
00695 noDigis = false;
00696 if (infoV > 1) {
00697 LogTrace("CSCCathodeLCTProcessor")
00698 << "found " << digiV[i_layer].size()
00699 << " comparator digi(s) in layer " << i_layer << " of ME"
00700 << ((theEndcap == 1) ? "+" : "-") << theStation << "/" << theRing
00701 << "/" << theChamber << " (trig. sector " << theSector
00702 << " subsector " << theSubsector << " id " << theTrigChamber << ")";
00703 }
00704 }
00705 }
00706
00707 return noDigis;
00708 }
00709
00710 void CSCCathodeLCTProcessor::getDigis(const CSCComparatorDigiCollection* compdc,
00711 const CSCDetId& id) {
00712 bool me1a = (id.station() == 1) && (id.ring() == 4);
00713 const CSCComparatorDigiCollection::Range rcompd = compdc->get(id);
00714 for (CSCComparatorDigiCollection::const_iterator digiIt = rcompd.first;
00715 digiIt != rcompd.second; ++digiIt) {
00716 if (me1a && digiIt->getStrip() <= 16) {
00717
00718
00719 CSCComparatorDigi digi_corr(digiIt->getStrip()+64,
00720 digiIt->getComparator(),
00721 digiIt->getTimeBinWord());
00722 digiV[id.layer()-1].push_back(digi_corr);
00723 }
00724 else {
00725 digiV[id.layer()-1].push_back(*digiIt);
00726 }
00727 }
00728 }
00729
00730 void CSCCathodeLCTProcessor::readComparatorDigis(
00731 std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
00732
00733
00734
00735
00736 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
00737 int i_digi = 0;
00738 for (std::vector<CSCComparatorDigi>::iterator pld = digiV[i_layer].begin();
00739 pld != digiV[i_layer].end(); pld++, i_digi++) {
00740
00741 if (infoV > 1) {
00742 std::ostringstream strstrm;
00743 strstrm << "Comparator digi: comparator = " << pld->getComparator()
00744 << " strip #" << pld->getStrip()
00745 << " time bins on:";
00746 std::vector<int> bx_times = pld->getTimeBinsOn();
00747 for (unsigned int tbin = 0; tbin < bx_times.size(); tbin++)
00748 strstrm << " " << bx_times[tbin];
00749 LogTrace("CSCCathodeLCTProcessor") << strstrm.str();
00750 }
00751
00752
00753
00754 int thisComparator = pld->getComparator();
00755 if (thisComparator != 0 && thisComparator != 1) {
00756 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00757 << "+++ Found comparator digi with wrong comparator value = "
00758 << thisComparator << "; skipping it... +++\n";
00759 continue;
00760 }
00761
00762
00763 int thisStrip = pld->getStrip() - 1;
00764 if (thisStrip < 0 || thisStrip >= numStrips) {
00765 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00766 << "+++ Found comparator digi with wrong strip number = "
00767 << thisStrip
00768 << " (max strips = " << numStrips << "); skipping it... +++\n";
00769 continue;
00770 }
00771
00772
00773
00774 int thisHalfstrip = 2*thisStrip + thisComparator + stagger[i_layer];
00775 if (thisHalfstrip >= 2*numStrips + 1) {
00776 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00777 << "+++ Found wrong halfstrip number = " << thisHalfstrip
00778 << "; skipping this digi... +++\n";
00779 continue;
00780 }
00781
00782
00783 std::vector<int> bx_times = pld->getTimeBinsOn();
00784 for (unsigned int i = 0; i < bx_times.size(); i++) {
00785
00786
00787
00788
00789
00790
00791
00792 if (bx_times[i] > 1 && bx_times[i] < static_cast<int>(fifo_tbins)) {
00793
00794 if (i == 0 || (i > 0 && bx_times[i]-bx_times[i-1] >=
00795 static_cast<int>(hit_persist))) {
00796
00797
00798
00799 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
00800 << "Comp digi: layer " << i_layer+1
00801 << " digi #" << i_digi+1
00802 << " strip " << thisStrip
00803 << " halfstrip " << thisHalfstrip
00804 << " distrip " << thisStrip/2 +
00805 ((thisStrip%2 == 1 && thisComparator == 1 && stagger[i_layer] == 1) ? 1 : 0)
00806 << " time " << bx_times[i]
00807 << " comparator " << thisComparator
00808 << " stagger " << stagger[i_layer];
00809 halfstrip[i_layer][thisHalfstrip].push_back(bx_times[i]);
00810 }
00811 else if (i > 0) {
00812 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
00813 << " Skipping comparator digi: strip = " << thisStrip
00814 << ", layer = " << i_layer+1 << ", bx = " << bx_times[i]
00815 << ", bx of previous hit = " << bx_times[i-1];
00816 }
00817 }
00818 else {
00819 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
00820 << "+++ Skipping comparator digi: strip = " << thisStrip
00821 << ", layer = " << i_layer+1 << ", bx = " << bx_times[i] << " +++";
00822 }
00823 }
00824 }
00825 }
00826 }
00827
00828 void CSCCathodeLCTProcessor::readComparatorDigis(
00829 std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
00830 std::vector<int> distrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
00831
00832
00833
00834
00835 int time[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_STRIPS];
00836 int comp[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_STRIPS];
00837 int digiNum[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_STRIPS];
00838 for (int i = 0; i < CSCConstants::NUM_LAYERS; i++){
00839 for (int j = 0; j < CSCConstants::MAX_NUM_STRIPS; j++) {
00840 time[i][j] = -999;
00841 comp[i][j] = 0;
00842 digiNum[i][j] = -999;
00843 }
00844 }
00845
00846 for (int i = 0; i < CSCConstants::NUM_LAYERS; i++) {
00847 std::vector <CSCComparatorDigi> layerDigiV = digiV[i];
00848 for (unsigned int j = 0; j < layerDigiV.size(); j++) {
00849
00850 CSCComparatorDigi thisDigi = layerDigiV[j];
00851
00852
00853 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
00854 << "Comparator digi: comparator = " << thisDigi.getComparator()
00855 << " strip #" << thisDigi.getStrip()
00856 << " time bin = " << thisDigi.getTimeBin();
00857
00858
00859
00860 int thisComparator = thisDigi.getComparator();
00861 if (thisComparator != 0 && thisComparator != 1) {
00862 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00863 << "+++ Comparator digi with wrong comparator value: digi #" << j
00864 << ", comparator = " << thisComparator << "; skipping it... +++\n";
00865 continue;
00866 }
00867
00868
00869 int thisStrip = thisDigi.getStrip() - 1;
00870 if (thisStrip < 0 || thisStrip >= numStrips) {
00871 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00872 << "+++ Comparator digi with wrong strip number: digi #" << j
00873 << ", strip = " << thisStrip
00874 << ", max strips = " << numStrips << "; skipping it... +++\n";
00875 continue;
00876 }
00877
00878
00879 int thisDigiBx = thisDigi.getTimeBin();
00880
00881
00882
00883 if (thisDigiBx >= 0 && thisDigiBx < static_cast<int>(fifo_tbins)) {
00884
00885
00886
00887
00888
00889
00890
00891
00892 if (time[i][thisStrip] == -999 || time[i][thisStrip] > thisDigiBx) {
00893 digiNum[i][thisStrip] = j;
00894 time[i][thisStrip] = thisDigiBx;
00895 comp[i][thisStrip] = thisComparator;
00896 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
00897 << "Comp digi: layer " << i+1
00898 << " digi #" << j+1
00899 << " strip " << thisStrip
00900 << " halfstrip " << 2*thisStrip + comp[i][thisStrip] + stagger[i]
00901 << " distrip " << thisStrip/2 +
00902 ((thisStrip%2 == 1 && comp[i][thisStrip] == 1 && stagger[i] == 1) ? 1 : 0)
00903 << " time " << time[i][thisStrip]
00904 << " comparator " << comp[i][thisStrip]
00905 << " stagger " << stagger[i];
00906 }
00907 }
00908 else {
00909 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
00910 << "+++ Skipping comparator digi: strip = " << thisStrip
00911 << ", layer = " << i+1 << ", bx = " << thisDigiBx << " +++";
00912 }
00913 }
00914 }
00915
00916
00917
00918 for (int i = 0; i < CSCConstants::NUM_LAYERS; i++) {
00919
00920
00921 for (int j = 0; j < CSCConstants::MAX_NUM_STRIPS; j++) {
00922 if (time[i][j] >= 0) {
00923 int i_halfstrip = 2*j + comp[i][j] + stagger[i];
00924
00925
00926
00927 if (i_halfstrip >= 2*numStrips + 1) {
00928 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00929 << "+++ Found wrong halfstrip number = " << i_halfstrip
00930 << "; skipping this digi... +++\n";
00931 continue;
00932 }
00933 halfstrip[i][i_halfstrip].push_back(time[i][j]);
00934 }
00935 }
00936
00937
00938 if (!isTMB07) {
00939
00940
00941
00942 static int test_iteration = 0;
00943 for (int j = 0; j < CSCConstants::MAX_NUM_STRIPS; j++){
00944 if (time[i][j] >= 0) {
00945 int i_distrip = j/2;
00946 if (j%2 == 1 && comp[i][j] == 1 && stagger[i] == 1) {
00947
00948 bool stagger_debug = (infoV > 2);
00949 distripStagger(comp[i], time[i], digiNum[i], j, stagger_debug);
00950 }
00951
00952
00953
00954
00955
00956
00957 if (infoV > 2 && test_iteration == 1) {
00958 testDistripStagger();
00959 test_iteration++;
00960 }
00961 if (i_distrip >= numStrips/2 + 1) {
00962 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00963 << "+++ Found wrong distrip number = " << i_distrip
00964 << "; skipping this digi... +++\n";
00965 continue;
00966 }
00967 distrip[i][i_distrip].push_back(time[i][j]);
00968 }
00969 }
00970 }
00971 }
00972 }
00973
00974 void CSCCathodeLCTProcessor::distripStagger(int stag_triad[CSCConstants::MAX_NUM_STRIPS],
00975 int stag_time[CSCConstants::MAX_NUM_STRIPS],
00976 int stag_digi[CSCConstants::MAX_NUM_STRIPS],
00977 int i_strip, bool debug) {
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 if (i_strip >= CSCConstants::MAX_NUM_STRIPS) {
00994 if (debug) edm::LogWarning("L1CSCTPEmulatorWrongInput")
00995 << "+++ Found wrong strip number = " << i_strip
00996 << "; cannot apply distrip staggering... +++\n";
00997 return;
00998 }
00999
01000 if (debug)
01001 LogDebug("CSCCathodeLCTProcessor")
01002 << " Enter distripStagger: i_strip = " << i_strip
01003 << " stag_triad[i_strip] = " << stag_triad[i_strip]
01004 << " stag_time[i_strip] = " << stag_time[i_strip]
01005 << " stag_triad[i_strip+2] = " << stag_triad[i_strip+2]
01006 << " stag_time[i_strip+2] = " << stag_time[i_strip+2];
01007
01008
01009
01010 if (i_strip+2 < CSCConstants::MAX_NUM_STRIPS && stag_triad[i_strip+2] == 1)
01011 distripStagger(stag_triad, stag_time, stag_digi, i_strip+2);
01012
01013
01014
01015
01016
01017 if (stag_time[i_strip+2] >= 0) {
01018 if (stag_time[i_strip] < stag_time[i_strip+2]) {
01019 stag_time[i_strip+2] = stag_time[i_strip];
01020 stag_digi[i_strip+2] = stag_digi[i_strip];
01021 }
01022 }
01023
01024
01025 else {
01026 stag_time[i_strip+2] = stag_time[i_strip];
01027 stag_digi[i_strip+2] = stag_digi[i_strip];
01028 }
01029
01030
01031
01032
01033
01034 stag_time[i_strip] = -999;
01035 stag_triad[i_strip] = 4;
01036 stag_digi[i_strip] = -999;
01037
01038 if (debug)
01039 LogDebug("CSCCathodeLCTProcessor")
01040 << " Exit distripStagger: i_strip = " << i_strip
01041 << " stag_triad[i_strip] = " << stag_triad[i_strip]
01042 << " stag_time[i_strip] = " << stag_time[i_strip]
01043 << " stag_triad[i_strip+2] = " << stag_triad[i_strip+2]
01044 << " stag_time[i_strip+2] = " << stag_time[i_strip+2];
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 std::vector<CSCCLCTDigi> CSCCathodeLCTProcessor::findLCTs(const std::vector<int> strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS], int stripType)
01058 {
01059 int j;
01060 int best_strip = 0;
01061 int first_bx = 999;
01062 const int max_lct_num = 2;
01063 const int adjacent_strips = 2;
01064
01065 const int ptrn_thrsh[2] = {nplanes_hit_pattern, nplanes_hit_pattern};
01066 int highest_quality = 0;
01067
01068 int keystrip_data[CSCConstants::NUM_HALF_STRIPS][7];
01069 int final_lcts[max_lct_num];
01070
01071 std::vector <CSCCLCTDigi> lctList;
01072
01073 int nStrips = 0;
01074 if (stripType == 1) nStrips = 2*numStrips + 1;
01075 else if (stripType == 0) nStrips = numStrips/2 + 1;
01076
01077 if (infoV > 1) dumpDigis(strip, stripType, nStrips);
01078
01079
01080
01081
01082 if (preTrigger(strip, stripType, nStrips, first_bx)){
01083 getKeyStripData(strip, keystrip_data, nStrips, first_bx, best_strip, stripType);
01084
01085
01086 for (j = 0; j < max_lct_num; j++)
01087 final_lcts[j] = -999;
01088
01089
01090
01091
01092
01093 final_lcts[0] = best_strip;
01094
01095 for (int key_strip = 0; key_strip < (nStrips-stripType); key_strip++){
01096
01097 if (abs(best_strip - key_strip) > adjacent_strips){
01098
01099 if (keystrip_data[key_strip][CLCT_QUALITY] > highest_quality){
01100 highest_quality = keystrip_data[key_strip][CLCT_QUALITY];
01101 final_lcts[1] = key_strip;
01102 }
01103 }
01104 }
01105
01106 for (j = 0; j < max_lct_num; j++){
01107
01108
01109 int keystrip = final_lcts[j];
01110 if (keystrip >= 0 &&
01111 keystrip_data[keystrip][CLCT_QUALITY] >= ptrn_thrsh[stripType]) {
01112
01113 keystrip_data[keystrip][CLCT_STRIP_TYPE] = stripType;
01114
01115 int theHalfStrip = (keystrip_data[keystrip][CLCT_STRIP_TYPE] ?
01116 keystrip_data[keystrip][CLCT_STRIP] :
01117 4*keystrip_data[keystrip][CLCT_STRIP]);
01118 keystrip_data[keystrip][CLCT_CFEB] = theHalfStrip/32;
01119 int halfstrip_in_cfeb =
01120 theHalfStrip - 32*keystrip_data[keystrip][CLCT_CFEB];
01121
01122 CSCCLCTDigi thisLCT(1, keystrip_data[keystrip][CLCT_QUALITY],
01123 keystrip_data[keystrip][CLCT_PATTERN],
01124 keystrip_data[keystrip][CLCT_STRIP_TYPE],
01125 keystrip_data[keystrip][CLCT_BEND],
01126 halfstrip_in_cfeb,
01127 keystrip_data[keystrip][CLCT_CFEB],
01128 keystrip_data[keystrip][CLCT_BX]);
01129 if (infoV > 2) {
01130 char stripType =
01131 (keystrip_data[keystrip][CLCT_STRIP_TYPE] == 0) ? 'D' : 'H';
01132 char bend =
01133 (keystrip_data[keystrip][CLCT_BEND] == 0) ? 'L' : 'R';
01134 LogTrace("CSCCathodeLCTProcessor")
01135 << " Raw Find: "
01136 << "Key Strip: " << std::setw(3)
01137 << keystrip_data[keystrip][CLCT_STRIP]
01138 << " Pattern: " << std::setw(2)
01139 << keystrip_data[keystrip][CLCT_PATTERN]
01140 << " Bend: " << std::setw(1) << bend
01141 << " Quality: " << std::setw(1)
01142 << keystrip_data[keystrip][CLCT_QUALITY]
01143 << " stripType: " << std::setw(1) << stripType
01144 << " BX: " << std::setw(1)
01145 << keystrip_data[keystrip][CLCT_BX];
01146 }
01147 lctList.push_back(thisLCT);
01148 }
01149 }
01150 }
01151
01152 return lctList;
01153 }
01154
01155
01156
01157 bool CSCCathodeLCTProcessor::preTrigger(const std::vector<int> strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01158 const int stripType, const int nStrips,
01159 int& first_bx)
01160 {
01161 static const int hs_thresh = nplanes_hit_pretrig;
01162 static const int ds_thresh = nplanes_hit_pretrig;
01163
01164 unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
01165 int i_layer, i_strip, this_layer, this_strip;
01166 int hits, layers_hit;
01167 bool hit_layer[CSCConstants::NUM_LAYERS];
01168
01169 const int pre_trigger_layer_min = (stripType == 1) ? hs_thresh : ds_thresh;
01170
01171
01172
01173 pulseExtension(strip, nStrips, pulse);
01174
01175
01176 for (unsigned int bx_time = 0; bx_time < fifo_tbins; bx_time++) {
01177
01178
01179
01180
01181
01182 for (int key_strip = 0; key_strip < nStrips; key_strip++){
01183
01184 hits = 0;
01185 layers_hit = 0;
01186 for (i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
01187 hit_layer[i_layer] = false;
01188
01189 for (i_strip = 0; i_strip < NUM_PATTERN_STRIPS; i_strip++){
01190 this_layer = pre_hit_pattern[0][i_strip];
01191 this_strip = pre_hit_pattern[1][i_strip]+key_strip;
01192 if (this_strip >= 0 && this_strip < nStrips) {
01193
01194 if (((pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
01195 hits++;
01196
01197 if (hit_layer[this_layer] == false) {
01198 hit_layer[this_layer] = true;
01199 layers_hit++;
01200
01201
01202
01203 if (layers_hit >= pre_trigger_layer_min) {
01204 first_bx = bx_time;
01205 return true;
01206 }
01207 }
01208 }
01209 }
01210 }
01211 }
01212 }
01213
01214 return false;
01215 }
01216
01217
01218
01219 void CSCCathodeLCTProcessor::getKeyStripData(const std::vector<int> strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01220 int keystrip_data[CSCConstants::NUM_HALF_STRIPS][7],
01221 int nStrips, int first_bx, int& best_strip, int stripType) {
01222 int lct_pattern[NUM_PATTERN_STRIPS];
01223 int key_strip, this_layer, this_strip;
01224 int quality, best_quality;
01225 int bend = 0;
01226 int highest_quality = 0;
01227 bool nullPattern;
01228
01229 for (key_strip = 0; key_strip < nStrips; key_strip++)
01230 for (int i = 0; i < 7; i++)
01231 keystrip_data[key_strip][i] = 0;
01232
01233
01234
01235
01236 for (key_strip = 0; key_strip < (nStrips-stripType); key_strip++){
01237 nullPattern = true;
01238 for (int pattern_strip = 0; pattern_strip < NUM_PATTERN_STRIPS; pattern_strip++){
01239 this_layer = pre_hit_pattern[0][pattern_strip];
01240 this_strip = pre_hit_pattern[1][pattern_strip] + key_strip;
01241
01242
01243 if ((this_strip >= 0 && this_strip < nStrips) &&
01244 !strip[this_layer][this_strip].empty()) {
01245 if (nullPattern) nullPattern = false;
01246 std::vector<int> bx_times = strip[this_layer][this_strip];
01247 lct_pattern[pattern_strip] = bx_times[0];
01248 }
01249 else
01250 lct_pattern[pattern_strip] = -999;
01251 }
01252
01253
01254 if (nullPattern) continue;
01255
01256
01257
01258 best_quality = 0;
01259
01260
01261
01262
01263
01264 for (int pattern_num = CSCConstants::NUM_CLCT_PATTERNS_PRE_TMB07-1; pattern_num > 0; pattern_num--) {
01265
01266
01267 int latch_bx = first_bx + drift_delay;
01268 getPattern(pattern_num, lct_pattern, latch_bx, quality, bend);
01269 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01270 << "Key_strip " << key_strip << " quality of pattern_num "
01271 << pattern_num << ": " << quality;
01272 if (quality > best_quality){
01273
01274 keystrip_data[key_strip][CLCT_PATTERN] = pattern_num;
01275 keystrip_data[key_strip][CLCT_BEND] = bend;
01276 keystrip_data[key_strip][CLCT_STRIP] = key_strip;
01277 keystrip_data[key_strip][CLCT_BX] = first_bx;
01278
01279 keystrip_data[key_strip][CLCT_QUALITY] = quality;
01280 if (quality > highest_quality){
01281
01282
01283
01284
01285 best_strip = key_strip;
01286 highest_quality = quality;
01287 }
01288 best_quality = quality;
01289 }
01290 }
01291 }
01292 }
01293
01294
01295
01296 void CSCCathodeLCTProcessor::getPattern(int pattern_num,
01297 int strip_value[NUM_PATTERN_STRIPS], int bx_time,
01298 int& quality, int& bend){
01299
01300
01301
01302 int layers_hit = 0;
01303 bool hit_layer[CSCConstants::NUM_LAYERS];
01304
01305
01306 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
01307 hit_layer[i_layer] = false;
01308
01309
01310 for (int strip_num = 0; strip_num < NUM_PATTERN_STRIPS; strip_num++){
01311 if (hitIsGood(strip_value[strip_num], bx_time)){
01312 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++){
01313
01314
01315 if (i_layer == pattern[pattern_num][strip_num]){
01316
01317 if (hit_layer[i_layer] == false){
01318 layers_hit++;
01319 hit_layer[i_layer] = true;
01320 }
01321 }
01322 }
01323 }
01324 }
01325
01326 bend = pattern[pattern_num][NUM_PATTERN_STRIPS];
01327 quality = layers_hit;
01328 }
01329
01330
01331
01332 bool CSCCathodeLCTProcessor::hitIsGood(int hitTime, int BX) {
01333
01334
01335 int dt = BX - hitTime;
01336 if (dt >= 0 && dt <= static_cast<int>(hit_persist)) {return true;}
01337 else {return false;}
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352 std::vector <CSCCLCTDigi> CSCCathodeLCTProcessor::findLCTs(
01353 const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01354 const std::vector<int> distrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
01355 std::vector <CSCCLCTDigi> lctList;
01356 int _bx[2] = {999, 999};
01357 int first_bx = 999;
01358
01359 const int nhStrips = 2*numStrips + 1;
01360 const int ndStrips = numStrips/2 + 1;
01361
01362 if (infoV > 1) {
01363 dumpDigis(halfstrip, 1, nhStrips);
01364 dumpDigis(distrip, 0, ndStrips);
01365 }
01366
01367
01368 int h_keyStrip[MAX_CFEBS];
01369 unsigned int h_nhits[MAX_CFEBS];
01370 int d_keyStrip[MAX_CFEBS];
01371 unsigned int d_nhits[MAX_CFEBS];
01372 int keystrip_data[2][7];
01373 unsigned int h_pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
01374 unsigned int d_pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
01375 bool pre_trig[2] = {false, false};
01376
01377
01378
01379 pre_trig[0] = preTrigger(halfstrip, h_pulse, 1, nhStrips, 0, _bx[0]);
01380 pre_trig[1] = preTrigger( distrip, d_pulse, 0, ndStrips, 0, _bx[1]);
01381
01382
01383
01384 if (pre_trig[0] || pre_trig[1]) {
01385 first_bx = (_bx[0] < _bx[1]) ? _bx[0] : _bx[1];
01386 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01387 << "half bx " << _bx[0] << " di bx " << _bx[1] << " first " << first_bx
01388 << "\n ..... waiting drift delay ..... ";
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419 int latch_bx = first_bx + drift_delay;
01420 latchLCTs(h_pulse, h_keyStrip, h_nhits, 1, CSCConstants::NUM_HALF_STRIPS,
01421 latch_bx);
01422 latchLCTs(d_pulse, d_keyStrip, d_nhits, 0, CSCConstants::NUM_DI_STRIPS,
01423 latch_bx);
01424
01425 if (infoV > 1) {
01426 LogTrace("CSCCathodeLCTProcessor")
01427 << "...............................\n"
01428 << "Final halfstrip hits and keys (after drift delay) ...";
01429 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01430 LogTrace("CSCCathodeLCTProcessor")
01431 << "cfeb " << icfeb << " key: " << h_keyStrip[icfeb]
01432 << " hits " << h_nhits[icfeb];
01433 }
01434 LogTrace("CSCCathodeLCTProcessor")
01435 << "Final distrip hits and keys (after drift delay) ...";
01436 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01437 LogTrace("CSCCathodeLCTProcessor")
01438 << "cfeb " << icfeb << " key: " << d_keyStrip[icfeb]
01439 << " hits " << d_nhits[icfeb];
01440 }
01441 }
01442 priorityEncode(h_keyStrip, h_nhits, d_keyStrip, d_nhits, keystrip_data);
01443 getKeyStripData(h_pulse, d_pulse, keystrip_data, first_bx);
01444
01445 for (int ilct = 0; ilct < 2; ilct++) {
01446 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01447 << "found lcts: ilct " << ilct
01448 << " key strip " << keystrip_data[ilct][CLCT_STRIP];
01449 if (keystrip_data[ilct][CLCT_STRIP] != -1) {
01450 int halfstrip_in_cfeb = 0;
01451 if (keystrip_data[ilct][CLCT_STRIP_TYPE] == 0)
01452 halfstrip_in_cfeb = 4*keystrip_data[ilct][CLCT_STRIP] -
01453 32*keystrip_data[ilct][CLCT_CFEB];
01454 else
01455 halfstrip_in_cfeb = keystrip_data[ilct][CLCT_STRIP] -
01456 32*keystrip_data[ilct][CLCT_CFEB];
01457
01458 CSCCLCTDigi thisLCT(1, keystrip_data[ilct][CLCT_QUALITY],
01459 keystrip_data[ilct][CLCT_PATTERN],
01460 keystrip_data[ilct][CLCT_STRIP_TYPE],
01461 keystrip_data[ilct][CLCT_BEND],
01462 halfstrip_in_cfeb,
01463 keystrip_data[ilct][CLCT_CFEB],
01464 keystrip_data[ilct][CLCT_BX]);
01465 lctList.push_back(thisLCT);
01466 }
01467 }
01468 }
01469
01470 return lctList;
01471
01472 }
01473
01474
01475
01476 bool CSCCathodeLCTProcessor::preTrigger(
01477 const std::vector<int> strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01478 unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01479 const int stripType, const int nStrips,
01480 const int start_bx, int& first_bx) {
01481 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01482 << "....................PreTrigger...........................";
01483
01484 if (start_bx == 0) {
01485
01486 pulseExtension(strip, nStrips, pulse);
01487 }
01488
01489 bool pre_trig = false;
01490
01491 for (unsigned int bx_time = start_bx; bx_time < fifo_tbins; bx_time++) {
01492
01493
01494
01495
01496
01497 pre_trig = preTrigLookUp(pulse, stripType, nStrips, bx_time);
01498 if (pre_trig) {
01499 first_bx = bx_time;
01500 return true;
01501 }
01502 }
01503
01504 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01505 << "no pretrigger for strip type " << stripType << ", returning \n";
01506 first_bx = fifo_tbins;
01507 return false;
01508 }
01509
01510
01511
01512 bool CSCCathodeLCTProcessor::preTrigLookUp(
01513 const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01514 const int stripType, const int nStrips,
01515 const unsigned int bx_time) {
01516 static const int hs_thresh = nplanes_hit_pretrig;
01517 static const int ds_thresh = nplanes_hit_pretrig;
01518
01519 bool hit_layer[CSCConstants::NUM_LAYERS];
01520 int key_strip, this_layer, this_strip, layers_hit;
01521
01522
01523 const int pre_trigger_layer_min = (stripType == 1) ? hs_thresh : ds_thresh;
01524
01525 if (stripType != 0 && stripType != 1) {
01526 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
01527 << "+++ preTrigLookUp: stripType = " << stripType
01528 << " does not correspond to half-strip/di-strip patterns! +++\n";
01529 return false;
01530 }
01531
01532 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01533
01534 for (int istrip = 0; istrip < cfeb_strips[stripType]; istrip++) {
01535
01536 key_strip = icfeb*cfeb_strips[stripType] + istrip;
01537 layers_hit = 0;
01538 for (int ilayer = 0; ilayer < CSCConstants::NUM_LAYERS; ilayer++)
01539 hit_layer[ilayer] = false;
01540
01541
01542 for (int pstrip = 0; pstrip < NUM_PATTERN_STRIPS; pstrip++) {
01543 this_layer = pre_hit_pattern[0][pstrip];
01544 this_strip = pre_hit_pattern[1][pstrip]+key_strip;
01545
01546 if (this_strip >= 0 && this_strip < nStrips) {
01547
01548 if (((pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
01549 if (hit_layer[this_layer] == false) {
01550 hit_layer[this_layer] = true;
01551 layers_hit++;
01552 if (layers_hit >= pre_trigger_layer_min) {
01553 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01554 << "pretrigger at bx: " << bx_time
01555 << ", cfeb " << icfeb << ", returning";
01556 return true;
01557 }
01558 }
01559 }
01560 }
01561 }
01562 }
01563 }
01564
01565 return false;
01566
01567 }
01568
01569
01570
01571 void CSCCathodeLCTProcessor::latchLCTs(
01572 const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01573 int keyStrip[MAX_CFEBS], unsigned int n_hits[MAX_CFEBS],
01574 const int stripType, const int nStrips, const int bx_time) {
01575
01576 bool hit_layer[CSCConstants::NUM_LAYERS];
01577 int key_strip, this_layer, this_strip;
01578 int layers_hit, prev_hits;
01579
01580 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01581 keyStrip[icfeb] = -1;
01582 n_hits[icfeb] = 0;
01583 }
01584
01585 if (stripType != 0 && stripType != 1) {
01586 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongInput")
01587 << "+++ latchLCTs: stripType = " << stripType
01588 << " does not correspond to half-strip/di-strip patterns! +++\n";
01589 return;
01590 }
01591
01592 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01593 prev_hits = 0;
01594
01595 for (int istrip = 0; istrip < cfeb_strips[stripType]; istrip++) {
01596
01597 key_strip = icfeb*cfeb_strips[stripType] + istrip;
01598 layers_hit = 0;
01599 for (int ilayer = 0; ilayer < CSCConstants::NUM_LAYERS; ilayer++)
01600 hit_layer[ilayer] = false;
01601
01602
01603 for (int pstrip = 0; pstrip < NUM_PATTERN_STRIPS; pstrip++) {
01604 this_layer = pre_hit_pattern[0][pstrip];
01605 this_strip = pre_hit_pattern[1][pstrip]+key_strip;
01606
01607 if (this_strip >= 0 && this_strip < nStrips) {
01608
01609 if (((pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
01610 if (hit_layer[this_layer] == false) {
01611 hit_layer[this_layer] = true;
01612 layers_hit++;
01613 }
01614 }
01615 }
01616 }
01617 if (infoV > 1) {
01618 if (layers_hit > 0) LogTrace("CSCCathodeLCTProcessor")
01619 << "cfeb: " << icfeb << " key_strip: " << key_strip
01620 << " n_hits: " << layers_hit;
01621 }
01622
01623
01624
01625 if (layers_hit > prev_hits) {
01626 prev_hits = layers_hit;
01627 keyStrip[icfeb] = key_strip;
01628 n_hits[icfeb] = layers_hit;
01629 }
01630 }
01631 }
01632 }
01633
01634
01635
01636 void CSCCathodeLCTProcessor::priorityEncode(
01637 const int h_keyStrip[MAX_CFEBS], const unsigned int h_nhits[MAX_CFEBS],
01638 const int d_keyStrip[MAX_CFEBS], const unsigned int d_nhits[MAX_CFEBS],
01639 int keystrip_data[2][7]) {
01640 static const unsigned int hs_thresh = nplanes_hit_pretrig;
01641
01642
01643 int ihits[2];
01644 int cfebs[2];
01645 const int nlcts = 2;
01646 int key_strip[MAX_CFEBS], key_phits[MAX_CFEBS], strip_type[MAX_CFEBS];
01647
01648
01649 for (int ilct = 0; ilct < nlcts; ilct++) {
01650 for (int j = 0; j < 7; j++) keystrip_data[ilct][j] = -1;
01651 ihits[ilct] = 0;
01652 cfebs[ilct] = -1;
01653 }
01654 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01655 key_strip[icfeb] = -1;
01656 key_phits[icfeb] = -1;
01657 strip_type[icfeb] = -1;
01658 }
01659
01660 if (infoV > 1) {
01661 LogTrace("CSCCathodeLCTProcessor")
01662 << ".....................PriorityEncode.......................";
01663 std::ostringstream strstrm;
01664 strstrm << "hkeys:";
01665 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01666 strstrm << std::setw(4) << h_keyStrip[icfeb];
01667 }
01668 strstrm << "\ndkeys:";
01669 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01670 strstrm << std::setw(4) << d_keyStrip[icfeb];
01671 }
01672 LogTrace("CSCCathodeLCTProcessor") << strstrm.str();
01673 }
01674
01675
01676
01677 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01678 if (h_keyStrip[icfeb] != -1 && d_keyStrip[icfeb] != -1) {
01679 if (h_nhits[icfeb] >= hs_thresh) {
01680 key_strip[icfeb] = h_keyStrip[icfeb];
01681 key_phits[icfeb] = h_nhits[icfeb] + 8;
01682 strip_type[icfeb]= 1;
01683 }
01684
01685
01686
01687 else {
01688 key_strip[icfeb] = d_keyStrip[icfeb];
01689 key_phits[icfeb] = d_nhits[icfeb];
01690 strip_type[icfeb]= 0;
01691 }
01692 }
01693 else if (h_keyStrip[icfeb] != -1) {
01694 if (h_nhits[icfeb] >= hs_thresh) {
01695 key_strip[icfeb] = h_keyStrip[icfeb];
01696 key_phits[icfeb] = h_nhits[icfeb] + 8;
01697 strip_type[icfeb]= 1;
01698 }
01699 }
01700 else if (d_keyStrip[icfeb] != -1) {
01701
01702 key_strip[icfeb] = d_keyStrip[icfeb];
01703 key_phits[icfeb] = d_nhits[icfeb];
01704 strip_type[icfeb]= 0;
01705
01706 }
01707 if (infoV > 1 && strip_type[icfeb] != -1) {
01708 if (strip_type[icfeb] == 0)
01709 LogTrace("CSCCathodeLCTProcessor")
01710 << " taking distrip pattern on cfeb " << icfeb;
01711 else if (strip_type[icfeb] == 1)
01712 LogTrace("CSCCathodeLCTProcessor")
01713 << " taking halfstrip pattern on cfeb " << icfeb;
01714 LogTrace("CSCCathodeLCTProcessor")
01715 << " cfeb " << icfeb << " key " << key_strip[icfeb]
01716 << " hits " << key_phits[icfeb] << " type " << strip_type[icfeb];
01717 }
01718 }
01719
01720
01721
01722
01723 int key[MAX_CFEBS];
01724 int loedge, hiedge;
01725
01726 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01727 << "...... Remove Duplicates ......";
01728 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01729 if(strip_type[icfeb] == 0) key[icfeb] = key_strip[icfeb]*4;
01730 else key[icfeb] = key_strip[icfeb];
01731 }
01732 for (int icfeb = 0; icfeb < MAX_CFEBS-1; icfeb++) {
01733 if (key[icfeb] >= 0 && key[icfeb+1] >= 0) {
01734 loedge = cfeb_strips[1]*(icfeb*8+7)/8;
01735 hiedge = cfeb_strips[1]*(icfeb*8+9)/8 - 1;
01736 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01737 << " key 1: " << key[icfeb] << " key 2: " << key[icfeb+1]
01738 << " low edge: " << loedge << " high edge: " << hiedge;
01739 if (key[icfeb] >= loedge && key[icfeb+1] <= hiedge) {
01740 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01741 << "Duplicate LCTs found at boundary of CFEB " << icfeb << " ...";
01742 if (key_phits[icfeb+1] > key_phits[icfeb]) {
01743 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01744 << " deleting LCT on CFEB " << icfeb;
01745 key_strip[icfeb] = -1;
01746 key_phits[icfeb] = -1;
01747 }
01748 else {
01749 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01750 << " deleting LCT on CFEB " << icfeb+1;
01751 key_strip[icfeb+1] = -1;
01752 key_phits[icfeb+1] = -1;
01753 }
01754 }
01755 }
01756 }
01757
01758
01759
01760 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01761 << "\n...... Select best LCTs ......";
01762 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01763 if (key_phits[icfeb] > ihits[0]) {
01764 ihits[1] = ihits[0];
01765 cfebs[1] = cfebs[0];
01766 ihits[0] = key_phits[icfeb];
01767 cfebs[0] = icfeb;
01768 if (infoV > 1) {
01769 std::ostringstream strstrm;
01770 for (int icfeb = 0; icfeb < MAX_CFEBS; icfeb++) {
01771 strstrm << std::setw(4) << strip_type[icfeb];
01772 }
01773 LogTrace("CSCCathodeLCTProcessor")
01774 << "strip_type" << strstrm.str()
01775 << "\n best: ihits " << ihits[0] << " cfeb " << cfebs[0]
01776 << " strip_type " << ((cfebs[0] >= 0) ? strip_type[cfebs[0]] : -1)
01777 << "\n next: ihits " << ihits[1] << " cfeb " << cfebs[1]
01778 << " strip_type " << ((cfebs[1] >= 0) ? strip_type[cfebs[1]] : -1);
01779 }
01780 }
01781 else if (key_phits[icfeb] > ihits[1]) {
01782 ihits[1] = key_phits[icfeb];
01783 cfebs[1] = icfeb;
01784 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01785 << "\n next: ihits " << ihits[1] << " cfeb " << cfebs[1]
01786 << " strip_type " << ((cfebs[1] >= 0) ? strip_type[cfebs[1]] : -1);
01787 }
01788 }
01789
01790
01791 int jlct = 0;
01792 for (int ilct = 0; ilct < nlcts; ilct++) {
01793 if (cfebs[ilct] != -1) {
01794 keystrip_data[jlct][CLCT_CFEB] = cfebs[ilct];
01795 keystrip_data[jlct][CLCT_STRIP] = key_strip[cfebs[ilct]];
01796 keystrip_data[jlct][CLCT_STRIP_TYPE] = strip_type[cfebs[ilct]];
01797 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01798 << "filling key: " << key_strip[cfebs[ilct]]
01799 << " type: " << strip_type[cfebs[ilct]];
01800 jlct++;
01801 }
01802 }
01803 }
01804
01805
01806
01807 void CSCCathodeLCTProcessor::getKeyStripData(
01808 const unsigned int h_pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01809 const unsigned int d_pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
01810 int keystrip_data[2][7], const int first_bx) {
01811
01812 int lct_pattern[NUM_PATTERN_STRIPS];
01813 int this_layer, this_strip;
01814 unsigned int quality = 0, bend = 0;
01815 unsigned int best_quality, best_pattern;
01816 bool valid[2] = {false,false};
01817
01818
01819 int latch_bx = first_bx + drift_delay;
01820
01821
01822
01823
01824
01825 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01826 << "...............getKeyStripData....................";
01827
01828 for (int ilct = 0; ilct < 2; ilct++) {
01829 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01830 << "lct " << ilct << " keystrip " << keystrip_data[ilct][CLCT_STRIP]
01831 << " type " << keystrip_data[ilct][CLCT_STRIP_TYPE];
01832 if (keystrip_data[ilct][CLCT_STRIP] == -1) {
01833 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01834 << "no lct at ilct " << ilct;
01835 continue;
01836 }
01837 for (int pattern_strip = 0; pattern_strip < NUM_PATTERN_STRIPS;
01838 pattern_strip++) {
01839 lct_pattern[pattern_strip] = -999;
01840 this_layer = pre_hit_pattern[0][pattern_strip];
01841 this_strip = pre_hit_pattern[1][pattern_strip] +
01842 keystrip_data[ilct][CLCT_STRIP];
01843
01844
01845 if (keystrip_data[ilct][CLCT_STRIP_TYPE] == 1) {
01846 if (this_strip >= 0 && this_strip < CSCConstants::NUM_HALF_STRIPS) {
01847
01848 if (((h_pulse[this_layer][this_strip] >> latch_bx) & 1) == 1)
01849 lct_pattern[pattern_strip] = 1;
01850 }
01851 }
01852 else {
01853 if (this_strip >= 0 && this_strip < CSCConstants::NUM_DI_STRIPS) {
01854
01855 if (((d_pulse[this_layer][this_strip] >> latch_bx) & 1) == 1)
01856 lct_pattern[pattern_strip] = 1;
01857 }
01858 }
01859 }
01860
01861
01862
01863 best_quality = 0;
01864 best_pattern = 0;
01865
01866 for (unsigned int pattern_num = 0;
01867 pattern_num < CSCConstants::NUM_CLCT_PATTERNS_PRE_TMB07; pattern_num++) {
01868 getPattern(pattern_num, lct_pattern, quality, bend);
01869 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01870 << "pattern " << pattern_num << " quality " << quality
01871 << " bend " << bend;
01872
01873
01874
01875 if (quality >= nplanes_hit_pattern) {
01876
01877
01878 if ((quality == best_quality && pattern_num > best_pattern) ||
01879 (quality > best_quality)) {
01880 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01881 << "valid = true at quality " << quality
01882 << " thresh " << nplanes_hit_pattern;
01883 valid[ilct] = true;
01884 keystrip_data[ilct][CLCT_PATTERN] = pattern_num;
01885 keystrip_data[ilct][CLCT_BEND] = bend;
01886 keystrip_data[ilct][CLCT_BX] = first_bx;
01887
01888 keystrip_data[ilct][CLCT_QUALITY] = quality;
01889 best_quality = quality;
01890 best_pattern = pattern_num;
01891 }
01892 }
01893 }
01894
01895 if (!valid[ilct]) {
01896 keystrip_data[ilct][CLCT_STRIP] = -1;
01897 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01898 << "lct " << ilct << " not over threshold: deleting";
01899 }
01900 else {
01901 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01902 << "\n" << "--------- final LCT: " << ilct << " -------------\n"
01903 << " key strip " << keystrip_data[ilct][CLCT_STRIP]
01904 << " pattern_num " << keystrip_data[ilct][CLCT_PATTERN]
01905 << " quality " << keystrip_data[ilct][CLCT_QUALITY]
01906 << " bend " << keystrip_data[ilct][CLCT_BEND]
01907 << " bx " << keystrip_data[ilct][CLCT_BX]
01908 << " type " << keystrip_data[ilct][CLCT_STRIP_TYPE] << "\n";
01909 }
01910 }
01911 }
01912
01913
01914
01915 void CSCCathodeLCTProcessor::getPattern(unsigned int pattern_num,
01916 const int strip_value[NUM_PATTERN_STRIPS],
01917 unsigned int& quality, unsigned int& bend) {
01918
01919
01920
01921
01922
01923
01924 unsigned int layers_hit = 0;
01925 bool hit_layer[CSCConstants::NUM_LAYERS];
01926
01927
01928 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
01929 hit_layer[i_layer] = false;
01930
01931
01932 for (int strip_num = 0; strip_num < NUM_PATTERN_STRIPS; strip_num++){
01933 if (strip_value[strip_num] == 1){
01934 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++){
01935
01936
01937 if (i_layer == pattern[pattern_num][strip_num]){
01938
01939 if (hit_layer[i_layer] == false){
01940 layers_hit++;
01941 hit_layer[i_layer] = true;
01942 }
01943 }
01944 }
01945 }
01946 }
01947
01948 bend = pattern[pattern_num][NUM_PATTERN_STRIPS];
01949 quality = layers_hit;
01950
01951 }
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 std::vector<CSCCLCTDigi> CSCCathodeLCTProcessor::findLCTs(const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
01962 std::vector<CSCCLCTDigi> lctList;
01963
01964
01965 const int maxHalfStrips = 2*numStrips + 1;
01966
01967 if (infoV > 1) dumpDigis(halfstrip, 1, maxHalfStrips);
01968
01969
01970 enum {max_lcts = 2};
01971
01972 int keystrip_data[max_lcts][7] = {{0}};
01973 unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
01974
01975
01976 pulseExtension(halfstrip, maxHalfStrips, pulse);
01977
01978 unsigned int start_bx = 0;
01979
01980
01981 unsigned int stop_bx = fifo_tbins - drift_delay;
01982
01983 while (start_bx < stop_bx) {
01984
01985
01986 int first_bx = 999;
01987 bool pre_trig = preTrigger(pulse, start_bx, first_bx);
01988
01989
01990
01991 if (pre_trig) {
01992 thePreTriggerBXs.push_back(first_bx);
01993 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
01994 << "..... pretrigger at bx = " << first_bx
01995 << "; waiting drift delay .....";
01996
01997
01998 int latch_bx = first_bx + drift_delay;
01999 bool hits_in_time = ptnFinding(pulse, maxHalfStrips, latch_bx);
02000 if (infoV > 1) {
02001 if (hits_in_time) {
02002 for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER-1];
02003 hstrip < maxHalfStrips; hstrip++) {
02004 if (nhits[hstrip] > 0) {
02005 LogTrace("CSCCathodeLCTProcessor")
02006 << " bx = " << std::setw(2) << latch_bx << " --->"
02007 << " halfstrip = " << std::setw(3) << hstrip
02008 << " best pid = " << std::setw(2) << best_pid[hstrip]
02009 << " nhits = " << nhits[hstrip];
02010 }
02011 }
02012 }
02013 }
02014
02015
02016 start_bx = first_bx + 1;
02017
02018
02019 int quality[CSCConstants::NUM_HALF_STRIPS];
02020 int best_halfstrip[max_lcts], best_quality[max_lcts];
02021 for (int ilct = 0; ilct < max_lcts; ilct++) {
02022 best_halfstrip[ilct] = -1;
02023 best_quality[ilct] = 0;
02024 }
02025
02026
02027
02028 if (hits_in_time) {
02029 for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER-1];
02030 hstrip < maxHalfStrips; hstrip++) {
02031
02032
02033 quality[hstrip] = (best_pid[hstrip] & 14) | (nhits[hstrip] << 5);
02034 if (quality[hstrip] > best_quality[0]) {
02035 best_halfstrip[0] = hstrip;
02036 best_quality[0] = quality[hstrip];
02037 }
02038 if (infoV > 1 && quality[hstrip] > 0) {
02039 LogTrace("CSCCathodeLCTProcessor")
02040 << " 1st CLCT: halfstrip = " << std::setw(3) << hstrip
02041 << " quality = " << std::setw(3) << quality[hstrip]
02042 << " best halfstrip = " << std::setw(3) << best_halfstrip[0]
02043 << " best quality = " << std::setw(3) << best_quality[0];
02044 }
02045 }
02046 }
02047
02048
02049 if (best_halfstrip[0] >= 0) {
02050
02051
02052 markBusyKeys(best_halfstrip[0], best_pid[best_halfstrip[0]], quality);
02053
02054 for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER-1];
02055 hstrip < maxHalfStrips; hstrip++) {
02056 if (quality[hstrip] > best_quality[1]) {
02057 best_halfstrip[1] = hstrip;
02058 best_quality[1] = quality[hstrip];
02059 }
02060 if (infoV > 1 && quality[hstrip] > 0) {
02061 LogTrace("CSCCathodeLCTProcessor")
02062 << " 2nd CLCT: halfstrip = " << std::setw(3) << hstrip
02063 << " quality = " << std::setw(3) << quality[hstrip]
02064 << " best halfstrip = " << std::setw(3) << best_halfstrip[1]
02065 << " best quality = " << std::setw(3) << best_quality[1];
02066 }
02067 }
02068
02069
02070 bool ptn_trig = false;
02071 for (int ilct = 0; ilct < max_lcts; ilct++) {
02072 int best_hs = best_halfstrip[ilct];
02073 if (best_hs >= 0 && nhits[best_hs] >= nplanes_hit_pattern) {
02074 ptn_trig = true;
02075 keystrip_data[ilct][CLCT_PATTERN] = best_pid[best_hs];
02076 keystrip_data[ilct][CLCT_BEND] =
02077 pattern2007[best_pid[best_hs]][NUM_PATTERN_HALFSTRIPS];
02078
02079 keystrip_data[ilct][CLCT_STRIP] =
02080 best_hs - stagger[CSCConstants::KEY_CLCT_LAYER-1];
02081 keystrip_data[ilct][CLCT_BX] = first_bx;
02082 keystrip_data[ilct][CLCT_STRIP_TYPE] = 1;
02083 keystrip_data[ilct][CLCT_QUALITY] = nhits[best_hs];
02084 keystrip_data[ilct][CLCT_CFEB] =
02085 keystrip_data[ilct][CLCT_STRIP]/cfeb_strips[1];
02086 int halfstrip_in_cfeb = keystrip_data[ilct][CLCT_STRIP] -
02087 cfeb_strips[1]*keystrip_data[ilct][CLCT_CFEB];
02088
02089 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
02090 << " Final selection: ilct " << ilct
02091 << " key halfstrip " << keystrip_data[ilct][CLCT_STRIP]
02092 << " quality " << keystrip_data[ilct][CLCT_QUALITY]
02093 << " pattern " << keystrip_data[ilct][CLCT_PATTERN]
02094 << " bx " << keystrip_data[ilct][CLCT_BX];
02095
02096 CSCCLCTDigi thisLCT(1, keystrip_data[ilct][CLCT_QUALITY],
02097 keystrip_data[ilct][CLCT_PATTERN],
02098 keystrip_data[ilct][CLCT_STRIP_TYPE],
02099 keystrip_data[ilct][CLCT_BEND],
02100 halfstrip_in_cfeb,
02101 keystrip_data[ilct][CLCT_CFEB],
02102 keystrip_data[ilct][CLCT_BX]);
02103 lctList.push_back(thisLCT);
02104 }
02105 }
02106
02107 if (ptn_trig) {
02108
02109
02110
02111
02112
02113 start_bx = fifo_tbins;
02114
02115
02116
02117 unsigned int stop_time = fifo_tbins - drift_delay;
02118 for (unsigned int bx = latch_bx + 1; bx < stop_time; bx++) {
02119 bool return_to_idle = true;
02120 bool hits_in_time = ptnFinding(pulse, maxHalfStrips, bx);
02121 if (hits_in_time) {
02122 for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER-1];
02123 hstrip < maxHalfStrips; hstrip++) {
02124 if (nhits[hstrip] >= nplanes_hit_pattern) {
02125 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
02126 << " State machine busy at bx = " << bx;
02127 return_to_idle = false;
02128 break;
02129 }
02130 }
02131 }
02132 if (return_to_idle) {
02133 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
02134 << " State machine returns to idle state at bx = " << bx;
02135 start_bx = bx;
02136 break;
02137 }
02138 }
02139 }
02140 }
02141 }
02142 else {
02143 start_bx = first_bx + 1;
02144 }
02145 }
02146
02147 return lctList;
02148 }
02149
02150
02151
02152 void CSCCathodeLCTProcessor::pulseExtension(
02153 const std::vector<int> time[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
02154 const int nStrips,
02155 unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
02156
02157 static unsigned int bits_in_pulse = 8*sizeof(pulse[0][0]);
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++)
02168 for (int i_strip = 0; i_strip < nStrips; i_strip++)
02169 pulse[i_layer][i_strip] = 0;
02170
02171
02172 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
02173 for (int i_strip = 0; i_strip < nStrips; i_strip++) {
02174
02175
02176 if (time[i_layer][i_strip].size() > 0) {
02177 std::vector<int> bx_times = time[i_layer][i_strip];
02178 for (unsigned int i = 0; i < bx_times.size(); i++) {
02179
02180 if (bx_times[i] < 0 || bx_times[i] + hit_persist >= bits_in_pulse) {
02181 if (infoV > 0) edm::LogWarning("L1CSCTPEmulatorOutOfTimeDigi")
02182 << "+++ BX time of comparator digi (halfstrip = " << i_strip
02183 << " layer = " << i_layer << ") bx = " << bx_times[i]
02184 << " is not within the range (0-" << bits_in_pulse
02185 << "] allowed for pulse extension. Skip this digi! +++\n";
02186 continue;
02187 }
02188 for (unsigned int bx = bx_times[i];
02189 bx < bx_times[i] + hit_persist; bx++)
02190 pulse[i_layer][i_strip] = pulse[i_layer][i_strip] | (1 << bx);
02191 }
02192 }
02193 }
02194 }
02195 }
02196
02197
02198
02199 bool CSCCathodeLCTProcessor::preTrigger(
02200 const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
02201 const int start_bx, int& first_bx) {
02202 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor")
02203 << "....................PreTrigger...........................";
02204
02205
02206 const int nStrips = 2*numStrips + 1;
02207
02208 bool pre_trig = false;
02209
02210 for (unsigned int bx_time = start_bx; bx_time < fifo_tbins; bx_time++) {
02211
02212
02213
02214
02215
02216 bool hits_in_time = ptnFinding(pulse, nStrips, bx_time);
02217 if (hits_in_time) {
02218 for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER-1];
02219 hstrip < nStrips; hstrip++) {
02220 if (infoV > 1) {
02221 if (nhits[hstrip] > 0) {
02222 LogTrace("CSCCathodeLCTProcessor")
02223 << " bx = " << std::setw(2) << bx_time << " --->"
02224 << " halfstrip = " << std::setw(3) << hstrip
02225 << " best pid = " << std::setw(2) << best_pid[hstrip]
02226 << " nhits = " << nhits[hstrip];
02227 }
02228 }
02229 if (nhits[hstrip] >= nplanes_hit_pretrig &&
02230 best_pid[hstrip] >= pid_thresh_pretrig) {
02231 pre_trig = true;
02232 }
02233 }
02234
02235 if (pre_trig) {
02236 first_bx = bx_time;
02237 return true;
02238 }
02239 }
02240 }
02241
02242 if (infoV > 1) LogTrace("CSCCathodeLCTProcessor") <<
02243 "no pretrigger, returning \n";
02244 first_bx = fifo_tbins;
02245 return false;
02246 }
02247
02248
02249
02250 bool CSCCathodeLCTProcessor::ptnFinding(
02251 const unsigned int pulse[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS],
02252 const int nStrips, const unsigned int bx_time) {
02253 if (bx_time >= fifo_tbins) return false;
02254
02255
02256
02257
02258 unsigned int layers_hit = 0;
02259 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
02260 for (int i_hstrip = 0; i_hstrip < nStrips; i_hstrip++) {
02261 if (((pulse[i_layer][i_hstrip] >> bx_time) & 1) == 1) {
02262 layers_hit++;
02263 break;
02264 }
02265 }
02266 }
02267 if (layers_hit < nplanes_hit_pretrig) return false;
02268
02269 for (int key_hstrip = 0; key_hstrip < nStrips; key_hstrip++) {
02270 best_pid[key_hstrip] = 0;
02271 nhits[key_hstrip] = 0;
02272 }
02273
02274
02275 bool hit_layer[CSCConstants::NUM_LAYERS];
02276 for (int key_hstrip = stagger[CSCConstants::KEY_CLCT_LAYER-1];
02277 key_hstrip < nStrips; key_hstrip++) {
02278
02279 for (unsigned int pid = CSCConstants::NUM_CLCT_PATTERNS-1;
02280 pid >= pid_thresh_pretrig; pid--) {
02281 layers_hit = 0;
02282 for (int ilayer = 0; ilayer < CSCConstants::NUM_LAYERS; ilayer++)
02283 hit_layer[ilayer] = false;
02284
02285
02286
02287 for (int strip_num = 0; strip_num < NUM_PATTERN_HALFSTRIPS;
02288 strip_num++) {
02289 int this_layer = pattern2007[pid][strip_num];
02290 if (this_layer >= 0 && this_layer < CSCConstants::NUM_LAYERS) {
02291 int this_strip = pattern2007_offset[strip_num] + key_hstrip;
02292 if (this_strip >= 0 && this_strip < nStrips) {
02293 if (infoV > 3) LogTrace("CSCCathodeLCTProcessor")
02294 << " In ptnFinding: key_strip = " << key_hstrip
02295 << " pid = " << pid << " strip_num = " << strip_num
02296 << " layer = " << this_layer << " strip = " << this_strip;
02297
02298 if (((pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
02299 if (hit_layer[this_layer] == false) {
02300 hit_layer[this_layer] = true;
02301 layers_hit++;
02302 }
02303 }
02304 }
02305 }
02306 }
02307
02308 if (layers_hit > nhits[key_hstrip]) {
02309 best_pid[key_hstrip] = pid;
02310 nhits[key_hstrip] = layers_hit;
02311
02312
02313 if (nhits[key_hstrip] == CSCConstants::NUM_LAYERS) break;
02314 }
02315 }
02316 }
02317 return true;
02318 }
02319
02320
02321
02322 void CSCCathodeLCTProcessor::markBusyKeys(const int best_hstrip,
02323 const int best_patid,
02324 int quality[CSCConstants::NUM_HALF_STRIPS]) {
02325 int nspan = min_separation;
02326 int pspan = min_separation;
02327
02328 for (int hstrip = best_hstrip-nspan; hstrip <= best_hstrip+pspan; hstrip++) {
02329 if (hstrip >= 0 && hstrip < CSCConstants::NUM_HALF_STRIPS) {
02330 quality[hstrip] = 0;
02331 }
02332 }
02333 }
02334
02335
02336
02337
02338
02339 void CSCCathodeLCTProcessor::dumpConfigParams() const {
02340 std::ostringstream strm;
02341 strm << "\n";
02342 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
02343 strm << "+ CLCT configuration parameters: +\n";
02344 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
02345 strm << " fifo_tbins [total number of time bins in DAQ readout] = "
02346 << fifo_tbins << "\n";
02347 strm << " fifo_pretrig [start time of cathode raw hits in DAQ readout] = "
02348 << fifo_pretrig << "\n";
02349 strm << " hit_persist [duration of signal pulse, in 25 ns bins] = "
02350 << hit_persist << "\n";
02351 strm << " drift_delay [time after pre-trigger before TMB latches LCTs] = "
02352 << drift_delay << "\n";
02353 strm << " nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = "
02354 << nplanes_hit_pretrig << "\n";
02355 strm << " nplanes_hit_pattern [min. number of layers hit for trigger] = "
02356 << nplanes_hit_pattern << "\n";
02357 if (isTMB07) {
02358 strm << " pid_thresh_pretrig [lower threshold on pattern id] = "
02359 << pid_thresh_pretrig << "\n";
02360 strm << " min_separation [region of busy key strips] = "
02361 << min_separation << "\n";
02362 }
02363 strm << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
02364 LogDebug("CSCCathodeLCTProcessor") << strm.str();
02365 }
02366
02367
02368 void CSCCathodeLCTProcessor::dumpDigis(const std::vector<int> strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS], const int stripType, const int nStrips) const
02369 {
02370 LogDebug("CSCCathodeLCTProcessor")
02371 << "ME" << ((theEndcap == 1) ? "+" : "-") << theStation << "/"
02372 << CSCTriggerNumbering::ringFromTriggerLabels(theStation, theTrigChamber)
02373 << "/" << CSCTriggerNumbering::chamberFromTriggerLabels(theSector,
02374 theSubsector, theStation, theTrigChamber)
02375 << " strip type " << stripType << " nStrips " << nStrips;
02376
02377 std::ostringstream strstrm;
02378 for (int i_strip = 0; i_strip < nStrips; i_strip++) {
02379 if (i_strip%10 == 0) {
02380 if (i_strip < 100) strstrm << i_strip/10;
02381 else strstrm << (i_strip-100)/10;
02382 }
02383 else strstrm << " ";
02384 if ((i_strip+1)%cfeb_strips[stripType] == 0) strstrm << " ";
02385 }
02386 strstrm << "\n";
02387 for (int i_strip = 0; i_strip < nStrips; i_strip++) {
02388 strstrm << i_strip%10;
02389 if ((i_strip+1)%cfeb_strips[stripType] == 0) strstrm << " ";
02390 }
02391 for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
02392 strstrm << "\n";
02393 for (int i_strip = 0; i_strip < nStrips; i_strip++) {
02394 if (!strip[i_layer][i_strip].empty()) {
02395 std::vector<int> bx_times = strip[i_layer][i_strip];
02396
02397 strstrm << std::hex << bx_times[0] << std::dec;
02398 }
02399 else {
02400 strstrm << "-";
02401 }
02402 if ((i_strip+1)%cfeb_strips[stripType] == 0) strstrm << " ";
02403 }
02404 }
02405 LogTrace("CSCCathodeLCTProcessor") << strstrm.str();
02406 }
02407
02408
02409
02410 std::vector<CSCCLCTDigi> CSCCathodeLCTProcessor::readoutCLCTs() {
02411 std::vector<CSCCLCTDigi> tmpV;
02412
02413
02414
02415
02416
02417
02418
02419
02420 static int early_tbins = 4;
02421
02422
02423
02424
02425
02426 static int tmb_l1a_window_size = 7;
02427 static int lct_bins =
02428 (tmb_l1a_window_size%2 == 0) ? tmb_l1a_window_size : tmb_l1a_window_size-1;
02429 static int late_tbins = early_tbins + lct_bins;
02430
02431 static int ifois = 0;
02432 if (ifois == 0) {
02433 if (infoV >= 0 && early_tbins < 0) {
02434 edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
02435 << "+++ early_tbins = " << early_tbins
02436 << "; in-time CLCTs are not getting read-out!!! +++" << "\n";
02437 }
02438
02439 if (late_tbins > MAX_CLCT_BINS-1) {
02440 if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorSuspiciousParameters")
02441 << "+++ Allowed range of time bins, [0-" << late_tbins
02442 << "] exceeds max allowed, " << MAX_CLCT_BINS-1 << " +++\n"
02443 << "+++ Set late_tbins to max allowed +++\n";
02444 late_tbins = MAX_CLCT_BINS-1;
02445 }
02446 ifois = 1;
02447 }
02448
02449
02450
02451 int bx_readout = -1;
02452 std::vector<CSCCLCTDigi> all_lcts = getCLCTs();
02453 for (std::vector <CSCCLCTDigi>::const_iterator plct = all_lcts.begin();
02454 plct != all_lcts.end(); plct++) {
02455 if (!plct->isValid()) continue;
02456
02457 int bx = (*plct).getBX();
02458
02459 if (bx <= early_tbins) {
02460 if (infoV > 1) LogDebug("CSCCathodeLCTProcessor")
02461 << " Do not report CLCT on key halfstrip " << plct->getKeyStrip()
02462 << ": found at bx " << bx << ", whereas the earliest allowed bx is "
02463 << early_tbins+1;
02464 continue;
02465 }
02466
02467
02468 if (bx > late_tbins) {
02469 if (infoV > 1) LogDebug("CSCCathodeLCTProcessor")
02470 << " Do not report CLCT on key halfstrip " << plct->getKeyStrip()
02471 << ": found at bx " << bx << ", whereas the latest allowed bx is "
02472 << late_tbins;
02473 continue;
02474 }
02475
02476
02477
02478
02479 if (bx_readout == -1 || bx == bx_readout) {
02480 tmpV.push_back(*plct);
02481 if (bx_readout == -1) bx_readout = bx;
02482 }
02483 }
02484 return tmpV;
02485 }
02486
02487
02488 std::vector<CSCCLCTDigi> CSCCathodeLCTProcessor::getCLCTs() {
02489 std::vector<CSCCLCTDigi> tmpV;
02490 for (int bx = 0; bx < MAX_CLCT_BINS; bx++) {
02491 if (bestCLCT[bx].isValid()) tmpV.push_back(bestCLCT[bx]);
02492 if (secondCLCT[bx].isValid()) tmpV.push_back(secondCLCT[bx]);
02493 }
02494 return tmpV;
02495 }
02496
02497
02498
02499
02500
02501 void CSCCathodeLCTProcessor::testDistripStagger() {
02502
02503
02504
02505 bool debug = true;
02506 int test_triad[CSCConstants::NUM_DI_STRIPS], test_time[CSCConstants::NUM_DI_STRIPS];
02507 int test_digi[CSCConstants::NUM_DI_STRIPS];
02508 int distrip = 0;
02509 test_triad[distrip] = 3;
02510 test_triad[distrip+1] = 3;
02511 test_triad[distrip+2] = 3;
02512 test_triad[distrip+3] = 3;
02513 test_triad[distrip+4] = 3;
02514 test_triad[distrip+5] = 3;
02515 test_triad[distrip+6] = 3;
02516 test_triad[distrip+7] = 3;
02517 test_triad[distrip+8] = 3;
02518 test_triad[distrip+9] = 3;
02519 test_triad[distrip+10] = 2;
02520
02521 test_time[distrip] = 4;
02522 test_time[distrip+1] = 10;
02523 test_time[distrip+2] = 2;
02524 test_time[distrip+3] = 0;
02525 test_time[distrip+4] = 6;
02526 test_time[distrip+5] = 8;
02527 test_time[distrip+6] = 10;
02528 test_time[distrip+7] = 1;
02529 test_time[distrip+8] = 8;
02530 test_time[distrip+9] = 5;
02531 test_time[distrip+10] = 6;
02532
02533 std::cout << "\n ------------------------------------------------- \n";
02534 std::cout << "!!!!!!Testing distripStagger routine!!!!!!" << std::endl;
02535 std::cout << "Values before distripStagger routine:" << std::endl;
02536 for (int i=distrip; i<distrip+11; i++){
02537 test_digi[i] = 999;
02538 std::cout << "test_triad[" << i << "] = " << test_triad[i];
02539 std::cout << " test_time[" << i << "] = " << test_time[i] << std::endl;
02540 }
02541 distripStagger(test_triad, test_time, test_digi, distrip, debug);
02542 std::cout << "Values after distripStagger routine:" << std::endl;
02543 for (int i=distrip; i<distrip+11; i++){
02544 std::cout << "test_triad[" << i << "] = " << test_triad[i];
02545 std::cout << " test_time[" << i << "] = " << test_time[i] << std::endl;
02546 }
02547 std::cout << "\n ------------------------------------------------- \n \n";
02548 }
02549
02550 void CSCCathodeLCTProcessor::testLCTs() {
02551
02552 for (int ptn = 0; ptn < 8; ptn++) {
02553 for (int bend = 0; bend < 2; bend++) {
02554 for (int cfeb = 0; cfeb < MAX_CFEBS; cfeb++) {
02555 for (int key_strip = 0; key_strip < 32; key_strip++) {
02556 for (int bx = 0; bx < 7; bx++) {
02557 for (int stripType = 0; stripType < 2; stripType++) {
02558 for (int quality = 3; quality < 6; quality++) {
02559 CSCCLCTDigi thisLCT(1, quality, ptn, stripType, bend,
02560 key_strip, cfeb, bx);
02561 if (ptn != thisLCT.getPattern())
02562 LogTrace("CSCCathodeLCTProcessor")
02563 << "pattern mismatch: " << ptn << " "
02564 << thisLCT.getPattern();
02565 if (bend != thisLCT.getBend())
02566 LogTrace("CSCCathodeLCTProcessor")
02567 << "bend mismatch: " << bend << " " << thisLCT.getBend();
02568 if (cfeb != thisLCT.getCFEB())
02569 LogTrace("CSCCathodeLCTProcessor")
02570 << "cfeb mismatch: " << cfeb << " " << thisLCT.getCFEB();
02571 if (key_strip != thisLCT.getKeyStrip())
02572 LogTrace("CSCCathodeLCTProcessor")
02573 << "strip mismatch: " << key_strip << " "
02574 << thisLCT.getKeyStrip();
02575 if (bx != thisLCT.getBX())
02576 LogTrace("CSCCathodeLCTProcessor")
02577 << "bx mismatch: " << bx << " " << thisLCT.getBX();
02578 if (stripType != thisLCT.getStripType())
02579 LogTrace("CSCCathodeLCTProcessor")
02580 << "Strip Type mismatch: " << stripType << " "
02581 << thisLCT.getStripType();
02582 if (quality != thisLCT.getQuality())
02583 LogTrace("CSCCathodeLCTProcessor")
02584 << "quality mismatch: " << quality << " "
02585 << thisLCT.getQuality();
02586 }
02587 }
02588 }
02589 }
02590 }
02591 }
02592 }
02593 }
02594
02595 void CSCCathodeLCTProcessor::printPatterns() {
02596
02597 std::cout<<" Printing patterns for Cathode LCT"<<std::endl;
02598 std::cout<<" ";
02599 for (int patternNum = 0; patternNum < CSCConstants::NUM_CLCT_PATTERNS_PRE_TMB07; patternNum++) {
02600 std::cout<<" Pattern "<<patternNum<<" ";
02601 }
02602 std::cout<<std::endl;
02603 std::cout<<" Layer ";
02604 for (int patternNum = 0; patternNum < CSCConstants::NUM_CLCT_PATTERNS_PRE_TMB07; patternNum++) {
02605 std::cout<<" Bend "<<(pattern[patternNum][NUM_PATTERN_STRIPS]==0 ? "L": "R")<<" ";
02606 }
02607 std::cout<<std::endl;
02608 for (int layer = 0; layer < CSCConstants::NUM_LAYERS; layer++) {
02609 for (int patternNum = 0; patternNum < CSCConstants::NUM_CLCT_PATTERNS_PRE_TMB07; patternNum++) {
02610 if (patternNum == 0) std::cout<<" "<<layer<<" ";
02611 if ((isTMB07 && layer != CSCConstants::KEY_CLCT_LAYER-1) ||
02612 (!isTMB07 && layer != CSCConstants::KEY_CLCT_LAYER_PRE_TMB07-1)) {
02613 int minStrip =0;
02614 if ((isTMB07 && layer < CSCConstants::KEY_CLCT_LAYER-1) ||
02615 (!isTMB07 && layer < CSCConstants::KEY_CLCT_LAYER_PRE_TMB07-1)) {
02616 minStrip = 3*layer;
02617 } else {
02618 minStrip = 3*layer - 2;
02619 }
02620 for (int strip = minStrip; strip < minStrip + 3; strip++) {
02621 if (layer == pattern[patternNum][strip]) {
02622 std::cout<<"X";
02623 } else {
02624 std::cout<<"_";
02625 }
02626 }
02627 } else {
02628 std::cout<<" X ";
02629 }
02630 std::cout<<" ";
02631 }
02632 std::cout<<std::endl;
02633 }
02634 }
02635
02636 void CSCCathodeLCTProcessor::testPatterns() {
02637
02638
02639
02640
02641
02642 for (int possibleHits = 0; possibleHits < 65536; possibleHits++) {
02643 std::vector<int> stripsHit[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS];
02644
02645 stripsHit[0][ 9].push_back(( possibleHits & 1 ) != 0);
02646 stripsHit[0][10].push_back(( possibleHits & 2 ) != 0);
02647 stripsHit[0][11].push_back(( possibleHits & 4 ) != 0);
02648 stripsHit[1][ 9].push_back(( possibleHits & 8 ) != 0);
02649 stripsHit[1][10].push_back(( possibleHits & 16 ) != 0);
02650 stripsHit[1][11].push_back(( possibleHits & 32 ) != 0);
02651 stripsHit[2][ 9].push_back(( possibleHits & 64 ) != 0);
02652 stripsHit[2][10].push_back(( possibleHits & 128 ) != 0);
02653 stripsHit[2][11].push_back(( possibleHits & 256 ) != 0);
02654 stripsHit[3][10].push_back(( possibleHits & 512 ) != 0);
02655 stripsHit[4][ 9].push_back(( possibleHits & 1024 ) != 0);
02656 stripsHit[4][10].push_back(( possibleHits & 2048 ) != 0);
02657 stripsHit[4][11].push_back(( possibleHits & 4096 ) != 0);
02658 stripsHit[5][ 9].push_back(( possibleHits & 8192 ) != 0);
02659 stripsHit[5][10].push_back(( possibleHits & 16384 ) != 0);
02660 stripsHit[5][11].push_back(( possibleHits & 32768 ) != 0);
02661 int numLayersHit = findNumLayersHit(stripsHit);
02662 std::vector <CSCCLCTDigi> results = findLCTs(stripsHit, 1);
02663
02664
02665
02666
02667
02668
02669 if (numLayersHit > 3 || results.size() > 0) {
02670 std::cout<<"Input "<<possibleHits<<"/"<< 65536 <<" # Found Patterns "<<results.size()<<std::endl<<" ";
02671 for (int layer = 0; layer < CSCConstants::NUM_LAYERS; layer++) {
02672 if ((isTMB07 && layer != CSCConstants::KEY_CLCT_LAYER - 1) ||
02673 (!isTMB07 && layer != CSCConstants::KEY_CLCT_LAYER_PRE_TMB07 - 1)) {
02674 for (int strip = 9; strip < 12; strip++) {
02675 if (!stripsHit[layer][strip].empty()) {
02676 if (results.size() > 0) {
02677 int thePatternStrip = strip - (results[0].getKeyStrip() - 2) + 3*layer;
02678 if ((isTMB07 && layer>=CSCConstants::KEY_CLCT_LAYER) ||
02679 (!isTMB07 && layer>=CSCConstants::KEY_CLCT_LAYER_PRE_TMB07))
02680 thePatternStrip -= 2;
02681
02682 if (pattern[results[0].getPattern()][thePatternStrip] == layer)
02683 {
02684 std::cout<<"X";
02685 } else {
02686 std::cout<<"x";
02687 }
02688 } else {
02689 std::cout<<"o";
02690 }
02691 } else {
02692 std::cout<<"_";
02693 }
02694 }
02695 std::cout<<" ";
02696 for (unsigned int output = 0; output < results.size(); output++) {
02697 int minStrip;
02698 if ((isTMB07 && layer < CSCConstants::KEY_CLCT_LAYER-1) ||
02699 (!isTMB07 && layer < CSCConstants::KEY_CLCT_LAYER_PRE_TMB07-1)) {
02700 minStrip = 3*layer;
02701 } else {
02702 minStrip = 3*layer - 2;
02703 }
02704 for (int strip = minStrip; strip < minStrip + 3; strip++) {
02705 if (layer == pattern[results[output].getPattern()][strip]) {
02706 std::cout<<"X";
02707 } else {
02708 std::cout<<"_";
02709 }
02710 }
02711 std::cout<<" ";
02712 }
02713 } else {
02714 if (!stripsHit[layer][10].empty()) {
02715 std::cout<<" X ";
02716 } else {
02717 std::cout<<" _ ";
02718 }
02719 for (unsigned int output = 0; output < results.size(); output++)
02720 std::cout<<" X ";
02721 }
02722 if (layer < static_cast<int>(results.size()) ) {
02723 std::cout<<results[layer];
02724 std::cout<<" ";
02725 } else {
02726 std::cout<<" "<<std::endl<<" ";
02727 }
02728 }
02729 }
02730 }
02731 }
02732
02733 int CSCCathodeLCTProcessor::findNumLayersHit(std::vector<int>
02734 stripsHit[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS]) {
02735 int number = 0;
02736 for (int layer = 0; layer < CSCConstants::NUM_LAYERS; layer++) {
02737 if ((!stripsHit[layer][ 9].empty()) ||
02738 (!stripsHit[layer][10].empty()) ||
02739 (!stripsHit[layer][11].empty()) ) number++;
02740 }
02741 return number;
02742 }