CMS 3D CMS Logo

HcalTriggerPrimitiveAlgo.cc
Go to the documentation of this file.
2 
6 
10 
13 
16 
18 
19 #include <iostream>
20 
21 using namespace std;
22 
23 HcalTriggerPrimitiveAlgo::HcalTriggerPrimitiveAlgo( bool pf, const std::vector<double>& w, int latency,
24  uint32_t FG_threshold, const std::vector<uint32_t>& FG_HF_thresholds, uint32_t ZS_threshold,
27  uint32_t minSignalThreshold, uint32_t PMT_NoiseThreshold
28  )
29  : incoder_(nullptr), outcoder_(nullptr),
30  theThreshold(0), peakfind_(pf), weights_(w), latency_(latency),
31  FG_threshold_(FG_threshold), FG_HF_thresholds_(FG_HF_thresholds), ZS_threshold_(ZS_threshold),
32  numberOfSamples_(numberOfSamples),
33  numberOfPresamples_(numberOfPresamples),
34  numberOfSamplesHF_(numberOfSamplesHF),
35  numberOfPresamplesHF_(numberOfPresamplesHF),
36  useTDCInMinBiasBits_(useTDCInMinBiasBits),
37  minSignalThreshold_(minSignalThreshold),
38  PMT_NoiseThreshold_(PMT_NoiseThreshold),
39  NCTScaleShift(0), RCTScaleShift(0),
40  peak_finder_algorithm_(2),
41  override_parameters_()
42 {
43  //No peak finding setting (for Fastsim)
44  if (!peakfind_){
45  numberOfSamples_ = 1;
47  numberOfSamplesHF_ = 1;
49  }
50  // Switch to integer for comparisons - remove compiler warning
52 }
53 
54 
56 }
57 
58 
59 void
61 {
62  upgrade_hb_ = hb;
63  upgrade_he_ = he;
64  upgrade_hf_ = hf;
65 }
66 
67 
68 void
70 {
72 
73  if (override_parameters_.exists("ADCThresholdHF")) {
74  override_adc_hf_ = true;
75  override_adc_hf_value_ = override_parameters_.getParameter<uint32_t>("ADCThresholdHF");
76  }
77  if (override_parameters_.exists("TDCMaskHF")) {
78  override_tdc_hf_ = true;
79  override_tdc_hf_value_ = override_parameters_.getParameter<unsigned long long>("TDCMaskHF");
80  }
81 }
82 
83 
85  // TODO: Need to add support for seperate 28, 29 in HE
86  //Hack for 300_pre10, should be removed.
87  if (frame.id().depth()==5) return;
88 
89  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
90  assert(ids.size() == 1 || ids.size() == 2);
91  IntegerCaloSamples samples1(ids[0], int(frame.size()));
92 
93  samples1.setPresamples(frame.presamples());
94  incoder_->adc2Linear(frame, samples1);
95 
96  std::vector<bool> msb;
97  incoder_->lookupMSB(frame, msb);
98 
99  if(ids.size() == 2) {
100  // make a second trigprim for the other one, and split the energy
101  IntegerCaloSamples samples2(ids[1], samples1.size());
102  for(int i = 0; i < samples1.size(); ++i) {
103  samples1[i] = uint32_t(samples1[i]*0.5);
104  samples2[i] = samples1[i];
105  }
106  samples2.setPresamples(frame.presamples());
107  addSignal(samples2);
108  addFG(ids[1], msb);
109  }
110  addSignal(samples1);
111  addFG(ids[0], msb);
112 }
113 
114 
116  if(frame.id().depth() == 1 || frame.id().depth() == 2) {
117  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
118  std::vector<HcalTrigTowerDetId>::const_iterator it;
119  for (it = ids.begin(); it != ids.end(); ++it) {
120  HcalTrigTowerDetId trig_tower_id = *it;
121  IntegerCaloSamples samples(trig_tower_id, frame.size());
122  samples.setPresamples(frame.presamples());
123  incoder_->adc2Linear(frame, samples);
124 
125  // Don't add to final collection yet
126  // HF PMT veto sum is calculated in analyzerHF()
127  IntegerCaloSamples zero_samples(trig_tower_id, frame.size());
128  zero_samples.setPresamples(frame.presamples());
129  addSignal(zero_samples);
130 
131  // Pre-LS1 Configuration
132  if (trig_tower_id.version() == 0) {
133  // Mask off depths: fgid is the same for both depths
134  uint32_t fgid = (frame.id().maskDepth());
135 
136  if ( theTowerMapFGSum.find(trig_tower_id) == theTowerMapFGSum.end() ) {
137  SumFGContainer sumFG;
138  theTowerMapFGSum.insert(std::pair<HcalTrigTowerDetId, SumFGContainer>(trig_tower_id, sumFG));
139  }
140 
141  SumFGContainer& sumFG = theTowerMapFGSum[trig_tower_id];
142  SumFGContainer::iterator sumFGItr;
143  for ( sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
144  if (sumFGItr->id() == fgid) { break; }
145  }
146  // If find
147  if (sumFGItr != sumFG.end()) {
148  for (int i=0; i<samples.size(); ++i) {
149  (*sumFGItr)[i] += samples[i];
150  }
151  }
152  else {
153  //Copy samples (change to fgid)
154  IntegerCaloSamples sumFGSamples(DetId(fgid), samples.size());
155  sumFGSamples.setPresamples(samples.presamples());
156  for (int i=0; i<samples.size(); ++i) {
157  sumFGSamples[i] = samples[i];
158  }
159  sumFG.push_back(sumFGSamples);
160  }
161 
162  // set veto to true if Long or Short less than threshold
163  if (HF_Veto.find(fgid) == HF_Veto.end()) {
164  vector<bool> vetoBits(samples.size(), false);
165  HF_Veto[fgid] = vetoBits;
166  }
167  for (int i=0; i<samples.size(); ++i) {
168  if (samples[i] < minSignalThreshold_) {
169  HF_Veto[fgid][i] = true;
170  }
171  }
172  }
173  // HF 1x1
174  else if (trig_tower_id.version() == 1) {
175  uint32_t fgid = (frame.id().maskDepth());
176  HFDetails& details = theHFDetailMap[trig_tower_id][fgid];
177  // Check the frame type to determine long vs short
178  if (frame.id().depth() == 1) { // Long
179  details.long_fiber = samples;
180  details.LongDigi = frame;
181  } else if (frame.id().depth() == 2) { // Short
182  details.short_fiber = samples;
183  details.ShortDigi = frame;
184  } else {
185  // Neither long nor short... So we have no idea what to do
186  edm::LogWarning("HcalTPAlgo") << "Unable to figure out what to do with data frame for " << frame.id();
187  return;
188  }
189  }
190  // Uh oh, we are in a bad/unknown state! Things will start crashing.
191  else {
192  return;
193  }
194  }
195  }
196 }
197 
198 void
200 {
201  HcalDetId detId = frame.detid();
202  // prevent QIE10 calibration channels from entering TP emulation
203  if(detId.subdet() != HcalForward) return;
204 
205  auto ids = theTrigTowerGeometry->towerIds(frame.id());
206  for (const auto& id: ids) {
207  if (id.version() == 0) {
208  edm::LogError("HcalTPAlgo") << "Encountered QIE10 data frame mapped to TP version 0:" << id;
209  continue;
210  }
211 
212  int nsamples=frame.samples();
213 
214  IntegerCaloSamples samples(id, nsamples);
215  samples.setPresamples(frame.presamples());
216  incoder_->adc2Linear(frame, samples);
217 
218  // Don't add to final collection yet
219  // HF PMT veto sum is calculated in analyzerHF()
220  IntegerCaloSamples zero_samples(id, nsamples);
221  zero_samples.setPresamples(frame.presamples());
222  addSignal(zero_samples);
223 
224  auto fid = HcalDetId(frame.id());
225  auto& details = theHFUpgradeDetailMap[id][fid.maskDepth()];
226  auto& detail = details[fid.depth()-1];
227  detail.samples = samples;
228  detail.digi = frame;
229  detail.validity.resize(nsamples);
230  detail.passTDC.resize(nsamples);
231  incoder_->lookupMSB(frame, detail.fgbits);
232  for (int idx = 0; idx < nsamples; ++idx){
233  detail.validity[idx] = validChannel(frame, idx);
234  detail.passTDC[idx] = passTDC(frame, idx);
235  }
236  }
237 }
238 
239 void
241 {
242  HcalDetId detId(frame.id());
243  // prevent QIE11 calibration channels from entering TP emulation
244  if(detId.subdet() != HcalEndcap && detId.subdet() != HcalBarrel) return;
245 
246  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
247  assert(ids.size() == 1 || ids.size() == 2);
248  IntegerCaloSamples samples1(ids[0], int(frame.samples()));
249 
250  samples1.setPresamples(frame.presamples());
251  incoder_->adc2Linear(frame, samples1);
252 
253  std::vector<std::bitset<2>> msb(frame.samples(), 0);
254  incoder_->lookupMSB(frame, msb);
255 
256  if(ids.size() == 2) {
257  // make a second trigprim for the other one, and share the energy
258  IntegerCaloSamples samples2(ids[1], samples1.size());
259  for(int i = 0; i < samples1.size(); ++i) {
260  samples1[i] = uint32_t(samples1[i]);
261  samples2[i] = samples1[i];
262  }
263  samples2.setPresamples(frame.presamples());
264  addSignal(samples2);
265  addUpgradeFG(ids[1], detId.depth(), msb);
266  }
267  addSignal(samples1);
268  addUpgradeFG(ids[0], detId.depth(), msb);
269 }
270 
272  HcalTrigTowerDetId id(samples.id());
273  SumMap::iterator itr = theSumMap.find(id);
274  if(itr == theSumMap.end()) {
275  theSumMap.insert(std::make_pair(id, samples));
276  }
277  else {
278  // wish CaloSamples had a +=
279  for(int i = 0; i < samples.size(); ++i) {
280  (itr->second)[i] += samples[i];
281  }
282  }
283 }
284 
285 
287  int shrink = weights_.size() - 1;
288  std::vector<bool>& msb = fgMap_[samples.id()];
289  IntegerCaloSamples sum(samples.id(), samples.size());
290 
291  //slide algo window
292  for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
293  int algosumvalue = 0;
294  for(unsigned int i = 0; i < weights_.size(); i++) {
295  //add up value * scale factor
296  algosumvalue += int(samples[ibin+i] * weights_[i]);
297  }
298  if (algosumvalue<0) sum[ibin]=0; // low-side
299  //high-side
300  //else if (algosumvalue>QIE8_LINEARIZATION_ET) sum[ibin]=QIE8_LINEARIZATION_ET;
301  else sum[ibin] = algosumvalue; //assign value to sum[]
302  }
303 
304  // Align digis and TP
305  int dgPresamples=samples.presamples();
306  int tpPresamples=numberOfPresamples_;
307  int shift = dgPresamples - tpPresamples;
308  int dgSamples=samples.size();
309  int tpSamples=numberOfSamples_;
310  if(peakfind_){
311  if((shift<shrink) || (shift + tpSamples + shrink > dgSamples - (peak_finder_algorithm_ - 1) ) ){
312  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyze") <<
313  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
314  shift=shrink;
315  tpPresamples=dgPresamples-shrink;
316  tpSamples=dgSamples-(peak_finder_algorithm_-1)-shrink-shift;
317  }
318  }
319 
320  std::vector<int> finegrain(tpSamples,false);
321 
322  IntegerCaloSamples output(samples.id(), tpSamples);
323  output.setPresamples(tpPresamples);
324 
325  for (int ibin = 0; ibin < tpSamples; ++ibin) {
326  // ibin - index for output TP
327  // idx - index for samples + shift
328  int idx = ibin + shift;
329 
330  //Peak finding
331  if (peakfind_) {
332  bool isPeak = false;
333  switch (peak_finder_algorithm_) {
334  case 1 :
335  isPeak = (samples[idx] > samples[idx-1] && samples[idx] >= samples[idx+1] && samples[idx] > theThreshold);
336  break;
337  case 2:
338  isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
339  break;
340  default:
341  break;
342  }
343 
344  if (isPeak){
345  output[ibin] = std::min<unsigned int>(sum[idx],QIE8_LINEARIZATION_ET);
346  finegrain[ibin] = msb[idx];
347  }
348  // Not a peak
349  else output[ibin] = 0;
350  }
351  else { // No peak finding, just output running sum
352  output[ibin] = std::min<unsigned int>(sum[idx],QIE8_LINEARIZATION_ET);
353  finegrain[ibin] = msb[idx];
354  }
355 
356  // Only Pegged for 1-TS algo.
357  if (peak_finder_algorithm_ == 1) {
358  if (samples[idx] >= QIE8_LINEARIZATION_ET)
360  }
361  }
362  outcoder_->compress(output, finegrain, result);
363 }
364 
365 
366 void
368 {
369  int shrink = weights_.size() - 1;
370  auto& msb = fgUpgradeMap_[samples.id()];
371  IntegerCaloSamples sum(samples.id(), samples.size());
372 
373  HcalDetId detId(samples.id());
374  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
375  //slide algo window
376  for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
377  int algosumvalue = 0;
378  for(unsigned int i = 0; i < weights_.size(); i++) {
379  //add up value * scale factor
380  // In addition, divide by two in the 10 degree phi segmentation region
381  // to mimic 5 degree segmentation for the trigger
382  unsigned int sample = samples[ibin+i];
384  if(ids.size()==2) algosumvalue += int(sample * 0.5 * weights_[i]);
385  else algosumvalue += int(sample * weights_[i]);
386  }
387  if (algosumvalue<0) sum[ibin]=0; // low-side
388  //high-side
389  //else if (algosumvalue>QIE11_LINEARIZATION_ET) sum[ibin]=QIE11_LINEARIZATION_ET;
390  else sum[ibin] = algosumvalue; //assign value to sum[]
391  }
392 
393  // Align digis and TP
394  int dgPresamples=samples.presamples();
395  int tpPresamples=numberOfPresamples_;
396  int shift = dgPresamples - tpPresamples;
397  int dgSamples=samples.size();
398  int tpSamples=numberOfSamples_;
399 
400  if((shift<shrink) || (shift + tpSamples + shrink > dgSamples - (peak_finder_algorithm_ - 1) ) ){
401  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyze") <<
402  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
403  shift=shrink;
404  tpPresamples=dgPresamples-shrink;
405  tpSamples=dgSamples-(peak_finder_algorithm_-1)-shrink-shift;
406  }
407 
408  std::vector<int> finegrain(tpSamples,false);
409 
410  IntegerCaloSamples output(samples.id(), tpSamples);
411  output.setPresamples(tpPresamples);
412 
413  for (int ibin = 0; ibin < tpSamples; ++ibin) {
414  // ibin - index for output TP
415  // idx - index for samples + shift
416  int idx = ibin + shift;
417  bool isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
418 
419  if (isPeak){
420  output[ibin] = std::min<unsigned int>(sum[idx],QIE11_MAX_LINEARIZATION_ET);
421  } else {
422  // Not a peak
423  output[ibin] = 0;
424  }
425  // peak-finding is not applied for FG bits
426  finegrain[ibin] = fg_algo.compute(msb[idx]).to_ulong();
427  }
428  outcoder_->compress(output, finegrain, result);
429 }
430 
431 
433  HcalTrigTowerDetId detId(samples.id());
434 
435  // Align digis and TP
436  int dgPresamples=samples.presamples();
437  int tpPresamples=numberOfPresamplesHF_;
438  int shift = dgPresamples - tpPresamples;
439  int dgSamples=samples.size();
440  int tpSamples=numberOfSamplesHF_;
441  if(shift<0 || shift+tpSamples>dgSamples){
442  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyzeHF") <<
443  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
444  tpPresamples=dgPresamples;
445  shift=0;
446  tpSamples=dgSamples;
447  }
448 
449  std::vector<int> finegrain(tpSamples, false);
450 
451  TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
452  assert(tower2fg != theTowerMapFGSum.end());
453 
454  const SumFGContainer& sumFG = tower2fg->second;
455  // Loop over all L+S pairs that mapped from samples.id()
456  // Note: 1 samples.id() = 6 x (L+S) without noZS
457  for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
458  const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
459  for (int ibin = 0; ibin < tpSamples; ++ibin) {
460  int idx = ibin + shift;
461  // if not vetod, add L+S to total sum and calculate FG
462  bool vetoed = idx<int(veto.size()) && veto[idx];
463  if (!(vetoed && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
464  samples[idx] += (*sumFGItr)[idx];
465  finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
466  }
467  }
468  }
469 
470  IntegerCaloSamples output(samples.id(), tpSamples);
471  output.setPresamples(tpPresamples);
472 
473  for (int ibin = 0; ibin < tpSamples; ++ibin) {
474  int idx = ibin + shift;
475  output[ibin] = samples[idx] >> hf_lumi_shift;
476  static const int MAX_OUTPUT = QIE8_LINEARIZATION_ET; // QIE8_LINEARIZATION_ET = 1023
477  if (output[ibin] > MAX_OUTPUT) output[ibin] = MAX_OUTPUT;
478  }
479  outcoder_->compress(output, finegrain, result);
480 }
481 
485  const int hf_lumi_shift,
486  const HcalFeatureBit* embit
487  ) {
488  // Align digis and TP
489  const int SHIFT = samples.presamples() - numberOfPresamplesHF_;
490  assert(SHIFT >= 0);
491  assert((SHIFT + numberOfSamplesHF_) <= samples.size());
492 
493  // Try to find the HFDetails from the map corresponding to our samples
494  const HcalTrigTowerDetId detId(samples.id());
495  HFDetailMap::const_iterator it = theHFDetailMap.find(detId);
496  // Missing values will give an empty digi
497  if (it == theHFDetailMap.end()) {
498  return;
499  }
500 
501  std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
502 
503  // Set up out output of IntergerCaloSamples
505  output.setPresamples(numberOfPresamplesHF_);
506 
507  for (const auto& item: it->second) {
508  auto& details = item.second;
509  for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
510  const int IDX = ibin + SHIFT;
511  int long_fiber_val = 0;
512  if (IDX < details.long_fiber.size()) {
513  long_fiber_val = details.long_fiber[IDX];
514  }
515  int short_fiber_val = 0;
516  if (IDX < details.short_fiber.size()) {
517  short_fiber_val = details.short_fiber[IDX];
518  }
519  output[ibin] += (long_fiber_val + short_fiber_val);
520 
521  uint32_t ADCLong = details.LongDigi[ibin].adc();
522  uint32_t ADCShort = details.ShortDigi[ibin].adc();
523 
524  if (details.LongDigi.id().ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
525  finegrain[ibin][1] = (ADCLong > FG_HF_thresholds_[0] || ADCShort > FG_HF_thresholds_[0]);
526 
527  if (embit != nullptr)
528  finegrain[ibin][0] = embit->fineGrainbit(details.ShortDigi, details.LongDigi, ibin);
529  }
530  }
531  }
532 
533  for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
534  static const unsigned int MAX_OUTPUT = QIE8_LINEARIZATION_ET; // QIE8_LINEARIZATION_ET = 1023
535  output[bin] = min({MAX_OUTPUT, output[bin] >> hf_lumi_shift});
536  }
537 
538  std::vector<int> finegrain_converted;
539  for (const auto& fg: finegrain)
540  finegrain_converted.push_back(fg.to_ulong());
541  outcoder_->compress(output, finegrain_converted, result);
542 }
543 
544 bool
546 {
548  auto adc_threshold = parameters->getADCThresholdHF();
549  auto tdc_mask = parameters->getTDCMaskHF();
550 
551  if (override_adc_hf_)
552  adc_threshold = override_adc_hf_value_;
553  if (override_tdc_hf_)
554  tdc_mask = override_tdc_hf_value_;
555 
556  if (digi[ts].adc() < adc_threshold)
557  return true;
558 
559  return (1ul << digi[ts].le_tdc()) & tdc_mask;
560 }
561 
562 bool
564 {
565  // channels with invalid data should not contribute to the sum
566  if(digi.linkError() || ts>=digi.samples() || !digi[ts].ok()) return false;
567 
569  if (mask)
570  return false;
571 
572  return true;
573 }
574 
577  const int hf_lumi_shift, const HcalFeatureBit* embit)
578 {
579  // Align digis and TP
580  const int shift = samples.presamples() - numberOfPresamplesHF_;
581  assert(shift >= 0);
582  assert((shift + numberOfSamplesHF_) <= samples.size());
583  assert(hf_lumi_shift>=2);
584 
585  // Try to find the HFDetails from the map corresponding to our samples
586  const HcalTrigTowerDetId detId(samples.id());
587  auto it = theHFUpgradeDetailMap.find(detId);
588  // Missing values will give an empty digi
589  if (it == theHFUpgradeDetailMap.end()) {
590  return;
591  }
592 
593  std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
594 
595  // Set up out output of IntergerCaloSamples
597  output.setPresamples(numberOfPresamplesHF_);
598 
599  for (const auto& item: it->second) {
600  auto& details = item.second;
601  for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
602  const int idx = ibin + shift;
603 
604  int long_fiber_val = 0;
605  int long_fiber_count = 0;
606  int short_fiber_val = 0;
607  int short_fiber_count = 0;
608 
609  bool saturated = false;
610 
611  for (auto i: {0, 2}) {
612  if (idx < details[i].samples.size() and details[i].validity[idx] and details[i].passTDC[idx]) {
613  long_fiber_val += details[i].samples[idx];
614  saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
615  ++long_fiber_count;
616  }
617  }
618  for (auto i: {1, 3}) {
619  if (idx < details[i].samples.size() and details[i].validity[idx] and details[i].passTDC[idx]) {
620  short_fiber_val += details[i].samples[idx];
621  saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
622  ++short_fiber_count;
623  }
624  }
625 
626  if (saturated) {
628  } else {
629  // For details of the energy handling, see:
630  // https://cms-docdb.cern.ch/cgi-bin/DocDB/ShowDocument?docid=12306
631  // If both readouts are valid, average of the two energies is taken
632  // division by 2 is compensated by adjusting the total scale shift in the end
633  if (long_fiber_count == 2) long_fiber_val >>=1;
634  if (short_fiber_count == 2) short_fiber_val >>=1;
635 
636  auto sum = long_fiber_val + short_fiber_val;
637  // Similar to above, if both channels are valid,
638  // average of the two energies is calculated
639  // division by 2 here is also compensated by adjusting the total scale shift in the end
640  if (long_fiber_count > 0 and short_fiber_count > 0) sum >>=1;
641 
642  output[ibin] += sum;
643  }
644 
645  for (const auto& detail: details) {
646  if (idx < int(detail.digi.size()) and detail.validity[idx] and HcalDetId(detail.digi.id()).ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
647  if(useTDCInMinBiasBits_ && !detail.passTDC[idx]) continue;
648  finegrain[ibin][1] = finegrain[ibin][1] or detail.fgbits[idx][0];
649  // what is commonly called the "second" HF min-bias bit is
650  // actually the 0-th bit, which can also be used instead for the EM bit
651  // (called finegrain[ibin][0] below) in non-HI running
652  finegrain[ibin][0] = finegrain[ibin][0] or detail.fgbits[idx][1];
653  }
654  }
655  // the EM bit is only used if the "second" FG bit is disabled
656  if (embit != nullptr and FG_HF_thresholds_.at(1) != 255) {
657  finegrain[ibin][0] = embit->fineGrainbit(
658  details[1].digi, details[3].digi,
659  details[0].digi, details[2].digi,
660  details[1].validity[idx], details[3].validity[idx],
661  details[0].validity[idx], details[2].validity[idx],
662  idx
663  );
664  }
665  }
666  }
667 
668  for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
669  output[bin] = min({(unsigned int) QIE10_MAX_LINEARIZATION_ET, output[bin] >> (hf_lumi_shift-2)});
670  }
671  std::vector<int> finegrain_converted;
672  for (const auto& fg: finegrain)
673  finegrain_converted.push_back(fg.to_ulong());
674  outcoder_->compress(output, finegrain_converted, result);
675 }
676 
678  for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
679  bool ZS = true;
680  for (int i=0; i<tp->size(); ++i) {
681  if (tp->sample(i).compressedEt() > ZS_threshold_I_) {
682  ZS=false;
683  break;
684  }
685  }
686  if (ZS) tp->setZSInfo(false,true);
687  else tp->setZSInfo(true,false);
688  }
689 }
690 
692  const HcalElectronicsMap *emap,
694  ){
695  std::set<uint32_t> FrontEndErrors;
696 
698  const FEDRawData& raw = rawraw->FEDData(i);
699  if (raw.size()<12) continue;
700  const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
701  if(!dccHeader) continue;
702  HcalHTRData htr;
703  for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
704  if (!dccHeader->getSpigotPresent(spigot)) continue;
705  dccHeader->getSpigotData(spigot,htr,raw.size());
706  int dccid = dccHeader->getSourceId();
707  int errWord = htr.getErrorsWord() & 0x1FFFF;
708  bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800)!=0);
709 
710  if(HTRError) {
711  bool valid =false;
712  for(int fchan=0; fchan<3 && !valid; fchan++) {
713  for(int fib=0; fib<9 && !valid; fib++) {
714  HcalElectronicsId eid(fchan,fib,spigot,dccid-FEDNumbering::MINHCALFEDID);
715  eid.setHTR(htr.readoutVMECrateId(),htr.htrSlot(),htr.htrTopBottom());
716  DetId detId = emap->lookup(eid);
717  if(detId.null()) continue;
718  HcalSubdetector subdet=(HcalSubdetector(detId.subdetId()));
719  if (detId.det()!=4||
720  (subdet!=HcalBarrel && subdet!=HcalEndcap &&
721  subdet!=HcalForward )) continue;
722  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
723  for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId=ids.begin(); triggerId != ids.end(); ++triggerId) {
724  FrontEndErrors.insert(triggerId->rawId());
725  }
726  //valid = true;
727  }
728  }
729  }
730  }
731  }
732 
733  // Loop over TP collection
734  // Set TP to zero if there is FE Format Error
735  HcalTriggerPrimitiveSample zeroSample(0);
736  for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
737  if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
738  for (int i=0; i<tp->size(); ++i) tp->setSample(i, zeroSample);
739  }
740  }
741 }
742 
743 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb){
744  FGbitMap::iterator itr = fgMap_.find(id);
745  if (itr != fgMap_.end()){
746  std::vector<bool>& _msb = itr->second;
747  for (size_t i=0; i<msb.size(); ++i)
748  _msb[i] = _msb[i] || msb[i];
749  }
750  else fgMap_[id] = msb;
751 }
752 
753 bool
755 {
756  if (depth > LAST_FINEGRAIN_DEPTH)
757  return false;
758  if (id.ietaAbs() > LAST_FINEGRAIN_TOWER)
759  return false;
760  if (id.ietaAbs() == HBHE_OVERLAP_TOWER and not upgrade_hb_)
761  return false;
762  return true;
763 }
764 
765 bool
767 {
768  // This tower (ietaAbs == 16) does not accept upgraded FG bits,
769  // but needs pseudo legacy ones to ensure that the tower is processed
770  // even when the QIE8 depths in front of it do not have energy deposits.
771  if (id.ietaAbs() == HBHE_OVERLAP_TOWER and not upgrade_hb_)
772  return true;
773  return false;
774 }
775 
776 void
777 HcalTriggerPrimitiveAlgo::addUpgradeFG(const HcalTrigTowerDetId& id, int depth, const std::vector<std::bitset<2>>& bits)
778 {
779  if (not validUpgradeFG(id, depth)) {
780  if (needLegacyFG(id)) {
781  std::vector<bool> pseudo(bits.size(), false);
782  addFG(id, pseudo);
783  }
784  return;
785  }
786 
787  auto it = fgUpgradeMap_.find(id);
788  if (it == fgUpgradeMap_.end()) {
789  FGUpgradeContainer element;
790  element.resize(bits.size());
791  it = fgUpgradeMap_.insert(std::make_pair(id, element)).first;
792  }
793  for (unsigned int i = 0; i < bits.size(); ++i) {
794  it->second[i][0][depth-1] = bits[i][0];
795  it->second[i][1][depth-1] = bits[i][1];
796  }
797 }
798 
800  if (algo <=0 && algo>2)
801  throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
803 }
804 
807 }
808 
811 }
int samples() const
total number of samples in the digi
constexpr void setHTR(int crate, int slot, int tb)
T getParameter(std::string const &) const
void analyze(IntegerCaloSamples &samples, HcalTriggerPrimitiveDigi &result)
adds the actual digis
void adc2Linear(const HBHEDataFrame &df, IntegerCaloSamples &ics) const override
void runFEFormatError(const FEDRawDataCollection *rawraw, const HcalElectronicsMap *emap, HcalTrigPrimDigiCollection &result)
HcalTriggerPrimitiveAlgo(bool pf, const std::vector< double > &w, int latency, uint32_t FG_threshold, const std::vector< uint32_t > &FG_HF_thresholds, uint32_t ZS_threshold, int numberOfSamples, int numberOfPresamples, int numberOfSamplesHF, int numberOfPresamplesHF, bool useTDCInMinBiasBits, uint32_t minSignalThreshold=0, uint32_t PMT_NoiseThreshold=0)
int presamples() const
access presample information
std::vector< uint32_t > FG_HF_thresholds_
HFUpgradeDetailMap theHFUpgradeDetailMap
bool passTDC(const QIE10DataFrame &digi, int ts) const
void analyzeHF(IntegerCaloSamples &samples, HcalTriggerPrimitiveDigi &result, const int hf_lumi_shift)
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:146
bool check() const
Check for a good event Requires a minimum length, matching wordcount and length, not an empty event...
Definition: HcalHTRData.cc:62
std::vector< HcalTrigTowerDetId > towerIds(const HcalDetId &cellId) const
the mapping to and from DetIds
const double w
Definition: UKUtility.cc:23
const HcalTPChannelParameter * getHcalTPChannelParameter(const HcalGenericDetId &fId) const
unsigned int htrTopBottom() const
HcalElectronicsId-style HTR top/bottom (1=top/0=bottom)
Definition: HcalHTRData.cc:343
static const int QIE10_MAX_LINEARIZATION_ET
void analyzeHF2016(const IntegerCaloSamples &SAMPLES, HcalTriggerPrimitiveDigi &result, const int HF_LUMI_SHIFT, const HcalFeatureBit *HCALFEM)
constexpr bool null() const
is this a null id ?
Definition: DetId.h:52
int presamples() const
for backward compatibility
int size() const
total number of samples in the digi
Definition: HBHEDataFrame.h:31
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision bits
void analyzeHFQIE10(const IntegerCaloSamples &SAMPLES, HcalTriggerPrimitiveDigi &result, const int HF_LUMI_SHIFT, const HcalFeatureBit *HCALFEM)
bool linkError() const
#define nullptr
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::DataFrame::id_type id() const
const HcalTPGCompressor * outcoder_
void setPresamples(int pre)
set presample information
void addFG(const HcalTrigTowerDetId &id, std::vector< bool > &msb)
void analyzeQIE11(IntegerCaloSamples &samples, HcalTriggerPrimitiveDigi &result, const HcalFinegrainBit &fg_algo)
bool needLegacyFG(const HcalTrigTowerDetId &id) const
int getSpigotData(int nspigot, HcalHTRData &decodeTool, int validSize) const
uint32_t maskDepth() const
get the tower depth
Definition: HcalDetId.h:179
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
bool validChannel(const QIE10DataFrame &digi, int ts) const
std::vector< IntegerCaloSamples > SumFGContainer
int size() const
get the size
unsigned int htrSlot() const
HcalElectronicsId-style HTR slot.
Definition: HcalHTRData.cc:339
int depth() const
get the tower depth
Definition: HcalDetId.h:166
const HcalTrigTowerGeometry * theTrigTowerGeometry
const HcalDbService * conditions_
void lookupMSB(const HBHEDataFrame &df, std::vector< bool > &msb) const
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
HcalDetId const & id() const
Definition: HFDataFrame.h:26
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Definition: helper.h:68
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
edm::DataFrame::id_type id() const
HcalSubdetector
Definition: HcalAssistant.h:31
DetId detid() const
Get the detector id.
bool getSpigotPresent(unsigned int nspigot) const
Read the "PRESENT" bit for this spigot.
std::bitset< 4 > compute(const Tower &) const
T min(T a, T b)
Definition: MathUtil.h:58
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
void compress(const IntegerCaloSamples &ics, const std::vector< int > &fineGrain, HcalTriggerPrimitiveDigi &digi) const
int presamples() const
number of samples before the sample from the triggered beam crossing (according to the hardware) ...
Definition: HBHEDataFrame.h:33
void runZS(HcalTrigPrimDigiCollection &tp)
std::vector< T >::iterator iterator
bin
set the eta bin as selection string.
const_iterator end() const
int getSourceId() const
Definition: HcalDCCHeader.h:32
std::vector< HcalFinegrainBit::Tower > FGUpgradeContainer
Definition: DetId.h:18
int size() const
total number of samples in the digi
Definition: HFDataFrame.h:30
unsigned long long override_tdc_hf_value_
bool validUpgradeFG(const HcalTrigTowerDetId &id, int depth) const
unsigned int getErrorsWord() const
Get the errors word.
Definition: HcalHTRData.h:157
static const int QIE11_MAX_LINEARIZATION_ET
int version() const
get the version code for the trigger tower
const HcalTPParameters * getHcalTPParameters() const
ZS_threshold
thresholds for setting fine grain bit
void addUpgradeFG(const HcalTrigTowerDetId &id, int depth, const std::vector< std::bitset< 2 >> &bits)
unsigned int readoutVMECrateId() const
HcalElectronicsId-style VME crate number.
Definition: HcalHTRData.cc:347
int presamples() const
for backward compatibility
const HcaluLUTTPGCoder * incoder_
static const int SPIGOT_COUNT
Definition: HcalDCCHeader.h:19
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
static unsigned int const shift
const HcalDetId & id() const
Definition: HBHEDataFrame.h:27
virtual bool fineGrainbit(const QIE10DataFrame &short1, const QIE10DataFrame &short2, const QIE10DataFrame &long1, const QIE10DataFrame &long2, bool validShort1, bool validShort2, bool validLong1, bool validLong2, int idx) const =0
int presamples() const
number of samples before the sample from the triggered beam crossing (according to the hardware) ...
Definition: HFDataFrame.h:32
DetId id() const
get the (generic) id
int samples() const
total number of samples in the digi
latency
hardware algo
Readout chain identification for Hcal.
void addSignal(const HBHEDataFrame &frame)
adds the signal to the map
void setUpgradeFlags(bool hb, bool he, bool hf)
void overrideParameters(const edm::ParameterSet &ps)
const DetId lookup(HcalElectronicsId fId) const
lookup the logical detid associated with the given electronics id
int getADCThresholdHF() const
get ADC threshold fof TDC mask of HF
bool isHistogramEvent() const
Is this event a histogram event? (do not call standard unpack in this case!!!!!)
Definition: HcalHTRData.cc:386
const_iterator begin() const
uint32_t getMask() const
get mask for channel validity and self trigger information
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:39