00001 #include "EventFilter/EcalRawToDigiDev/interface/DCCMemBlock.h"
00002 #include "EventFilter/EcalRawToDigiDev/interface/DCCEventBlock.h"
00003 #include "EventFilter/EcalRawToDigiDev/interface/DCCDataUnpacker.h"
00004 #include <stdio.h>
00005 #include "EventFilter/EcalRawToDigiDev/interface/EcalElectronicsMapper.h"
00006
00007
00008
00009 DCCMemBlock::DCCMemBlock( DCCDataUnpacker * u,EcalElectronicsMapper * m, DCCEventBlock * e)
00010 :DCCDataBlockPrototype(u,m,e)
00011 {
00012
00013 unfilteredTowerBlockLength_ = mapper_->getUnfilteredTowerBlockLength();
00014 expXtalTSamples_ = mapper_->numbXtalTSamples();
00015
00016 numbDWInXtalBlock_ = (expXtalTSamples_-2)/4+1;
00017 xtalBlockSize_ = numbDWInXtalBlock_*8;
00018 kSamplesPerPn_ = expXtalTSamples_*5;
00019
00020 uint numbOfXtalBlocks = (unfilteredTowerBlockLength_-1)/numbDWInXtalBlock_;
00021 uint numbOfPnBlocks = numbOfXtalBlocks/5;
00022 uint vectorSize = numbOfPnBlocks*10*expXtalTSamples_;
00023
00024
00025 for(uint i =0; i< vectorSize; i++){ pn_.push_back(-1);}
00026
00027 }
00028
00029 void DCCMemBlock::updateCollectors(){
00030
00031 invalidMemChIds_ = unpacker_->invalidMemChIdsCollection();
00032 invalidMemBlockSizes_ = unpacker_->invalidMemBlockSizesCollection();
00033 invalidMemTtIds_ = unpacker_->invalidMemTtIdsCollection();
00034 invalidMemGains_ = unpacker_->invalidMemGainsCollection();
00035 pnDiodeDigis_ = unpacker_->pnDiodeDigisCollection();
00036
00037 }
00038
00039
00040
00041 int DCCMemBlock::unpack(uint64_t ** data, uint * dwToEnd, uint expectedTowerID){
00042
00043 error_ = false;
00044 datap_ = data;
00045 data_ = *data;
00046 dwToEnd_ = dwToEnd;
00047
00048
00049 if( (*dwToEnd_)<1){
00050 if( ! DCCDataUnpacker::silentMode_ ){
00051 edm::LogWarning("EcalRawToDigiDevMemBlock")
00052 <<"\nUnable to unpack MEM block for event "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00053 <<"\nThe end of event was reached !";
00054 }
00055 return STOP_EVENT_UNPACKING;
00056 }
00057
00058 lastStripId_ = 0;
00059 lastXtalId_ = 0;
00060 expTowerID_ = expectedTowerID;
00061
00062
00063
00064 data_++;
00065
00066 towerId_ = ( *data_ ) & TOWER_ID_MASK;
00067 nTSamples_ = ( *data_>>TOWER_NSAMP_B ) & TOWER_NSAMP_MASK;
00068 bx_ = ( *data_>>TOWER_BX_B ) & TOWER_BX_MASK;
00069 l1_ = ( *data_>>TOWER_L1_B ) & TOWER_L1_MASK;
00070 blockLength_ = ( *data_>>TOWER_LENGTH_B ) & TOWER_LENGTH_MASK;
00071
00072
00073
00074
00075
00076 if ( unfilteredTowerBlockLength_ != blockLength_ ){
00077
00078
00079 EcalElectronicsId id( mapper_->getActiveSM() , expTowerID_,1, 1);
00080 (*invalidMemBlockSizes_)->push_back(id);
00081 if( ! DCCDataUnpacker::silentMode_ ){
00082 edm::LogWarning("EcalRawToDigiDevMemBlock")
00083 <<"\nFor event "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower block "<<towerId_
00084 <<"\nExpected mem block size is "<<(unfilteredTowerBlockLength_*8)<<" bytes while "<<(blockLength_*8)<<" was found";
00085 }
00086 return STOP_EVENT_UNPACKING;
00087
00088 }
00089
00090
00091 if((*dwToEnd_)<blockLength_){
00092 if( ! DCCDataUnpacker::silentMode_ ){
00093 edm::LogWarning("EcalRawToDigiDevMemBlock")
00094 <<"\nUnable to unpack MEM block for event "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00095 <<"\n Only "<<((*dwToEnd_)*8)<<" bytes are available while "<<(blockLength_*8)<<" are needed!";
00096
00097 }
00098 EcalElectronicsId id( mapper_->getActiveSM() , expTowerID_,1, 1);
00099 (*invalidMemBlockSizes_)->push_back(id);
00100 return STOP_EVENT_UNPACKING;
00101 }
00102
00103
00104 if(sync_){
00105 uint dccBx = ( event_->l1A())&TOWER_BX_MASK;
00106 uint dccL1 = ( event_->bx() )&TOWER_L1_MASK;
00107
00108 if( dccBx != bx_ || dccL1 != (l1_+1) ){
00109 if( ! DCCDataUnpacker::silentMode_ ){
00110 edm::LogWarning("EcalRawToDigiDevMemBlock")
00111 <<"\nSynchronization error for Mem block in event with DCC L1A: "<<event_->l1A()<<" with DCC bx: "<<event_->bx()
00112 <<" in fed: <<"<<mapper_->getActiveDCC()<<"\nMem local L1A is: "<<l1_<<" Mem local bx is: "<<bx_;
00113 }
00114
00115
00116 return STOP_EVENT_UNPACKING;
00117 }
00118 }
00119
00120
00121 if( nTSamples_ != expXtalTSamples_ ){
00122 if( ! DCCDataUnpacker::silentMode_ ){
00123 edm::LogWarning("EcalRawToDigiDevMemBlock")
00124 <<"\nUnable to unpack MEM block for event "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00125 <<"\nNumber of time samples "<<nTSamples_<<" is not the same as expected ("<<expXtalTSamples_<<")";
00126 }
00127
00128 return STOP_EVENT_UNPACKING;
00129 }
00130
00131
00132
00133 if( expTowerID_ != towerId_){
00134
00135
00136 EcalElectronicsId id( mapper_->getActiveSM() , expTowerID_, 1,1);
00137 (*invalidMemTtIds_)->push_back(id);
00138 if( ! DCCDataUnpacker::silentMode_ ){
00139 edm::LogWarning("EcalRawToDigiDevMemTowerId")
00140 <<"\nFor event "<<event_->l1A()<<" and fed "<<mapper_->getActiveDCC() << " and sm: " << mapper_->getActiveSM()
00141 <<"\nExpected mem tower block is "<<expTowerID_<<" while "<<towerId_<<" was found ";
00142 }
00143
00144 towerId_=expTowerID_;
00145
00146
00147 error_= true;
00148
00149 updateEventPointers();
00150 return SKIP_BLOCK_UNPACKING;
00151 }
00152
00153
00154
00155 data_++;
00156
00157
00158 unpackMemTowerData();
00159
00160 if(!error_){ fillPnDiodeDigisCollection();}
00161
00162 updateEventPointers();
00163
00164 return BLOCK_UNPACKED;
00165
00166 }
00167
00168
00169
00170 void DCCMemBlock::unpackMemTowerData(){
00171
00172
00173
00174
00175
00176 lastTowerBeforeMem_ = 0;
00177
00178 if (9 < mapper_->getActiveSM() || mapper_->getActiveSM() < 46){
00179 lastTowerBeforeMem_ = 69; }
00180 else {
00181 lastTowerBeforeMem_ = 69; }
00182
00183
00184 for(uint expStripId = 1; expStripId<= 5; expStripId++){
00185
00186 for(uint expXtalId = 1; expXtalId <= 5; expXtalId++){
00187
00188 uint16_t * xData_= reinterpret_cast<uint16_t *>(data_);
00189
00190
00191 uint stripId = (*xData_) & TOWER_STRIPID_MASK;
00192 uint xtalId =((*xData_)>>TOWER_XTALID_B ) & TOWER_XTALID_MASK;
00193
00194 bool errorOnDecoding(false);
00195
00196 if(expStripId != stripId || expXtalId != xtalId){
00197
00198
00199 EcalElectronicsId id( mapper_->getActiveSM() , towerId_, expStripId, expXtalId);
00200 (*invalidMemChIds_)->push_back(id);
00201
00202 if( ! DCCDataUnpacker::silentMode_ ){
00203 edm::LogWarning("EcalRawToDigiDevMemChId")
00204 <<"\nFor event "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower mem block "<<towerId_
00205 <<"\nThe expected strip is "<<expStripId<<" and "<<stripId<<" was found"
00206 <<"\nThe expected xtal is "<<expXtalId <<" and "<<xtalId<<" was found";
00207 }
00208
00209 stripId = expStripId;
00210 xtalId = expXtalId;
00211
00212
00213
00214 errorOnDecoding = true;
00215
00216
00217
00218 }
00219
00220 uint ipn, index;
00221
00222 if((stripId-1)%2==0){ ipn = (towerId_-lastTowerBeforeMem_)*5 + xtalId - 1; }
00223 else { ipn = (towerId_-lastTowerBeforeMem_)*5 + 5 - xtalId; }
00224
00225
00226
00227 for(uint i =0; i< nTSamples_ ;i++){
00228
00229 xData_++;
00230
00231 index = ipn*50 + (stripId-1)*nTSamples_+i;
00232
00233
00234
00235
00236 uint temp = (*xData_)&TOWER_DIGI_MASK;
00237
00238 short sample(0);
00239
00240
00241 if( (stripId-1)%2 ) {
00242
00243
00244 for(int ib=0;ib<14;ib++){
00245 sample <<= 1;
00246 sample |= (temp&1);
00247 temp >>= 1;
00248 }
00249
00250 } else { sample=temp;}
00251
00252 sample ^= 0x800;
00253 uint gain = sample>>12;
00254
00255 if( gain >= 2 ){
00256
00257 EcalElectronicsId id(mapper_->getActiveSM() , towerId_, stripId,xtalId);
00258 (*invalidMemGains_)->push_back(id);
00259
00260 if( ! DCCDataUnpacker::silentMode_ ){
00261 edm::LogWarning("EcalRawToDigiDevMemGain")
00262 <<"\nFor event "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" , mem tower block "<<towerId_
00263 <<"\nIn strip "<<stripId<<" xtal "<<xtalId<<" the gain is "<<gain<<" in sample "<<(i+1);
00264 }
00265
00266 errorOnDecoding=true;
00267 }
00268
00269 if( !errorOnDecoding && !error_){pn_[index]=sample;}
00270
00271 }
00272
00273 data_ += numbDWInXtalBlock_;
00274 }
00275 }
00276
00277
00278 }
00279
00280 void DCCMemBlock::fillPnDiodeDigisCollection(){
00281
00282
00283 for (int pnId=1; pnId<=5; pnId++){
00284 bool errorOnPn(false);
00285 uint realPnId = pnId;
00286
00287 if(towerId_==70){ realPnId += 5;}
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 int subdet(0);
00300 if (NUMB_SM_EB_MIN_MIN <= mapper_->getActiveSM() && mapper_->getActiveSM() <= NUMB_SM_EB_PLU_MAX)
00301 { subdet = EcalBarrel;}
00302 else if(NUMB_SM_EE_MIN_MIN <= mapper_->getActiveSM() && mapper_->getActiveSM() <= NUMB_SM_EE_MIN_MAX ||
00303 NUMB_SM_EE_PLU_MIN <= mapper_->getActiveSM() && mapper_->getActiveSM() <= NUMB_SM_EE_PLU_MAX)
00304 { subdet = EcalEndcap;}
00305 else{
00306 if( ! DCCDataUnpacker::silentMode_ ){
00307 edm::LogWarning("EcalRawToDigiDevMemBlock")
00308 <<"\n mapper points to non existing dccid: " << mapper_->getActiveSM();
00309 }
00310 }
00311
00312
00313 EcalPnDiodeDetId PnId(subdet, mapper_->getActiveSM(), realPnId );
00314
00315 EcalPnDiodeDigi thePnDigi(PnId );
00316 thePnDigi.setSize(kSamplesPerPn_);
00317
00318
00319 for (uint ts =0; ts <kSamplesPerPn_; ts++){
00320
00321 short pnDiodeData = pn_[(towerId_-lastTowerBeforeMem_)*250 + (pnId-1)*kSamplesPerPn_ + ts];
00322 if( pnDiodeData == -1){
00323 errorOnPn=true;
00324 break;
00325 }
00326
00327 EcalFEMSample thePnSample(pnDiodeData );
00328 thePnDigi.setSample(ts, thePnSample );
00329 }
00330
00331 if(!errorOnPn){ (*pnDiodeDigis_)->push_back(thePnDigi);}
00332
00333 }
00334
00335 }
00336
00337
00338
00339 void DCCMemBlock::display(std::ostream& o){
00340
00341 o<<"\n Unpacked Info for DCC MEM Block"
00342 <<"\n DW1 ============================="
00343 <<"\n Mem Tower Block Id "<<towerId_
00344 <<"\n Numb Samp "<<nTSamples_
00345 <<"\n Bx "<<bx_
00346 <<"\n L1 "<<l1_
00347 <<"\n blockLength "<<blockLength_;
00348 }
00349
00350
00351
00352