27 static std::atomic<bool> config_dumped{
false};
86 thresholds_ = shower.getParameter<std::vector<unsigned>>(
"showerThresholds");
118 static std::atomic<bool> config_dumped{
false};
133 if (!config_dumped) {
135 config_dumped =
true;
143 static const unsigned int max_fifo_tbins = 1 << 5;
144 static const unsigned int max_fifo_pretrig = 1 << 5;
145 static const unsigned int max_drift_delay = 1 << 2;
146 static const unsigned int max_nplanes_hit_pretrig = 1 << 3;
147 static const unsigned int max_nplanes_hit_pattern = 1 << 3;
148 static const unsigned int max_nplanes_hit_accel_pretrig = 1 << 3;
149 static const unsigned int max_nplanes_hit_accel_pattern = 1 << 3;
150 static const unsigned int max_trig_mode = 1 << 2;
151 static const unsigned int max_accel_mode = 1 << 2;
163 max_nplanes_hit_accel_pretrig,
165 "nplanes_hit_accel_pretrig");
167 max_nplanes_hit_accel_pattern,
169 "nplanes_hit_accel_pattern");
196 static std::atomic<bool> config_dumped{
false};
199 config_dumped =
true;
212 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
219 <<
" is not defined in current geometry! +++\n"
220 <<
"+++ CSC geometry looks garbled; no emulation possible +++\n";
229 <<
" numWireGroups = " <<
numWireGroups <<
"; ALCT emulation skipped! +++";
230 std::vector<CSCALCTDigi> emptyV;
245 const unsigned int min_layers =
250 unsigned int layersHit = 0;
253 if (!wireGroupTimes[i_layer][i_wire].
empty()) {
259 if (layersHit >= min_layers)
280 std::map<int, std::map<int, CSCALCTDigi::WireContainer>> hits_in_patterns;
281 hits_in_patterns.clear();
287 if (!chamber_empty) {
291 if (
unsigned(i_wire) >= max_wire)
294 unsigned int start_bx = 0;
296 while (start_bx < stop_bx) {
302 int ghost_cleared[2] = {0, 0};
324 int valid = (ghost_cleared[0] == 0) ? 1 : 0;
332 LogTrace(
"CSCAnodeLCTProcessor") <<
"Add one ALCT to list " <<
lct_list.back();
353 LogTrace(
"CSCAnodeLCTProcessor") <<
"Add one ALCT to list " <<
lct_list.back();
387 bool hasDigis =
false;
391 digiV[i_layer].clear();
405 LogTrace(
"CSCAnodeLCTProcessor") <<
"found " <<
digiV[i_layer].size() <<
" wire digi(s) in layer " << i_layer
408 for (
const auto& wd :
digiV[i_layer]) {
409 LogTrace(
"CSCAnodeLCTProcessor") <<
" " << wd;
421 digiV[
id.layer() - 1].push_back(*digiIt);
431 for (
const auto& wd :
digiV[i_layer]) {
432 int i_wire = wd.getWireGroup() - 1;
433 std::vector<int> bx_times = wd.getTimeBinsOn();
439 <<
"+++ Found wire digi with wrong wire number = " << i_wire <<
" (max wires = " <<
numWireGroups
440 <<
"); skipping it... +++\n";
450 int last_time = -999;
452 wire[i_layer][i_wire].push_back(0);
453 wire[i_layer][i_wire].push_back(6);
455 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
457 if (
i > 0 && bx_times[
i] == (bx_times[
i - 1] + 1))
462 <<
"Digi on layer " << i_layer <<
" wire " << i_wire <<
" at time " << bx_times[
i];
467 if (last_time < 0 || ((bx_times[
i] - last_time) >= 6)) {
468 wire[i_layer][i_wire].push_back(bx_times[
i]);
469 last_time = bx_times[
i];
473 LogTrace(
"CSCAnodeLCTProcessor") <<
"+++ Skipping wire digi: wire = " << i_wire <<
" layer = " << i_layer
474 <<
", bx = " << bx_times[
i] <<
" +++";
484 bool chamber_empty =
true;
485 int i_wire, i_layer, digi_num;
502 for (
int j = 0;
j < 3;
j++)
509 if (!wire[i_layer][i_wire].
empty()) {
510 std::vector<int> bx_times = wire[i_layer][i_wire];
511 for (
unsigned int i = 0;
i < bx_times.size();
i++) {
513 if (bx_times[
i] < 0 || bx_times[
i] +
hit_persist >= bits_in_pulse) {
516 <<
"+++ BX time of wire digi (wire = " << i_wire <<
" layer = " << i_layer <<
") bx = " << bx_times[
i]
517 <<
" is not within the range (0-" << bits_in_pulse
518 <<
"] allowed for pulse extension. Skip this digi! +++\n";
524 chamber_empty =
false;
531 LogTrace(
"CSCAnodeLCTProcessor") <<
"Wire digi: layer " << i_layer <<
" digi #" << ++digi_num
532 <<
" wire group " << i_wire <<
" time " << bx_times[
i];
534 std::ostringstream strstrm;
535 for (
int i = 1;
i <= 32;
i++) {
538 LogTrace(
"CSCAnodeLCTProcessor") <<
" Pulse: " << strstrm.str();
546 if (
infoV > 1 && !chamber_empty) {
550 return chamber_empty;
554 int nPreTriggers = 0;
556 unsigned int layers_hit;
561 const unsigned int nplanes_hit_pretrig_acc =
571 for (
unsigned int bx_time = start_bx; bx_time < stop_bx; bx_time++) {
575 hit_layer[i_layer] =
false;
588 if (!hit_layer[i_layer]) {
589 hit_layer[i_layer] =
true;
595 if (layers_hit >= pretrig_thresh[i_pattern]) {
598 LogTrace(
"CSCAnodeLCTProcessor") <<
"Pretrigger was satisfied for wire: " << key_wire
599 <<
" pattern: " << i_pattern <<
" bx_time: " << bx_time;
621 const int key_wire,
std::map<
int, std::map<int, CSCALCTDigi::WireContainer>>& hits_in_patterns) {
624 unsigned int temp_quality;
625 int this_wire, delta_wire;
628 const unsigned int nplanes_hit_pattern_acc =
632 const std::string ptn_label[] = {
"Accelerator",
"CollisionA",
"CollisionB"};
639 hit_layer[i_layer] =
false;
643 hits_single_pattern.clear();
645 for (
auto&
p : hits_single_pattern) {
649 double num_pattern_hits = 0., times_sum = 0.;
650 std::multiset<int> mset_for_median;
651 mset_for_median.clear();
658 this_wire = delta_wire + key_wire;
664 hits_single_pattern[i_layer][i_wire] = this_wire;
668 if (!hit_layer[i_layer]) {
671 hit_layer[i_layer] =
true;
674 <<
"bx_time: " <<
first_bx[key_wire] <<
" pattern: " << i_pattern <<
" keywire: " << key_wire
675 <<
" layer: " << i_layer <<
" quality: " << temp_quality;
679 if (
abs(delta_wire) < 2) {
683 for (
unsigned int dbx = 0; dbx <
hit_persist; dbx++) {
689 times_sum += (double)first_bx_layer;
690 num_pattern_hits += 1.;
691 mset_for_median.insert(first_bx_layer);
693 LogTrace(
"CSCAnodeLCTProcessor") <<
" 1st bx in layer: " << first_bx_layer <<
" sum bx: " << times_sum
694 <<
" #pat. hits: " << num_pattern_hits;
703 const int sz = mset_for_median.size();
705 std::multiset<int>::iterator im = mset_for_median.begin();
707 std::advance(im, sz / 2 - 1);
710 else if ((sz % 2) == 1)
715 #if defined(EDM_ML_DEBUG)
717 auto lt =
LogTrace(
"CSCAnodeLCTProcessor")
719 for (im = mset_for_median.begin(); im != mset_for_median.end(); im++) {
727 if (temp_quality >= pattern_thresh[i_pattern]) {
729 hits_in_patterns[key_wire][i_pattern] = hits_single_pattern;
746 LogTrace(
"CSCAnodeLCTProcessor") <<
"Pattern found; keywire: " << key_wire <<
" type: " << ptn_label[i_pattern]
747 <<
" quality: " << temp_quality <<
"\n";
753 LogTrace(
"CSCAnodeLCTProcessor") <<
"Collision Pattern A is chosen"
756 LogTrace(
"CSCAnodeLCTProcessor") <<
"Collision Pattern B is chosen"
766 for (
int i_pattern = 0; i_pattern < 2; i_pattern++) {
767 ghost_cleared[i_pattern] = 0;
772 int qual_this =
quality[key_wire][i_pattern];
781 if (not(
p.getKeyWG() == key_wire - 1 and 1 -
p.getAccelerator() == i_pattern))
784 bool ghost_cleared_prev =
false;
785 int qual_prev =
p.getQuality();
786 int first_bx_prev =
p.getBX();
789 <<
"ghost concellation logic "
791 << key_wire <<
" quality " << qual_this <<
" bx " <<
first_bx[key_wire] <<
" previous key_wire "
792 << key_wire - 1 <<
" quality " << qual_prev <<
" bx " <<
first_bx[key_wire - 1];
803 if (qual_prev >= qual_this)
804 ghost_cleared[i_pattern] = 1;
805 else if (qual_prev < qual_this)
806 ghost_cleared_prev =
true;
809 ghost_cleared[i_pattern] = 1;
812 ghost_cleared_prev =
true;
815 if (ghost_cleared[i_pattern] == 1) {
819 <<
" pattern ghost cancelled on key_wire " << key_wire <<
" q=" << qual_this <<
" by wire "
820 << key_wire - 1 <<
" q=" << qual_prev;
824 if (ghost_cleared_prev) {
828 <<
" pattern ghost cancelled on key_wire " << key_wire - 1 <<
" q=" << qual_prev <<
" by wire "
829 << key_wire <<
" q=" << qual_this;
844 int n_alct_all = 0, n_alct = 0;
849 for (
const auto&
p : fourBest) {
855 <<
"C:" <<
theChamber <<
" all " << n_alct_all <<
" found " << n_alct;
860 for (
const auto&
p : fourBest) {
861 const int bx =
p.getBX();
866 <<
"; skipping it... +++\n";
915 LogTrace(
"CSCAnodeLCTProcessor") << all_alcts.size() <<
" ALCTs at the input of best-track selector: ";
916 for (
const auto&
p : all_alcts) {
925 for (
const auto&
p : all_alcts) {
937 int accel =
p.getAccelerator();
938 int qual =
p.getQuality();
939 int wire =
p.getKeyWG();
946 if (!vA || qual > qA || (qual == qA && wire > wA)) {
949 if (!vB || qual > qB || (qual == qB && wire < wB)) {
955 for (
int accel = 0; accel <= 1; accel++) {
959 LogTrace(
"CSCAnodeLCTProcessor") <<
"tA: " << tA[
bx][accel];
960 LogTrace(
"CSCAnodeLCTProcessor") <<
"tB: " << tB[
bx][accel];
962 bestALCTs[
bx][accel] = tA[
bx][accel];
965 if (tA[
bx][accel] != tB[
bx][accel] && tA[
bx][accel].getQuality() == tB[
bx][accel].getQuality()) {
966 secondALCTs[
bx][accel] = tB[
bx][accel];
972 for (
const auto&
p : all_alcts) {
973 if (
p.isValid() &&
p.getAccelerator() == accel &&
p.getBX() ==
bx &&
976 p.getKeyWG() >= secondALCTs[
bx][accel].
getKeyWG()) {
977 secondALCTs[
bx][accel] =
p;
986 std::vector<CSCALCTDigi> fourBest;
990 fourBest.push_back(bestALCTs[
bx][
i]);
995 fourBest.push_back(secondALCTs[
bx][
i]);
1001 LogTrace(
"CSCAnodeLCTProcessor") << fourBest.size() <<
" ALCTs selected: ";
1002 for (
const auto&
p : fourBest) {
1011 bool returnValue =
false;
1029 if (qual1 > qual2) {
1061 LogTrace(
"CSCAnodeLCTProcessor") <<
"trigMode(): collision track " << key_wire <<
" disabled"
1070 LogTrace(
"CSCAnodeLCTProcessor") <<
"trigMode(): accelerator track " << key_wire <<
" disabled"
1080 LogTrace(
"CSCAnodeLCTProcessor") <<
"trigMode(): collision track " << key_wire <<
" disabled"
1088 int promotionBit = 1 << 2;
1094 if (
quality[key_wire][0] > 0) {
1097 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): accelerator track " << key_wire <<
" ignored"
1106 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): collision track " << key_wire <<
" promoted"
1115 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): accelerator track " << key_wire <<
" promoted"
1124 LogTrace(
"CSCAnodeLCTProcessor") <<
"alctMode(): collision track " << key_wire <<
" ignored"
1133 std::ostringstream strm;
1135 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1136 strm <<
"+ ALCT configuration parameters: +\n";
1137 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1138 strm <<
" fifo_tbins [total number of time bins in DAQ readout] = " <<
fifo_tbins <<
"\n";
1139 strm <<
" fifo_pretrig [start time of anode raw hits in DAQ readout] = " <<
fifo_pretrig <<
"\n";
1140 strm <<
" drift_delay [drift delay after pre-trigger, in 25 ns bins] = " <<
drift_delay <<
"\n";
1141 strm <<
" nplanes_hit_pretrig [min. number of layers hit for pre-trigger] = " <<
nplanes_hit_pretrig <<
"\n";
1142 strm <<
" nplanes_hit_pattern [min. number of layers hit for trigger] = " <<
nplanes_hit_pattern <<
"\n";
1143 strm <<
" nplanes_hit_accel_pretrig [min. number of layers hit for accel."
1145 strm <<
" nplanes_hit_accel_pattern [min. number of layers hit for accel."
1147 strm <<
" trig_mode [enabling/disabling collision/accelerator tracks] = " <<
trig_mode <<
"\n";
1148 strm <<
" accel_mode [preference to collision/accelerator tracks] = " <<
accel_mode <<
"\n";
1149 strm <<
" l1a_window_width [L1Accept window width, in 25 ns bins] = " <<
l1a_window_width <<
"\n";
1150 strm <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1151 LogDebug(
"CSCAnodeLCTProcessor") << strm.str();
1159 std::ostringstream strstrm;
1161 if (i_wire % 10 == 0) {
1163 strstrm << i_wire / 10;
1165 strstrm << (i_wire - 100) / 10;
1171 strstrm << i_wire % 10;
1176 if (!wire[i_layer][i_wire].
empty()) {
1177 std::vector<int> bx_times = wire[i_layer][i_wire];
1178 strstrm << std::hex << bx_times[0] <<
std::dec;
1184 LogTrace(
"CSCAnodeLCTProcessor") << strstrm.str();
1190 std::vector<CSCALCTDigi> tmpV;
1196 static std::atomic<int> late_tbins{
early_tbins + lct_bins};
1198 static std::atomic<int> ifois{0};
1202 <<
"+++ fifo_pretrig = " <<
fifo_pretrig <<
"; in-time ALCTs are not getting read-out!!! +++"
1209 <<
"+++ Allowed range of time bins, [0-" << late_tbins <<
"] exceeds max allowed, "
1211 <<
"+++ Set late_tbins to max allowed +++\n";
1219 const std::vector<CSCALCTDigi>& all_alcts =
getALCTs();
1220 for (
const auto&
p : all_alcts) {
1228 LogDebug(
"CSCAnodeLCTProcessor") <<
" Do not report ALCT on keywire " <<
p.getKeyWG() <<
": found at bx " <<
bx
1229 <<
", whereas the earliest allowed bx is " <<
early_tbins + 1;
1234 if (
bx > late_tbins) {
1236 LogDebug(
"CSCAnodeLCTProcessor") <<
" Do not report ALCT on keywire " <<
p.getKeyWG() <<
": found at bx " <<
bx
1237 <<
", whereas the latest allowed bx is " << late_tbins;
1250 for (
auto&
p : tmpV) {
1256 for (
const auto& alct : tmpV) {
1265 std::vector<CSCALCTDigi> tmpV;
1288 std::ostringstream strstrm_header;
1289 LogTrace(
"CSCAnodeLCTProcessor") <<
"\n"
1290 <<
"Pattern: " << i_pattern <<
" Key wire: " << key_wire;
1291 for (
int i = 1;
i <= 32;
i++) {
1292 strstrm_header << ((32 -
i) % 10);
1294 LogTrace(
"CSCAnodeLCTProcessor") << strstrm_header.str();
1299 std::ostringstream strstrm_pulse;
1302 for (
int i = 1;
i <= 32;
i++) {
1305 LogTrace(
"CSCAnodeLCTProcessor") << strstrm_pulse.str() <<
" on layer " << i_layer <<
" wire " << this_wire;
1310 LogTrace(
"CSCAnodeLCTProcessor") <<
"-------------------------------------------";
1316 if (temp_quality > 3)
1317 Q = temp_quality - 3;
1325 for (
auto&
p : wireHits) {
1349 unsigned hitsInTime = 0;
1350 unsigned hitsOutTime = 0;
1353 auto times =
wires[i_layer][i_wire];
1354 hitsInTime += std::count_if(times.begin(), times.end(), inTime);
1355 hitsOutTime += std::count_if(times.begin(), times.end(), outTime);
1364 std::vector<unsigned> station_thresholds = {
1368 for (
unsigned i = 0;
i < station_thresholds.size();
i++) {
1369 if (hitsInTime >= station_thresholds[
i]) {
1372 if (hitsOutTime >= station_thresholds[
i]) {