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  unsigned int sample = samples[ibin+i];
381  if(ids.size()==2) algosumvalue += int(sample * 0.5 * weights_[i]);
382  else algosumvalue += int(sample * weights_[i]);
383  }
384  if (algosumvalue<0) sum[ibin]=0; // low-side
385  //high-side
386  //else if (algosumvalue>QIE11_LINEARIZATION_ET) sum[ibin]=QIE11_LINEARIZATION_ET;
387  else sum[ibin] = algosumvalue; //assign value to sum[]
388  }
389 
390  // Align digis and TP
391  int dgPresamples=samples.presamples();
392  int tpPresamples=numberOfPresamples_;
393  int shift = dgPresamples - tpPresamples;
394  int dgSamples=samples.size();
395  int tpSamples=numberOfSamples_;
396 
397  if((shift<shrink) || (shift + tpSamples + shrink > dgSamples - (peak_finder_algorithm_ - 1) ) ){
398  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyze") <<
399  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
400  shift=shrink;
401  tpPresamples=dgPresamples-shrink;
402  tpSamples=dgSamples-(peak_finder_algorithm_-1)-shrink-shift;
403  }
404 
405  std::vector<int> finegrain(tpSamples,false);
406 
407  IntegerCaloSamples output(samples.id(), tpSamples);
408  output.setPresamples(tpPresamples);
409 
410  for (int ibin = 0; ibin < tpSamples; ++ibin) {
411  // ibin - index for output TP
412  // idx - index for samples + shift
413  int idx = ibin + shift;
414  bool isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
415 
416  if (isPeak){
417  output[ibin] = std::min<unsigned int>(sum[idx],QIE11_MAX_LINEARIZATION_ET);
418  finegrain[ibin] = fg_algo.compute(msb[idx]).to_ulong();
419  } else {
420  // Not a peak
421  output[ibin] = 0;
422  finegrain[ibin] = 0;
423  }
424  }
425  outcoder_->compress(output, finegrain, result);
426 }
427 
428 
430  HcalTrigTowerDetId detId(samples.id());
431 
432  // Align digis and TP
433  int dgPresamples=samples.presamples();
434  int tpPresamples=numberOfPresamplesHF_;
435  int shift = dgPresamples - tpPresamples;
436  int dgSamples=samples.size();
437  int tpSamples=numberOfSamplesHF_;
438  if(shift<0 || shift+tpSamples>dgSamples){
439  edm::LogInfo("HcalTriggerPrimitiveAlgo::analyzeHF") <<
440  "TP presample or size from the configuration file is out of the accessible range. Using digi values from data instead...";
441  tpPresamples=dgPresamples;
442  shift=0;
443  tpSamples=dgSamples;
444  }
445 
446  std::vector<int> finegrain(tpSamples, false);
447 
448  TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
449  assert(tower2fg != theTowerMapFGSum.end());
450 
451  const SumFGContainer& sumFG = tower2fg->second;
452  // Loop over all L+S pairs that mapped from samples.id()
453  // Note: 1 samples.id() = 6 x (L+S) without noZS
454  for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
455  const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
456  for (int ibin = 0; ibin < tpSamples; ++ibin) {
457  int idx = ibin + shift;
458  // if not vetod, add L+S to total sum and calculate FG
459  bool vetoed = idx<int(veto.size()) && veto[idx];
460  if (!(vetoed && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
461  samples[idx] += (*sumFGItr)[idx];
462  finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
463  }
464  }
465  }
466 
467  IntegerCaloSamples output(samples.id(), tpSamples);
468  output.setPresamples(tpPresamples);
469 
470  for (int ibin = 0; ibin < tpSamples; ++ibin) {
471  int idx = ibin + shift;
472  output[ibin] = samples[idx] >> hf_lumi_shift;
473  static const int MAX_OUTPUT = QIE8_LINEARIZATION_ET; // QIE8_LINEARIZATION_ET = 1023
474  if (output[ibin] > MAX_OUTPUT) output[ibin] = MAX_OUTPUT;
475  }
476  outcoder_->compress(output, finegrain, result);
477 }
478 
482  const int hf_lumi_shift,
483  const HcalFeatureBit* embit
484  ) {
485  // Align digis and TP
486  const int SHIFT = samples.presamples() - numberOfPresamplesHF_;
487  assert(SHIFT >= 0);
488  assert((SHIFT + numberOfSamplesHF_) <= samples.size());
489 
490  // Try to find the HFDetails from the map corresponding to our samples
491  const HcalTrigTowerDetId detId(samples.id());
492  HFDetailMap::const_iterator it = theHFDetailMap.find(detId);
493  // Missing values will give an empty digi
494  if (it == theHFDetailMap.end()) {
495  return;
496  }
497 
498  std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
499 
500  // Set up out output of IntergerCaloSamples
502  output.setPresamples(numberOfPresamplesHF_);
503 
504  for (const auto& item: it->second) {
505  auto& details = item.second;
506  for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
507  const int IDX = ibin + SHIFT;
508  int long_fiber_val = 0;
509  if (IDX < details.long_fiber.size()) {
510  long_fiber_val = details.long_fiber[IDX];
511  }
512  int short_fiber_val = 0;
513  if (IDX < details.short_fiber.size()) {
514  short_fiber_val = details.short_fiber[IDX];
515  }
516  output[ibin] += (long_fiber_val + short_fiber_val);
517 
518  uint32_t ADCLong = details.LongDigi[ibin].adc();
519  uint32_t ADCShort = details.ShortDigi[ibin].adc();
520 
521  if (details.LongDigi.id().ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
522  finegrain[ibin][1] = (ADCLong > FG_HF_threshold_ || ADCShort > FG_HF_threshold_);
523 
524  if (embit != nullptr)
525  finegrain[ibin][0] = embit->fineGrainbit(details.ShortDigi, details.LongDigi, ibin);
526  }
527  }
528  }
529 
530  for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
531  static const unsigned int MAX_OUTPUT = QIE8_LINEARIZATION_ET; // QIE8_LINEARIZATION_ET = 1023
532  output[bin] = min({MAX_OUTPUT, output[bin] >> hf_lumi_shift});
533  }
534 
535  std::vector<int> finegrain_converted;
536  for (const auto& fg: finegrain)
537  finegrain_converted.push_back(fg.to_ulong());
538  outcoder_->compress(output, finegrain_converted, result);
539 }
540 
541 bool
543 {
544  // channels with invalid data should not contribute to the sum
545  if(digi.linkError() || ts>=digi.samples() || !digi[ts].ok()) return false;
546 
548  if (mask)
549  return false;
550 
552  auto adc_threshold = parameters->getADCThresholdHF();
553  auto tdc_mask = parameters->getTDCMaskHF();
554 
555  if (override_adc_hf_)
556  adc_threshold = override_adc_hf_value_;
557  if (override_tdc_hf_)
558  tdc_mask = override_tdc_hf_value_;
559 
560  if (digi[ts].adc() < adc_threshold)
561  return true;
562 
563  return (1ul << digi[ts].le_tdc()) & tdc_mask;
564 }
565 
568  const int hf_lumi_shift, const HcalFeatureBit* embit)
569 {
570  // Align digis and TP
571  const int shift = samples.presamples() - numberOfPresamplesHF_;
572  assert(shift >= 0);
573  assert((shift + numberOfSamplesHF_) <= samples.size());
574  assert(hf_lumi_shift>=2);
575 
576  // Try to find the HFDetails from the map corresponding to our samples
577  const HcalTrigTowerDetId detId(samples.id());
578  auto it = theHFUpgradeDetailMap.find(detId);
579  // Missing values will give an empty digi
580  if (it == theHFUpgradeDetailMap.end()) {
581  return;
582  }
583 
584  std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
585 
586  // Set up out output of IntergerCaloSamples
588  output.setPresamples(numberOfPresamplesHF_);
589 
590  for (const auto& item: it->second) {
591  auto& details = item.second;
592  for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
593  const int idx = ibin + shift;
594 
595  int long_fiber_val = 0;
596  int long_fiber_count = 0;
597  int short_fiber_val = 0;
598  int short_fiber_count = 0;
599 
600  bool saturated = false;
601 
602  for (auto i: {0, 2}) {
603  if (idx < details[i].samples.size() and details[i].validity[idx]) {
604  long_fiber_val += details[i].samples[idx];
605  saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
606  ++long_fiber_count;
607  }
608  }
609  for (auto i: {1, 3}) {
610  if (idx < details[i].samples.size() and details[i].validity[idx]) {
611  short_fiber_val += details[i].samples[idx];
612  saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
613  ++short_fiber_count;
614  }
615  }
616 
617  if (saturated) {
619  } else {
620  // For details of the energy handling, see:
621  // https://cms-docdb.cern.ch/cgi-bin/DocDB/ShowDocument?docid=12306
622  // If both readouts are valid, average of the two energies is taken
623  // division by 2 is compensated by adjusting the total scale shift in the end
624  if (long_fiber_count == 2) long_fiber_val >>=1;
625  if (short_fiber_count == 2) short_fiber_val >>=1;
626 
627  auto sum = long_fiber_val + short_fiber_val;
628  // Similar to above, if both channels are valid,
629  // average of the two energies is calculated
630  // division by 2 here is also compensated by adjusting the total scale shift in the end
631  if (long_fiber_count > 0 and short_fiber_count > 0) sum >>=1;
632 
633  output[ibin] += sum;
634  }
635 
636  for (const auto& detail: details) {
637  if (idx < int(detail.digi.size()) and detail.validity[idx] and HcalDetId(detail.digi.id()).ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
638  finegrain[ibin][1] = finegrain[ibin][1] or detail.fgbit[idx];
639  }
640  }
641 
642  if (embit != nullptr) {
643  finegrain[ibin][0] = embit->fineGrainbit(
644  details[1].digi, details[3].digi,
645  details[0].digi, details[2].digi,
646  details[1].validity[idx], details[3].validity[idx],
647  details[0].validity[idx], details[2].validity[idx],
648  idx
649  );
650  }
651  }
652  }
653 
654  for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
655  output[bin] = min({(unsigned int) QIE10_MAX_LINEARIZATION_ET, output[bin] >> (hf_lumi_shift-2)});
656  }
657  std::vector<int> finegrain_converted;
658  for (const auto& fg: finegrain)
659  finegrain_converted.push_back(fg.to_ulong());
660  outcoder_->compress(output, finegrain_converted, result);
661 }
662 
664  for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
665  bool ZS = true;
666  for (int i=0; i<tp->size(); ++i) {
667  if (tp->sample(i).compressedEt() > ZS_threshold_I_) {
668  ZS=false;
669  break;
670  }
671  }
672  if (ZS) tp->setZSInfo(false,true);
673  else tp->setZSInfo(true,false);
674  }
675 }
676 
678  const HcalElectronicsMap *emap,
680  ){
681  std::set<uint32_t> FrontEndErrors;
682 
684  const FEDRawData& raw = rawraw->FEDData(i);
685  if (raw.size()<12) continue;
686  const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
687  if(!dccHeader) continue;
688  HcalHTRData htr;
689  for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
690  if (!dccHeader->getSpigotPresent(spigot)) continue;
691  dccHeader->getSpigotData(spigot,htr,raw.size());
692  int dccid = dccHeader->getSourceId();
693  int errWord = htr.getErrorsWord() & 0x1FFFF;
694  bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800)!=0);
695 
696  if(HTRError) {
697  bool valid =false;
698  for(int fchan=0; fchan<3 && !valid; fchan++) {
699  for(int fib=0; fib<9 && !valid; fib++) {
700  HcalElectronicsId eid(fchan,fib,spigot,dccid-FEDNumbering::MINHCALFEDID);
701  eid.setHTR(htr.readoutVMECrateId(),htr.htrSlot(),htr.htrTopBottom());
702  DetId detId = emap->lookup(eid);
703  if(detId.null()) continue;
704  HcalSubdetector subdet=(HcalSubdetector(detId.subdetId()));
705  if (detId.det()!=4||
706  (subdet!=HcalBarrel && subdet!=HcalEndcap &&
707  subdet!=HcalForward )) continue;
708  std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
709  for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId=ids.begin(); triggerId != ids.end(); ++triggerId) {
710  FrontEndErrors.insert(triggerId->rawId());
711  }
712  //valid = true;
713  }
714  }
715  }
716  }
717  }
718 
719  // Loop over TP collection
720  // Set TP to zero if there is FE Format Error
721  HcalTriggerPrimitiveSample zeroSample(0);
722  for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
723  if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
724  for (int i=0; i<tp->size(); ++i) tp->setSample(i, zeroSample);
725  }
726  }
727 }
728 
729 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb){
730  FGbitMap::iterator itr = fgMap_.find(id);
731  if (itr != fgMap_.end()){
732  std::vector<bool>& _msb = itr->second;
733  for (size_t i=0; i<msb.size(); ++i)
734  _msb[i] = _msb[i] || msb[i];
735  }
736  else fgMap_[id] = msb;
737 }
738 
739 bool
741 {
742  if (depth > LAST_FINEGRAIN_DEPTH)
743  return false;
744  if (id.ietaAbs() > LAST_FINEGRAIN_TOWER)
745  return false;
746  if (id.ietaAbs() == HBHE_OVERLAP_TOWER and not upgrade_hb_)
747  return false;
748  return true;
749 }
750 
751 bool
753 {
754  // This tower (ietaAbs == 16) does not accept upgraded FG bits,
755  // but needs pseudo legacy ones to ensure that the tower is processed
756  // even when the QIE8 depths in front of it do not have energy deposits.
757  if (id.ietaAbs() == HBHE_OVERLAP_TOWER and not upgrade_hb_)
758  return true;
759  return false;
760 }
761 
762 void
763 HcalTriggerPrimitiveAlgo::addUpgradeFG(const HcalTrigTowerDetId& id, int depth, const std::vector<std::bitset<2>>& bits)
764 {
765  if (not validUpgradeFG(id, depth)) {
766  if (needLegacyFG(id)) {
767  std::vector<bool> pseudo(bits.size(), false);
768  addFG(id, pseudo);
769  }
770  return;
771  }
772 
773  auto it = fgUpgradeMap_.find(id);
774  if (it == fgUpgradeMap_.end()) {
775  FGUpgradeContainer element;
776  element.resize(bits.size());
777  it = fgUpgradeMap_.insert(std::make_pair(id, element)).first;
778  }
779  for (unsigned int i = 0; i < bits.size(); ++i) {
780  it->second[i][0][depth] = bits[i][0];
781  it->second[i][1][depth] = bits[i][1];
782  }
783 }
784 
786  if (algo <=0 && algo>2)
787  throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
789 }
790 
793 }
794 
797 }
int adc(sample_type sample)
get the ADC sample (12 bits)
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 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:142
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:49
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
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
int getSpigotData(int nspigot, HcalHTRData &decodeTool, int validSize) const
uint32_t maskDepth() const
get the tower depth
Definition: HcalDetId.h:175
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:162
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
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
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< 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
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
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: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
void analyzeHF2017(const IntegerCaloSamples &SAMPLES, HcalTriggerPrimitiveDigi &result, const int HF_LUMI_SHIFT, const HcalFeatureBit *HCALFEM)
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
void analyze2017(IntegerCaloSamples &samples, HcalTriggerPrimitiveDigi &result, const HcalFinegrainBit &fg_algo)
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:39