CMS 3D CMS Logo

EcalSelectiveReadout.cc
Go to the documentation of this file.
1 //emacs settings:-*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-"
2 /*
3  */
4 
10 #include <string>
11 #include <iomanip>
12 #include <cassert>
13 #include <atomic>
14 //#include <iostream> //for debugging
15 
16 using std::vector;
17 
18 const char EcalSelectiveReadout::srpFlagMarker[] = {'.', 'S', 'N', 'C',
19  '4', '5', '6', '7'};
20 
22  theTriggerMap(nullptr), theElecMap(nullptr), dEta(dEta_), dPhi(dPhi_) {
23 }
24 
26  //init superCrystalInterest (sets all elts to 'UNKNOWN'):
27  for(size_t iCap=0; iCap < nEndcaps; ++iCap){
28  for(int iDccPhi = 0; iDccPhi < nDccPerEe; ++iDccPhi){
29  for(int iDccCh = 0; iDccCh < maxDccChs; ++iDccCh){
30  eeRuInterest_[iCap][iDccPhi][iDccCh] = UNKNOWN;
31  }
32  }
33  }
34 }
35 
36 void
38 
39  //printDccChMap(std::cout);
40 
41  //classifies the trigger towers (single,center,neighbor,low interest)
42  classifyTriggerTowers(ttFlags);
43 
44  //count number of TT in each interest class for debugging display
45  int nTriggerTowerE[] = {0, 0, 0, 0, 0, 0, 0, 0};
46  int nTriggerTowerB[] = {0, 0, 0, 0, 0, 0, 0, 0};
47  static std::atomic<int> ncall{0};
48  if(ncall < 10){
49  ++ncall;
50  for(size_t iPhi = 0; iPhi < nTriggerTowersInPhi; ++iPhi){
51  for(size_t iEta = 0; iEta < nTriggerTowersInEta; ++iEta){
54  //in endcaps
55  ++nTriggerTowerE[towerInterest[iEta][iPhi]];
56  } else{//in barrel
57  ++nTriggerTowerB[towerInterest[iEta][iPhi]];
58  }
59 
60  assert(towerInterest[iEta][iPhi] >= 0
61  && towerInterest[iEta][iPhi] <= 0x7);
62  }
63  }
64  edm::LogInfo("EcalSelectiveReadout")
65  << "without forced bit + with forced bit set:\n"
66  << nTriggerTowerB[LOWINTEREST] << " + "
67  << nTriggerTowerB[LOWINTEREST | FORCED_MASK]
68  << " low interest TT(s) in barrel\n"
69  << nTriggerTowerB[SINGLE] << " + "
70  << nTriggerTowerB[SINGLE | FORCED_MASK]
71  << " single TT(s) in barrel\n"
72  << nTriggerTowerB[NEIGHBOUR] << " + "
73  << nTriggerTowerB[NEIGHBOUR | FORCED_MASK]
74  << " neighbor interest TT(s) in barrel\n"
75  << nTriggerTowerB[CENTER] << " + "
76  << nTriggerTowerB[CENTER | FORCED_MASK]
77  << " centre interest TT(s) in barrel\n"
78  << nTriggerTowerE[LOWINTEREST] << " + "
79  << nTriggerTowerE[LOWINTEREST | FORCED_MASK]
80  << " low interest TT(s) in endcap\n"
81  << nTriggerTowerE[SINGLE] << " + "
82  << nTriggerTowerE[SINGLE | FORCED_MASK]
83  << " single TT(s) in endcap\n"
84  << nTriggerTowerE[NEIGHBOUR] << " + "
85  << nTriggerTowerE[NEIGHBOUR | FORCED_MASK]
86  << " neighbor TT(s) in endcap\n"
87  << nTriggerTowerE[CENTER] << " + "
88  << nTriggerTowerE[CENTER | FORCED_MASK]
89  << " center TT(s) in endcap\n";
90  }
91  //end TT interest class composition debugging display
92 
93  //For the endcap the TT classification must be mapped to the SC:
95 
96 #ifndef ECALSELECTIVEREADOUT_NOGEOM
97  const std::vector<DetId>& endcapDetIds = theGeometry->getValidDetIds(DetId::Ecal, EcalEndcap);
98  for(std::vector<DetId>::const_iterator eeDetIdItr = endcapDetIds.begin();
99  eeDetIdItr != endcapDetIds.end(); ++eeDetIdItr){
100  // for each superCrystal, the interest is the highest interest
101  // of any trigger tower associated with at least one crystal from this SC.
102  // The forced bit must be set if the flag of one of these trigger towers has
103  // the forced bit set.
104  EcalTrigTowerDetId trigTower = theTriggerMap->towerOf(*eeDetIdItr);
105  assert(trigTower.rawId() != 0);
106  EEDetId eeDetId(*eeDetIdItr);
107  int iz = (eeDetId.zside() > 0) ? 1 : 0;
108  //Following statement will set properly the actual 2-bit flag value
109  //and the forced bit: TTF forced bit is propagated to every RU that
110  //overlaps with the corresponding TT.
111  combineFlags(eeRuInterest(eeDetId), getTowerInterest(trigTower));
112  }
113 #else //ECALSELECTIVEREADOUT_NOGEOM defined
114  EEDetId xtal;
115  for(int iZ0=0; iZ0<2; ++iZ0){//0->EE-, 1->EE+
116  for(unsigned iX0=0; iX0<nEndcapXBins; ++iX0){
117  for(unsigned iY0=0; iY0<nEndcapYBins; ++iY0){
118 
119  if (!(xtal.validDetId(iX0+1, iY0+1, (iZ0>0?1:-1)))){
120  continue;
121  }
122  xtal = EEDetId(iX0+1, iY0+1, (iZ0>0?1:-1));
123  //works around a EEDetId bug. To remove once the bug fixed.
124  if(39 <= iX0 && iX0 <= 60 && 45 <= iY0 && iY0 <= 54){
125  continue;
126  }
127  // for each superCrystal, the interest is the highest interest
128  // of any trigger tower associated with any crystal in this SC
129  EcalTrigTowerDetId trigTower = theTriggerMap->towerOf(xtal);
130  assert(trigTower.rawId() != 0);
131  //Following statement will set properly the actual 2-bit flag value
132  //and the forced bit: TTF forced bit is propagated to every RU that
133  //overlaps with the corresponding TT.
134  combineFlags(eeRuInterest(xtal), getTowerInterest(trigTower));
135 
136  assert(0<= eeRuInterest(xtal) && eeRuInterest(xtal) <= 0x7);
137 
138  } //next iY0
139  } //next iX0
140  } //next iZ0
141 #endif //ECALSELECTIVEREADOUT_NOGEOM not defined
142 }
143 
146 {
147  EcalTrigTowerDetId thisTower = theTriggerMap->towerOf(ebDetId);
148  return getTowerInterest(thisTower);
149 }
150 
151 
154 {
155  // int iz = (eeDetId.zside() > 0) ? 1 : 0;
156  // int superCrystalX = (eeDetId.ix()-1) / 5;
157  // int superCrystalY = (eeDetId.iy()-1) / 5;
158  // return supercrystalInterest[iz][superCrystalX][superCrystalY];
159  return const_cast<EcalSelectiveReadout*>(this)->eeRuInterest(eeDetId);
160 }
161 
164 {
165  return const_cast<EcalSelectiveReadout*>(this)->eeRuInterest(scDetId);
166 }
167 
170  const EcalElectronicsId& id = theElecMap->getElectronicsId(eeDetId);
171  const int iZ0 = id.zside()>0 ? 1 : 0;
172  const int iDcc0 = id.dccId()-1;
173  const int iDccPhi0 = (iDcc0<9)?iDcc0:(iDcc0-45);
174  const int iDccCh0 = id.towerId()-1;
175  assert(0 <= iDccPhi0 && iDccPhi0 < nDccPerEe);
176  assert(0 <= iDccCh0 && iDccCh0 < maxDccChs);
177 
178  assert(eeRuInterest_[iZ0][iDccPhi0][iDccCh0] == UNKNOWN
179  || (0<= eeRuInterest_[iZ0][iDccPhi0][iDccCh0]
180  && eeRuInterest_[iZ0][iDccPhi0][iDccCh0] <=7));
181 
182  return eeRuInterest_[iZ0][iDccPhi0][iDccCh0];
183 }
184 
187  std::pair<int, int> dccAndDccCh = theElecMap->getDCCandSC(scDetId);
188  const int iZ0 = (scDetId.zside()>0) ? 1: 0;
189  const int iDcc0 = dccAndDccCh.first-1;
190  const int iDccPhi0 = (iDcc0<9)?iDcc0:(iDcc0-45);
191  const int iDccCh0 = dccAndDccCh.second-1;
192  assert(0 <= iDccPhi0 && iDccPhi0 <= nDccPerEe);
193  assert(0 <= iDccCh0 && iDccCh0 <= maxDccChs);
194 
195  assert(-1<= eeRuInterest_[iZ0][iDccPhi0][iDccCh0] && eeRuInterest_[iZ0][iDccPhi0][iDccCh0] <=7);
196 
197  return eeRuInterest_[iZ0][iDccPhi0][iDccCh0];
198 }
199 
200 
203 {
204  // remember, array indices start at zero
205  int iEta = tower.ieta()<0? tower.ieta() + nTriggerTowersInEta/2
206  : tower.ieta() + nTriggerTowersInEta/2 -1;
207  int iPhi = tower.iphi() - 1;
208 
209  assert(-1 <= towerInterest[iEta][iPhi] && int(towerInterest[iEta][iPhi]) < 8);
210 
211  return towerInterest[iEta][iPhi];
212 }
213 
214 void
216 {
217  //starts with a all low interest map:
218  for(int iEta=0; iEta < (int)nTriggerTowersInEta; ++iEta){
219  for(int iPhi=0; iPhi < (int)nTriggerTowersInPhi; ++iPhi){
220  towerInterest[iEta][iPhi] = LOWINTEREST;
221  }
222  }
223 
224  for(int iEta=0; iEta < (int)nTriggerTowersInEta; ++iEta){
225  for(int iPhi=0; iPhi < (int)nTriggerTowersInPhi; ++iPhi){
226  //copy forced bit from ttFlags to towerInterests:
227  towerInterest[iEta][iPhi] = (towerInterest_t) (towerInterest[iEta][iPhi]
228  | (ttFlags[iEta][iPhi] & FORCED_MASK)) ;
229  if((ttFlags[iEta][iPhi] & ~FORCED_MASK) == TTF_HIGH_INTEREST){
230  //flags this tower as a center tower
231  towerInterest[iEta][iPhi] = CENTER;
232  //flags the neighbours of this tower
233  for(int iEtaNeigh = std::max<int>(0,iEta-dEta);
234  iEtaNeigh <= std::min<int>(nTriggerTowersInEta-1, iEta+dEta);
235  ++iEtaNeigh){
236  for(int iPhiNeigh = iPhi-dPhi;
237  iPhiNeigh <= iPhi+dPhi;
238  ++iPhiNeigh){
239  //beware, iPhiNeigh must be moved to [0,72] interval
240  //=> %nTriggerTowersInPhi required
241  int iPhiNeigh_ = iPhiNeigh%(int)nTriggerTowersInPhi;
242  if(iPhiNeigh_<0) {
243  iPhiNeigh_ += nTriggerTowersInPhi;
244  }
245  combineFlags(towerInterest[iEtaNeigh][iPhiNeigh_],
246  NEIGHBOUR);
247  }
248  }
249  } else if((ttFlags[iEta][iPhi] & ~FORCED_MASK) == TTF_MID_INTEREST){
250  combineFlags(towerInterest[iEta][iPhi], SINGLE);
251  }
252  }
253  }
254 
255  //dealing with pseudo-TT in the two innest eta-ring of the endcaps
256  //=>choose the highest priority SRF of the 2 pseudo-TT constituting
257  //a TT. Note that for S and C, the 2 pseudo-TT must already have the
258  //same mask.
259  const size_t innerEtas[] = {0, 1,
261  for(size_t i=0; i < 4; ++i){
262  size_t iEta = innerEtas[i];
263  for(size_t iPhi = 0 ; iPhi < nTriggerTowersInPhi; iPhi+=2){
264  const towerInterest_t srf = std::max(towerInterest[iEta][iPhi],
265  towerInterest[iEta][iPhi+1]);
266  towerInterest[iEta][iPhi] = srf;
267  towerInterest[iEta][iPhi+1] = srf;
268  }
269  }
270 }
271 
272 void EcalSelectiveReadout::printHeader(std::ostream & os) const{
273  os << "#SRP flag map\n#\n"
274  "# +-->Phi/Y " << srpFlagMarker[0] << ": low interest\n"
275  "# | " << srpFlagMarker[1] << ": single\n"
276  "# | " << srpFlagMarker[2] << ": neighbour\n"
277  "# V Eta/X " << srpFlagMarker[3] << ": center\n"
278  "# " << srpFlagMarker[4] << ": forced low interest\n"
279  "# " << srpFlagMarker[5] << ": forced single\n"
280  "# " << srpFlagMarker[6] << ": forced neighbout\n"
281  "# " << srpFlagMarker[7] << ": forced center\n"
282  "#\n";
283 }
284 
285 void EcalSelectiveReadout::print(std::ostream & os) const
286 {
287  //EE-
288  printEndcap(0, os);
289 
290  //EB
291  printBarrel(os);
292 
293  //EE+
294  printEndcap(1, os);
295 }
296 
297 
298 void EcalSelectiveReadout::printBarrel(std::ostream & os) const
299 {
300  for(size_t iEta = nEndcapTriggerTowersInEta;
303  ++iEta){
304  for(size_t iPhi = 0; iPhi < nTriggerTowersInPhi; ++iPhi){
305  towerInterest_t srFlag
306  = towerInterest[iEta][iPhi];
307  os << srpFlagMarker[srFlag];
308  }
309  os << "\n"; //one phi per line
310  }
311 }
312 
313 
314 void EcalSelectiveReadout::printEndcap(int endcap, std::ostream & os) const
315 {
316  for(size_t iX=0; iX<nSupercrystalXBins; ++iX){
317  for(size_t iY=0; iY<nSupercrystalYBins; ++iY){
318  towerInterest_t srFlag;
319  char c;
320  if(!EcalScDetId::validDetId(iX+1,iY+1,endcap>=1?1:-1)){
321  // srFlag = UNKNOWN;
322  c = ' ';
323  } else{
324  srFlag
325  = getSuperCrystalInterest(EcalScDetId(iX+1, iY+1, endcap>=1?1:-1));//supercrystalInterest[endcap][iX][iY];
326  c = srFlag==UNKNOWN ? '?' : srpFlagMarker[srFlag];
327  }
328  os << c;
329  }
330  os << "\n"; //one Y supercystal column per line
331  } //next supercrystal X-index
332 }
333 
334 
335 std::ostream & operator<<(std::ostream & os, const EcalSelectiveReadout & selectiveReadout)
336 {
337  selectiveReadout.print(os);
338  return os;
339 }
340 
341 
342 void
343 EcalSelectiveReadout::printDccChMap(std::ostream& os) const{
344  for(int i=-1; i<=68; ++i){
345  if((i+1)%10==0) os << "//";
346  os << std::setw(2) << i << ": " << (char)('0'+i);
347  if(i%10==9) os << "\n"; else os << " ";
348  }
349 
350  os << "\n";
351 
352  for(int endcap = 0; endcap < 2; ++endcap){
353  os << "Sc2DCCch0: " << (endcap?"EE+":"EE-") << "\n";
354  for(size_t iY=0; iY<nSupercrystalYBins; ++iY){
355  os << "Sc2DCCch0: ";
356  for(size_t iX=0; iX<nSupercrystalXBins; ++iX){
357  //if(iX) os << ",";
358  if(!EcalScDetId::validDetId(iX+1,iY+1,endcap>=1?1:-1)){
359  //os << std::setw(2) << -1;
360  os << (char)('0'-1);
361  } else{
362  //os << std::setw(2) << theElecMap->getDCCandSC(EcalScDetId(iX+1, iY+1, endcap>0?1:-1)).second-1;
363  os << (char)('0'+(theElecMap->getDCCandSC(EcalScDetId(iX+1, iY+1, endcap>0?1:-1)).second-1));
364  }
365  }
366  os << "\n";
367  }
368  os << "\n";
369  }
370  os << "\n";
371 }
static bool validDetId(int ix, int iy, int iz)
Definition: EcalScDetId.cc:59
static const int FORCED_MASK
static const size_t nEndcapXBins
towerInterest_t getSuperCrystalInterest(const EcalScDetId &scDetId) const
Ecal readout channel identification [32:20] Unused (so far) [19:13] DCC id [12:6] tower [5:3] strip [...
#define nullptr
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
static const size_t nSupercrystalXBins
void printHeader(std::ostream &os) const
print out header for the map: see print(std::ostream&)
std::pair< int, int > getDCCandSC(EcalScDetId id) const
towerInterest_t getTowerInterest(const EcalTrigTowerDetId &towerId) const
static const size_t nEndcaps
static const int nDccPerEe
EcalTrigTowerDetId towerOf(const DetId &id) const
Get the tower id for this det id (or null if not known)
void printEndcap(int endcap, std::ostream &s) const
int ieta() const
get the tower ieta
void classifyTriggerTowers(const ttFlag_t ttFlags[nTriggerTowersInEta][nTriggerTowersInPhi])
towerInterest_t & eeRuInterest(const EEDetId &id)
static const size_t nEndcapYBins
static const size_t nSupercrystalYBins
EcalElectronicsId getElectronicsId(const DetId &id) const
Get the electronics id for this det id.
EcalSelectiveReadout(int dEta=1, int dPhi=1)
static const int maxDccChs
void combineFlags(T &var, T val) const
void printBarrel(std::ostream &os) const
static const size_t nEndcapTriggerTowersInEta
std::ostream & operator<<(std::ostream &os, const EcalSelectiveReadout &selectiveReadout)
const EcalElectronicsMapping * theElecMap
int zside() const
zside = +1 or -1
towerInterest_t eeRuInterest_[nEndcaps][nDccPerEe][maxDccChs]
int iphi() const
get the tower iphi
const EcalTrigTowerConstituentsMap * theTriggerMap
static bool validDetId(int crystal_ix, int crystal_iy, int iz)
Definition: EEDetId.h:248
void print(std::ostream &os) const
print out the map
static const size_t nTriggerTowersInEta
int zside() const
Definition: EcalScDetId.h:64
static const size_t nTriggerTowersInPhi
static const char srpFlagMarker[]
void runSelectiveReadout0(const ttFlag_t towerFlags[nTriggerTowersInEta][nTriggerTowersInPhi])
towerInterest_t towerInterest[nTriggerTowersInEta][nTriggerTowersInPhi]
static const size_t nBarrelTriggerTowersInEta
towerInterest_t getCrystalInterest(const EBDetId &ebDetId) const
void printDccChMap(std::ostream &os) const