29 static std::atomic<bool> config_dumped{
false};
67 if ((
infoV > 0) && !config_dumped) {
75 if ((i_layer + 1) % 2 == 0)
93 static std::atomic<bool> config_dumped{
false};
105 if (!config_dumped) {
107 config_dumped =
true;
113 if ((i_layer + 1) % 2 == 0)
137 static std::atomic<bool> config_dumped{
false};
150 if (!config_dumped) {
152 config_dumped =
true;
160 static const unsigned int max_fifo_tbins = 1 << 5;
161 static const unsigned int max_fifo_pretrig = 1 << 5;
162 static const unsigned int max_hit_persist = 1 << 4;
163 static const unsigned int max_drift_delay = 1 << 2;
164 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
165 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
166 static const unsigned int max_pid_thresh_pretrig = 1 << 4;
168 static const unsigned int max_tmb_l1a_window_size = 1 << 4;
200 static std::atomic<bool> config_dumped{
false};
201 if ((
infoV > 0) && !config_dumped) {
203 config_dumped =
true;
220 <<
"+++ Invalid ring number for this processor " <<
theRing <<
" was set in the config."
222 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
237 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
260 <<
" is not defined in current geometry! +++\n"
261 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
270 <<
" numStrips = " <<
numStrips <<
"; CLCT emulation skipped! +++";
271 std::vector<CSCCLCTDigi> emptyV;
289 unsigned int layersHit = 0;
292 if (!halfstrip[i_layer][i_hstrip].
empty()) {
306 std::vector<CSCCLCTDigi> tmpV =
getCLCTs();
315 for (
auto&
p : tmpV) {
329 std::vector<CSCCLCTDigi> CLCTlist =
findLCTs(halfstrip);
332 if (CLCTlist.size() > 1)
333 sort(CLCTlist.begin(), CLCTlist.end(), std::greater<CSCCLCTDigi>());
335 for (
const auto&
p : CLCTlist) {
336 const int bx =
p.getBX();
341 <<
"; skipping it... +++\n";
387 digiV[i_layer].clear();
400 LogTrace(
"CSCCathodeLCTProcessor") <<
"found " <<
digiV[i_layer].size() <<
" comparator digi(s) in layer "
411 const bool me1a = (
id.station() == 1) && (
id.
ring() == 4);
414 const unsigned int origStrip = digiIt->getStrip();
415 const unsigned int maxStripsME1a =
419 if (me1a && origStrip <= maxStripsME1a && !
disableME1a_) {
424 digiV[
id.layer() - 1].push_back(digi_corr);
426 digiV[
id.layer() - 1].push_back(*digiIt);
435 for (std::vector<CSCComparatorDigi>::iterator pld =
digiV[i_layer].
begin(); pld !=
digiV[i_layer].end();
439 std::ostringstream strstrm;
440 strstrm <<
"Comparator digi: comparator = " << pld->getComparator() <<
" strip #" << pld->getStrip()
442 std::vector<int> bx_times = pld->getTimeBinsOn();
443 for (
unsigned int tbin = 0; tbin < bx_times.size(); tbin++)
444 strstrm <<
" " << bx_times[tbin];
445 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
450 int thisComparator = pld->getComparator();
451 if (thisComparator != 0 && thisComparator != 1) {
455 <<
" Found comparator digi with wrong comparator value = " << thisComparator <<
"; skipping it... +++\n";
460 int thisStrip = pld->getStrip() - 1;
461 if (thisStrip < 0 || thisStrip >=
numStrips) {
465 <<
" Found comparator digi with wrong strip number = " << thisStrip <<
" (max strips = " <<
numStrips
466 <<
"); skipping it... +++\n";
472 int thisHalfstrip = 2 * thisStrip + thisComparator +
stagger[i_layer];
473 if (thisHalfstrip >= 2 *
numStrips + 1) {
477 <<
" Found wrong halfstrip number = " << thisHalfstrip <<
"; skipping this digi... +++\n";
482 std::vector<int> bx_times = pld->getTimeBinsOn();
483 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
493 if (bx_times[
i] > 1 && bx_times[
i] < static_cast<int>(
fifo_tbins)) {
494 if (
i == 0 || (
i > 0 && bx_times[
i] - bx_times[
i - 1] >= static_cast<int>(
hit_persist))) {
500 <<
"Comp digi: layer " << i_layer + 1 <<
" digi #" << i_digi + 1 <<
" strip " << thisStrip
501 <<
" halfstrip " << thisHalfstrip <<
" time " << bx_times[
i] <<
" comparator " << thisComparator
502 <<
" stagger " <<
stagger[i_layer];
503 halfstrip[i_layer][thisHalfstrip].push_back(bx_times[
i]);
508 <<
" Skipping comparator digi: strip = " << thisStrip <<
", layer = " << i_layer + 1
509 <<
", bx = " << bx_times[
i] <<
", bx of previous hit = " << bx_times[
i - 1];
514 <<
theChamber <<
"+++ Skipping comparator digi: strip = " << thisStrip
515 <<
", layer = " << i_layer + 1 <<
", bx = " << bx_times[
i] <<
" +++";
525 std::vector<CSCCLCTDigi> lctList;
528 const int maxHalfStrips = 2 *
numStrips + 1;
545 while (start_bx < stop_bx) {
556 LogTrace(
"CSCCathodeLCTProcessor") <<
"..... pretrigger at bx = " << first_bx <<
"; waiting drift delay .....";
567 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
568 hits_in_patterns.clear();
576 if (
nhits[hstrip] > 0) {
578 <<
" bx = " << std::setw(2) << latch_bx <<
" --->"
579 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
580 <<
" nhits = " <<
nhits[hstrip];
598 best_halfstrip[ilct] = -1;
599 best_quality[ilct] = 0;
609 if (
quality[hstrip] > best_quality[0]) {
610 best_halfstrip[0] = hstrip;
611 best_quality[0] =
quality[hstrip];
615 <<
" 1st CLCT: halfstrip = " << std::setw(3) << hstrip <<
" quality = " << std::setw(3)
616 <<
quality[hstrip] <<
" nhits = " << std::setw(3) <<
nhits[hstrip] <<
" pid = " << std::setw(3)
617 <<
best_pid[hstrip] <<
" best halfstrip = " << std::setw(3) << best_halfstrip[0]
618 <<
" best quality = " << std::setw(3) << best_quality[0];
624 if (best_halfstrip[0] >= 0) {
630 if (
quality[hstrip] > best_quality[1]) {
631 best_halfstrip[1] = hstrip;
632 best_quality[1] =
quality[hstrip];
636 <<
" 2nd 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[1]
639 <<
" best quality = " << std::setw(3) << best_quality[1];
645 int best_hs = best_halfstrip[ilct];
652 keystrip_data[ilct][
CLCT_BX] = first_bx;
656 int halfstrip_in_cfeb = keystrip_data[ilct][
CLCT_STRIP] -
661 <<
" Final selection: ilct " << ilct <<
" key halfstrip " << keystrip_data[ilct][
CLCT_STRIP]
662 <<
" quality " << keystrip_data[ilct][
CLCT_QUALITY] <<
" pattern "
675 auto compHits = hits_in_patterns[best_hs][keystrip_data[ilct][
CLCT_PATTERN]];
685 LogTrace(
"CSCCathodeLCTProcessor") <<
" Final selection: ilct " << ilct <<
" " << thisLCT << std::endl;
689 lctList.push_back(thisLCT);
704 for (
unsigned int bx = latch_bx + 1;
bx < stop_time;
bx++) {
705 bool return_to_idle =
true;
712 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine busy at bx = " <<
bx;
713 return_to_idle =
false;
718 if (return_to_idle) {
720 LogTrace(
"CSCCathodeLCTProcessor") <<
" State machine returns to idle state at bx = " <<
bx;
727 start_bx = first_bx + 1;
739 static const unsigned int bits_in_pulse = 8 *
sizeof(
pulse[0][0]);
750 for (
int i_strip = 0; i_strip <
nStrips; i_strip++)
751 pulse[i_layer][i_strip] = 0;
755 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
759 std::vector<int> bx_times =
time[i_layer][i_strip];
760 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
762 if (bx_times[
i] < 0 || bx_times[
i] +
hit_persist >= bits_in_pulse) {
765 <<
"+++ BX time of comparator digi (halfstrip = " << i_strip <<
" layer = " << i_layer
766 <<
") bx = " << bx_times[
i] <<
" is not within the range (0-" << bits_in_pulse
767 <<
"] allowed for pulse extension. Skip this digi! +++\n";
772 pulse[i_layer][i_strip] =
pulse[i_layer][i_strip] | (1 <<
bx);
783 LogTrace(
"CSCCathodeLCTProcessor") <<
"....................PreTrigger...........................";
788 int nPreTriggers = 0;
790 bool pre_trig =
false;
792 for (
unsigned int bx_time = start_bx; bx_time <
fifo_tbins; bx_time++) {
799 std::map<int, std::map<int, CSCCLCTDigi::ComparatorContainer>> hits_in_patterns;
800 hits_in_patterns.clear();
806 if (
nhits[hstrip] > 0) {
808 <<
" bx = " << std::setw(2) << bx_time <<
" --->"
809 <<
" halfstrip = " << std::setw(3) << hstrip <<
" best pid = " << std::setw(2) <<
best_pid[hstrip]
810 <<
" nhits = " <<
nhits[hstrip];
825 1,
nhits[hstrip],
best_pid[hstrip], 1,
bend, halfstrip, cfeb, bx_time, nPreTriggers, 0));
837 LogTrace(
"CSCCathodeLCTProcessor") <<
"no pretrigger, returning \n";
844 const PulseArray
pulse,
846 const unsigned int bx_time,
847 std::map<
int, std::map<int, CSCCLCTDigi::ComparatorContainer>>& hits_in_patterns) {
854 unsigned int layers_hit = 0;
856 for (
int i_hstrip = 0; i_hstrip <
nStrips; i_hstrip++) {
857 if (((
pulse[i_layer][i_hstrip] >> bx_time) & 1) == 1) {
866 for (
int key_hstrip = 0; key_hstrip <
nStrips; key_hstrip++) {
868 nhits[key_hstrip] = 0;
881 hit_layer[ilayer] =
false;
886 hits_single_pattern.resize(6);
887 for (
auto&
p : hits_single_pattern) {
892 double num_pattern_hits = 0., times_sum = 0.;
893 std::multiset<int> mset_for_median;
894 mset_for_median.clear();
908 if (this_strip >= 0 && this_strip <
nStrips) {
910 LogTrace(
"CSCCathodeLCTProcessor") <<
" In patternFinding: key_strip = " << key_hstrip <<
" pid = " << pid
911 <<
" layer = " << this_layer <<
" strip = " << this_strip << std::endl;
914 if (((
pulse[this_layer][this_strip] >> bx_time) & 1) == 1) {
915 if (hit_layer[this_layer] ==
false) {
916 hit_layer[this_layer] =
true;
919 hits_single_pattern[this_layer][strip_num] = this_strip -
stagger[this_layer];
924 int first_bx_layer = bx_time;
925 for (
unsigned int dbx = 0; dbx <
hit_persist; dbx++) {
926 if (((
pulse[this_layer][this_strip] >> (first_bx_layer - 1)) & 1) == 1)
931 times_sum += (double)first_bx_layer;
932 num_pattern_hits += 1.;
933 mset_for_median.insert(first_bx_layer);
935 LogTrace(
"CSCCathodeLCTProcessor") <<
" 1st bx in layer: " << first_bx_layer <<
" sum bx: " << times_sum
936 <<
" #pat. hits: " << num_pattern_hits;
944 hits_in_patterns[key_hstrip][pid] = hits_single_pattern;
948 if (layers_hit >
nhits[key_hstrip]) {
950 nhits[key_hstrip] = layers_hit;
953 const int sz = mset_for_median.size();
955 std::multiset<int>::iterator im = mset_for_median.begin();
957 std::advance(im, sz / 2 - 1);
960 else if ((sz % 2) == 1)
965 #if defined(EDM_ML_DEBUG)
968 auto lt =
LogTrace(
"CSCCathodeLCTProcessor")
970 for (im = mset_for_median.begin(); im != mset_for_median.end(); im++) {
991 const int best_patid,
996 for (
int hstrip = best_hstrip - nspan; hstrip <= best_hstrip + pspan; hstrip++) {
1004 for (
auto&
p : compHits) {
1005 p.erase(std::remove_if(
1016 std::ostringstream strm;
1018 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1019 strm <<
"+ CLCT configuration parameters: +\n";
1020 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1021 strm <<
" fifo_tbins [total number of time bins in DAQ readout] = " <<
fifo_tbins <<
"\n";
1022 strm <<
" fifo_pretrig [start time of cathode raw hits in DAQ readout] = " <<
fifo_pretrig <<
"\n";
1023 strm <<
" hit_persist [duration of signal pulse, in 25 ns bins] = " <<
hit_persist <<
"\n";
1024 strm <<
" drift_delay [time after pre-trigger before TMB latches LCTs] = " <<
drift_delay <<
"\n";
1025 strm <<
" nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = " <<
nplanes_hit_pretrig <<
"\n";
1026 strm <<
" nplanes_hit_pattern [min. number of layers hit for trigger] = " <<
nplanes_hit_pattern <<
"\n";
1027 strm <<
" pid_thresh_pretrig [lower threshold on pattern id] = " <<
pid_thresh_pretrig <<
"\n";
1028 strm <<
" min_separation [region of busy key strips] = " <<
min_separation <<
"\n";
1029 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1030 LogDebug(
"CSCCathodeLCTProcessor") << strm.str();
1039 std::ostringstream strstrm;
1040 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
1041 if (i_strip % 10 == 0) {
1043 strstrm << i_strip / 10;
1045 strstrm << (i_strip - 100) / 10;
1052 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
1053 strstrm << i_strip % 10;
1059 for (
int i_strip = 0; i_strip <
nStrips; i_strip++) {
1061 std::vector<int> bx_times =
strip[i_layer][i_strip];
1063 strstrm << std::hex << bx_times[0] <<
std::dec;
1071 LogTrace(
"CSCCathodeLCTProcessor") << strstrm.str();
1084 edm::LogError(
"CSCCathodeLCTProcessor") <<
"CSCLCTDigi with invalid bit set: " << clct.
isValid();
1091 <<
"CSCLCTDigi with invalid track number: " << clct.
getTrknmb() <<
"; allowed [1," << max_stubs <<
"]";
1101 <<
"CSCLCTDigi with invalid quality: " << clct.
getQuality() <<
"; allowed [0," << max_quality <<
"]";
1108 edm::LogError(
"CSCCathodeLCTProcessor") <<
"CSCLCTDigi with invalid half-strip: " << clct.
getStrip()
1116 <<
"CSCLCTDigi with invalid key half-strip: " << clct.
getKeyStrip() <<
"; allowed [0, " << max_strip - 1 <<
"]";
1122 edm::LogError(
"CSCCathodeLCTProcessor") <<
"CSCLCTDigi with invalid BX: " << clct.
getBX() <<
"; allowed [0, "
1130 <<
"CSCLCTDigi with invalid bending: " << clct.
getBend() <<
"; allowed [0,1]";
1137 <<
"; allowed [" << min_pattern <<
", " << max_pattern <<
"]";
1143 edm::LogError(
"CSCCathodeLCTProcessor") <<
"CSCLCTDigi with invalid CFEB ID: " << clct.
getCFEB() <<
"; allowed ["
1144 << min_cfeb <<
", " << max_cfeb <<
"]";
1152 <<
"; allowed [0, " <<
std::pow(2, 12) - 1 <<
"]";
1162 <<
"; allowed [0, " << max_quartstrip - 1 <<
"]";
1169 <<
"; allowed [0, " << max_eightstrip - 1 <<
"]";
1182 std::vector<CSCCLCTDigi> tmpV;
1194 static std::atomic<int> lct_bins;
1196 static std::atomic<int> late_tbins;
1199 static std::atomic<int> ifois{0};
1203 <<
"+++ early_tbins = " <<
early_tbins <<
"; in-time CLCTs are not getting read-out!!! +++"
1210 <<
"+++ Allowed range of time bins, [0-" << late_tbins <<
"] exceeds max allowed, "
1212 <<
"+++ Set late_tbins to max allowed +++\n";
1220 int bx_readout = -1;
1221 const std::vector<CSCCLCTDigi>& all_lcts =
getCLCTs(nMaxCLCTs);
1222 for (
const auto&
p : all_lcts) {
1227 const int bx =
p.getBX();
1232 <<
" Do not report CLCT on key halfstrip " <<
p.getKeyStrip() <<
": found at bx " <<
bx
1233 <<
", whereas the earliest allowed bx is " <<
early_tbins + 1;
1238 if (
bx > late_tbins) {
1241 <<
" Do not report CLCT on key halfstrip " <<
p.getKeyStrip() <<
": found at bx " <<
bx
1242 <<
", whereas the latest allowed bx is " << late_tbins;
1250 if (bx_readout == -1 ||
bx == bx_readout) {
1252 if (bx_readout == -1)
1260 for (
const auto& clct : tmpV) {
1270 std::vector<CSCCLCTDigi> tmpV;
1273 const std::vector<CSCCLCTDigi>& allCLCTs =
readoutCLCTs(nMaxCLCTs);
1274 for (
const auto& clct : allCLCTs)
1275 if (clct.getCFEB() >= 4)
1276 tmpV.push_back(clct);
1283 std::vector<CSCCLCTDigi> tmpV;
1286 const std::vector<CSCCLCTDigi>& allCLCTs =
readoutCLCTs(nMaxCLCTs);
1287 for (
const auto& clct : allCLCTs)
1288 if (clct.getCFEB() < 4)
1289 tmpV.push_back(clct);
1294 std::vector<CSCCLCTPreTriggerDigi> tmpV;
1297 const std::vector<CSCCLCTPreTriggerDigi>& allPretriggerdigis =
preTriggerDigis();
1298 for (
const auto& preclct : allPretriggerdigis)
1299 if (preclct.getCFEB() >= 4)
1300 tmpV.push_back(preclct);
1305 std::vector<CSCCLCTPreTriggerDigi> tmpV;
1308 const std::vector<CSCCLCTPreTriggerDigi>& allPretriggerdigis =
preTriggerDigis();
1309 for (
const auto& preclct : allPretriggerdigis)
1310 if (preclct.getCFEB() < 4)
1311 tmpV.push_back(preclct);
1317 std::vector<CSCCLCTDigi> tmpV;