28 static std::atomic<bool> config_dumped{
false};
87 static std::atomic<bool> config_dumped{
false};
100 config_dumped =
true;
137 static std::atomic<bool> config_dumped{
false};
152 if (!config_dumped) {
155 config_dumped =
true;
163 static const unsigned int max_fifo_tbins = 1 << 5;
164 static const unsigned int max_fifo_pretrig = 1 << 5;
165 static const unsigned int max_drift_delay = 1 << 2;
166 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
167 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
168 static const unsigned int max_nplanes_hit_accel_pretrig = 1 << 3;
169 static const unsigned int max_nplanes_hit_accel_pattern = 1 << 3;
170 static const unsigned int max_trig_mode = 1 << 2;
171 static const unsigned int max_accel_mode = 1 << 2;
183 max_nplanes_hit_accel_pretrig,
185 "nplanes_hit_accel_pretrig");
187 max_nplanes_hit_accel_pattern,
189 "nplanes_hit_accel_pattern");
214 static std::atomic<bool> config_dumped{
false};
218 config_dumped =
true;
231 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
238 <<
" is not defined in current geometry! +++\n"
239 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
248 <<
" numWireGroups = " <<
numWireGroups <<
"; ALCT emulation skipped! +++";
249 std::vector<CSCALCTDigi> emptyV;
264 const unsigned int min_layers =
269 unsigned int layersHit = 0;
272 if (!wire[i_layer][i_wire].
empty()) {
278 if (layersHit >= min_layers)
296 if (!chamber_empty) {
300 if (
unsigned(i_wire) >= max_wire)
303 unsigned int start_bx = 0;
305 while (start_bx < stop_bx) {
311 int ghost_cleared[2] = {0, 0};
321 int valid = (ghost_cleared[0] == 0) ? 1 : 0;
326 LogTrace(
"CSCAnodeLCTProcessor") <<
"Add one ALCT to list " <<
lct_list.back();
331 int valid = (ghost_cleared[1] == 0) ? 1 : 0;
337 LogTrace(
"CSCAnodeLCTProcessor") <<
"Add one ALCT to list " <<
lct_list.back();
369 digiV[i_layer].clear();
383 LogTrace(
"CSCAnodeLCTProcessor") <<
"found " <<
digiV[i_layer].size() <<
" wire digi(s) in layer " << i_layer
386 for (
const auto& wd :
digiV[i_layer]) {
387 LogTrace(
"CSCAnodeLCTProcessor") <<
" " << wd;
399 digiV[
id.layer() - 1].push_back(*digiIt);
408 for (
const auto& wd :
digiV[i_layer]) {
409 int i_wire = wd.getWireGroup() - 1;
410 std::vector<int> bx_times = wd.getTimeBinsOn();
416 <<
"+++ Found wire digi with wrong wire number = " << i_wire <<
" (max wires = " <<
numWireGroups
417 <<
"); skipping it... +++\n";
427 int last_time = -999;
429 wire[i_layer][i_wire].push_back(0);
430 wire[i_layer][i_wire].push_back(6);
432 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
434 if (
i > 0 && bx_times[
i] == (bx_times[
i - 1] + 1))
439 <<
"Digi on layer " << i_layer <<
" wire " << i_wire <<
" at time " << bx_times[
i];
444 if (last_time < 0 || ((bx_times[
i] - last_time) >= 6)) {
445 wire[i_layer][i_wire].push_back(bx_times[
i]);
446 last_time = bx_times[
i];
450 LogTrace(
"CSCAnodeLCTProcessor") <<
"+++ Skipping wire digi: wire = " << i_wire <<
" layer = " << i_layer
451 <<
", bx = " << bx_times[
i] <<
" +++";
461 bool chamber_empty =
true;
462 int i_wire, i_layer, digi_num;
463 const unsigned int bits_in_pulse = 8 *
sizeof(
pulse[0][0]);
467 pulse[i_layer][i_wire] = 0;
471 for (
int j = 0;
j < 3;
j++)
478 if (!wire[i_layer][i_wire].
empty()) {
479 std::vector<int> bx_times = wire[i_layer][i_wire];
480 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
482 if (bx_times[
i] < 0 || bx_times[
i] +
hit_persist >= bits_in_pulse) {
485 <<
"+++ BX time of wire digi (wire = " << i_wire <<
" layer = " << i_layer <<
") bx = " << bx_times[
i]
486 <<
" is not within the range (0-" << bits_in_pulse
487 <<
"] allowed for pulse extension. Skip this digi! +++\n";
493 chamber_empty =
false;
497 pulse[i_layer][i_wire] =
pulse[i_layer][i_wire] | (1 <<
bx);
501 LogTrace(
"CSCAnodeLCTProcessor") <<
"Wire digi: layer " << i_layer <<
" digi #" << ++digi_num
502 <<
" wire group " << i_wire <<
" time " << bx_times[
i];
504 std::ostringstream strstrm;
505 for (
int i = 1;
i <= 32;
i++) {
506 strstrm << ((
pulse[i_layer][i_wire] >> (32 -
i)) & 1);
508 LogTrace(
"CSCAnodeLCTProcessor") <<
" Pulse: " << strstrm.str();
516 if (
infoV > 1 && !chamber_empty) {
520 return chamber_empty;
524 int nPreTriggers = 0;
526 unsigned int layers_hit;
528 int this_layer, this_wire;
531 const unsigned int nplanes_hit_pretrig_acc =
541 for (
unsigned int bx_time = start_bx; bx_time < stop_bx; bx_time++) {
544 hit_layer[i_layer] =
false;
553 if (((
pulse[this_layer][this_wire] >> bx_time) & 1) == 1) {
555 if (hit_layer[this_layer] ==
false) {
556 hit_layer[this_layer] =
true;
562 if (layers_hit >= pretrig_thresh[i_pattern]) {
565 LogTrace(
"CSCAnodeLCTProcessor") <<
"Pretrigger was satisfied for wire: " << key_wire
566 <<
" pattern: " << i_pattern <<
" bx_time: " << bx_time;
589 unsigned int temp_quality;
590 int this_layer, this_wire, delta_wire;
593 const unsigned int nplanes_hit_pattern_acc =
597 const std::string ptn_label[] = {
"Accelerator",
"CollisionA",
"CollisionB"};
602 hit_layer[i_layer] =
false;
604 double num_pattern_hits = 0., times_sum = 0.;
605 std::multiset<int> mset_for_median;
606 mset_for_median.clear();
612 this_wire = delta_wire + key_wire;
619 if (hit_layer[this_layer] ==
false) {
622 hit_layer[this_layer] =
true;
625 <<
"bx_time: " <<
first_bx[key_wire] <<
" pattern: " << i_pattern <<
" keywire: " << key_wire
626 <<
" layer: " << this_layer <<
" quality: " << temp_quality;
630 if (
abs(delta_wire) < 2) {
634 for (
unsigned int dbx = 0; dbx <
hit_persist; dbx++) {
635 if (((
pulse[this_layer][this_wire] >> (first_bx_layer - 1)) & 1) == 1)
640 times_sum += (double)first_bx_layer;
641 num_pattern_hits += 1.;
642 mset_for_median.insert(first_bx_layer);
644 LogTrace(
"CSCAnodeLCTProcessor") <<
" 1st bx in layer: " << first_bx_layer <<
" sum bx: " << times_sum
645 <<
" #pat. hits: " << num_pattern_hits;
653 const int sz = mset_for_median.size();
655 std::multiset<int>::iterator im = mset_for_median.begin();
657 std::advance(im, sz / 2 - 1);
660 else if ((sz % 2) == 1)
665 #if defined(EDM_ML_DEBUG)
667 auto lt =
LogTrace(
"CSCAnodeLCTProcessor")
669 for (im = mset_for_median.begin(); im != mset_for_median.end(); im++) {
676 if (temp_quality >= pattern_thresh[i_pattern]) {
683 if (i_pattern == 0) {
685 quality[key_wire][0] = temp_quality;
688 if (static_cast<int>(temp_quality) >
quality[key_wire][1]) {
689 quality[key_wire][1] = temp_quality;
690 quality[key_wire][2] = i_pattern - 1;
694 LogTrace(
"CSCAnodeLCTProcessor") <<
"Pattern found; keywire: " << key_wire <<
" type: " << ptn_label[i_pattern]
695 <<
" quality: " << temp_quality <<
"\n";
701 LogTrace(
"CSCAnodeLCTProcessor") <<
"Collision Pattern A is chosen"
703 else if (
quality[key_wire][2] == 1)
704 LogTrace(
"CSCAnodeLCTProcessor") <<
"Collision Pattern B is chosen"
716 for (
int key_wire = 0; key_wire <
numWireGroups; key_wire++) {
717 for (
int i_pattern = 0; i_pattern < 2; i_pattern++) {
718 ghost_cleared[key_wire][i_pattern] = 0;
721 int qual_this =
quality[key_wire][i_pattern];
724 int qual_prev = (key_wire > 0) ?
quality[key_wire - 1][i_pattern] : 0;
734 if (qual_prev >= qual_this)
735 ghost_cleared[key_wire][i_pattern] = 1;
738 ghost_cleared[key_wire][i_pattern] = 1;
744 if (ghost_cleared[key_wire][i_pattern] == 1) {
747 << ((i_pattern == 0) ?
"Accelerator" :
"Collision") <<
" pattern ghost cancelled on key_wire "
748 << key_wire <<
" q=" << qual_this <<
" by wire " << key_wire - 1 <<
" q=" << qual_prev;
757 if (qual_next > qual_this)
758 ghost_cleared[key_wire][i_pattern] = 1;
761 ghost_cleared[key_wire][i_pattern] = 1;
764 if (ghost_cleared[key_wire][i_pattern] == 1) {
767 << ((i_pattern == 0) ?
"Accelerator" :
"Collision") <<
" pattern ghost cancelled on key_wire "
768 << key_wire <<
" q=" << qual_this <<
" by wire " << key_wire + 1 <<
" q=" << qual_next;
778 for (
int key_wire = 0; key_wire <
numWireGroups; key_wire++) {
779 for (
int i_pattern = 0; i_pattern < 2; i_pattern++) {
780 if (ghost_cleared[key_wire][i_pattern] > 0) {
781 clear(key_wire, i_pattern);
790 for (
int i_pattern = 0; i_pattern < 2; i_pattern++) {
791 ghost_cleared[i_pattern] = 0;
796 int qual_this =
quality[key_wire][i_pattern];
805 if (not(
p.getKeyWG() == key_wire - 1 and 1 -
p.getAccelerator() == i_pattern))
808 bool ghost_cleared_prev =
false;
809 int qual_prev =
p.getQuality();
810 int first_bx_prev =
p.getBX();
813 <<
"ghost concellation logic " << ((i_pattern == 0) ?
"Accelerator" :
"Collision") <<
" key_wire "
814 << key_wire <<
" quality " << qual_this <<
" bx " <<
first_bx[key_wire] <<
" previous key_wire "
815 << key_wire - 1 <<
" quality " << qual_prev <<
" bx " <<
first_bx[key_wire - 1];
826 if (qual_prev >= qual_this)
827 ghost_cleared[i_pattern] = 1;
828 else if (qual_prev < qual_this)
829 ghost_cleared_prev =
true;
832 ghost_cleared[i_pattern] = 1;
835 ghost_cleared_prev =
true;
838 if (ghost_cleared[i_pattern] == 1) {
841 << ((i_pattern == 0) ?
"Accelerator" :
"Collision") <<
" pattern ghost cancelled on key_wire "
842 << key_wire <<
" q=" << qual_this <<
" by wire " << key_wire - 1 <<
" q=" << qual_prev;
846 if (ghost_cleared_prev) {
849 << ((i_pattern == 0) ?
"Accelerator" :
"Collision") <<
" pattern ghost cancelled on key_wire "
850 << key_wire - 1 <<
" q=" << qual_prev <<
" by wire " << key_wire <<
" q=" << qual_this;
865 int n_alct_all = 0, n_alct = 0;
870 for (
const auto&
p : fourBest) {
876 <<
"C:" <<
theChamber <<
" all " << n_alct_all <<
" found " << n_alct;
881 for (
const auto&
p : fourBest) {
882 const int bx =
p.getBX();
887 <<
"; skipping it... +++\n";
936 LogTrace(
"CSCAnodeLCTProcessor") << all_alcts.size() <<
" ALCTs at the input of best-track selector: ";
937 for (
const auto&
p : all_alcts) {
946 for (
const auto&
p : all_alcts) {
958 int accel =
p.getAccelerator();
959 int qual =
p.getQuality();
960 int wire =
p.getKeyWG();
967 if (!vA || qual > qA || (qual == qA && wire > wA)) {
970 if (!vB || qual > qB || (qual == qB && wire < wB)) {
976 for (
int accel = 0; accel <= 1; accel++) {
978 if (tA[
bx][accel].isValid()) {
980 LogTrace(
"CSCAnodeLCTProcessor") <<
"tA: " << tA[
bx][accel];
981 LogTrace(
"CSCAnodeLCTProcessor") <<
"tB: " << tB[
bx][accel];
983 bestALCTs[
bx][accel] = tA[
bx][accel];
986 if (tA[
bx][accel] != tB[
bx][accel] && tA[
bx][accel].getQuality() == tB[
bx][accel].getQuality()) {
987 secondALCTs[
bx][accel] = tB[
bx][accel];
993 for (
const auto&
p : all_alcts) {
994 if (
p.isValid() &&
p.getAccelerator() == accel &&
p.getBX() ==
bx &&
997 p.getKeyWG() >= secondALCTs[
bx][accel].
getKeyWG()) {
998 secondALCTs[
bx][accel] =
p;
1007 std::vector<CSCALCTDigi> fourBest;
1010 if (bestALCTs[
bx][
i].isValid()) {
1011 fourBest.push_back(bestALCTs[
bx][
i]);
1015 if (secondALCTs[
bx][
i].isValid()) {
1016 fourBest.push_back(secondALCTs[
bx][
i]);
1022 LogTrace(
"CSCAnodeLCTProcessor") << fourBest.size() <<
" ALCTs selected: ";
1023 for (
const auto&
p : fourBest) {
1032 bool returnValue =
false;
1050 if (qual1 > qual2) {
1079 if (
quality[key_wire][1] > 0) {
1082 LogTrace(
"CSCAnodeLCTProcessor") <<
"trigMode(): collision track " << key_wire <<
" disabled"
1088 if (
quality[key_wire][0] > 0) {
1091 LogTrace(
"CSCAnodeLCTProcessor") <<
"trigMode(): accelerator track " << key_wire <<
" disabled"
1101 LogTrace(
"CSCAnodeLCTProcessor") <<
"trigMode(): collision track " << key_wire <<
" disabled"
1109 int promotionBit = 1 << 2;
1115 if (
quality[key_wire][0] > 0) {
1118 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): accelerator track " << key_wire <<
" ignored"
1124 if (
quality[key_wire][1] > 0) {
1125 quality[key_wire][1] += promotionBit;
1127 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): collision track " << key_wire <<
" promoted"
1133 if (
quality[key_wire][0] > 0) {
1134 quality[key_wire][0] += promotionBit;
1136 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): accelerator track " << key_wire <<
" promoted"
1142 if (
quality[key_wire][1] > 0) {
1145 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): collision track " << key_wire <<
" ignored"
1154 std::ostringstream strm;
1156 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1157 strm <<
"+ ALCT configuration parameters: +\n";
1158 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1159 strm <<
" fifo_tbins [total number of time bins in DAQ readout] = " <<
fifo_tbins <<
"\n";
1160 strm <<
" fifo_pretrig [start time of anode raw hits in DAQ readout] = " <<
fifo_pretrig <<
"\n";
1161 strm <<
" drift_delay [drift delay after pre-trigger, in 25 ns bins] = " <<
drift_delay <<
"\n";
1162 strm <<
" nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = " <<
nplanes_hit_pretrig <<
"\n";
1163 strm <<
" nplanes_hit_pattern [min. number of layers hit for trigger] = " <<
nplanes_hit_pattern <<
"\n";
1164 strm <<
" nplanes_hit_accel_pretrig [min. number of layers hit for accel."
1166 strm <<
" nplanes_hit_accel_pattern [min. number of layers hit for accel."
1168 strm <<
" trig_mode [enabling/disabling collision/accelerator tracks] = " <<
trig_mode <<
"\n";
1169 strm <<
" accel_mode [preference to collision/accelerator tracks] = " <<
accel_mode <<
"\n";
1170 strm <<
" l1a_window_width [L1Accept window width, in 25 ns bins] = " <<
l1a_window_width <<
"\n";
1171 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1172 LogDebug(
"CSCAnodeLCTProcessor") << strm.str();
1181 std::ostringstream strstrm;
1183 if (i_wire % 10 == 0) {
1185 strstrm << i_wire / 10;
1187 strstrm << (i_wire - 100) / 10;
1193 strstrm << i_wire % 10;
1198 if (!wire[i_layer][i_wire].
empty()) {
1199 std::vector<int> bx_times = wire[i_layer][i_wire];
1200 strstrm << std::hex << bx_times[0] <<
std::dec;
1206 LogTrace(
"CSCAnodeLCTProcessor") << strstrm.str();
1223 edm::LogError(
"CSCAnodeLCTProcessor") <<
"CSCALCTDigi with invalid bit set: " << alct.
isValid();
1230 <<
"CSCALCTDigi with invalid track number: " << alct.
getTrknmb() <<
"; allowed [1," << max_stubs <<
"]";
1238 <<
"CSCALCTDigi with invalid quality: " << alct.
getQuality() <<
"; allowed [0," << max_quality <<
"]";
1245 <<
"CSCALCTDigi with invalid wire-group: " << alct.
getKeyWG() <<
"; allowed [0, " << max_wire <<
"]";
1251 edm::LogError(
"CSCAnodeLCTProcessor") <<
"CSCALCTDigi with invalid BX: " << alct.
getBX() <<
"; allowed [0, "
1259 <<
"CSCALCTDigi with invalid accel/coll bit: " << alct.
getCollisionB() <<
"; allowed [0,1]";
1271 std::vector<CSCALCTDigi> tmpV;
1277 static std::atomic<int> late_tbins{
early_tbins + lct_bins};
1279 static std::atomic<int> ifois{0};
1283 <<
"+++ fifo_pretrig = " <<
fifo_pretrig <<
"; in-time ALCTs are not getting read-out!!! +++"
1290 <<
"+++ Allowed range of time bins, [0-" << late_tbins <<
"] exceeds max allowed, "
1292 <<
"+++ Set late_tbins to max allowed +++\n";
1300 const std::vector<CSCALCTDigi>& all_alcts =
getALCTs(nMaxALCTs);
1301 for (
const auto&
p : all_alcts) {
1309 LogDebug(
"CSCAnodeLCTProcessor") <<
" Do not report ALCT on keywire " <<
p.getKeyWG() <<
": found at bx " <<
bx
1310 <<
", whereas the earliest allowed bx is " <<
early_tbins + 1;
1315 if (
bx > late_tbins) {
1317 LogDebug(
"CSCAnodeLCTProcessor") <<
" Do not report ALCT on keywire " <<
p.getKeyWG() <<
": found at bx " <<
bx
1318 <<
", whereas the latest allowed bx is " << late_tbins;
1331 for (
auto&
p : tmpV) {
1336 for (
const auto& alct : tmpV) {
1345 std::vector<CSCALCTDigi> tmpV;
1365 std::ostringstream strstrm_header;
1366 LogTrace(
"CSCAnodeLCTProcessor") <<
"\n"
1367 <<
"Pattern: " << i_pattern <<
" Key wire: " << key_wire;
1368 for (
int i = 1;
i <= 32;
i++) {
1369 strstrm_header << ((32 -
i) % 10);
1371 LogTrace(
"CSCAnodeLCTProcessor") << strstrm_header.str();
1374 std::ostringstream strstrm_pulse;
1378 for (
int i = 1;
i <= 32;
i++) {
1379 strstrm_pulse << ((
pulse[this_layer][this_wire] >> (32 -
i)) & 1);
1382 << strstrm_pulse.str() <<
" on layer " << this_layer <<
" wire " << this_wire;
1386 LogTrace(
"CSCAnodeLCTProcessor") <<
"-------------------------------------------";
1392 if (temp_quality > 3)
1393 Q = temp_quality - 3;