File indexing completed on 2023-03-17 11:00:22
0001 #include <iomanip>
0002 #include <iostream>
0003 #include <sstream>
0004
0005 #include <fmt/format.h>
0006
0007 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0008 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0009 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0010 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0011 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
0012 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
0013 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0014 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/Utilities/interface/CRC16.h"
0017
0018 #include "SiStripDigiToRaw.h"
0019
0020 namespace sistrip {
0021
0022
0023
0024 DigiToRaw::DigiToRaw(FEDReadoutMode mode, uint8_t packetCode, bool useFedKey)
0025 : mode_(mode),
0026 packetCode_(packetCode),
0027 useFedKey_(useFedKey),
0028 bufferGenerator_(),
0029 warnings_("DigiToRaw", "[sistrip::DigiToRaw::createFedBuffers_]", edm::isDebugEnabled()) {
0030 if (edm::isDebugEnabled()) {
0031 LogDebug("DigiToRaw") << "[sistrip::DigiToRaw::DigiToRaw]"
0032 << " Constructing object...";
0033 }
0034 bufferGenerator_.setReadoutMode(mode_);
0035 }
0036
0037
0038
0039 DigiToRaw::~DigiToRaw() {
0040 if (edm::isDebugEnabled()) {
0041 LogDebug("DigiToRaw") << "[sistrip::DigiToRaw::~DigiToRaw]"
0042 << " Destructing object...";
0043 }
0044 }
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 void DigiToRaw::createFedBuffers(edm::Event& event,
0056 edm::ESHandle<SiStripFedCabling>& cabling,
0057 edm::Handle<edm::DetSetVector<SiStripDigi> >& collection,
0058 std::unique_ptr<FEDRawDataCollection>& buffers) {
0059 createFedBuffers_(event, cabling, collection, buffers, true);
0060 }
0061
0062 void DigiToRaw::createFedBuffers(edm::Event& event,
0063 edm::ESHandle<SiStripFedCabling>& cabling,
0064 edm::Handle<edm::DetSetVector<SiStripRawDigi> >& collection,
0065 std::unique_ptr<FEDRawDataCollection>& buffers) {
0066 createFedBuffers_(event, cabling, collection, buffers, false);
0067 }
0068
0069
0070 void DigiToRaw::createFedBuffers(edm::Event& event,
0071 edm::ESHandle<SiStripFedCabling>& cabling,
0072 edm::Handle<FEDRawDataCollection>& rawbuffers,
0073 edm::Handle<edm::DetSetVector<SiStripDigi> >& collection,
0074 std::unique_ptr<FEDRawDataCollection>& buffers) {
0075 createFedBuffers_(event, cabling, rawbuffers, collection, buffers, true);
0076 }
0077
0078 void DigiToRaw::createFedBuffers(edm::Event& event,
0079 edm::ESHandle<SiStripFedCabling>& cabling,
0080 edm::Handle<FEDRawDataCollection>& rawbuffers,
0081 edm::Handle<edm::DetSetVector<SiStripRawDigi> >& collection,
0082 std::unique_ptr<FEDRawDataCollection>& buffers) {
0083 createFedBuffers_(event, cabling, rawbuffers, collection, buffers, false);
0084 }
0085
0086 template <class Digi_t>
0087 void DigiToRaw::createFedBuffers_(edm::Event& event,
0088 edm::ESHandle<SiStripFedCabling>& cabling,
0089 edm::Handle<edm::DetSetVector<Digi_t> >& collection,
0090 std::unique_ptr<FEDRawDataCollection>& buffers,
0091 bool zeroSuppressed) {
0092 edm::Handle<FEDRawDataCollection> rawbuffers;
0093
0094 createFedBuffers_(event, cabling, rawbuffers, collection, buffers, zeroSuppressed);
0095 }
0096
0097 template <class Digi_t>
0098 void DigiToRaw::createFedBuffers_(edm::Event& event,
0099 edm::ESHandle<SiStripFedCabling>& cabling,
0100 edm::Handle<FEDRawDataCollection>& rawbuffers,
0101 edm::Handle<edm::DetSetVector<Digi_t> >& collection,
0102 std::unique_ptr<FEDRawDataCollection>& buffers,
0103 bool zeroSuppressed) {
0104 const bool dataIsAlready8BitTruncated =
0105 zeroSuppressed &&
0106 (!(
0107
0108 (mode_ == READOUT_MODE_PREMIX_RAW)
0109
0110 || ((mode_ == READOUT_MODE_ZERO_SUPPRESSED) && (packetCode_ == PACKET_CODE_ZERO_SUPPRESSED10)) ||
0111 (mode_ == READOUT_MODE_ZERO_SUPPRESSED_LITE10) ||
0112 (mode_ == READOUT_MODE_ZERO_SUPPRESSED_LITE10_CMOVERRIDE)));
0113 try {
0114
0115 bufferGenerator_.setL1ID(0xFFFFFF & event.id().event());
0116 auto fed_ids = cabling->fedIds();
0117
0118
0119 if (rawbuffers.isValid()) {
0120 if (edm::isDebugEnabled()) {
0121 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0122 << " Valid raw buffers, getting headers from them..."
0123 << " Number of feds: " << fed_ids.size() << " between " << *(fed_ids.begin())
0124 << " and " << *(fed_ids.end());
0125 }
0126
0127 const FEDRawDataCollection& rawDataCollection = *rawbuffers;
0128
0129 for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ++ifed) {
0130 const FEDRawData& rawfedData = rawDataCollection.FEDData(*ifed);
0131
0132 if (edm::isDebugEnabled()) {
0133 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0134 << "Fed " << *ifed << " : size of buffer = " << rawfedData.size();
0135 }
0136
0137
0138 if (rawfedData.size() == 0)
0139 warnings_.add("Invalid raw data for FED, skipping", fmt::format("id {0}", *ifed));
0140 const auto st_buffer = preconstructCheckFEDBuffer(rawfedData, true);
0141 if (FEDBufferStatusCode::SUCCESS != st_buffer) {
0142 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0143 << " Could not construct FEDBuffer for FED " << *ifed << std::endl;
0144 continue;
0145 }
0146 sistrip::FEDBuffer fedbuffer{rawfedData, true};
0147 const auto st_chan = fedbuffer.findChannels();
0148 if (FEDBufferStatusCode::SUCCESS != st_chan) {
0149 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0150 << " Could not construct FEDBuffer for FED " << *ifed << std::endl;
0151 }
0152 if (fedbuffer.headerType() == sistrip::HEADER_TYPE_INVALID) {
0153 warnings_.add("Invalid header type for FED, skipping", fmt::format("id {0}", *ifed));
0154 continue;
0155 }
0156
0157 if (edm::isDebugEnabled()) {
0158 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0159 << " Original header type: " << fedbuffer.headerType();
0160 }
0161
0162 bufferGenerator_.setHeaderType(FEDHeaderType::HEADER_TYPE_FULL_DEBUG);
0163
0164 bufferGenerator_.daqHeader() = fedbuffer.daqHeader();
0165 bufferGenerator_.daqTrailer() = fedbuffer.daqTrailer();
0166
0167 bufferGenerator_.trackerSpecialHeader() = fedbuffer.trackerSpecialHeader();
0168 bufferGenerator_.setReadoutMode(mode_);
0169
0170 if (edm::isDebugEnabled()) {
0171 std::ostringstream debugStream;
0172 if (ifed == fed_ids.begin()) {
0173 bufferGenerator_.trackerSpecialHeader().print(std::cout);
0174 std::cout << std::endl;
0175 }
0176 bufferGenerator_.trackerSpecialHeader().print(debugStream);
0177 edm::LogWarning("DigiToRaw")
0178 << "[sistrip::DigiToRaw::createFedBuffers_]"
0179 << " Tracker special header apveAddress: "
0180 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().apveAddress())
0181 << " - event type = " << bufferGenerator_.getDAQEventType()
0182 << " - buffer format = " << bufferGenerator_.getBufferFormat() << "\n"
0183 << " - SpecialHeader bufferformat " << bufferGenerator_.trackerSpecialHeader().bufferFormat()
0184 << " - headertype " << bufferGenerator_.trackerSpecialHeader().headerType() << " - readoutmode "
0185 << bufferGenerator_.trackerSpecialHeader().readoutMode() << " - apvaddrregister " << std::hex
0186 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().apvAddressErrorRegister())
0187 << " - feenabledregister " << std::hex
0188 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().feEnableRegister())
0189 << " - feoverflowregister " << std::hex
0190 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().feOverflowRegister())
0191 << " - statusregister " << bufferGenerator_.trackerSpecialHeader().fedStatusRegister() << "\n"
0192 << " SpecialHeader: " << debugStream.str();
0193 }
0194
0195 std::unique_ptr<FEDFEHeader> tempFEHeader(fedbuffer.feHeader()->clone());
0196 FEDFullDebugHeader* fedFeHeader = dynamic_cast<FEDFullDebugHeader*>(tempFEHeader.get());
0197 if (edm::isDebugEnabled()) {
0198 std::ostringstream debugStream;
0199 if (ifed == fed_ids.begin()) {
0200 std::cout << "FEHeader before transfer: " << std::endl;
0201 fedFeHeader->print(std::cout);
0202 std::cout << std::endl;
0203 }
0204 fedFeHeader->print(debugStream);
0205 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0206 << " length of original feHeader: " << fedFeHeader->lengthInBytes() << "\n"
0207 << debugStream.str();
0208 }
0209
0210 (bufferGenerator_.feHeader()).setBEStatusRegister(fedFeHeader->beStatusRegister());
0211 (bufferGenerator_.feHeader()).setDAQRegister2(fedFeHeader->daqRegister2());
0212 (bufferGenerator_.feHeader()).setDAQRegister(fedFeHeader->daqRegister());
0213 for (uint8_t iFE = 1; iFE < 6; iFE++) {
0214 (bufferGenerator_.feHeader())
0215 .set32BitReservedRegister(iFE, fedFeHeader->get32BitWordFrom(fedFeHeader->feWord(iFE) + 10));
0216 }
0217
0218 std::vector<bool> feEnabledVec;
0219 feEnabledVec.resize(FEUNITS_PER_FED, true);
0220 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0221 feEnabledVec[iFE] = fedbuffer.trackerSpecialHeader().feEnabled(iFE);
0222 (bufferGenerator_.feHeader()).setFEUnitMajorityAddress(iFE, fedFeHeader->feUnitMajorityAddress(iFE));
0223 for (uint8_t iFEUnitChannel = 0; iFEUnitChannel < FEDCH_PER_FEUNIT; iFEUnitChannel++) {
0224 (bufferGenerator_.feHeader())
0225 .setChannelStatus(iFE, iFEUnitChannel, fedFeHeader->getChannelStatus(iFE, iFEUnitChannel));
0226 }
0227 }
0228 bufferGenerator_.setFEUnitEnables(feEnabledVec);
0229
0230 if (edm::isDebugEnabled()) {
0231 std::ostringstream debugStream;
0232 if (ifed == fed_ids.begin()) {
0233 std::cout << "\nFEHeader after transfer: " << std::endl;
0234 bufferGenerator_.feHeader().print(std::cout);
0235 std::cout << std::endl;
0236 }
0237 bufferGenerator_.feHeader().print(debugStream);
0238 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0239 << " length of feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
0240 << "\n"
0241 << debugStream.str();
0242 }
0243 auto conns = cabling->fedConnections(*ifed);
0244
0245 FEDStripData fedData(dataIsAlready8BitTruncated);
0246
0247 for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
0248
0249 uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
0250
0251
0252 uint32_t key = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? fed_key : iconn->detId();
0253
0254
0255 if (!key || (key == sistrip::invalid32_)) {
0256 continue;
0257 }
0258
0259
0260 uint16_t ipair = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? 0 : iconn->apvPairNumber();
0261
0262 FEDStripData::ChannelData& chanData = fedData[iconn->fedCh()];
0263
0264
0265 if (!collection.isValid()) {
0266 if (edm::isDebugEnabled()) {
0267 edm::LogWarning("DigiToRaw") << "[DigiToRaw::createFedBuffers] "
0268 << "digis collection is not valid...";
0269 }
0270 break;
0271 }
0272 typename std::vector<edm::DetSet<Digi_t> >::const_iterator digis = collection->find(key);
0273 if (digis == collection->end()) {
0274 continue;
0275 }
0276
0277 typename edm::DetSet<Digi_t>::const_iterator idigi, digis_begin(digis->data.begin());
0278 for (idigi = digis_begin; idigi != digis->data.end(); idigi++) {
0279 if (STRIP(idigi, digis_begin) < ipair * 256 || STRIP(idigi, digis_begin) > ipair * 256 + 255) {
0280 continue;
0281 }
0282 const unsigned short strip = STRIP(idigi, digis_begin) % 256;
0283
0284 if (strip >= STRIPS_PER_FEDCH) {
0285 if (edm::isDebugEnabled()) {
0286 std::stringstream ss;
0287 ss << "[sistrip::DigiToRaw::createFedBuffers]"
0288 << " strip >= strips_per_fedCh";
0289 edm::LogWarning("DigiToRaw") << ss.str();
0290 }
0291 continue;
0292 }
0293
0294
0295 if (edm::isDebugEnabled()) {
0296 const uint16_t value = 0;
0297 if (value && value != (*idigi).adc()) {
0298 std::stringstream ss;
0299 ss << "[sistrip::DigiToRaw::createFedBuffers]"
0300 << " Incompatible ADC values in buffer!"
0301 << " FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
0302 << " DetStrip: " << STRIP(idigi, digis_begin) << " FedChStrip: " << strip
0303 << " AdcValue: " << (*idigi).adc() << " RawData[" << strip << "]: " << value;
0304 edm::LogWarning("DigiToRaw") << ss.str();
0305 }
0306 }
0307
0308
0309 chanData[strip] = (*idigi).adc();
0310 }
0311 }
0312
0313
0314 if (edm::isDebugEnabled()) {
0315 edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
0316 << "Almost at the end...";
0317 }
0318
0319 FEDRawData& fedrawdata = buffers->FEDData(*ifed);
0320 bufferGenerator_.generateBuffer(&fedrawdata, fedData, *ifed, packetCode_);
0321
0322 if (edm::isDebugEnabled()) {
0323 std::ostringstream debugStream;
0324 bufferGenerator_.feHeader().print(debugStream);
0325 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0326 << " length of final feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
0327 << "\n"
0328 << debugStream.str();
0329 }
0330 }
0331 if (edm::isDebugEnabled()) {
0332 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0333 << "end of first loop on feds";
0334 }
0335
0336 }
0337 else {
0338 if (edm::isDebugEnabled()) {
0339 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0340 << "Now getting the digis..."
0341 << " Number of feds: " << fed_ids.size() << " between " << *(fed_ids.begin())
0342 << " and " << *(fed_ids.end());
0343 }
0344
0345 for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ++ifed) {
0346 auto conns = cabling->fedConnections(*ifed);
0347
0348 FEDStripData fedData(dataIsAlready8BitTruncated);
0349
0350 for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
0351
0352 uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
0353
0354
0355 uint32_t key = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? fed_key : iconn->detId();
0356
0357
0358 if (!key || (key == sistrip::invalid32_)) {
0359 continue;
0360 }
0361
0362
0363 uint16_t ipair = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? 0 : iconn->apvPairNumber();
0364
0365 FEDStripData::ChannelData& chanData = fedData[iconn->fedCh()];
0366
0367
0368 if (!collection.isValid()) {
0369 if (edm::isDebugEnabled()) {
0370 edm::LogWarning("DigiToRaw") << "[DigiToRaw::createFedBuffers] "
0371 << "digis collection is not valid...";
0372 }
0373 break;
0374 }
0375 typename std::vector<edm::DetSet<Digi_t> >::const_iterator digis = collection->find(key);
0376 if (digis == collection->end()) {
0377 continue;
0378 }
0379
0380 typename edm::DetSet<Digi_t>::const_iterator idigi, digis_begin(digis->data.begin());
0381 for (idigi = digis_begin; idigi != digis->data.end(); idigi++) {
0382 if (STRIP(idigi, digis_begin) < ipair * 256 || STRIP(idigi, digis_begin) > ipair * 256 + 255) {
0383 continue;
0384 }
0385 const unsigned short strip = STRIP(idigi, digis_begin) % 256;
0386
0387 if (strip >= STRIPS_PER_FEDCH) {
0388 if (edm::isDebugEnabled()) {
0389 std::stringstream ss;
0390 ss << "[sistrip::DigiToRaw::createFedBuffers]"
0391 << " strip >= strips_per_fedCh";
0392 edm::LogWarning("DigiToRaw") << ss.str();
0393 }
0394 continue;
0395 }
0396
0397
0398 if (edm::isDebugEnabled()) {
0399 const uint16_t value = 0;
0400 if (value && value != (*idigi).adc()) {
0401 std::stringstream ss;
0402 ss << "[sistrip::DigiToRaw::createFedBuffers]"
0403 << " Incompatible ADC values in buffer!"
0404 << " FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
0405 << " DetStrip: " << STRIP(idigi, digis_begin) << " FedChStrip: " << strip
0406 << " AdcValue: " << (*idigi).adc() << " RawData[" << strip << "]: " << value;
0407 edm::LogWarning("DigiToRaw") << ss.str();
0408 }
0409 }
0410
0411
0412 chanData[strip] = (*idigi).adc();
0413 }
0414 }
0415
0416
0417 if (edm::isDebugEnabled()) {
0418 edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
0419 << "Almost at the end...";
0420 }
0421
0422 FEDRawData& fedrawdata = buffers->FEDData(*ifed);
0423 bufferGenerator_.generateBuffer(&fedrawdata, fedData, *ifed, packetCode_);
0424
0425 if (edm::isDebugEnabled()) {
0426 std::ostringstream debugStream;
0427 bufferGenerator_.feHeader().print(debugStream);
0428 edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0429 << " length of final feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
0430 << "\n"
0431 << debugStream.str();
0432 }
0433 }
0434 }
0435 }
0436 catch (const std::exception& e) {
0437 if (edm::isDebugEnabled()) {
0438 edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
0439 << "Exception caught : " << e.what();
0440 }
0441 }
0442 }
0443
0444 inline uint16_t DigiToRaw::STRIP(const edm::DetSet<SiStripDigi>::const_iterator& it,
0445 const edm::DetSet<SiStripDigi>::const_iterator& begin) const {
0446 return it->strip();
0447 }
0448 inline uint16_t DigiToRaw::STRIP(const edm::DetSet<SiStripRawDigi>::const_iterator& it,
0449 const edm::DetSet<SiStripRawDigi>::const_iterator& begin) const {
0450 return it - begin;
0451 }
0452
0453 }