CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
EcalSelectiveReadoutSuppressor.cc
Go to the documentation of this file.
6 
7 // Geometry
13 
15 
16 //exceptions:
18 
19 #include <cmath>
20 #include <iostream>
21 #include <limits>
22 #include <memory>
23 
24 using namespace boost;
25 using namespace std;
26 
28 
31  : ttThresOnCompressedEt_(false), ievt_(0), geoToken_(iC.esConsumes()) {
32  int defTtf = params.getParameter<int>("defaultTtf");
33  if (defTtf < 0 || defTtf > 7) {
34  throw cms::Exception("InvalidParameter") << "Value of EcalSelectiveReadoutProducer module parameter defaultTtf, "
35  << defaultTtf_ << ", is out of the valid range 0..7\n";
36  } else {
38  }
39 
40  trigPrimBypass_ = params.getParameter<bool>("trigPrimBypass");
41  trigPrimBypassMode_ = params.getParameter<int>("trigPrimBypassMode");
42  trigPrimBypassWithPeakFinder_ = params.getParameter<bool>("trigPrimBypassWithPeakFinder");
43  trigPrimBypassLTH_ = params.getParameter<double>("trigPrimBypassLTH");
44  trigPrimBypassHTH_ = params.getParameter<double>("trigPrimBypassHTH");
45  if (trigPrimBypass_) {
46  edm::LogWarning("Digitization") << "Beware a simplified trigger primitive "
47  "computation is used for the ECAL selective readout";
48  if (trigPrimBypassMode_ != 0 && trigPrimBypassMode_ != 1) {
49  throw cms::Exception("InvalidParameter")
50  << "Invalid value for EcalSelectiveReadoutProducer parameter 'trigPrimBypassMode_'."
51  " Valid values are 0 and 1.\n";
52  }
53  ttThresOnCompressedEt_ = (trigPrimBypassMode_ == 1);
54  }
55 }
56 
58  firstFIRSample = settings->ecalDccZs1stSample_[0];
59  weights = settings->dccNormalizedWeights_[0];
60  symetricZS = settings->symetricZS_[0];
61  actions_ = settings->actions_;
62 
63  //online configuration has only 4 actions flags, the 4 'forced' flags being the same with the force
64  //bit set to 1. Extends the actions vector for case of online-type configuration:
65  if (actions_.size() == 4) {
66  for (int i = 0; i < 4; ++i) {
67  actions_.push_back(actions_[i] | 0x4);
68  }
69  }
70 
71  bool actionValid = actions_.size() == 8;
72  for (size_t i = 0; i < actions_.size(); ++i) {
73  if (actions_[i] < 0 || actions_[i] > 7)
74  actionValid = false;
75  }
76 
77  if (!actionValid) {
78  throw cms::Exception("InvalidParameter")
79  << "EcalSelectiveReadoutProducer module parameter 'actions' is "
80  "not valid. It must be a vector of 8 integer values comprised between 0 and 7\n";
81  }
82 
83  double adcToGeV = settings->ebDccAdcToGeV_;
84  thrUnit[BARREL] = adcToGeV / 4.; //unit=1/4th ADC count
85 
86  adcToGeV = settings->eeDccAdcToGeV_;
87  thrUnit[ENDCAP] = adcToGeV / 4.; //unit=1/4th ADC count
88  ecalSelectiveReadout = std::make_unique<EcalSelectiveReadout>(settings->deltaEta_[0], settings->deltaPhi_[0]);
89  const int eb = 0;
90  const int ee = 1;
92  settings->srpLowInterestChannelZS_[ee],
93  settings->srpHighInterestChannelZS_[eb],
94  settings->srpHighInterestChannelZS_[ee]);
95 }
96 
98  theTriggerMap = map;
99  ecalSelectiveReadout->setTriggerMap(map);
100 }
101 
103  ecalSelectiveReadout->setElecMap(map);
104 }
105 
107 #ifndef ECALSELECTIVEREADOUT_NOGEOM
108  ecalSelectiveReadout->setGeometry(caloGeometry);
109 #endif
110 }
111 
113  double endcapLowInterest,
114  double barrelHighInterest,
115  double endcapHighInterest) {
116  //center, neighbour and single RUs are grouped into a single
117  //'high interest' group
118  int lowInterestThr[2]; //index for BARREL/ENDCAP
119  // int lowInterestSrFlag[2];
120  int highInterestThr[2];
121  // int highInterestSrFlag[2];
122 
123  lowInterestThr[BARREL] = internalThreshold(barrelLowInterest, BARREL);
124  // lowInterestSrFlag[BARREL] = thr2Srf(lowInterestThr[BARREL],
125  // EcalSrFlag::SRF_ZS1);
126 
127  highInterestThr[BARREL] = internalThreshold(barrelHighInterest, BARREL);
128  // highInterestSrFlag[BARREL] = thr2Srf(highInterestThr[BARREL],
129  // EcalSrFlag::SRF_ZS2);
130 
131  lowInterestThr[ENDCAP] = internalThreshold(endcapLowInterest, ENDCAP);
132  //lowInterestSrFlag[ENDCAP] = thr2Srf(lowInterestThr[ENDCAP],
133  // EcalSrFlag::SRF_ZS1);
134 
135  highInterestThr[ENDCAP] = internalThreshold(endcapHighInterest, ENDCAP);
136  // highInterestSrFlag[ENDCAP] = thr2Srf(highInterestThr[ENDCAP],
137  // EcalSrFlag::SRF_ZS2);
138 
139  const int FORCED_MASK = EcalSelectiveReadout::FORCED_MASK;
140 
141  for (int iSubDet = 0; iSubDet < 2; ++iSubDet) {
142  //low interest
143  //zsThreshold[iSubDet][0] = lowInterestThr[iSubDet];
144  //srFlags[iSubDet][0] = lowInterestSrFlag[iSubDet];
145  //srFlags[iSubDet][0 + FORCED_MASK] = FORCED_MASK | lowInterestSrFlag[iSubDet];
146 
147  //single->high interest
148  //zsThreshold[iSubDet][1] = highInterestThr[iSubDet];
149  //srFlags[iSubDet][1] = highInterestSrFlag[iSubDet];
150  //srFlags[iSubDet][1 + FORCED_MASK] = FORCED_MASK | highInterestSrFlag[iSubDet];
151 
152  //neighbour->high interest
153  //zsThreshold[iSubDet][2] = highInterestThr[iSubDet];
154  //srFlags[iSubDet][2] = highInterestSrFlag[iSubDet];
155  //srFlags[iSubDet][2 + FORCED_MASK] = FORCED_MASK | highInterestSrFlag[iSubDet];
156 
157  //center->high interest
158  //zsThreshold[iSubDet][3] = highInterestThr[iSubDet];
159  //srFlags[iSubDet][3] = highInterestSrFlag[iSubDet];
160  //srFlags[iSubDet][3 + FORCED_MASK] = FORCED_MASK | highInterestSrFlag[iSubDet];
161  for (size_t i = 0; i < 8; ++i) {
162  srFlags[iSubDet][i] = actions_[i];
163  if ((actions_[i] & ~FORCED_MASK) == 0)
164  zsThreshold[iSubDet][i] = numeric_limits<int>::max();
165  else if ((actions_[i] & ~FORCED_MASK) == 1)
166  zsThreshold[iSubDet][i] = lowInterestThr[iSubDet];
167  else if ((actions_[i] & ~FORCED_MASK) == 2)
168  zsThreshold[iSubDet][i] = highInterestThr[iSubDet];
169  else
170  zsThreshold[iSubDet][i] = numeric_limits<int>::min();
171  }
172 
173  // for(size_t i = 0; i < 8; ++i){
174  // cout << "zsThreshold[" << iSubDet << "][" << i << "] = " << zsThreshold[iSubDet][i] << endl;
175  // }
176  }
177 }
178 
179 // int EcalSelectiveReadoutSuppressor::thr2Srf(int thr, int zsFlag) const{
180 // if(thr==numeric_limits<int>::max()){
181 // return EcalSrFlag::SRF_SUPPRESS;
182 // }
183 // if(thr==numeric_limits<int>::min()){
184 // return EcalSrFlag::SRF_FULL;
185 // }
186 // return zsFlag;
187 // }
188 
189 int EcalSelectiveReadoutSuppressor::internalThreshold(double thresholdInGeV, int iSubDet) const {
190  double thr_ = thresholdInGeV / thrUnit[iSubDet];
191  //treating over- and underflows, threshold is coded on 11+1 signed bits
192  //an underflow threshold is considered here as if NoRO DCC switch is on
193  //an overflow threshold is considered here as if ForcedRO DCC switch in on
194  //Beware that conparison must be done on a double type, because conversion
195  //cast to an int of a double higher than MAX_INT is undefined.
196  int thr;
197  if (thr_ >= 0x7FF + .5) {
198  thr = numeric_limits<int>::max();
199  } else if (thr_ <= -0x7FF - .5) {
200  thr = numeric_limits<int>::min();
201  } else {
202  thr = lround(thr_);
203  }
204  return thr;
205 }
206 
207 //This implementation assumes that int is coded on at least 28-bits,
208 //which in pratice should be always true.
210  //FIR filter weights:
211  const vector<int>& w = getFIRWeigths();
212 
213  //accumulator used to compute weighted sum of samples
214  int acc = 0;
215  bool gain12saturated = false;
216  const int gain12 = 0x01;
217  const int lastFIRSample = firstFIRSample + nFIRTaps - 1;
218  //LogDebug("DccFir") << "DCC FIR operation: ";
219  int iWeight = 0;
220  for (int iSample = firstFIRSample - 1; iSample < lastFIRSample; ++iSample, ++iWeight) {
221  if (iSample >= 0 && iSample < (int)frame.size()) {
222  EcalMGPASample sample(frame[iSample]);
223  if (sample.gainId() != gain12)
224  gain12saturated = true;
225  //LogTrace("DccFir") << (iSample>=firstFIRSample?"+":"") << sample.adc()
226  // << "*(" << w[iWeight] << ")";
227  acc += sample.adc() * w[iWeight];
228  } else {
229  edm::LogWarning("DccFir") << __FILE__ << ":" << __LINE__
230  << ": Not enough samples in data frame or 'ecalDccZs1stSample' module "
231  "parameter is not valid...";
232  }
233  }
234 
235  if (symetricZS) { //cut on absolute value
236  if (acc < 0)
237  acc = -acc;
238  }
239 
240  //LogTrace("DccFir") << "\n";
241  //discards the 8 LSBs
242  //(result of shift operator on negative numbers depends on compiler
243  //implementation, therefore the value is offset to make sure it is positive
244  //before performing the bit shift).
245  acc = ((acc + (1 << 30)) >> 8) - (1 << (30 - 8));
246 
247  //ZS passed if weigthed sum acc above ZS threshold or if
248  //one sample has a lower gain than gain 12 (that is gain 12 output
249  //is saturated)
250 
251  const bool result = (acc >= thr) || gain12saturated;
252 
253  //LogTrace("DccFir") << "acc: " << acc << "\n"
254  // << "threshold: " << thr << " ("
255  // << thr*thrUnit[((EcalDataFrame&)frame).id().subdetId()==EcalBarrel?0:1]
256  // << "GeV)\n"
257  // << "saturated: " << (gain12saturated?"yes":"no") << "\n"
258  // << "ZS passed: " << (result?"yes":"no")
259  // << (symetricZS?" (symetric cut)":"") << "\n";
260 
261  return result;
262 }
263 
265  const EcalTrigPrimDigiCollection& trigPrims,
268  EBDigiCollection selectedBarrelDigis;
269  EEDigiCollection selectedEndcapDigis;
270 
271  run(eventSetup, trigPrims, barrelDigis, endcapDigis, &selectedBarrelDigis, &selectedEndcapDigis, nullptr, nullptr);
272 
273  //replaces the input with the suppressed version
274  barrelDigis.swap(selectedBarrelDigis);
275  endcapDigis.swap(selectedEndcapDigis);
276 }
277 
279  const EcalTrigPrimDigiCollection& trigPrims,
282  EBDigiCollection* selectedBarrelDigis,
283  EEDigiCollection* selectedEndcapDigis,
284  EBSrFlagCollection* ebSrFlags,
285  EESrFlagCollection* eeSrFlags) {
286  ++ievt_;
287  if (!trigPrimBypass_ || ttThresOnCompressedEt_) { //uses output of TPG emulator
288  setTtFlags(trigPrims);
289  } else { //debug mode, run w/o TP digis
290  setTtFlags(eventSetup, barrelDigis, endcapDigis);
291  }
292 
293  ecalSelectiveReadout->runSelectiveReadout0(ttFlags);
294 
295  if (selectedBarrelDigis) {
296  selectedBarrelDigis->reserve(barrelDigis.size() / 20);
297 
298  // do barrel first
299  for (EBDigiCollection::const_iterator digiItr = barrelDigis.begin(); digiItr != barrelDigis.end(); ++digiItr) {
300  int interestLevel = ecalSelectiveReadout->getCrystalInterest(EBDigiCollection::DetId(digiItr->id())) &
301  ~EcalSelectiveReadout::FORCED_MASK;
302  if (accept(*digiItr, zsThreshold[BARREL][interestLevel])) {
303  selectedBarrelDigis->push_back(digiItr->id(), digiItr->begin());
304  }
305  }
306  }
307 
308  // and endcaps
309  if (selectedEndcapDigis) {
310  selectedEndcapDigis->reserve(endcapDigis.size() / 20);
311  for (EEDigiCollection::const_iterator digiItr = endcapDigis.begin(); digiItr != endcapDigis.end(); ++digiItr) {
312  int interestLevel = ecalSelectiveReadout->getCrystalInterest(EEDigiCollection::DetId(digiItr->id())) &
313  ~EcalSelectiveReadout::FORCED_MASK;
314  if (accept(*digiItr, zsThreshold[ENDCAP][interestLevel])) {
315  selectedEndcapDigis->push_back(digiItr->id(), digiItr->begin());
316  }
317  }
318  }
319 
320  if (ievt_ <= 10) {
321  int neb = (selectedBarrelDigis ? selectedBarrelDigis->size() : 0);
322  if (selectedEndcapDigis)
323  LogDebug("EcalSelectiveReadout")
324  // << __FILE__ << ":" << __LINE__ << ": "
325  << "Number of EB digis passing the SR: " << neb << " / " << barrelDigis.size() << "\n";
326  if (selectedEndcapDigis)
327  LogDebug("EcalSelectiveReadout")
328  // << __FILE__ << ":" << __LINE__ << ": "
329  << "\nNumber of EE digis passing the SR: " << selectedEndcapDigis->size() << " / " << endcapDigis.size()
330  << "\n";
331  }
332 
333  if (ebSrFlags)
334  ebSrFlags->reserve(34 * 72);
335  if (eeSrFlags)
336  eeSrFlags->reserve(624);
337  //SR flags:
338  for (int iZ = -1; iZ <= 1; iZ += 2) { //-1=>EE-, EB-, +1=>EE+, EB+
339  //barrel:
340  for (unsigned iEta = 1; iEta <= nBarrelTriggerTowersInEta / 2; ++iEta) {
341  for (unsigned iPhi = 1; iPhi <= nTriggerTowersInPhi; ++iPhi) {
342  const EcalTrigTowerDetId id(iZ, EcalBarrel, iEta, iPhi);
343  EcalSelectiveReadout::towerInterest_t interest = ecalSelectiveReadout->getTowerInterest(id);
344  if (interest < 0) {
345  throw cms::Exception("EcalSelectiveReadout") << __FILE__ << ":" << __LINE__ << ": "
346  << "unknown SR flag. for "
347  << " TT " << id << ". Most probably a bug.";
348  }
349  int flag;
350  // if(interest==EcalSelectiveReadout::FORCED_RO){
351  // flag = EcalSrFlag::SRF_FORCED_MASK | EcalSrFlag::SRF_FULL;
352  //} else{
353  flag = srFlags[BARREL][interest];
354  //}
355  if (ebSrFlags)
356  ebSrFlags->push_back(EBSrFlag(id, flag));
357  } //next iPhi
358  } //next barrel iEta
359 
360  //endcap:
361  EcalScDetId id;
362  for (int iX = 1; iX <= 20; ++iX) {
363  for (int iY = 1; iY <= 20; ++iY) {
364  if (EcalScDetId::validDetId(iX, iY, iZ))
365  id = EcalScDetId(iX, iY, iZ);
366  else
367  continue;
368 
369  EcalSelectiveReadout::towerInterest_t interest = ecalSelectiveReadout->getSuperCrystalInterest(id);
370 
371  if (interest >= 0) { //negative no SC at (iX,iY) coordinates
372  int flag;
373  // if(interest==EcalSelectiveReadout::FORCED_RO){
374  // flag = EcalSrFlag::SRF_FORCED_MASK | EcalSrFlag::SRF_FULL;
375  //} else{
376  flag = srFlags[ENDCAP][interest];
377  //}
378  if (eeSrFlags)
379  eeSrFlags->push_back(EESrFlag(id, flag));
380  } else if (iX < 9 || iX > 12 || iY < 9 || iY > 12) { //not an inner partial SC
381  edm::LogError("EcalSelectiveReadout") << __FILE__ << ":" << __LINE__ << ": "
382  << "negative interest in EE for SC " << id << "\n";
383  }
384  } //next iY
385  } //next iX
386  }
387 }
388 
390  for (size_t iEta0 = 0; iEta0 < nTriggerTowersInEta; ++iEta0) {
391  for (size_t iPhi0 = 0; iPhi0 < nTriggerTowersInPhi; ++iPhi0) {
392  ttFlags[iEta0][iPhi0] = defaultTtf_;
393  }
394  }
395  for (EcalTrigPrimDigiCollection::const_iterator trigPrim = trigPrims.begin(); trigPrim != trigPrims.end();
396  ++trigPrim) {
397  int iEta = trigPrim->id().ieta();
398  unsigned int iEta0;
399  if (iEta < 0) { //z- half ECAL: transforming ranges -28;-1 => 0;27
400  iEta0 = iEta + nTriggerTowersInEta / 2;
401  } else { //z+ halfECAL: transforming ranges 1;28 => 28;55
402  iEta0 = iEta + nTriggerTowersInEta / 2 - 1;
403  }
404 
405  unsigned int iPhi0 = trigPrim->id().iphi() - 1;
406 
407  if (!ttThresOnCompressedEt_) {
408  ttFlags[iEta0][iPhi0] = (EcalSelectiveReadout::ttFlag_t)trigPrim->ttFlag();
409  } else {
410  int compressedEt = trigPrim->compressedEt();
411  if (compressedEt < trigPrimBypassLTH_) {
413  } else if (compressedEt < trigPrimBypassHTH_) {
415  } else {
417  }
418  }
419  }
420 }
421 
423  if (firWeights.empty()) {
424  firWeights = vector<int>(nFIRTaps, 0); //default weight: 0;
425  const static int maxWeight = 0xEFF; //weights coded on 11+1 signed bits
426  for (unsigned i = 0; i < min((size_t)nFIRTaps, weights.size()); ++i) {
427  firWeights[i] = lround(weights[i] * (1 << 10));
428  if (abs(firWeights[i]) > maxWeight) { //overflow
429  firWeights[i] = firWeights[i] < 0 ? -maxWeight : maxWeight;
430  }
431  }
432  }
433  return firWeights;
434 }
435 
437  const EBDigiCollection& ebDigis,
438  const EEDigiCollection& eeDigis) {
439  double trigPrim[nTriggerTowersInEta][nTriggerTowersInPhi];
440 
441  //ecal geometry:
442  // static const CaloSubdetectorGeometry* eeGeometry = 0;
443  // static const CaloSubdetectorGeometry* ebGeometry = 0;
444  const CaloSubdetectorGeometry* eeGeometry = nullptr;
445  const CaloSubdetectorGeometry* ebGeometry = nullptr;
446  // if(eeGeometry==0 || ebGeometry==0){
447  auto const& geo = es.getData(geoToken_);
448  eeGeometry = geo.getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
449  ebGeometry = geo.getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
450  // }
451 
452  //init trigPrim array:
453  bzero(trigPrim, sizeof(trigPrim));
454 
455  for (EBDigiCollection::const_iterator it = ebDigis.begin(); it != ebDigis.end(); ++it) {
456  EBDataFrame frame(*it);
457  const EcalTrigTowerDetId& ttId = theTriggerMap->towerOf(frame.id());
458  // edm:::LogDebug("TT") << __FILE__ << ":" << __LINE__ << ": "
459  // << ((EBDetId&)frame.id()).ieta()
460  // << "," << ((EBDetId&)frame.id()).iphi()
461  // << " -> " << ttId.ieta() << "," << ttId.iphi() << "\n";
462  const int iTTEta0 = iTTEta2cIndex(ttId.ieta());
463  const int iTTPhi0 = iTTPhi2cIndex(ttId.iphi());
464  double theta = ebGeometry->getGeometry(frame.id())->getPosition().theta();
465  double e = frame2Energy(frame);
466  if (!trigPrimBypassWithPeakFinder_ || ((frame2Energy(frame, -1) < e) && (frame2Energy(frame, 1) < e))) {
467  trigPrim[iTTEta0][iTTPhi0] += e * sin(theta);
468  }
469  }
470 
471  for (EEDigiCollection::const_iterator it = eeDigis.begin(); it != eeDigis.end(); ++it) {
472  EEDataFrame frame(*it);
473  const EcalTrigTowerDetId& ttId = theTriggerMap->towerOf(frame.id());
474  const int iTTEta0 = iTTEta2cIndex(ttId.ieta());
475  const int iTTPhi0 = iTTPhi2cIndex(ttId.iphi());
476  // cout << __FILE__ << ":" << __LINE__ << ": EE xtal->TT "
477  // << ((EEDetId&)frame.id()).ix()
478  // << "," << ((EEDetId&)frame.id()).iy()
479  // << " -> " << ttId.ieta() << "," << ttId.iphi() << "\n";
480  double theta = eeGeometry->getGeometry(frame.id())->getPosition().theta();
481  double e = frame2Energy(frame);
482  if (!trigPrimBypassWithPeakFinder_ || ((frame2Energy(frame, -1) < e) && (frame2Energy(frame, 1) < e))) {
483  trigPrim[iTTEta0][iTTPhi0] += e * sin(theta);
484  }
485  }
486 
487  //dealing with pseudo-TT in two inner EE eta-ring:
488  int innerTTEtas[] = {0, 1, 54, 55};
489  for (unsigned iRing = 0; iRing < sizeof(innerTTEtas) / sizeof(innerTTEtas[0]); ++iRing) {
490  int iTTEta0 = innerTTEtas[iRing];
491  //this detector eta-section is divided in only 36 phi bins
492  //For this eta regions,
493  //current tower eta numbering scheme is inconsistent. For geometry
494  //version 133:
495  //- TT are numbered from 0 to 72 for 36 bins
496  //- some TT have an even index, some an odd index
497  //For geometry version 125, there are 72 phi bins.
498  //The code below should handle both geometry definition.
499  //If there are 72 input trigger primitives for each inner eta-ring,
500  //then the average of the trigger primitive of the two pseudo-TT of
501  //a pair (nEta, nEta+1) is taken as Et of both pseudo TTs.
502  //If there are only 36 input TTs for each inner eta ring, then half
503  //of the present primitive of a pseudo TT pair is used as Et of both
504  //pseudo TTs.
505 
506  for (unsigned iTTPhi0 = 0; iTTPhi0 < nTriggerTowersInPhi - 1; iTTPhi0 += 2) {
507  double et = .5 * (trigPrim[iTTEta0][iTTPhi0] + trigPrim[iTTEta0][iTTPhi0 + 1]);
508  //divides the TT into 2 phi bins in order to match with 72 phi-bins SRP
509  //scheme or average the Et on the two pseudo TTs if the TT is already
510  //divided into two trigger primitives.
511  trigPrim[iTTEta0][iTTPhi0] = et;
512  trigPrim[iTTEta0][iTTPhi0 + 1] = et;
513  }
514  }
515 
516  for (unsigned iTTEta0 = 0; iTTEta0 < nTriggerTowersInEta; ++iTTEta0) {
517  for (unsigned iTTPhi0 = 0; iTTPhi0 < nTriggerTowersInPhi; ++iTTPhi0) {
518  if (trigPrim[iTTEta0][iTTPhi0] > trigPrimBypassHTH_) {
520  } else if (trigPrim[iTTEta0][iTTPhi0] > trigPrimBypassLTH_) {
522  } else {
524  }
525 
526  // cout /*LogDebug("TT")*/
527  // << "ttFlags[" << iTTEta0 << "][" << iTTPhi0 << "] = "
528  // << ttFlags[iTTEta0][iTTPhi0] << "\n";
529  }
530  }
531 }
532 
533 template <class T>
534 double EcalSelectiveReadoutSuppressor::frame2Energy(const T& frame, int offset) const {
535  //we have to start by 0 in order to handle offset=-1
536  //(however Fenix FIR has AFAK only 5 taps)
537  double weights[] = {0., -1 / 3., -1 / 3., -1 / 3., 0., 1.};
538 
539  double adc2GeV = 0.;
540  if (typeid(frame) == typeid(EBDataFrame)) {
541  adc2GeV = 0.035;
542  } else if (typeid(frame) == typeid(EEDataFrame)) {
543  adc2GeV = 0.060;
544  } else { //T is an invalid type!
545  //TODO: replace message by a cms exception
546  cerr << "Severe error. " << __FILE__ << ":" << __LINE__ << ": "
547  << "this is a bug. Please report it.\n";
548  }
549 
550  double acc = 0;
551 
552  const int n = min<int>(frame.size(), sizeof(weights) / sizeof(weights[0]));
553 
554  double gainInv[] = {12., 1., 6., 12.};
555 
556  //cout << __PRETTY_FUNCTION__ << ": ";
557  for (int i = offset; i < n; ++i) {
558  int iframe = i + offset;
559  if (iframe >= 0 && iframe < frame.size()) {
560  acc += weights[i] * frame[iframe].adc() * gainInv[frame[iframe].gainId()] * adc2GeV;
561  //cout << (iframe>offset?"+":"")
562  // << frame[iframe].adc() << "*" << gainInv[frame[iframe].gainId()]
563  // << "*" << adc2GeV << "*(" << weights[i] << ")";
564  }
565  }
566  //cout << "\n";
567  return acc;
568 }
569 
570 void EcalSelectiveReadoutSuppressor::printTTFlags(ostream& os, int iEvent, bool withHeader) const {
571  const char tccFlagMarker[] = {'?', '.', 'S', '?', 'C', 'E', 'E', 'E', 'E'};
574 
575  if (withHeader) {
576  os << "# TCC flag map\n#\n"
577  "# +-->Phi "
578  << tccFlagMarker[1 + 0]
579  << ": 000 (low interest)\n"
580  "# | "
581  << tccFlagMarker[1 + 1]
582  << ": 001 (mid interest)\n"
583  "# | "
584  << tccFlagMarker[1 + 2]
585  << ": 010 (not valid)\n"
586  "# V Eta "
587  << tccFlagMarker[1 + 3]
588  << ": 011 (high interest)\n"
589  "# "
590  << tccFlagMarker[1 + 4] << ": 1xx forced readout (Hw error)\n";
591  }
592 
593  if (iEvent >= 0) {
594  os << "#\n#Event " << iEvent << "\n";
595  }
596 
597  for (int iEta = 0; iEta < nEta; ++iEta) {
598  for (int iPhi = 0; iPhi < nPhi; ++iPhi) {
599  os << tccFlagMarker[ttFlags[iEta][iPhi] + 1];
600  }
601  os << "\n";
602  }
603 }
void push_back(const Digi &digi)
void setGeometry(const CaloGeometry *caloGeometry)
static bool validDetId(int ix, int iy, int iz)
Definition: EcalScDetId.cc:59
void setSettings(const EcalSRSettings *settings)
void swap(EBDigiCollection &other)
EcalSelectiveReadoutSuppressor(const edm::ParameterSet &params, edm::ConsumesCollector iC)
key_type id() const
Definition: EBDataFrame.h:28
static const int FORCED_MASK
const double w
Definition: UKUtility.cc:23
uint16_t *__restrict__ id
void initCellThresholds(double barrelLowInterest, double endcapLowInterest, double barrelHighInterest, double endcapHighInterest)
helpers for constructors
void printTTFlags(std::ostream &os, int iEvent=-1, bool withHeader=true) const
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
double frame2Energy(const T &frame, int timeOffset=0) const
std::vector< T >::const_iterator const_iterator
Geom::Theta< T > theta() const
void push_back(T const &t)
std::vector< std::vector< float > > dccNormalizedWeights_
const char tccFlagMarker[]
Definition: GenABIO.cc:164
const_iterator begin() const
The iterator returned can not safely be used across threads.
Log< level::Error, false > LogError
int gainId() const
get the gainId (2 bits)
unsigned ttId(DetId const &, EcalElectronicsMapping const *)
EcalTrigTowerDetId towerOf(const DetId &id) const
Get the tower id for this det id (or null if not known)
int ieta() const
get the tower ieta
std::vector< float > srpHighInterestChannelZS_
tuple result
Definition: mps_fire.py:311
void setTriggerMap(const EcalTrigTowerConstituentsMap *map)
std::unique_ptr< EcalSelectiveReadout > ecalSelectiveReadout
EcalSelectiveReadout::ttFlag_t ttFlags[nTriggerTowersInEta][nTriggerTowersInPhi]
bool getData(T &iHolder) const
Definition: EventSetup.h:128
std::vector< int > actions_
void run(const edm::EventSetup &eventSetup, const EcalTrigPrimDigiCollection &trigPrims, EBDigiCollection &barrelDigis, EEDigiCollection &endcapDigis)
int internalThreshold(double thresholdInGeV, int iSubDet) const
int iEvent
Definition: GenABIO.cc:224
std::vector< int > ecalDccZs1stSample_
constexpr size_type size() const
Definition: DataFrame.h:43
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
EcalSelectiveReadout::ttFlag_t defaultTtf_
T min(T a, T b)
Definition: MathUtil.h:58
key_type id() const
Definition: EEDataFrame.h:24
std::vector< int > deltaPhi_
const_iterator end() const
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geoToken_
void reserve(size_t isize)
int iphi() const
get the tower iphi
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
std::vector< int > symetricZS_
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
float ebDccAdcToGeV_
ADC to GeV conversion factor used in ZS filter for EB.
static const size_t nTriggerTowersInEta
static const size_t nTriggerTowersInPhi
boost::transform_iterator< IterHelp, boost::counting_iterator< int > > const_iterator
const_iterator end() const
std::vector< float > srpLowInterestChannelZS_
std::vector< int > deltaEta_
bool accept(const edm::DataFrame &frame, int thr)
void push_back(const Digi &digi)
void setTtFlags(const edm::EventSetup &eventSetup, const EBDigiCollection &ebDigis, const EEDigiCollection &eeDigis)
void reserve(size_type n)
void setElecMap(const EcalElectronicsMapping *map)
const EcalTrigTowerConstituentsMap * theTriggerMap
float eeDccAdcToGeV_
ADC to GeV conversion factor used in ZS filter for EE.
Log< level::Warning, false > LogWarning
long double T
void swap(EEDigiCollection &other)
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const_iterator begin() const
int adc() const
get the ADC sample (12 bits)
#define LogDebug(id)