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;
237 <<
"+++ Invalid ring number for this processor " <<
theRing <<
" was set in the config."
239 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
257 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
282 <<
" is not defined in current geometry! +++\n"
283 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
294 <<
" numStrips_ = " <<
numStrips_ <<
"; CLCT emulation skipped! +++";
295 std::vector<CSCCLCTDigi> emptyV;
313 unsigned int layersHit = 0;
316 if (!halfstrip[i_layer][i_hstrip].
empty()) {
330 std::vector<CSCCLCTDigi> tmpV =
getCLCTs();
339 for (
auto&
p : tmpV) {
353 std::vector<CSCCLCTDigi> CLCTlist =
findLCTs(halfstrip);
356 if (CLCTlist.size() > 1)
357 sort(CLCTlist.begin(), CLCTlist.end(), std::greater<CSCCLCTDigi>());
359 for (
const auto&
p : CLCTlist) {
360 const int bx =
p.getBX();
365 <<
"; skipping it... +++\n";
407 bool hasDigis =
false;
411 digiV[i_layer].clear();
424 LogTrace(
"CSCCathodeLCTProcessor") <<
"found " <<
digiV[i_layer].size() <<
" comparator digi(s) in layer "
435 const bool me1a = (
id.station() == 1) && (
id.
ring() == 4);
438 const unsigned int origStrip = digiIt->getStrip();
439 const unsigned int maxStripsME1a =
443 if (me1a && origStrip <= maxStripsME1a && !
disableME1a_) {
448 digiV[
id.layer() - 1].push_back(digi_corr);
450 digiV[
id.layer() - 1].push_back(*digiIt);
459 for (std::vector<CSCComparatorDigi>::iterator pld =
digiV[i_layer].begin(); pld !=
digiV[i_layer].end();
463 std::ostringstream strstrm;
464 strstrm <<
"Comparator digi: comparator = " << pld->getComparator() <<
" strip #" << pld->getStrip()
466 std::vector<int> bx_times = pld->getTimeBinsOn();
467 for (
unsigned int tbin = 0; tbin < bx_times.size(); tbin++)
468 strstrm <<
" " << bx_times[tbin];
469 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
474 int thisComparator = pld->getComparator();
475 if (thisComparator != 0 && thisComparator != 1) {
479 <<
" Found comparator digi with wrong comparator value = " << thisComparator <<
"; skipping it... +++\n";
484 int thisStrip = pld->getStrip() - 1;
485 if (thisStrip < 0 || thisStrip >=
numStrips_) {
489 <<
" Found comparator digi with wrong strip number = " << thisStrip <<
" (max strips = " <<
numStrips_
490 <<
"); skipping it... +++\n";
496 int thisHalfstrip = 2 * thisStrip + thisComparator +
stagger[i_layer];
501 <<
" Found wrong halfstrip number = " << thisHalfstrip <<
"; skipping this digi... +++\n";
506 std::vector<int> bx_times = pld->getTimeBinsOn();
507 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
517 if (bx_times[
i] > 1 && bx_times[
i] < static_cast<int>(
fifo_tbins)) {
518 if (
i == 0 || (
i > 0 && bx_times[
i] - bx_times[
i - 1] >= static_cast<int>(
hit_persist))) {
524 <<
"Comp digi: layer " << i_layer + 1 <<
" digi #" << i_digi + 1 <<
" strip " << thisStrip
525 <<
" halfstrip " << thisHalfstrip <<
" time " << bx_times[
i] <<
" comparator " << thisComparator
526 <<
" stagger " <<
stagger[i_layer];
527 halfstrip[i_layer][thisHalfstrip].push_back(bx_times[
i]);
532 <<
" Skipping comparator digi: strip = " << thisStrip <<
", layer = " << i_layer + 1
533 <<
", bx = " << bx_times[
i] <<
", bx of previous hit = " << bx_times[
i - 1];
538 <<
theChamber <<
"+++ Skipping comparator digi: strip = " << thisStrip
539 <<
", layer = " << i_layer + 1 <<
", bx = " << bx_times[
i] <<
" +++";
549 std::vector<CSCCLCTDigi> lctList;
566 while (start_bx < stop_bx) {
577 LogTrace(
"CSCCathodeLCTProcessor") <<
"..... pretrigger at bx = " << first_bx <<
"; waiting drift delay .....";
588 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
589 hits_in_patterns.clear();
597 if (
nhits[hstrip] > 0) {
599 <<
" bx = " << std::setw(2) << latch_bx <<
" --->"
600 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
601 <<
" nhits = " <<
nhits[hstrip];
619 best_halfstrip[ilct] = -1;
620 best_quality[ilct] = 0;
630 if (
quality[hstrip] > best_quality[0]) {
631 best_halfstrip[0] = hstrip;
632 best_quality[0] =
quality[hstrip];
636 <<
" 1st CLCT: halfstrip = " << std::setw(3) << hstrip <<
" quality = " << std::setw(3)
637 <<
quality[hstrip] <<
" nhits = " << std::setw(3) <<
nhits[hstrip] <<
" pid = " << std::setw(3)
638 <<
best_pid[hstrip] <<
" best halfstrip = " << std::setw(3) << best_halfstrip[0]
639 <<
" best quality = " << std::setw(3) << best_quality[0];
645 if (best_halfstrip[0] >= 0) {
651 if (
quality[hstrip] > best_quality[1]) {
652 best_halfstrip[1] = hstrip;
653 best_quality[1] =
quality[hstrip];
657 <<
" 2nd CLCT: halfstrip = " << std::setw(3) << hstrip <<
" quality = " << std::setw(3)
658 <<
quality[hstrip] <<
" nhits = " << std::setw(3) <<
nhits[hstrip] <<
" pid = " << std::setw(3)
659 <<
best_pid[hstrip] <<
" best halfstrip = " << std::setw(3) << best_halfstrip[1]
660 <<
" best quality = " << std::setw(3) << best_quality[1];
666 int best_hs = best_halfstrip[ilct];
673 keystrip_data[ilct][
CLCT_BX] = first_bx;
677 int halfstrip_in_cfeb = keystrip_data[ilct][
CLCT_STRIP] -
682 <<
" Final selection: ilct " << ilct <<
" key halfstrip " << keystrip_data[ilct][
CLCT_STRIP]
683 <<
" quality " << keystrip_data[ilct][
CLCT_QUALITY] <<
" pattern "
703 const auto& compHits = hits_in_patterns[best_hs][keystrip_data[ilct][
CLCT_PATTERN]];
718 LogTrace(
"CSCCathodeLCTProcessor") <<
" Final selection: ilct " << ilct <<
" " << thisLCT << std::endl;
721 lctList.push_back(thisLCT);
736 for (
unsigned int bx = latch_bx + 1;
bx < stop_time;
bx++) {
737 bool return_to_idle =
true;
744 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine busy at bx = " <<
bx;
745 return_to_idle =
false;
750 if (return_to_idle) {
752 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine returns to idle state at bx = " <<
bx;
759 start_bx = first_bx + 1;
769 static const unsigned int bits_in_pulse = 8 *
sizeof(
pulse[0][0]);
781 pulse[i_layer][i_strip] = 0;
789 std::vector<int> bx_times =
time[i_layer][i_strip];
790 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
792 if (bx_times[
i] < 0 || bx_times[
i] +
hit_persist >= bits_in_pulse) {
795 <<
"+++ BX time of comparator digi (halfstrip = " << i_strip <<
" layer = " << i_layer
796 <<
") bx = " << bx_times[
i] <<
" is not within the range (0-" << bits_in_pulse
797 <<
"] allowed for pulse extension. Skip this digi! +++\n";
802 pulse[i_layer][i_strip] =
pulse[i_layer][i_strip] | (1 <<
bx);
813 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,
872 const unsigned int bx_time,
873 std::map<
int, std::map<int, CSCCLCTDigi::ComparatorContainer>>& hits_in_patterns) {
880 unsigned int layers_hit = 0;
883 if (((
pulse[i_layer][i_hstrip] >> bx_time) & 1) == 1) {
892 for (
int key_hstrip = 0; key_hstrip <
numHalfStrips_; key_hstrip++) {
894 nhits[key_hstrip] = 0;
907 hit_layer[ilayer] =
false;
912 hits_single_pattern.resize(6);
913 for (
auto&
p : hits_single_pattern) {
918 double num_pattern_hits = 0., times_sum = 0.;
919 std::multiset<int> mset_for_median;
920 mset_for_median.clear();
936 LogTrace(
"CSCCathodeLCTProcessor") <<
" In patternFinding: key_strip = " << key_hstrip <<
" pid = " << pid
937 <<
" layer = " << this_layer <<
" strip = " << this_strip << std::endl;
940 if (((
pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
941 if (hit_layer[this_layer] ==
false) {
942 hit_layer[this_layer] =
true;
945 hits_single_pattern[this_layer][strip_num] = this_strip -
stagger[this_layer];
950 int first_bx_layer = bx_time;
951 for (
unsigned int dbx = 0; dbx <
hit_persist; dbx++) {
952 if (((
pulse[this_layer][this_strip] >> (first_bx_layer - 1)) & 1) == 1)
957 times_sum += (double)first_bx_layer;
958 num_pattern_hits += 1.;
959 mset_for_median.insert(first_bx_layer);
961 LogTrace(
"CSCCathodeLCTProcessor") <<
" 1st bx in layer: " << first_bx_layer <<
" sum bx: " << times_sum
962 <<
" #pat. hits: " << num_pattern_hits;
970 hits_in_patterns[key_hstrip][pid] = hits_single_pattern;
974 if (layers_hit >
nhits[key_hstrip]) {
976 nhits[key_hstrip] = layers_hit;
979 const int sz = mset_for_median.size();
981 std::multiset<int>::iterator im = mset_for_median.begin();
983 std::advance(im, sz / 2 - 1);
986 else if ((sz % 2) == 1)
991 #if defined(EDM_ML_DEBUG)
994 auto lt =
LogTrace(
"CSCCathodeLCTProcessor")
996 for (im = mset_for_median.begin(); im != mset_for_median.end(); im++) {
1017 const int best_patid,
1022 for (
int hstrip = best_hstrip - nspan; hstrip <= best_hstrip + pspan; hstrip++) {
1031 for (
auto&
p : newHits) {
1032 p.erase(std::remove_if(
1044 std::ostringstream strm;
1046 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1047 strm <<
"+ CLCT configuration parameters: +\n";
1048 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1049 strm <<
" fifo_tbins [total number of time bins in DAQ readout] = " <<
fifo_tbins <<
"\n";
1050 strm <<
" fifo_pretrig [start time of cathode raw hits in DAQ readout] = " <<
fifo_pretrig <<
"\n";
1051 strm <<
" hit_persist [duration of signal pulse, in 25 ns bins] = " <<
hit_persist <<
"\n";
1052 strm <<
" drift_delay [time after pre-trigger before TMB latches LCTs] = " <<
drift_delay <<
"\n";
1053 strm <<
" nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = " <<
nplanes_hit_pretrig <<
"\n";
1054 strm <<
" nplanes_hit_pattern [min. number of layers hit for trigger] = " <<
nplanes_hit_pattern <<
"\n";
1055 strm <<
" pid_thresh_pretrig [lower threshold on pattern id] = " <<
pid_thresh_pretrig <<
"\n";
1056 strm <<
" min_separation [region of busy key strips] = " <<
min_separation <<
"\n";
1057 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1058 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1066 std::ostringstream strstrm;
1068 if (i_strip % 10 == 0) {
1070 strstrm << i_strip / 10;
1072 strstrm << (i_strip - 100) / 10;
1080 strstrm << i_strip % 10;
1088 std::vector<int> bx_times =
strip[i_layer][i_strip];
1090 strstrm << std::hex << bx_times[0] <<
std::dec;
1098 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
1104 std::vector<CSCCLCTDigi> tmpV;
1116 static std::atomic<int> lct_bins;
1118 static std::atomic<int> late_tbins;
1121 static std::atomic<int> ifois{0};
1125 <<
"+++ early_tbins = " <<
early_tbins <<
"; in-time CLCTs are not getting read-out!!! +++"
1132 <<
"+++ Allowed range of time bins, [0-" << late_tbins <<
"] exceeds max allowed, "
1134 <<
"+++ Set late_tbins to max allowed +++\n";
1142 int bx_readout = -1;
1143 const std::vector<CSCCLCTDigi>& all_lcts =
getCLCTs(nMaxCLCTs);
1144 for (
const auto&
p : all_lcts) {
1149 const int bx =
p.getBX();
1154 <<
" Do not report CLCT on key halfstrip " <<
p.getKeyStrip() <<
": found at bx " <<
bx
1155 <<
", whereas the earliest allowed bx is " <<
early_tbins + 1;
1160 if (
bx > late_tbins) {
1163 <<
" Do not report CLCT on key halfstrip " <<
p.getKeyStrip() <<
": found at bx " <<
bx
1164 <<
", whereas the latest allowed bx is " << late_tbins;
1172 if (bx_readout == -1 ||
bx == bx_readout) {
1174 if (bx_readout == -1)
1183 for (
const auto& clct : tmpV) {
1193 std::vector<CSCCLCTDigi> tmpV;
1196 const std::vector<CSCCLCTDigi>& allCLCTs =
readoutCLCTs(nMaxCLCTs);
1197 for (
const auto& clct : allCLCTs)
1198 if (clct.getCFEB() >= 4)
1199 tmpV.push_back(clct);
1206 std::vector<CSCCLCTDigi> tmpV;
1209 const std::vector<CSCCLCTDigi>& allCLCTs =
readoutCLCTs(nMaxCLCTs);
1210 for (
const auto& clct : allCLCTs)
1211 if (clct.getCFEB() < 4)
1212 tmpV.push_back(clct);
1217 std::vector<CSCCLCTPreTriggerDigi> tmpV;
1220 const std::vector<CSCCLCTPreTriggerDigi>& allPretriggerdigis =
preTriggerDigis();
1221 for (
const auto& preclct : allPretriggerdigis)
1222 if (preclct.getCFEB() >= 4)
1223 tmpV.push_back(preclct);
1228 std::vector<CSCCLCTPreTriggerDigi> tmpV;
1231 const std::vector<CSCCLCTPreTriggerDigi>& allPretriggerdigis =
preTriggerDigis();
1232 for (
const auto& preclct : allPretriggerdigis)
1233 if (preclct.getCFEB() < 4)
1234 tmpV.push_back(preclct);
1240 std::vector<CSCCLCTDigi> tmpV;
1277 for (
int row = 2; row >= 0; row--) {
1278 rowPat = rowPat << 1;
1279 rowPat += halfStripPattern[column][row];
1299 id += (rowCode << 2 * column);
1305 std::tuple<int16_t, bool, bool>& returnValue)
const {
1326 std::vector<std::tuple<int16_t, bool, bool>> my_tuple = {
1344 returnValue = my_tuple[
offset];
1350 std::ostringstream strm;
1352 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1353 strm <<
"+ Before CCCLUT algorithm: +\n";
1354 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1355 strm <<
" Old CLCT digi " << digi <<
"\n";
1356 strm <<
" 1/4 strip bit " << digi.
getQuartStrip() <<
" 1/8 strip bit " << digi.getEighthStrip() <<
"\n";
1357 strm <<
" 1/4 strip number " << digi.getKeyStrip(4) <<
" 1/8 strip number " << digi.getKeyStrip(8) <<
"\n";
1358 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1359 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1366 auto compHits = digi.
getHits();
1377 compHitsCC[
i][iCC] = 1;
1379 compHitsCC[
i][iCC] = 0;
1399 const unsigned positionCC(
lutpos_[
pattern]->lookup(comparatorCode));
1404 const bool slopeCCSign((slopeCC >> 4) & 0
x1);
1405 const unsigned slopeCCValue(slopeCC & 0xf);
1410 std::tuple<int16_t, bool, bool> stripoffset;
1412 const int halfstripoffset = std::get<0>(stripoffset);
1413 halfstrip += halfstripoffset;
1419 if (digi.
getStrip() == 0 and halfstripoffset <= -1 and digi.
getCFEB() > 0) {
1443 std::ostringstream strm;
1445 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1446 strm <<
"+ CCCLUT algorithm results: +\n";
1447 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1448 strm <<
" New CLCT digi " << digi <<
"\n";
1449 strm <<
" 1/4 strip bit " << digi.
getQuartStrip() <<
" 1/8 strip bit " << digi.getEighthStrip() <<
"\n";
1450 strm <<
" 1/4 strip number " << digi.getKeyStrip(4) <<
" 1/8 strip number " << digi.getKeyStrip(8) <<
"\n";
1451 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1452 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1457 const unsigned slopeList[32] = {10, 10, 10, 8, 8, 8, 6, 6, 6, 6, 4, 4, 2, 2, 2, 2,
1458 10, 10, 10, 9, 9, 9, 7, 7, 7, 7, 5, 5, 3, 3, 3, 3};
1459 return slopeList[
slope];