29 static std::atomic<bool> config_dumped{
false};
68 if ((
infoV > 0) && !config_dumped) {
76 if ((i_layer + 1) % 2 == 0)
94 for (
int i = 0;
i < 5; ++
i) {
109 static std::atomic<bool> config_dumped{
false};
121 if (!config_dumped) {
123 config_dumped =
true;
129 if ((i_layer + 1) % 2 == 0)
153 static std::atomic<bool> config_dumped{
false};
166 if (!config_dumped) {
168 config_dumped =
true;
176 static const unsigned int max_fifo_tbins = 1 << 5;
177 static const unsigned int max_fifo_pretrig = 1 << 5;
178 static const unsigned int max_hit_persist = 1 << 4;
179 static const unsigned int max_drift_delay = 1 << 2;
180 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
181 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
182 static const unsigned int max_pid_thresh_pretrig = 1 << 4;
184 static const unsigned int max_tmb_l1a_window_size = 1 << 4;
216 static std::atomic<bool> config_dumped{
false};
217 if ((
infoV > 0) && !config_dumped) {
219 config_dumped =
true;
236 <<
"+++ Invalid ring number for this processor " <<
theRing <<
" was set in the config."
238 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
253 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
276 <<
" is not defined in current geometry! +++\n"
277 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
286 <<
" numStrips = " <<
numStrips <<
"; CLCT emulation skipped! +++";
287 std::vector<CSCCLCTDigi> emptyV;
305 unsigned int layersHit = 0;
308 if (!halfstrip[i_layer][i_hstrip].
empty()) {
322 std::vector<CSCCLCTDigi> tmpV =
getCLCTs();
331 for (
auto&
p : tmpV) {
345 std::vector<CSCCLCTDigi> CLCTlist =
findLCTs(halfstrip);
348 if (CLCTlist.size() > 1)
349 sort(CLCTlist.begin(), CLCTlist.end(), std::greater<CSCCLCTDigi>());
351 for (
const auto&
p : CLCTlist) {
352 const int bx =
p.getBX();
357 <<
"; skipping it... +++\n";
403 digiV[i_layer].clear();
416 LogTrace(
"CSCCathodeLCTProcessor") <<
"found " <<
digiV[i_layer].size() <<
" comparator digi(s) in layer "
427 const bool me1a = (
id.station() == 1) && (
id.
ring() == 4);
430 const unsigned int origStrip = digiIt->getStrip();
431 const unsigned int maxStripsME1a =
435 if (me1a && origStrip <= maxStripsME1a && !
disableME1a_) {
440 digiV[
id.layer() - 1].push_back(digi_corr);
442 digiV[
id.layer() - 1].push_back(*digiIt);
451 for (std::vector<CSCComparatorDigi>::iterator pld =
digiV[i_layer].begin(); pld !=
digiV[i_layer].end();
455 std::ostringstream strstrm;
456 strstrm <<
"Comparator digi: comparator = " << pld->getComparator() <<
" strip #" << pld->getStrip()
458 std::vector<int> bx_times = pld->getTimeBinsOn();
459 for (
unsigned int tbin = 0; tbin < bx_times.size(); tbin++)
460 strstrm <<
" " << bx_times[tbin];
461 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
466 int thisComparator = pld->getComparator();
467 if (thisComparator != 0 && thisComparator != 1) {
471 <<
" Found comparator digi with wrong comparator value = " << thisComparator <<
"; skipping it... +++\n";
476 int thisStrip = pld->getStrip() - 1;
477 if (thisStrip < 0 || thisStrip >=
numStrips) {
481 <<
" Found comparator digi with wrong strip number = " << thisStrip <<
" (max strips = " <<
numStrips
482 <<
"); skipping it... +++\n";
488 int thisHalfstrip = 2 * thisStrip + thisComparator +
stagger[i_layer];
489 if (thisHalfstrip >= 2 *
numStrips + 1) {
493 <<
" Found wrong halfstrip number = " << thisHalfstrip <<
"; skipping this digi... +++\n";
498 std::vector<int> bx_times = pld->getTimeBinsOn();
499 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
509 if (bx_times[
i] > 1 && bx_times[
i] < static_cast<int>(
fifo_tbins)) {
510 if (
i == 0 || (
i > 0 && bx_times[
i] - bx_times[
i - 1] >= static_cast<int>(
hit_persist))) {
516 <<
"Comp digi: layer " << i_layer + 1 <<
" digi #" << i_digi + 1 <<
" strip " << thisStrip
517 <<
" halfstrip " << thisHalfstrip <<
" time " << bx_times[
i] <<
" comparator " << thisComparator
518 <<
" stagger " <<
stagger[i_layer];
519 halfstrip[i_layer][thisHalfstrip].push_back(bx_times[
i]);
524 <<
" Skipping comparator digi: strip = " << thisStrip <<
", layer = " << i_layer + 1
525 <<
", bx = " << bx_times[
i] <<
", bx of previous hit = " << bx_times[
i - 1];
530 <<
theChamber <<
"+++ Skipping comparator digi: strip = " << thisStrip
531 <<
", layer = " << i_layer + 1 <<
", bx = " << bx_times[
i] <<
" +++";
541 std::vector<CSCCLCTDigi> lctList;
544 const int maxHalfStrips = 2 *
numStrips + 1;
561 while (start_bx < stop_bx) {
572 LogTrace(
"CSCCathodeLCTProcessor") <<
"..... pretrigger at bx = " << first_bx <<
"; waiting drift delay .....";
583 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
584 hits_in_patterns.clear();
592 if (
nhits[hstrip] > 0) {
594 <<
" bx = " << std::setw(2) << latch_bx <<
" --->"
595 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
596 <<
" nhits = " <<
nhits[hstrip];
614 best_halfstrip[ilct] = -1;
615 best_quality[ilct] = 0;
625 if (
quality[hstrip] > best_quality[0]) {
626 best_halfstrip[0] = hstrip;
627 best_quality[0] =
quality[hstrip];
631 <<
" 1st CLCT: halfstrip = " << std::setw(3) << hstrip <<
" quality = " << std::setw(3)
632 <<
quality[hstrip] <<
" nhits = " << std::setw(3) <<
nhits[hstrip] <<
" pid = " << std::setw(3)
633 <<
best_pid[hstrip] <<
" best halfstrip = " << std::setw(3) << best_halfstrip[0]
634 <<
" best quality = " << std::setw(3) << best_quality[0];
640 if (best_halfstrip[0] >= 0) {
646 if (
quality[hstrip] > best_quality[1]) {
647 best_halfstrip[1] = hstrip;
648 best_quality[1] =
quality[hstrip];
652 <<
" 2nd CLCT: halfstrip = " << std::setw(3) << hstrip <<
" quality = " << std::setw(3)
653 <<
quality[hstrip] <<
" nhits = " << std::setw(3) <<
nhits[hstrip] <<
" pid = " << std::setw(3)
654 <<
best_pid[hstrip] <<
" best halfstrip = " << std::setw(3) << best_halfstrip[1]
655 <<
" best quality = " << std::setw(3) << best_quality[1];
661 int best_hs = best_halfstrip[ilct];
668 keystrip_data[ilct][
CLCT_BX] = first_bx;
672 int halfstrip_in_cfeb = keystrip_data[ilct][
CLCT_STRIP] -
677 <<
" Final selection: ilct " << ilct <<
" key halfstrip " << keystrip_data[ilct][
CLCT_STRIP]
678 <<
" quality " << keystrip_data[ilct][
CLCT_QUALITY] <<
" pattern "
698 const auto& compHits = hits_in_patterns[best_hs][keystrip_data[ilct][
CLCT_PATTERN]];
713 LogTrace(
"CSCCathodeLCTProcessor") <<
" Final selection: ilct " << ilct <<
" " << thisLCT << std::endl;
716 lctList.push_back(thisLCT);
731 for (
unsigned int bx = latch_bx + 1;
bx < stop_time;
bx++) {
732 bool return_to_idle =
true;
739 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine busy at bx = " <<
bx;
740 return_to_idle =
false;
745 if (return_to_idle) {
747 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine returns to idle state at bx = " <<
bx;
754 start_bx = first_bx + 1;
766 static const unsigned int bits_in_pulse = 8 *
sizeof(
pulse[0][0]);
777 for (
int i_strip = 0; i_strip <
nStrips; i_strip++)
778 pulse[i_layer][i_strip] = 0;
782 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
786 std::vector<int> bx_times =
time[i_layer][i_strip];
787 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
789 if (bx_times[
i] < 0 || bx_times[
i] +
hit_persist >= bits_in_pulse) {
792 <<
"+++ BX time of comparator digi (halfstrip = " << i_strip <<
" layer = " << i_layer
793 <<
") bx = " << bx_times[
i] <<
" is not within the range (0-" << bits_in_pulse
794 <<
"] allowed for pulse extension. Skip this digi! +++\n";
799 pulse[i_layer][i_strip] =
pulse[i_layer][i_strip] | (1 <<
bx);
810 LogTrace(
"CSCCathodeLCTProcessor") <<
"....................PreTrigger...........................";
815 int nPreTriggers = 0;
817 bool pre_trig =
false;
819 for (
unsigned int bx_time = start_bx; bx_time <
fifo_tbins; bx_time++) {
826 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
827 hits_in_patterns.clear();
833 if (
nhits[hstrip] > 0) {
835 <<
" bx = " << std::setw(2) << bx_time <<
" --->"
836 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
837 <<
" nhits = " <<
nhits[hstrip];
852 1,
nhits[hstrip],
best_pid[hstrip], 1,
bend, halfstrip, cfeb, bx_time, nPreTriggers, 0));
864 LogTrace(
"CSCCathodeLCTProcessor") <<
"no pretrigger, returning \n";
871 const PulseArray
pulse,
873 const unsigned int bx_time,
874 std::map<
int, std::map<int, CSCCLCTDigi::ComparatorContainer>>& hits_in_patterns) {
881 unsigned int layers_hit = 0;
883 for (
int i_hstrip = 0; i_hstrip <
nStrips; i_hstrip++) {
884 if (((
pulse[i_layer][i_hstrip] >> bx_time) & 1) == 1) {
893 for (
int key_hstrip = 0; key_hstrip <
nStrips; key_hstrip++) {
895 nhits[key_hstrip] = 0;
908 hit_layer[ilayer] =
false;
913 hits_single_pattern.resize(6);
914 for (
auto&
p : hits_single_pattern) {
919 double num_pattern_hits = 0., times_sum = 0.;
920 std::multiset<int> mset_for_median;
921 mset_for_median.clear();
935 if (this_strip >= 0 && this_strip <
nStrips) {
937 LogTrace(
"CSCCathodeLCTProcessor") <<
" In patternFinding: key_strip = " << key_hstrip <<
" pid = " << pid
938 <<
" layer = " << this_layer <<
" strip = " << this_strip << std::endl;
941 if (((
pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
942 if (hit_layer[this_layer] ==
false) {
943 hit_layer[this_layer] =
true;
946 hits_single_pattern[this_layer][strip_num] = this_strip -
stagger[this_layer];
951 int first_bx_layer = bx_time;
952 for (
unsigned int dbx = 0; dbx <
hit_persist; dbx++) {
953 if (((
pulse[this_layer][this_strip] >> (first_bx_layer - 1)) & 1) == 1)
958 times_sum += (double)first_bx_layer;
959 num_pattern_hits += 1.;
960 mset_for_median.insert(first_bx_layer);
962 LogTrace(
"CSCCathodeLCTProcessor") <<
" 1st bx in layer: " << first_bx_layer <<
" sum bx: " << times_sum
963 <<
" #pat. hits: " << num_pattern_hits;
971 hits_in_patterns[key_hstrip][pid] = hits_single_pattern;
975 if (layers_hit >
nhits[key_hstrip]) {
977 nhits[key_hstrip] = layers_hit;
980 const int sz = mset_for_median.size();
982 std::multiset<int>::iterator im = mset_for_median.begin();
984 std::advance(im, sz / 2 - 1);
987 else if ((sz % 2) == 1)
992 #if defined(EDM_ML_DEBUG)
995 auto lt =
LogTrace(
"CSCCathodeLCTProcessor")
997 for (im = mset_for_median.begin(); im != mset_for_median.end(); im++) {
1018 const int best_patid,
1023 for (
int hstrip = best_hstrip - nspan; hstrip <= best_hstrip + pspan; hstrip++) {
1032 for (
auto&
p : newHits) {
1033 p.erase(std::remove_if(
1045 std::ostringstream strm;
1047 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1048 strm <<
"+ CLCT configuration parameters: +\n";
1049 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1050 strm <<
" fifo_tbins [total number of time bins in DAQ readout] = " <<
fifo_tbins <<
"\n";
1051 strm <<
" fifo_pretrig [start time of cathode raw hits in DAQ readout] = " <<
fifo_pretrig <<
"\n";
1052 strm <<
" hit_persist [duration of signal pulse, in 25 ns bins] = " <<
hit_persist <<
"\n";
1053 strm <<
" drift_delay [time after pre-trigger before TMB latches LCTs] = " <<
drift_delay <<
"\n";
1054 strm <<
" nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = " <<
nplanes_hit_pretrig <<
"\n";
1055 strm <<
" nplanes_hit_pattern [min. number of layers hit for trigger] = " <<
nplanes_hit_pattern <<
"\n";
1056 strm <<
" pid_thresh_pretrig [lower threshold on pattern id] = " <<
pid_thresh_pretrig <<
"\n";
1057 strm <<
" min_separation [region of busy key strips] = " <<
min_separation <<
"\n";
1058 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1059 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1068 std::ostringstream strstrm;
1069 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
1070 if (i_strip % 10 == 0) {
1072 strstrm << i_strip / 10;
1074 strstrm << (i_strip - 100) / 10;
1081 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
1082 strstrm << i_strip % 10;
1088 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
1090 std::vector<int> bx_times =
strip[i_layer][i_strip];
1092 strstrm << std::hex << bx_times[0] <<
std::dec;
1100 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
1106 std::vector<CSCCLCTDigi> tmpV;
1118 static std::atomic<int> lct_bins;
1120 static std::atomic<int> late_tbins;
1123 static std::atomic<int> ifois{0};
1127 <<
"+++ early_tbins = " <<
early_tbins <<
"; in-time CLCTs are not getting read-out!!! +++"
1134 <<
"+++ Allowed range of time bins, [0-" << late_tbins <<
"] exceeds max allowed, "
1136 <<
"+++ Set late_tbins to max allowed +++\n";
1144 int bx_readout = -1;
1145 const std::vector<CSCCLCTDigi>& all_lcts =
getCLCTs(nMaxCLCTs);
1146 for (
const auto&
p : all_lcts) {
1151 const int bx =
p.getBX();
1156 <<
" Do not report CLCT on key halfstrip " <<
p.getKeyStrip() <<
": found at bx " <<
bx
1157 <<
", whereas the earliest allowed bx is " <<
early_tbins + 1;
1162 if (
bx > late_tbins) {
1165 <<
" Do not report CLCT on key halfstrip " <<
p.getKeyStrip() <<
": found at bx " <<
bx
1166 <<
", whereas the latest allowed bx is " << late_tbins;
1174 if (bx_readout == -1 ||
bx == bx_readout) {
1176 if (bx_readout == -1)
1185 for (
const auto& clct : tmpV) {
1195 std::vector<CSCCLCTDigi> tmpV;
1198 const std::vector<CSCCLCTDigi>& allCLCTs =
readoutCLCTs(nMaxCLCTs);
1199 for (
const auto& clct : allCLCTs)
1200 if (clct.getCFEB() >= 4)
1201 tmpV.push_back(clct);
1208 std::vector<CSCCLCTDigi> tmpV;
1211 const std::vector<CSCCLCTDigi>& allCLCTs =
readoutCLCTs(nMaxCLCTs);
1212 for (
const auto& clct : allCLCTs)
1213 if (clct.getCFEB() < 4)
1214 tmpV.push_back(clct);
1219 std::vector<CSCCLCTPreTriggerDigi> tmpV;
1222 const std::vector<CSCCLCTPreTriggerDigi>& allPretriggerdigis =
preTriggerDigis();
1223 for (
const auto& preclct : allPretriggerdigis)
1224 if (preclct.getCFEB() >= 4)
1225 tmpV.push_back(preclct);
1230 std::vector<CSCCLCTPreTriggerDigi> tmpV;
1233 const std::vector<CSCCLCTPreTriggerDigi>& allPretriggerdigis =
preTriggerDigis();
1234 for (
const auto& preclct : allPretriggerdigis)
1235 if (preclct.getCFEB() < 4)
1236 tmpV.push_back(preclct);
1242 std::vector<CSCCLCTDigi> tmpV;
1279 for (
int row = 2; row >= 0; row--) {
1280 rowPat = rowPat << 1;
1281 rowPat += halfStripPattern[column][row];
1301 id += (rowCode << 2 * column);
1307 std::tuple<uint16_t, bool, bool>& returnValue)
const {
1328 std::vector<std::tuple<uint16_t, bool, bool>> my_tuple = {
1346 returnValue = my_tuple[
offset];
1352 std::ostringstream strm;
1354 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1355 strm <<
"+ Before CCCLUT algorithm: +\n";
1356 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1357 strm <<
" Old CLCT digi " << digi <<
"\n";
1358 strm <<
" 1/4 strip bit " << digi.
getQuartStrip() <<
" 1/8 strip bit " << digi.getEightStrip() <<
"\n";
1359 strm <<
" 1/4 strip number " << digi.getKeyStrip(4) <<
" 1/8 strip number " << digi.getKeyStrip(8) <<
"\n";
1360 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1361 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1368 auto compHits = digi.
getHits();
1379 compHitsCC[
i][iCC] = 1;
1381 compHitsCC[
i][iCC] = 0;
1401 const unsigned positionCC(
lutpos_[
pattern]->lookup(comparatorCode));
1406 const bool slopeCCSign((slopeCC >> 4) & 0
x1);
1407 const unsigned slopeCCValue(slopeCC & 0xf);
1412 std::tuple<uint16_t, bool, bool> halfstripoffset;
1414 halfstrip += std::get<0>(halfstripoffset);
1425 if (run2PatternCC == 0) {
1432 std::ostringstream strm;
1434 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1435 strm <<
"+ CCCLUT algorithm results: +\n";
1436 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1437 strm <<
" New CLCT digi " << digi <<
"\n";
1438 strm <<
" 1/4 strip bit " << digi.
getQuartStrip() <<
" 1/8 strip bit " << digi.getEightStrip() <<
"\n";
1439 strm <<
" 1/4 strip number " << digi.getKeyStrip(4) <<
" 1/8 strip number " << digi.getKeyStrip(8) <<
"\n";
1440 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1441 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1446 const unsigned slopeList[32] = {2, 2, 2, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 8, 10, 10,
1447 10, 10, 9, 9, 9, 9, 7, 7, 7, 7, 5, 5, 5, 3, 3, 3};
1448 return slopeList[
slope];