File indexing completed on 2023-03-17 10:59:41
0001 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.h"
0002 #include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
0003 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
0004 #include <cstdio>
0005 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
0006
0007 DCCMemBlock::DCCMemBlock(DCCDataUnpacker* u, EcalElectronicsMapper* m, DCCEventBlock* e)
0008 : DCCDataBlockPrototype(u, m, e) {
0009 unfilteredTowerBlockLength_ = mapper_->getUnfilteredTowerBlockLength();
0010 expXtalTSamples_ = mapper_->numbXtalTSamples();
0011
0012 numbDWInXtalBlock_ = (expXtalTSamples_ - 2) / 4 + 1;
0013 xtalBlockSize_ = numbDWInXtalBlock_ * 8;
0014 kSamplesPerPn_ = expXtalTSamples_ * 5;
0015
0016 unsigned int numbOfXtalBlocks = (unfilteredTowerBlockLength_ - 1) / numbDWInXtalBlock_;
0017 unsigned int numbOfPnBlocks = numbOfXtalBlocks / 5;
0018 unsigned int vectorSize = numbOfPnBlocks * 10 * expXtalTSamples_;
0019
0020
0021 for (unsigned int i = 0; i < vectorSize; i++) {
0022 pn_.push_back(-1);
0023 }
0024 }
0025
0026 void DCCMemBlock::updateCollectors() {
0027 invalidMemChIds_ = unpacker_->invalidMemChIdsCollection();
0028 invalidMemBlockSizes_ = unpacker_->invalidMemBlockSizesCollection();
0029 invalidMemTtIds_ = unpacker_->invalidMemTtIdsCollection();
0030 invalidMemGains_ = unpacker_->invalidMemGainsCollection();
0031 pnDiodeDigis_ = unpacker_->pnDiodeDigisCollection();
0032 }
0033
0034 int DCCMemBlock::unpack(const uint64_t** data, unsigned int* dwToEnd, unsigned int expectedTowerID) {
0035 error_ = false;
0036 datap_ = data;
0037 data_ = *data;
0038 dwToEnd_ = dwToEnd;
0039
0040 if ((*dwToEnd_) < 1) {
0041 if (!DCCDataUnpacker::silentMode_) {
0042 edm::LogWarning("IncorrectEvent") << "\nUnable to unpack MEM block for event " << event_->l1A() << " in fed "
0043 << mapper_->getActiveDCC() << "\nThe end of event was reached !";
0044 }
0045 return STOP_EVENT_UNPACKING;
0046 }
0047
0048 lastStripId_ = 0;
0049 lastXtalId_ = 0;
0050 expTowerID_ = expectedTowerID;
0051
0052
0053 data_++;
0054
0055 towerId_ = (*data_) & TOWER_ID_MASK;
0056 nTSamples_ = (*data_ >> TOWER_NSAMP_B) & TOWER_NSAMP_MASK;
0057 bx_ = (*data_ >> TOWER_BX_B) & TOWER_BX_MASK;
0058 l1_ = (*data_ >> TOWER_L1_B) & TOWER_L1_MASK;
0059 blockLength_ = (*data_ >> TOWER_LENGTH_B) & TOWER_LENGTH_MASK;
0060
0061 event_->setFESyncNumbers(l1_, bx_, short(expectedTowerID - 1));
0062
0063
0064
0065
0066
0067 if (unfilteredTowerBlockLength_ != blockLength_) {
0068
0069 EcalElectronicsId id(mapper_->getActiveSM(), expTowerID_, 1, 1);
0070 (*invalidMemBlockSizes_)->push_back(id);
0071 if (!DCCDataUnpacker::silentMode_) {
0072 edm::LogWarning("IncorrectEvent") << "\nFor event " << event_->l1A() << ", fed " << mapper_->getActiveDCC()
0073 << " and tower block " << towerId_ << "\nExpected mem block size is "
0074 << (unfilteredTowerBlockLength_ * 8) << " bytes while " << (blockLength_ * 8)
0075 << " was found";
0076 }
0077 return STOP_EVENT_UNPACKING;
0078 }
0079
0080
0081 if ((*dwToEnd_) < blockLength_) {
0082 if (!DCCDataUnpacker::silentMode_) {
0083 edm::LogWarning("IncorrectEvent") << "\nUnable to unpack MEM block for event " << event_->l1A() << " in fed "
0084 << mapper_->getActiveDCC() << "\n Only " << ((*dwToEnd_) * 8)
0085 << " bytes are available while " << (blockLength_ * 8) << " are needed!";
0086
0087 }
0088 EcalElectronicsId id(mapper_->getActiveSM(), expTowerID_, 1, 1);
0089 (*invalidMemBlockSizes_)->push_back(id);
0090 return STOP_EVENT_UNPACKING;
0091 }
0092
0093
0094 if (sync_) {
0095 const unsigned int dccBx = (event_->bx()) & TOWER_BX_MASK;
0096 const unsigned int dccL1 = (event_->l1A()) & TOWER_L1_MASK;
0097 const unsigned int fov = (event_->fov()) & H_FOV_MASK;
0098
0099 if (!isSynced(dccBx, bx_, dccL1, l1_, FE_MEM, fov)) {
0100 if (!DCCDataUnpacker::silentMode_) {
0101 edm::LogWarning("IncorrectEvent")
0102 << "Synchronization error for Mem block"
0103 << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << ")\n"
0104 << " dccBx = " << dccBx << " bx_ = " << bx_ << " dccL1 = " << dccL1 << " l1_ = " << l1_ << "\n"
0105 << " => Stop event unpacking";
0106 }
0107
0108
0109 return STOP_EVENT_UNPACKING;
0110 }
0111 }
0112
0113
0114 if (nTSamples_ != expXtalTSamples_) {
0115 if (!DCCDataUnpacker::silentMode_) {
0116 edm::LogWarning("IncorrectEvent") << "\nUnable to unpack MEM block for event " << event_->l1A() << " in fed "
0117 << mapper_->getActiveDCC() << "\nNumber of time samples " << nTSamples_
0118 << " is not the same as expected (" << expXtalTSamples_ << ")";
0119 }
0120
0121 return STOP_EVENT_UNPACKING;
0122 }
0123
0124
0125 if (expTowerID_ != towerId_) {
0126
0127 EcalElectronicsId id(mapper_->getActiveSM(), expTowerID_, 1, 1);
0128 (*invalidMemTtIds_)->push_back(id);
0129 if (!DCCDataUnpacker::silentMode_) {
0130 edm::LogWarning("IncorrectBlock") << "For event " << event_->l1A() << " and fed " << mapper_->getActiveDCC()
0131 << " and sm: " << mapper_->getActiveSM() << "\nExpected mem tower block is "
0132 << expTowerID_ << " while " << towerId_ << " was found ";
0133 }
0134
0135 towerId_ = expTowerID_;
0136
0137
0138 error_ = true;
0139
0140 updateEventPointers();
0141 return SKIP_BLOCK_UNPACKING;
0142 }
0143
0144
0145 data_++;
0146
0147 unpackMemTowerData();
0148
0149 if (!error_) {
0150 fillPnDiodeDigisCollection();
0151 }
0152
0153 updateEventPointers();
0154
0155 return BLOCK_UNPACKED;
0156 }
0157
0158 void DCCMemBlock::unpackMemTowerData() {
0159
0160
0161 lastTowerBeforeMem_ = 0;
0162
0163 if (9 < mapper_->getActiveSM() || mapper_->getActiveSM() < 46) {
0164 lastTowerBeforeMem_ = 69;
0165 } else {
0166 lastTowerBeforeMem_ = 69;
0167 }
0168
0169 for (unsigned int expStripId = 1; expStripId <= 5; expStripId++) {
0170 for (unsigned int expXtalId = 1; expXtalId <= 5; expXtalId++) {
0171 const uint16_t* xData_ = reinterpret_cast<const uint16_t*>(data_);
0172
0173
0174 unsigned int stripId = (*xData_) & TOWER_STRIPID_MASK;
0175 unsigned int xtalId = ((*xData_) >> TOWER_XTALID_B) & TOWER_XTALID_MASK;
0176
0177 bool errorOnDecoding(false);
0178
0179 if (expStripId != stripId || expXtalId != xtalId) {
0180
0181 EcalElectronicsId id(mapper_->getActiveSM(), towerId_, expStripId, expXtalId);
0182 (*invalidMemChIds_)->push_back(id);
0183
0184 if (!DCCDataUnpacker::silentMode_) {
0185 edm::LogWarning("IncorrectBlock")
0186 << "For event " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower mem block "
0187 << towerId_ << "\nThe expected strip is " << expStripId << " and " << stripId << " was found"
0188 << "\nThe expected xtal is " << expXtalId << " and " << xtalId << " was found";
0189 }
0190
0191 stripId = expStripId;
0192 xtalId = expXtalId;
0193
0194 errorOnDecoding = true;
0195
0196
0197 }
0198
0199 unsigned int ipn, index;
0200
0201 if ((stripId - 1) % 2 == 0) {
0202 ipn = (towerId_ - lastTowerBeforeMem_) * 5 + xtalId - 1;
0203 } else {
0204 ipn = (towerId_ - lastTowerBeforeMem_) * 5 + 5 - xtalId;
0205 }
0206
0207
0208 for (unsigned int i = 0; i < nTSamples_; i++) {
0209 xData_++;
0210
0211 index = ipn * 50 + (stripId - 1) * nTSamples_ + i;
0212
0213
0214
0215
0216 unsigned int temp = (*xData_) & TOWER_DIGI_MASK;
0217
0218 short sample(0);
0219
0220 if ((stripId - 1) % 2) {
0221
0222 for (int ib = 0; ib < 14; ib++) {
0223 sample <<= 1;
0224 sample |= (temp & 1);
0225 temp >>= 1;
0226 }
0227
0228 } else {
0229 sample = temp;
0230 }
0231
0232 sample ^= 0x800;
0233 unsigned int gain = sample >> 12;
0234
0235 if (gain >= 2) {
0236 EcalElectronicsId id(mapper_->getActiveSM(), towerId_, stripId, xtalId);
0237 (*invalidMemGains_)->push_back(id);
0238
0239 if (!DCCDataUnpacker::silentMode_) {
0240 edm::LogWarning("IncorrectGain")
0241 << "For event " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " , mem tower block "
0242 << towerId_ << "\nIn strip " << stripId << " xtal " << xtalId << " the gain is " << gain
0243 << " in sample " << (i + 1);
0244 }
0245
0246 errorOnDecoding = true;
0247 }
0248
0249 if (!errorOnDecoding && !error_) {
0250 pn_[index] = sample;
0251 }
0252
0253 }
0254
0255 data_ += numbDWInXtalBlock_;
0256 }
0257 }
0258 }
0259
0260 void DCCMemBlock::fillPnDiodeDigisCollection() {
0261
0262 for (int pnId = 1; pnId <= 5; pnId++) {
0263 bool errorOnPn(false);
0264 unsigned int realPnId = pnId;
0265
0266 if (towerId_ == 70) {
0267 realPnId += 5;
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 const int activeSM = mapper_->getActiveSM();
0281 int subdet(0);
0282 if (NUMB_SM_EB_MIN_MIN <= activeSM && activeSM <= NUMB_SM_EB_PLU_MAX) {
0283 subdet = EcalBarrel;
0284 } else if ((NUMB_SM_EE_MIN_MIN <= activeSM && activeSM <= NUMB_SM_EE_MIN_MAX) ||
0285 (NUMB_SM_EE_PLU_MIN <= activeSM && activeSM <= NUMB_SM_EE_PLU_MAX)) {
0286 subdet = EcalEndcap;
0287 } else {
0288 if (!DCCDataUnpacker::silentMode_) {
0289 edm::LogWarning("IncorrectMapping") << "\n mapper points to non existing dccid: " << activeSM;
0290 }
0291 }
0292
0293 EcalPnDiodeDetId PnId(subdet, activeSM, realPnId);
0294
0295 EcalPnDiodeDigi thePnDigi(PnId);
0296 thePnDigi.setSize(kSamplesPerPn_);
0297
0298 for (unsigned int ts = 0; ts < kSamplesPerPn_; ts++) {
0299 short pnDiodeData = pn_[(towerId_ - lastTowerBeforeMem_) * 250 + (pnId - 1) * kSamplesPerPn_ + ts];
0300 if (pnDiodeData == -1) {
0301 errorOnPn = true;
0302 break;
0303 }
0304
0305 EcalFEMSample thePnSample(pnDiodeData);
0306 thePnDigi.setSample(ts, thePnSample);
0307 }
0308
0309 if (!errorOnPn) {
0310 (*pnDiodeDigis_)->push_back(thePnDigi);
0311 }
0312 }
0313 }
0314
0315 void DCCMemBlock::display(std::ostream& o) {
0316 o << "\n Unpacked Info for DCC MEM Block"
0317 << "\n DW1 ============================="
0318 << "\n Mem Tower Block Id " << towerId_ << "\n Numb Samp " << nTSamples_ << "\n Bx " << bx_ << "\n L1 " << l1_
0319 << "\n blockLength " << blockLength_;
0320 }