CMS 3D CMS Logo

DCCTowerBlock.cc
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <algorithm>
7 
8 
9 
11 : DCCFEBlock(u,m,e,unpack,forceToKeepFRdata){}
12 
13 
15 
17 
18  // needs to be update for eb/ee
20 
24 
25 }
26 
27 
28 
29 int DCCTowerBlock::unpackXtalData(unsigned int expStripID, unsigned int expXtalID){
30 
31  bool errorOnXtal(false);
32 
33  const uint16_t * xData_= reinterpret_cast<const uint16_t *>(data_);
34 
35  // Get xtal data ids
36  unsigned int stripId = (*xData_) & TOWER_STRIPID_MASK;
37  unsigned int xtalId = ((*xData_)>>TOWER_XTALID_B ) & TOWER_XTALID_MASK;
38 
39  // check id in case data are not 0suppressed
40  if( !zs_ && (expStripID != stripId || expXtalID != xtalId)){
42  edm::LogWarning("IncorrectBlock")
43  <<"For event L1A: "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower "<<towerId_
44  <<"\n The expected strip is "<<expStripID<<" and "<<stripId<<" was found"
45  <<"\n The expected xtal is "<<expXtalID <<" and "<<xtalId<<" was found";
46  }
47  // using expected cry_di to raise warning about xtal_id problem
48  pDetId_ = (EBDetId*) mapper_->getDetIdPointer(towerId_,expStripID,expXtalID);
49  (*invalidChIds_)->push_back(*pDetId_);
50 
51  stripId = expStripID;
52  xtalId = expXtalID;
53  errorOnXtal= true;
54 
55  // return here, so to skip all following checks
56  lastXtalId_++;
59  return BLOCK_UNPACKED;
60  }
61 
62 
63  // check id in case of 0suppressed data
64 
65  else if(zs_){
66 
67  // Check for valid Ids 1) values out of range
68 
69  if(stripId == 0 || stripId > 5 || xtalId == 0 || xtalId > 5){
71  edm::LogWarning("IncorrectBlock")
72  <<"For event L1A: "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower "<<towerId_
73  <<"\n Invalid strip : "<<stripId<<" or xtal : "<<xtalId
74  <<" ids ( last strip was: " << lastStripId_ << " last ch was: " << lastXtalId_ << ")";
75  }
76 
77  int st = lastStripId_;
78  int ch = lastXtalId_;
79  ch++;
80  if (ch > NUMB_XTAL) {ch=1; st++;}
81  if (st > NUMB_STRIP) {ch=1; st=1;}
82 
83  // adding channel following the last valid
84  //pDetId_ = (EBDetId*) mapper_->getDetIdPointer(towerId_,st,ch);
85  //(*invalidChIds_)->push_back(*pDetId_);
87 
88  errorOnXtal = true;
89 
90  lastStripId_ = st;
91  lastXtalId_ = ch;
92 
93  // return here, so to skip all following checks
94  return SKIP_BLOCK_UNPACKING;
95 
96  }else{
97 
98  // Check for zs valid Ids 2) if channel-in-strip has increased wrt previous xtal
99 
100 
101  // Check for zs valid Ids 2) if channel-in-strip has increased wrt previous xtal
102  // 3) if strip has increased wrt previous xtal
103  if( ( stripId == lastStripId_ && xtalId <= lastXtalId_ ) ||
104  (stripId < lastStripId_))
105  {
107  edm::LogWarning("IncorrectBlock")
108  << "Xtal id was expected to increase but it didn't - last valid xtal id was " << lastXtalId_ << " while current xtal is " << xtalId
109  << " (LV1 " << event_->l1A() << " fed " << mapper_->getActiveDCC() << " tower " << towerId_ << ")";
110  }
111 
112  int st = lastStripId_;
113  int ch = lastXtalId_;
114  ch++;
115  if (ch > NUMB_XTAL) {ch=1; st++;}
116  if (st > NUMB_STRIP) {ch=1; st=1;}
117 
118  // adding channel following the last valid
119  //pDetId_ = (EBDetId*) mapper_->getDetIdPointer(towerId_,st,ch);
120  //(*invalidChIds_)->push_back(*pDetId_);
122 
123  errorOnXtal = true;
124  lastStripId_ = st;
125  lastXtalId_ = ch;
126 
127  // return here, so to skip all following checks
128  return SKIP_BLOCK_UNPACKING;
129 
130  }
131 
132  // if channel id not proven wrong, update lastStripId_ and lastXtalId_
133  lastStripId_ = stripId;
134  lastXtalId_ = xtalId;
135  }//end else
136  }// end if (zs_)
137 
138 
139  bool addedFrame=false;
140 
141  // if there is an error on xtal id ignore next error checks
142  // otherwise, assume channel_id is valid and proceed with making and checking the data frame
143  if(errorOnXtal) return SKIP_BLOCK_UNPACKING;
144 
145  pDetId_ = (EBDetId*) mapper_->getDetIdPointer(towerId_,stripId,xtalId);
146  (*digis_)->push_back(*pDetId_);
147  EBDataFrame df( (*digis_)->back() );
148  addedFrame=true;
149  bool wrongGain(false);
150 
151  //set samples in the data frame
152  for(unsigned int i =0; i< nTSamples_ ;i++){ // loop on samples
153  xData_++;
154  unsigned int data = (*xData_) & TOWER_DIGI_MASK;
155  unsigned int gain = data>>12;
156  xtalGains_[i]=gain;
157  if(gain == 0){
158  wrongGain = true;
159  // although gain==0 found, produce the dataFrame in order to have it, for saturation case
160  }
161  df.setSample(i,data);
162  }// loop on samples
163 
164  bool isSaturation(true);
165  if(wrongGain){
166 
167  // check whether the gain==0 has features of saturation or not
168  // gain==0 occurs either in case of data corruption or of ADC saturation
169  // \->reject digi \-> keep digi
170 
171  // determine where gainId==0 starts
172  short firstGainZeroSampID(-1); short firstGainZeroSampADC(-1);
173  for (unsigned int s=0; s<nTSamples_; s++ ) {
174  if(df.sample(s).gainId()==0 && firstGainZeroSampID==-1)
175  {
176  firstGainZeroSampID = s;
177  firstGainZeroSampADC = df.sample(s).adc();
178  break;
179  }
180  }
181 
182  // check whether gain==0 and adc() stays constant for (at least) 5 consecutive samples
183  unsigned int plateauEnd = std::min(nTSamples_,(unsigned int)(firstGainZeroSampID+5));
184  for (unsigned int s=firstGainZeroSampID; s<plateauEnd; s++)
185  {
186  if( df.sample(s).gainId()==0 && df.sample(s).adc()==firstGainZeroSampADC ) {;}
187  else
188  { isSaturation=false; break;} //it's not saturation
189  }
190  // get rid of channels which are stuck in gain0
191  if(firstGainZeroSampID<3) {isSaturation=false; }
192 
194  if (unpacker_->getChannelValue(mapper_->getActiveDCC(), towerId_, stripId, xtalId) != 10) {
195  edm::LogWarning("IncorrectGain")
196  << "Gain zero" << (isSaturation ? " with features of saturation" : "" ) << " was found in Tower Block"
197  << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC()
198  << " tower " << towerId_ << " strip " << stripId << " xtal " << xtalId << ")";
199  }
200  }
201 
202  if (! isSaturation)
203  {
204  (*invalidGains_)->push_back(*pDetId_);
205  (*digis_)->pop_back();
206  errorOnXtal = true;
207 
208  //Point to begin of next xtal Block
210  //return here, so to skip all the rest
211  //make special collection for gain0 data frames when due to saturation
212  return BLOCK_UNPACKED;
213  }//end isSaturation
214  else {
216  return BLOCK_UNPACKED;
217  }
218 
219  }//end WrongGain
220 
221 
222  // from here on, care about gain switches
223 
224  short numGain=1;
225  bool gainSwitchError = false;
226 
227  for (unsigned int i=1; i<nTSamples_; i++ ) {
228  if (xtalGains_[i-1] > xtalGains_[i] && numGain<5) gainSwitchError = true;
229  if (xtalGains_[i-1] == xtalGains_[i]) numGain++;
230  else numGain=1;
231  }
232 
233  if (gainSwitchError) {
235  edm::LogWarning("IncorrectGain")
236  << "A wrong gain transition switch was found for Tower Block in strip " << stripId << " and xtal " << xtalId
237  << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower " << towerId_ << ")";
238  }
239 
240  (*invalidGainsSwitch_)->push_back(*pDetId_);
241  errorOnXtal = true;
242  }
243 
244  //Add frame to collection only if all data format and gain rules are respected
245  if (errorOnXtal && addedFrame) {
246  (*digis_)->pop_back();
247  }
248 
249  //Point to begin of next xtal Block
251 
252  return BLOCK_UNPACKED;
253 }
254 
255 
256 
257 void DCCTowerBlock::fillEcalElectronicsError( std::unique_ptr<EcalElectronicsIdCollection> * errorColection ){
258 
259  const int activeDCC = mapper_->getActiveSM();
260 
261  if(NUMB_SM_EB_MIN_MIN<=activeDCC && activeDCC<=NUMB_SM_EB_PLU_MAX){
263  (*errorColection)->push_back(*eleTp);
264  }else{
266  edm::LogWarning("IncorrectBlock")
267  <<"For event "<<event_->l1A()<<" there's fed: "<< activeDCC
268  <<" activeDcc: "<<mapper_->getActiveSM()
269  <<" but that activeDcc is not valid in EB.";
270  }
271 
272  }
273 
274 }
275 
unsigned int towerId_
Definition: DCCFEBlock.h:57
void updateCollectors()
unsigned int expTowerID_
Definition: DCCFEBlock.h:50
bool zs_
Definition: DCCFEBlock.h:45
Ecal readout channel identification [32:20] Unused (so far) [19:13] DCC id [12:6] tower [5:3] strip [...
DetId * getDetIdPointer(unsigned int feChannel, unsigned int strip, unsigned int xtal)
std::unique_ptr< EBDetIdCollection > * invalidGainsCollection()
unsigned int nTSamples_
Definition: DCCFEBlock.h:60
std::unique_ptr< EBDetIdCollection > * invalidGainsSwitch_
Definition: DCCTowerBlock.h:43
std::unique_ptr< EBDetIdCollection > * invalidChIds_
Definition: DCCTowerBlock.h:44
virtual void updateCollectors()
Definition: DCCFEBlock.cc:20
static std::atomic< bool > silentMode_
unsigned int lastXtalId_
Definition: DCCFEBlock.h:55
int unpackXtalData(unsigned int stripID, unsigned int xtalID)
uint16_t getChannelValue(const DetId &id) const
unsigned int bx()
Definition: DCCEventBlock.h:55
std::unique_ptr< EBDetIdCollection > * invalidGainsSwitchCollection()
T min(T a, T b)
Definition: MathUtil.h:58
EBDetId * pDetId_
Definition: DCCTowerBlock.h:39
std::unique_ptr< EBDetIdCollection > * invalidChIdsCollection()
unsigned int lastStripId_
Definition: DCCFEBlock.h:54
DCCDataUnpacker * unpacker_
std::unique_ptr< EBDetIdCollection > * invalidGains_
Definition: DCCTowerBlock.h:42
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
unsigned int numbDWInXtalBlock_
Definition: DCCFEBlock.h:58
std::unique_ptr< EBDigiCollection > * digis_
Definition: DCCTowerBlock.h:37
void fillEcalElectronicsError(std::unique_ptr< EcalElectronicsIdCollection > *)
EcalElectronicsMapper * mapper_
std::unique_ptr< EcalElectronicsIdCollection > * invalidZSXtalIds_
Definition: DCCFEBlock.h:68
EcalElectronicsId * getTTEleIdPointer(unsigned int tccId, unsigned int tower)
DCCTowerBlock(DCCDataUnpacker *u, EcalElectronicsMapper *m, DCCEventBlock *e, bool unpack, bool forceToKeepFRdata)
short * xtalGains_
Definition: DCCFEBlock.h:66
std::unique_ptr< EBDigiCollection > * ebDigisCollection()
unsigned int l1A()
Definition: DCCEventBlock.h:54