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_(0), outcoder_(0),
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  IntegerCaloSamples samples(id, frame.samples());
212  samples.setPresamples(frame.presamples());
213  incoder_->adc2Linear(frame, samples);
214 
215  // Don't add to final collection yet
216  // HF PMT veto sum is calculated in analyzerHF()
217  IntegerCaloSamples zero_samples(id, frame.samples());
218  zero_samples.setPresamples(frame.presamples());
219  addSignal(zero_samples);
220 
221  auto fid = HcalDetId(frame.id());
222  auto& details = theHFUpgradeDetailMap[id][fid.maskDepth()];
223  details[fid.depth() - 1].samples = samples;
224  details[fid.depth() - 1].digi = frame;
225  details[fid.depth() - 1].validity.resize(frame.samples());
226  for (int idx = 0; idx < frame.samples(); ++idx)
227  details[fid.depth() - 1].validity[idx] = validChannel(frame, idx);
228  }
229 }
230 
231 void
233 {
234  HcalDetId detId(frame.id());
235  // prevent QIE11 calibration channels from entering TP emulation
236  if(detId.subdet() != HcalEndcap && detId.subdet() != HcalBarrel) return;
237 
238  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
239  assert(ids.size() == 1 || ids.size() == 2);
240  IntegerCaloSamples samples1(ids[0], int(frame.samples()));
241 
242  samples1.setPresamples(frame.presamples());
243  incoder_->adc2Linear(frame, samples1);
244 
245  std::vector<std::bitset<2>> msb(frame.samples(), 0);
246  incoder_->lookupMSB(frame, msb);
247 
248  if(ids.size() == 2) {
249  // make a second trigprim for the other one, and share the energy
250  IntegerCaloSamples samples2(ids[1], samples1.size());
251  for(int i = 0; i < samples1.size(); ++i) {
252  samples1[i] = uint32_t(samples1[i]);
253  samples2[i] = samples1[i];
254  }
255  samples2.setPresamples(frame.presamples());
256  addSignal(samples2);
257  addUpgradeFG(ids[1], detId.depth(), msb);
258  }
259  addSignal(samples1);
260  addUpgradeFG(ids[0], detId.depth(), msb);
261 }
262 
264  HcalTrigTowerDetId id(samples.id());
265  SumMap::iterator itr = theSumMap.find(id);
266  if(itr == theSumMap.end()) {
267  theSumMap.insert(std::make_pair(id, samples));
268  }
269  else {
270  // wish CaloSamples had a +=
271  for(int i = 0; i < samples.size(); ++i) {
272  (itr->second)[i] += samples[i];
273  }
274  }
275 }
276 
277 
279  int shrink = weights_.size() - 1;
280  std::vector<bool>& msb = fgMap_[samples.id()];
281  IntegerCaloSamples sum(samples.id(), samples.size());
282 
283  //slide algo window
284  for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
285  int algosumvalue = 0;
286  for(unsigned int i = 0; i < weights_.size(); i++) {
287  //add up value * scale factor
288  algosumvalue += int(samples[ibin+i] * weights_[i]);
289  }
290  if (algosumvalue<0) sum[ibin]=0; // low-side
291  //high-side
292  //else if (algosumvalue>QIE8_LINEARIZATION_ET) sum[ibin]=QIE8_LINEARIZATION_ET;
293  else sum[ibin] = algosumvalue; //assign value to sum[]
294  }
295 
296  // Align digis and TP
297  int dgPresamples=samples.presamples();
298  int tpPresamples=numberOfPresamples_;
299  int shift = dgPresamples - tpPresamples;
300  int dgSamples=samples.size();
301  int tpSamples=numberOfSamples_;
302  if(peakfind_){
303  if((shift<shrink) || (shift + tpSamples + shrink > dgSamples - (peak_finder_algorithm_ - 1) ) ){
304  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyze") <<
305  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
306  shift=shrink;
307  tpPresamples=dgPresamples-shrink;
308  tpSamples=dgSamples-(peak_finder_algorithm_-1)-shrink-shift;
309  }
310  }
311 
312  std::vector<int> finegrain(tpSamples,false);
313 
314  IntegerCaloSamples output(samples.id(), tpSamples);
315  output.setPresamples(tpPresamples);
316 
317  for (int ibin = 0; ibin < tpSamples; ++ibin) {
318  // ibin - index for output TP
319  // idx - index for samples + shift
320  int idx = ibin + shift;
321 
322  //Peak finding
323  if (peakfind_) {
324  bool isPeak = false;
325  switch (peak_finder_algorithm_) {
326  case 1 :
327  isPeak = (samples[idx] > samples[idx-1] && samples[idx] >= samples[idx+1] && samples[idx] > theThreshold);
328  break;
329  case 2:
330  isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
331  break;
332  default:
333  break;
334  }
335 
336  if (isPeak){
337  output[ibin] = std::min<unsigned int>(sum[idx],QIE8_LINEARIZATION_ET);
338  finegrain[ibin] = msb[idx];
339  }
340  // Not a peak
341  else output[ibin] = 0;
342  }
343  else { // No peak finding, just output running sum
344  output[ibin] = std::min<unsigned int>(sum[idx],QIE8_LINEARIZATION_ET);
345  finegrain[ibin] = msb[idx];
346  }
347 
348  // Only Pegged for 1-TS algo.
349  if (peak_finder_algorithm_ == 1) {
350  if (samples[idx] >= QIE8_LINEARIZATION_ET)
352  }
353  }
354  outcoder_->compress(output, finegrain, result);
355 }
356 
357 
358 void
360 {
361  int shrink = weights_.size() - 1;
362  auto& msb = fgUpgradeMap_[samples.id()];
363  IntegerCaloSamples sum(samples.id(), samples.size());
364 
365  HcalDetId detId(samples.id());
366  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
367  //slide algo window
368  for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
369  int algosumvalue = 0;
370  for(unsigned int i = 0; i < weights_.size(); i++) {
371  //add up value * scale factor
372  // In addition, divide by two in the 10 degree phi segmentation region
373  // to mimic 5 degree segmentation for the trigger
374  if(ids.size()==2) algosumvalue += int(samples[ibin+i] * 0.5 * weights_[i]);
375  else algosumvalue += int(samples[ibin+i] * weights_[i]);
376  }
377  if (algosumvalue<0) sum[ibin]=0; // low-side
378  //high-side
379  //else if (algosumvalue>QIE11_LINEARIZATION_ET) sum[ibin]=QIE11_LINEARIZATION_ET;
380  else sum[ibin] = algosumvalue; //assign value to sum[]
381  }
382 
383  // Align digis and TP
384  int dgPresamples=samples.presamples();
385  int tpPresamples=numberOfPresamples_;
386  int shift = dgPresamples - tpPresamples;
387  int dgSamples=samples.size();
388  int tpSamples=numberOfSamples_;
389 
390  if((shift<shrink) || (shift + tpSamples + shrink > dgSamples - (peak_finder_algorithm_ - 1) ) ){
391  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyze") <<
392  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
393  shift=shrink;
394  tpPresamples=dgPresamples-shrink;
395  tpSamples=dgSamples-(peak_finder_algorithm_-1)-shrink-shift;
396  }
397 
398  std::vector<int> finegrain(tpSamples,false);
399 
400  IntegerCaloSamples output(samples.id(), tpSamples);
401  output.setPresamples(tpPresamples);
402 
403  for (int ibin = 0; ibin < tpSamples; ++ibin) {
404  // ibin - index for output TP
405  // idx - index for samples + shift
406  int idx = ibin + shift;
407  bool isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
408 
409  if (isPeak){
410  output[ibin] = std::min<unsigned int>(sum[idx],QIE11_MAX_LINEARIZATION_ET);
411  finegrain[ibin] = fg_algo.compute(msb[idx]).to_ulong();
412  } else {
413  // Not a peak
414  output[ibin] = 0;
415  finegrain[ibin] = 0;
416  }
417  }
418  outcoder_->compress(output, finegrain, result);
419 }
420 
421 
423  HcalTrigTowerDetId detId(samples.id());
424 
425  // Align digis and TP
426  int dgPresamples=samples.presamples();
427  int tpPresamples=numberOfPresamplesHF_;
428  int shift = dgPresamples - tpPresamples;
429  int dgSamples=samples.size();
430  int tpSamples=numberOfSamplesHF_;
431  if(shift<0 || shift+tpSamples>dgSamples){
432  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyzeHF") <<
433  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
434  tpPresamples=dgPresamples;
435  shift=0;
436  tpSamples=dgSamples;
437  }
438 
439  std::vector<int> finegrain(tpSamples, false);
440 
441  TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
442  assert(tower2fg != theTowerMapFGSum.end());
443 
444  const SumFGContainer& sumFG = tower2fg->second;
445  // Loop over all L+S pairs that mapped from samples.id()
446  // Note: 1 samples.id() = 6 x (L+S) without noZS
447  for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
448  const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
449  for (int ibin = 0; ibin < tpSamples; ++ibin) {
450  int idx = ibin + shift;
451  // if not vetod, add L+S to total sum and calculate FG
452  bool vetoed = idx<int(veto.size()) && veto[idx];
453  if (!(vetoed && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
454  samples[idx] += (*sumFGItr)[idx];
455  finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
456  }
457  }
458  }
459 
460  IntegerCaloSamples output(samples.id(), tpSamples);
461  output.setPresamples(tpPresamples);
462 
463  for (int ibin = 0; ibin < tpSamples; ++ibin) {
464  int idx = ibin + shift;
465  output[ibin] = samples[idx] >> hf_lumi_shift;
466  static const int MAX_OUTPUT = QIE8_LINEARIZATION_ET; // QIE8_LINEARIZATION_ET = 1023
467  if (output[ibin] > MAX_OUTPUT) output[ibin] = MAX_OUTPUT;
468  }
469  outcoder_->compress(output, finegrain, result);
470 }
471 
475  const int hf_lumi_shift,
476  const HcalFeatureBit* embit
477  ) {
478  // Align digis and TP
479  const int SHIFT = samples.presamples() - numberOfPresamplesHF_;
480  assert(SHIFT >= 0);
481  assert((SHIFT + numberOfSamplesHF_) <= samples.size());
482 
483  // Try to find the HFDetails from the map corresponding to our samples
484  const HcalTrigTowerDetId detId(samples.id());
485  HFDetailMap::const_iterator it = theHFDetailMap.find(detId);
486  // Missing values will give an empty digi
487  if (it == theHFDetailMap.end()) {
488  return;
489  }
490 
491  std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
492 
493  // Set up out output of IntergerCaloSamples
495  output.setPresamples(numberOfPresamplesHF_);
496 
497  for (const auto& item: it->second) {
498  auto& details = item.second;
499  for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
500  const int IDX = ibin + SHIFT;
501  int long_fiber_val = 0;
502  if (IDX < details.long_fiber.size()) {
503  long_fiber_val = details.long_fiber[IDX];
504  }
505  int short_fiber_val = 0;
506  if (IDX < details.short_fiber.size()) {
507  short_fiber_val = details.short_fiber[IDX];
508  }
509  output[ibin] += (long_fiber_val + short_fiber_val);
510 
511  uint32_t ADCLong = details.LongDigi[ibin].adc();
512  uint32_t ADCShort = details.ShortDigi[ibin].adc();
513 
514  if (details.LongDigi.id().ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
515  finegrain[ibin][1] = (ADCLong > FG_HF_threshold_ || ADCShort > FG_HF_threshold_);
516 
517  if (embit != 0)
518  finegrain[ibin][0] = embit->fineGrainbit(details.ShortDigi, details.LongDigi, ibin);
519  }
520  }
521  }
522 
523  for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
524  static const unsigned int MAX_OUTPUT = QIE8_LINEARIZATION_ET; // QIE8_LINEARIZATION_ET = 1023
525  output[bin] = min({MAX_OUTPUT, output[bin] >> hf_lumi_shift});
526  }
527 
528  std::vector<int> finegrain_converted;
529  for (const auto& fg: finegrain)
530  finegrain_converted.push_back(fg.to_ulong());
531  outcoder_->compress(output, finegrain_converted, result);
532 }
533 
534 bool
536 {
537  // channels with invalid data should not contribute to the sum
538  if(digi.linkError() || ts>=digi.samples() || !digi[ts].ok()) return false;
539 
541  if (mask)
542  return false;
543 
545  auto adc_threshold = parameters->getADCThresholdHF();
546  auto tdc_mask = parameters->getTDCMaskHF();
547 
548  if (override_adc_hf_)
549  adc_threshold = override_adc_hf_value_;
550  if (override_tdc_hf_)
551  tdc_mask = override_tdc_hf_value_;
552 
553  if (digi[ts].adc() < adc_threshold)
554  return true;
555 
556  return (1ul << digi[ts].le_tdc()) & tdc_mask;
557 }
558 
561  const int hf_lumi_shift, const HcalFeatureBit* embit)
562 {
563  // Align digis and TP
564  const int shift = samples.presamples() - numberOfPresamplesHF_;
565  assert(shift >= 0);
566  assert((shift + numberOfSamplesHF_) <= samples.size());
567  assert(hf_lumi_shift>=2);
568 
569  // Try to find the HFDetails from the map corresponding to our samples
570  const HcalTrigTowerDetId detId(samples.id());
571  auto it = theHFUpgradeDetailMap.find(detId);
572  // Missing values will give an empty digi
573  if (it == theHFUpgradeDetailMap.end()) {
574  return;
575  }
576 
577  std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
578 
579  // Set up out output of IntergerCaloSamples
581  output.setPresamples(numberOfPresamplesHF_);
582 
583  for (const auto& item: it->second) {
584  auto& details = item.second;
585  for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
586  const int idx = ibin + shift;
587 
588  int long_fiber_val = 0;
589  int long_fiber_count = 0;
590  int short_fiber_val = 0;
591  int short_fiber_count = 0;
592 
593  bool saturated = false;
594 
595  for (auto i: {0, 2}) {
596  if (idx < details[i].samples.size() and details[i].validity[idx]) {
597  long_fiber_val += details[i].samples[idx];
598  saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
599  ++long_fiber_count;
600  }
601  }
602  for (auto i: {1, 3}) {
603  if (idx < details[i].samples.size() and details[i].validity[idx]) {
604  short_fiber_val += details[i].samples[idx];
605  saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
606  ++short_fiber_count;
607  }
608  }
609 
610  if (saturated) {
612  } else {
613  // For details of the energy handling, see:
614  // https://cms-docdb.cern.ch/cgi-bin/DocDB/ShowDocument?docid=12306
615  // If both readouts are valid, average of the two energies is taken
616  // division by 2 is compensated by adjusting the total scale shift in the end
617  if (long_fiber_count == 2) long_fiber_val >>=1;
618  if (short_fiber_count == 2) short_fiber_val >>=1;
619 
620  auto sum = long_fiber_val + short_fiber_val;
621  // Similar to above, if both channels are valid,
622  // average of the two energies is calculated
623  // division by 2 here is also compensated by adjusting the total scale shift in the end
624  if (long_fiber_count > 0 and short_fiber_count > 0) sum >>=1;
625 
626  output[ibin] += sum;
627  }
628 
629  for (const auto& detail: details) {
630  if (idx < int(detail.digi.size()) and detail.validity[idx] and HcalDetId(detail.digi.id()).ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
631  finegrain[ibin][1] = finegrain[ibin][1] or (detail.digi[idx].adc() > (int) FG_HF_threshold_);
632  }
633  }
634 
635  if (embit != 0) {
636  finegrain[ibin][0] = embit->fineGrainbit(
637  details[1].digi, details[3].digi,
638  details[0].digi, details[2].digi,
639  details[1].validity[idx], details[3].validity[idx],
640  details[0].validity[idx], details[2].validity[idx],
641  idx
642  );
643  }
644  }
645  }
646 
647  for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
648  output[bin] = min({(unsigned int) QIE10_MAX_LINEARIZATION_ET, output[bin] >> (hf_lumi_shift-2)});
649  }
650  std::vector<int> finegrain_converted;
651  for (const auto& fg: finegrain)
652  finegrain_converted.push_back(fg.to_ulong());
653  outcoder_->compress(output, finegrain_converted, result);
654 }
655 
657  for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
658  bool ZS = true;
659  for (int i=0; i<tp->size(); ++i) {
660  if (tp->sample(i).compressedEt() > ZS_threshold_I_) {
661  ZS=false;
662  break;
663  }
664  }
665  if (ZS) tp->setZSInfo(false,true);
666  else tp->setZSInfo(true,false);
667  }
668 }
669 
671  const HcalElectronicsMap *emap,
673  ){
674  std::set<uint32_t> FrontEndErrors;
675 
677  const FEDRawData& raw = rawraw->FEDData(i);
678  if (raw.size()<12) continue;
679  const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
680  if(!dccHeader) continue;
681  HcalHTRData htr;
682  for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
683  if (!dccHeader->getSpigotPresent(spigot)) continue;
684  dccHeader->getSpigotData(spigot,htr,raw.size());
685  int dccid = dccHeader->getSourceId();
686  int errWord = htr.getErrorsWord() & 0x1FFFF;
687  bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800)!=0);
688 
689  if(HTRError) {
690  bool valid =false;
691  for(int fchan=0; fchan<3 && !valid; fchan++) {
692  for(int fib=0; fib<9 && !valid; fib++) {
693  HcalElectronicsId eid(fchan,fib,spigot,dccid-FEDNumbering::MINHCALFEDID);
694  eid.setHTR(htr.readoutVMECrateId(),htr.htrSlot(),htr.htrTopBottom());
695  DetId detId = emap->lookup(eid);
696  if(detId.null()) continue;
697  HcalSubdetector subdet=(HcalSubdetector(detId.subdetId()));
698  if (detId.det()!=4||
699  (subdet!=HcalBarrel && subdet!=HcalEndcap &&
700  subdet!=HcalForward )) continue;
701  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
702  for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId=ids.begin(); triggerId != ids.end(); ++triggerId) {
703  FrontEndErrors.insert(triggerId->rawId());
704  }
705  //valid = true;
706  }
707  }
708  }
709  }
710  }
711 
712  // Loop over TP collection
713  // Set TP to zero if there is FE Format Error
714  HcalTriggerPrimitiveSample zeroSample(0);
715  for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
716  if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
717  for (int i=0; i<tp->size(); ++i) tp->setSample(i, zeroSample);
718  }
719  }
720 }
721 
722 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb){
723  FGbitMap::iterator itr = fgMap_.find(id);
724  if (itr != fgMap_.end()){
725  std::vector<bool>& _msb = itr->second;
726  for (size_t i=0; i<msb.size(); ++i)
727  _msb[i] = _msb[i] || msb[i];
728  }
729  else fgMap_[id] = msb;
730 }
731 
732 bool
734 {
735  if (depth > LAST_FINEGRAIN_DEPTH)
736  return false;
737  if (id.ietaAbs() > LAST_FINEGRAIN_TOWER)
738  return false;
739  return true;
740 }
741 
742 void
743 HcalTriggerPrimitiveAlgo::addUpgradeFG(const HcalTrigTowerDetId& id, int depth, const std::vector<std::bitset<2>>& bits)
744 {
745  if (not validUpgradeFG(id, depth)) {
746  return;
747  }
748 
749  auto it = fgUpgradeMap_.find(id);
750  if (it == fgUpgradeMap_.end()) {
751  FGUpgradeContainer element;
752  element.resize(bits.size());
753  it = fgUpgradeMap_.insert(std::make_pair(id, element)).first;
754  }
755  for (unsigned int i = 0; i < bits.size(); ++i) {
756  it->second[i][0][depth] = bits[i][0];
757  it->second[i][1][depth] = bits[i][1];
758  }
759 }
760 
762  if (algo <=0 && algo>2)
763  throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
765 }
766 
769 }
770 
773 }
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
virtual 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:342
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)
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:338
int depth() const
get the tower depth
Definition: HcalDetId.cc:108
const HcalTrigTowerGeometry * theTrigTowerGeometry
FG_HF_threshold
threshold for setting fine grain bit
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:37
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:45
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:346
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:35
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
bool isHistogramEvent() const
Is this event a histogram event? (do not call standard unpack in this case!!!!!)
Definition: HcalHTRData.cc:385
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)