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