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