28 static std::atomic<bool> config_dumped{
false};
73 if ((
infoV > 0) && !config_dumped) {
81 if ((i_layer + 1) % 2 == 0)
91 cclut_ = std::make_unique<ComparatorCodeLUT>(conf);
97 thresholds_ = shower.getParameter<std::vector<unsigned>>(
"showerThresholds");
124 static std::atomic<bool> config_dumped{
false};
137 if (!config_dumped) {
139 config_dumped =
true;
147 static const unsigned int max_fifo_tbins = 1 << 5;
148 static const unsigned int max_fifo_pretrig = 1 << 5;
149 static const unsigned int max_hit_persist = 1 << 4;
150 static const unsigned int max_drift_delay = 1 << 2;
151 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
152 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
153 static const unsigned int max_pid_thresh_pretrig = 1 << 4;
155 static const unsigned int max_tmb_l1a_window_size = 1 << 4;
189 static std::atomic<bool> config_dumped{
false};
190 if ((
infoV > 0) && !config_dumped) {
192 config_dumped =
true;
210 <<
"+++ Invalid ring number for this processor " <<
theRing <<
" was set in the config."
212 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
230 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
255 <<
" is not defined in current geometry! +++\n"
256 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
267 <<
" numStrips_ = " <<
numStrips_ <<
"; CLCT emulation skipped! +++";
268 std::vector<CSCCLCTDigi> emptyV;
286 unsigned int layersHit = 0;
289 if (!halfStripTimes[i_layer][i_hstrip].
empty()) {
306 std::vector<CSCCLCTDigi> tmpV =
getCLCTs();
315 for (
auto&
p : tmpV) {
334 std::vector<CSCCLCTDigi> CLCTlist =
findLCTs(halfstrip);
337 if (CLCTlist.size() > 1)
338 sort(CLCTlist.begin(), CLCTlist.end(), std::greater<CSCCLCTDigi>());
340 for (
const auto&
p : CLCTlist) {
341 const int bx =
p.getBX();
346 <<
"; skipping it... +++\n";
388 bool hasDigis =
false;
392 digiV[i_layer].clear();
405 LogTrace(
"CSCCathodeLCTProcessor") <<
"found " <<
digiV[i_layer].size() <<
" comparator digi(s) in layer "
416 const bool me1a = (
id.station() == 1) && (
id.
ring() == 4);
419 const unsigned int origStrip = digiIt->getStrip();
420 const unsigned int maxStripsME1a =
424 if (me1a && origStrip <= maxStripsME1a && !
disableME1a_) {
429 digiV[
id.layer() - 1].push_back(digi_corr);
431 digiV[
id.layer() - 1].push_back(*digiIt);
440 for (std::vector<CSCComparatorDigi>::iterator pld =
digiV[i_layer].begin(); pld !=
digiV[i_layer].end();
444 std::ostringstream strstrm;
445 strstrm <<
"Comparator digi: comparator = " << pld->getComparator() <<
" strip #" << pld->getStrip()
447 std::vector<int> bx_times = pld->getTimeBinsOn();
448 for (
unsigned int tbin = 0; tbin < bx_times.size(); tbin++)
449 strstrm <<
" " << bx_times[tbin];
450 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
455 int thisComparator = pld->getComparator();
456 if (thisComparator != 0 && thisComparator != 1) {
460 <<
" Found comparator digi with wrong comparator value = " << thisComparator <<
"; skipping it... +++\n";
465 int thisStrip = pld->getStrip() - 1;
466 if (thisStrip < 0 || thisStrip >=
numStrips_) {
470 <<
" Found comparator digi with wrong strip number = " << thisStrip <<
" (max strips = " <<
numStrips_
471 <<
"); skipping it... +++\n";
477 int thisHalfstrip = 2 * thisStrip + thisComparator +
stagger[i_layer];
482 <<
" Found wrong halfstrip number = " << thisHalfstrip <<
"; skipping this digi... +++\n";
487 std::vector<int> bx_times = pld->getTimeBinsOn();
488 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
498 if (bx_times[
i] > 1 && bx_times[
i] < static_cast<int>(
fifo_tbins)) {
499 if (
i == 0 || (
i > 0 && bx_times[
i] - bx_times[
i - 1] >= static_cast<int>(
hit_persist))) {
505 <<
"Comp digi: layer " << i_layer + 1 <<
" digi #" << i_digi + 1 <<
" strip " << thisStrip
506 <<
" halfstrip " << thisHalfstrip <<
" time " << bx_times[
i] <<
" comparator " << thisComparator
507 <<
" stagger " <<
stagger[i_layer];
508 halfstrip[i_layer][thisHalfstrip].push_back(bx_times[
i]);
513 <<
" Skipping comparator digi: strip = " << thisStrip <<
", layer = " << i_layer + 1
514 <<
", bx = " << bx_times[
i] <<
", bx of previous hit = " << bx_times[
i - 1];
519 <<
theChamber <<
"+++ Skipping comparator digi: strip = " << thisStrip
520 <<
", layer = " << i_layer + 1 <<
", bx = " << bx_times[
i] <<
" +++";
530 std::vector<CSCCLCTDigi> lctList;
543 while (start_bx < stop_bx) {
551 bool pre_trig =
preTrigger(start_bx, first_bx);
558 LogTrace(
"CSCCathodeLCTProcessor") <<
"..... pretrigger at bx = " << first_bx <<
"; waiting drift delay .....";
569 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
570 hits_in_patterns.clear();
578 if (
nhits[hstrip] > 0) {
580 <<
" bx = " << std::setw(2) << latch_bx <<
" --->"
581 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
582 <<
" nhits = " <<
nhits[hstrip];
600 best_halfstrip[ilct] = -1;
601 best_quality[ilct] = 0;
611 if (
quality[hstrip] > best_quality[0]) {
612 best_halfstrip[0] = hstrip;
613 best_quality[0] =
quality[hstrip];
616 const int best_hs(best_halfstrip[0]);
617 const int best_pat(
best_pid[best_hs]);
621 tempBestCLCT =
constructCLCT(first_bx, best_hs, hits_in_patterns[best_hs][best_pat]);
627 if (best_halfstrip[0] >= 0) {
638 if (
quality[hstrip] > best_quality[1]) {
639 best_halfstrip[1] = hstrip;
640 best_quality[1] =
quality[hstrip];
643 const int best_hs(best_halfstrip[1]);
644 const int best_pat(
best_pid[best_hs]);
648 tempSecondCLCT =
constructCLCT(first_bx, best_hs, hits_in_patterns[best_hs][best_pat]);
653 lctList.push_back(tempBestCLCT);
655 if (tempSecondCLCT.
isValid()) {
656 lctList.push_back(tempSecondCLCT);
670 for (
unsigned int bx = latch_bx + 1;
bx < stop_time;
bx++) {
671 bool return_to_idle =
true;
678 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine busy at bx = " <<
bx;
679 return_to_idle =
false;
684 if (return_to_idle) {
686 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine returns to idle state at bx = " <<
bx;
693 start_bx = first_bx + 1;
721 std::vector<int> bx_times =
time[i_layer][i_strip];
722 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
724 if (bx_times[
i] < 0 || bx_times[
i] +
hit_persist >= bits_in_pulse) {
727 <<
"+++ BX time of comparator digi (halfstrip = " << i_strip <<
" layer = " << i_layer
728 <<
") bx = " << bx_times[
i] <<
" is not within the range (0-" << bits_in_pulse
729 <<
"] allowed for pulse extension. Skip this digi! +++\n";
744 LogTrace(
"CSCCathodeLCTProcessor") <<
"....................PreTrigger...........................";
746 int nPreTriggers = 0;
748 bool pre_trig =
false;
750 for (
unsigned int bx_time = start_bx; bx_time <
fifo_tbins; bx_time++) {
757 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
758 hits_in_patterns.clear();
768 if (
nhits[hstrip] > 0) {
770 <<
" bx = " << std::setw(2) << bx_time <<
" --->"
771 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
772 <<
" nhits = " <<
nhits[hstrip];
795 LogTrace(
"CSCCathodeLCTProcessor") <<
"no pretrigger, returning \n";
802 const unsigned int bx_time,
std::map<
int, std::map<int, CSCCLCTDigi::ComparatorContainer>>& hits_in_patterns) {
810 for (
int key_hstrip = 0; key_hstrip <
numHalfStrips_; key_hstrip++) {
812 nhits[key_hstrip] = 0;
824 hit_layer[ilayer] =
false;
829 hits_single_pattern.resize(6);
830 for (
auto&
p : hits_single_pattern) {
835 double num_pattern_hits = 0., times_sum = 0.;
836 std::multiset<int> mset_for_median;
837 mset_for_median.clear();
853 LogTrace(
"CSCCathodeLCTProcessor") <<
" In patternFinding: key_strip = " << key_hstrip <<
" pid = " << pid
854 <<
" layer = " << this_layer <<
" strip = " << this_strip << std::endl;
858 if (hit_layer[this_layer] ==
false) {
859 hit_layer[this_layer] =
true;
862 hits_single_pattern[this_layer][strip_num] = this_strip -
stagger[this_layer];
867 int first_bx_layer = bx_time;
868 for (
unsigned int dbx = 0; dbx <
hit_persist; dbx++) {
874 times_sum += (double)first_bx_layer;
875 num_pattern_hits += 1.;
876 mset_for_median.insert(first_bx_layer);
878 LogTrace(
"CSCCathodeLCTProcessor") <<
" 1st bx in layer: " << first_bx_layer <<
" sum bx: " << times_sum
879 <<
" #pat. hits: " << num_pattern_hits;
887 hits_in_patterns[key_hstrip][pid] = hits_single_pattern;
891 if (layers_hit >
nhits[key_hstrip]) {
893 nhits[key_hstrip] = layers_hit;
909 const int best_patid,
914 for (
int hstrip = best_hstrip - nspan; hstrip <= best_hstrip + pspan; hstrip++) {
922 const unsigned halfstrip_withstagger,
959 LogTrace(
"CSCCathodeLCTProcessor") <<
"Produce CLCT " << clct << std::endl;
966 const unsigned hstrip,
967 const unsigned nPreTriggers)
const {
982 for (
auto&
p : newHits) {
995 std::ostringstream strm;
997 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
998 strm <<
"+ CLCT configuration parameters: +\n";
999 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1000 strm <<
" fifo_tbins [total number of time bins in DAQ readout] = " <<
fifo_tbins <<
"\n";
1001 strm <<
" fifo_pretrig [start time of cathode raw hits in DAQ readout] = " <<
fifo_pretrig <<
"\n";
1002 strm <<
" hit_persist [duration of signal pulse, in 25 ns bins] = " <<
hit_persist <<
"\n";
1003 strm <<
" drift_delay [time after pre-trigger before TMB latches LCTs] = " <<
drift_delay <<
"\n";
1004 strm <<
" nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = " <<
nplanes_hit_pretrig <<
"\n";
1005 strm <<
" nplanes_hit_pattern [min. number of layers hit for trigger] = " <<
nplanes_hit_pattern <<
"\n";
1006 strm <<
" pid_thresh_pretrig [lower threshold on pattern id] = " <<
pid_thresh_pretrig <<
"\n";
1007 strm <<
" min_separation [region of busy key strips] = " <<
min_separation <<
"\n";
1008 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1009 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1017 std::ostringstream strstrm;
1019 if (i_strip % 10 == 0) {
1021 strstrm << i_strip / 10;
1023 strstrm << (i_strip - 100) / 10;
1031 strstrm << i_strip % 10;
1039 std::vector<int> bx_times =
strip[i_layer][i_strip];
1041 strstrm << std::hex << bx_times[0] <<
std::dec;
1049 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
1056 std::vector<CSCCLCTDigi> tmpV;
1077 bool debugTimeBins =
true;
1078 if (debugTimeBins) {
1079 if (early_tbin < 0) {
1081 <<
"Early time bin (early_tbin) smaller than minimum allowed, which is 0. set early_tbin to 0.";
1084 if (late_tbin > max_late_tbin) {
1086 <<
"Late time bin (late_tbin) larger than maximum allowed, which is " << max_late_tbin
1087 <<
". set early_tbin to max allowed";
1090 debugTimeBins =
false;
1094 const auto& all_clcts =
getCLCTs();
1098 int bx_readout = -1;
1099 for (
const auto& clct : all_clcts) {
1101 if (!clct.isValid())
1104 const int bx = clct.getBX();
1106 if (
bx < early_tbin) {
1109 <<
" Do not report correlated CLCT on key halfstrip " << clct.getStrip() <<
": found at bx " <<
bx
1110 <<
", whereas the earliest allowed bx is " << early_tbin;
1115 if (
bx > late_tbin) {
1118 <<
" Do not report correlated CLCT on key halfstrip " << clct.getStrip() <<
": found at bx " <<
bx
1119 <<
", whereas the latest allowed bx is " << late_tbin;
1127 if (bx_readout == -1 ||
bx == bx_readout) {
1128 tmpV.push_back(clct);
1129 if (bx_readout == -1)
1133 tmpV.push_back(clct);
1138 for (
const auto& clct : tmpV) {
1147 std::vector<CSCCLCTDigi> tmpV;
1184 unsigned hitsInTime = 0;
1185 unsigned hitsOutTime = 0;
1188 auto times = halfstrip[i_layer][i_hstrip];
1189 hitsInTime += std::count_if(times.begin(), times.end(), inTime);
1190 hitsOutTime += std::count_if(times.begin(), times.end(), outTime);
1199 std::vector<unsigned> station_thresholds = {
1203 for (
unsigned i = 0;
i < station_thresholds.size();
i++) {
1204 if (hitsInTime >= station_thresholds[
i]) {
1207 if (hitsOutTime >= station_thresholds[
i]) {