File indexing completed on 2024-04-06 12:11:04
0001 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferGenerator.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <cstring>
0004 #include <stdexcept>
0005 #include <cmath>
0006
0007 namespace sistrip {
0008
0009
0010
0011 FEDStripData::FEDStripData(bool dataIsAlreadyConvertedTo8Bit, const size_t samplesPerChannel)
0012 : data_(FEDCH_PER_FED, ChannelData(dataIsAlreadyConvertedTo8Bit, samplesPerChannel)) {
0013 if (samplesPerChannel > SCOPE_MODE_MAX_SCOPE_LENGTH) {
0014 std::ostringstream ss;
0015 ss << "Scope length " << samplesPerChannel << " is too long. "
0016 << "Max scope length is " << SCOPE_MODE_MAX_SCOPE_LENGTH << ".";
0017 throw cms::Exception("FEDBufferGenerator") << ss.str();
0018 }
0019 }
0020
0021 const FEDStripData::ChannelData& FEDStripData::channel(const uint8_t internalFEDChannelNum) const {
0022 try {
0023 return data_.at(internalFEDChannelNum);
0024 } catch (const std::out_of_range&) {
0025 std::ostringstream ss;
0026 ss << "Channel index out of range. (" << uint16_t(internalFEDChannelNum) << ") "
0027 << "Index should be in internal numbering scheme (0-95). ";
0028 throw cms::Exception("FEDBufferGenerator") << ss.str();
0029 }
0030 }
0031
0032 void FEDStripData::ChannelData::setSample(const uint16_t sampleNumber, const uint16_t value) {
0033 if (value > 0x3FF) {
0034 std::ostringstream ss;
0035 ss << "Sample value (" << value << ") is too large. Maximum allowed is 1023. ";
0036 throw cms::Exception("FEDBufferGenerator") << ss.str();
0037 }
0038 try {
0039 data_.at(sampleNumber) = value;
0040 } catch (const std::out_of_range&) {
0041 std::ostringstream ss;
0042 ss << "Sample index out of range. "
0043 << "Requesting sample " << sampleNumber << " when channel has only " << data_.size() << " samples.";
0044 throw cms::Exception("FEDBufferGenerator") << ss.str();
0045 }
0046 }
0047
0048
0049
0050 FEDBufferPayload::FEDBufferPayload(const std::vector<std::vector<uint8_t> >& channelBuffers) {
0051
0052 uint32_t totalSize = 0;
0053 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0054 for (uint8_t iCh = 0; iCh < FEDCH_PER_FEUNIT; iCh++) {
0055 totalSize += channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].size();
0056 }
0057
0058 if (totalSize % 8) {
0059 totalSize = ((totalSize / 8) + 1) * 8;
0060 }
0061 }
0062 data_.resize(totalSize);
0063 size_t indexInBuffer = 0;
0064 feLengths_.reserve(FEUNITS_PER_FED);
0065
0066 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0067 const size_t lengthAtStartOfFEUnit = indexInBuffer;
0068
0069 for (uint8_t iCh = 0; iCh < FEDCH_PER_FEUNIT; iCh++) {
0070 appendToBuffer(&indexInBuffer,
0071 channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].begin(),
0072 channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].end());
0073 }
0074
0075 feLengths_.push_back(indexInBuffer - lengthAtStartOfFEUnit);
0076
0077 while (indexInBuffer % 8)
0078 appendToBuffer(&indexInBuffer, 0);
0079 }
0080 }
0081
0082 const uint8_t* FEDBufferPayload::data() const {
0083
0084 if (lengthInBytes())
0085 return &data_[0];
0086
0087 else
0088 return nullptr;
0089 }
0090
0091 uint16_t FEDBufferPayload::getFELength(const uint8_t internalFEUnitNum) const {
0092 try {
0093 return feLengths_.at(internalFEUnitNum);
0094 } catch (const std::out_of_range&) {
0095 std::ostringstream ss;
0096 ss << "Invalid FE unit number " << internalFEUnitNum << ". "
0097 << "Number should be in internal numbering scheme (0-7). ";
0098 throw cms::Exception("FEDBufferGenerator") << ss.str();
0099 }
0100 }
0101
0102 FEDBufferPayload FEDBufferPayloadCreator::createPayload(FEDReadoutMode mode,
0103 uint8_t packetCode,
0104 const FEDStripData& data) const {
0105 std::vector<std::vector<uint8_t> > channelBuffers(FEDCH_PER_FED, std::vector<uint8_t>());
0106 for (size_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
0107 if (!feUnitsEnabled_[iCh / FEDCH_PER_FEUNIT])
0108 continue;
0109 fillChannelBuffer(&channelBuffers[iCh], mode, packetCode, data.channel(iCh), channelsEnabled_[iCh]);
0110 }
0111 return FEDBufferPayload(channelBuffers);
0112 }
0113
0114 void FEDBufferPayloadCreator::fillChannelBuffer(std::vector<uint8_t>* channelBuffer,
0115 FEDReadoutMode mode,
0116 uint8_t packetCode,
0117 const FEDStripData::ChannelData& data,
0118 const bool channelEnabled) const {
0119 switch (mode) {
0120 case READOUT_MODE_SCOPE:
0121 fillRawChannelBuffer(channelBuffer, PACKET_CODE_SCOPE, data, channelEnabled, false);
0122 break;
0123 case READOUT_MODE_VIRGIN_RAW:
0124 switch (packetCode) {
0125 case PACKET_CODE_VIRGIN_RAW:
0126 fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW, data, channelEnabled, true);
0127 break;
0128 case PACKET_CODE_VIRGIN_RAW10:
0129 fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW10, data, channelEnabled, true);
0130 break;
0131 case PACKET_CODE_VIRGIN_RAW8_BOTBOT:
0132 fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW8_BOTBOT, data, channelEnabled, true);
0133 break;
0134 case PACKET_CODE_VIRGIN_RAW8_TOPBOT:
0135 fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW8_TOPBOT, data, channelEnabled, true);
0136 break;
0137 }
0138 break;
0139 case READOUT_MODE_PROC_RAW:
0140 fillRawChannelBuffer(channelBuffer, PACKET_CODE_PROC_RAW, data, channelEnabled, false);
0141 break;
0142 case READOUT_MODE_ZERO_SUPPRESSED:
0143
0144 fillZeroSuppressedChannelBuffer(channelBuffer, packetCode, data, channelEnabled);
0145 break;
0146 case READOUT_MODE_ZERO_SUPPRESSED_LITE10:
0147 case READOUT_MODE_ZERO_SUPPRESSED_LITE10_CMOVERRIDE:
0148 case READOUT_MODE_ZERO_SUPPRESSED_LITE8:
0149 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_CMOVERRIDE:
0150 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT:
0151 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT_CMOVERRIDE:
0152 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT:
0153 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT_CMOVERRIDE:
0154 fillZeroSuppressedLiteChannelBuffer(channelBuffer, data, channelEnabled, mode);
0155 break;
0156 case READOUT_MODE_PREMIX_RAW:
0157 fillPreMixRawChannelBuffer(channelBuffer, data, channelEnabled);
0158 break;
0159 default:
0160 std::ostringstream ss;
0161 ss << "Invalid readout mode " << mode;
0162 throw cms::Exception("FEDBufferGenerator") << ss.str();
0163 break;
0164 }
0165 }
0166
0167 void FEDBufferPayloadCreator::fillRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
0168 const uint8_t packetCode,
0169 const FEDStripData::ChannelData& data,
0170 const bool channelEnabled,
0171 const bool reorderData) const {
0172 const uint16_t nSamples = data.size();
0173 uint16_t channelLength = 0;
0174 switch (packetCode) {
0175 case PACKET_CODE_VIRGIN_RAW:
0176 channelLength = nSamples * 2 + 3;
0177 break;
0178 case PACKET_CODE_VIRGIN_RAW10:
0179 channelLength = std::ceil(nSamples * 1.25) + 3;
0180 break;
0181 case PACKET_CODE_VIRGIN_RAW8_BOTBOT:
0182 case PACKET_CODE_VIRGIN_RAW8_TOPBOT:
0183 channelLength = nSamples * 1 + 3;
0184 break;
0185 }
0186 channelBuffer->reserve(channelLength);
0187
0188 channelBuffer->push_back(channelLength & 0xFF);
0189 channelBuffer->push_back((channelLength & 0xF00) >> 8);
0190
0191 channelBuffer->push_back(packetCode);
0192
0193 uint16_t sampleValue_pre = 0;
0194 for (uint16_t sampleNumber = 0; sampleNumber < nSamples; sampleNumber++) {
0195 const uint16_t sampleIndex =
0196 (reorderData ? FEDStripOrdering::physicalOrderForStripInChannel(sampleNumber) : sampleNumber);
0197 const uint16_t sampleValue = (channelEnabled ? data.getSample(sampleIndex) : 0);
0198 switch (packetCode) {
0199 case PACKET_CODE_VIRGIN_RAW:
0200 channelBuffer->push_back(sampleValue & 0xFF);
0201 channelBuffer->push_back((sampleValue & 0x300) >> 8);
0202 break;
0203 case PACKET_CODE_VIRGIN_RAW10:
0204 if (sampleNumber % 4 == 0) {
0205 channelBuffer->push_back((sampleValue & 0x3FC) >> 2);
0206 } else if (sampleNumber % 4 == 1) {
0207 channelBuffer->push_back(((sampleValue_pre & 0x3) << 6) | ((sampleValue & 0x3F0) >> 4));
0208 } else if (sampleNumber % 4 == 2) {
0209 channelBuffer->push_back(((sampleValue_pre & 0xF) << 4) | ((sampleValue & 0x3C0) >> 6));
0210 } else if (sampleNumber % 4 == 3) {
0211 channelBuffer->push_back(((sampleValue_pre & 0x3F) << 2) | ((sampleValue & 0x300) >> 8));
0212 channelBuffer->push_back(sampleValue & 0xFF);
0213 }
0214 sampleValue_pre = sampleValue;
0215 break;
0216 case PACKET_CODE_VIRGIN_RAW8_BOTBOT:
0217 channelBuffer->push_back((sampleValue & 0x3FC) >> 2);
0218 break;
0219 case PACKET_CODE_VIRGIN_RAW8_TOPBOT:
0220 channelBuffer->push_back((sampleValue & 0x1FE) >> 1);
0221 break;
0222 }
0223 }
0224 }
0225
0226 void FEDBufferPayloadCreator::fillZeroSuppressedChannelBuffer(std::vector<uint8_t>* channelBuffer,
0227 const uint8_t packetCode,
0228 const FEDStripData::ChannelData& data,
0229 const bool channelEnabled) const {
0230 channelBuffer->reserve(50);
0231
0232 if (!channelEnabled) {
0233
0234 channelBuffer->push_back(7);
0235 channelBuffer->push_back(0);
0236
0237 channelBuffer->push_back(packetCode);
0238
0239 channelBuffer->insert(channelBuffer->end(), 4, 0);
0240 return;
0241 }
0242
0243
0244 channelBuffer->push_back(0xFF);
0245 channelBuffer->push_back(0xFF);
0246
0247 channelBuffer->push_back(packetCode);
0248
0249 const std::pair<uint16_t, uint16_t> medians = data.getMedians();
0250 channelBuffer->push_back(medians.first & 0xFF);
0251 channelBuffer->push_back((medians.first & 0x300) >> 8);
0252 channelBuffer->push_back(medians.second & 0xFF);
0253 channelBuffer->push_back((medians.second & 0x300) >> 8);
0254
0255 fillClusterData(channelBuffer, packetCode, data, READOUT_MODE_ZERO_SUPPRESSED);
0256
0257 const uint16_t length = channelBuffer->size();
0258 (*channelBuffer)[0] = (length & 0xFF);
0259 (*channelBuffer)[1] = ((length & 0x300) >> 8);
0260 }
0261
0262 void FEDBufferPayloadCreator::fillZeroSuppressedLiteChannelBuffer(std::vector<uint8_t>* channelBuffer,
0263 const FEDStripData::ChannelData& data,
0264 const bool channelEnabled,
0265 const FEDReadoutMode mode) const {
0266 channelBuffer->reserve(50);
0267
0268 if (!channelEnabled) {
0269
0270 channelBuffer->push_back(2);
0271 channelBuffer->push_back(0);
0272 return;
0273 }
0274
0275
0276 channelBuffer->push_back(0xFF);
0277 channelBuffer->push_back(0xFF);
0278
0279 fillClusterData(channelBuffer, 0, data, mode);
0280
0281 const uint16_t length = channelBuffer->size();
0282 (*channelBuffer)[0] = (length & 0xFF);
0283 (*channelBuffer)[1] = ((length & 0x300) >> 8);
0284 }
0285
0286 void FEDBufferPayloadCreator::fillPreMixRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
0287 const FEDStripData::ChannelData& data,
0288 const bool channelEnabled) const {
0289 channelBuffer->reserve(50);
0290
0291 if (!channelEnabled) {
0292
0293 channelBuffer->push_back(7);
0294 channelBuffer->push_back(0);
0295
0296 channelBuffer->push_back(PACKET_CODE_ZERO_SUPPRESSED);
0297
0298 channelBuffer->insert(channelBuffer->end(), 4, 0);
0299 return;
0300 }
0301
0302
0303 channelBuffer->push_back(0xFF);
0304 channelBuffer->push_back(0xFF);
0305
0306 channelBuffer->push_back(PACKET_CODE_ZERO_SUPPRESSED);
0307
0308 const std::pair<uint16_t, uint16_t> medians = data.getMedians();
0309 channelBuffer->push_back(medians.first & 0xFF);
0310 channelBuffer->push_back((medians.first & 0x300) >> 8);
0311 channelBuffer->push_back(medians.second & 0xFF);
0312 channelBuffer->push_back((medians.second & 0x300) >> 8);
0313
0314 fillClusterDataPreMixMode(channelBuffer, data);
0315
0316 const uint16_t length = channelBuffer->size();
0317 (*channelBuffer)[0] = (length & 0xFF);
0318 (*channelBuffer)[1] = ((length & 0x300) >> 8);
0319 }
0320
0321 void FEDBufferPayloadCreator::fillClusterData(std::vector<uint8_t>* channelBuffer,
0322 uint8_t packetCode,
0323 const FEDStripData::ChannelData& data,
0324 const FEDReadoutMode mode) const {
0325
0326 switch (mode) {
0327 case READOUT_MODE_ZERO_SUPPRESSED_LITE8:
0328 packetCode = PACKET_CODE_ZERO_SUPPRESSED;
0329 break;
0330 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT:
0331 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT_CMOVERRIDE:
0332 packetCode = PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT;
0333 break;
0334 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT:
0335 case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT_CMOVERRIDE:
0336 packetCode = PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT;
0337 break;
0338 case READOUT_MODE_ZERO_SUPPRESSED_LITE10:
0339 case READOUT_MODE_ZERO_SUPPRESSED_LITE10_CMOVERRIDE:
0340 packetCode = PACKET_CODE_ZERO_SUPPRESSED10;
0341 break;
0342 default:;
0343 }
0344 const bool is10Bit = (packetCode == PACKET_CODE_ZERO_SUPPRESSED10);
0345 const uint16_t bShift = (packetCode == PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
0346 ? 2
0347 : (packetCode == PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT ? 1 : 0));
0348
0349 uint16_t clusterSize = 0;
0350 std::size_t size_pos = 0;
0351 uint16_t adc_pre = 0;
0352 const uint16_t nSamples = data.size();
0353 for (uint16_t strip = 0; strip < nSamples; ++strip) {
0354 const uint16_t adc = is10Bit ? data.get10BitSample(strip) : data.get8BitSample(strip, bShift);
0355 if (adc) {
0356 if (clusterSize == 0 || strip == STRIPS_PER_APV) {
0357 if (clusterSize) {
0358 if (is10Bit && (clusterSize % 4)) {
0359 channelBuffer->push_back(adc_pre);
0360 }
0361 (*channelBuffer)[size_pos] = clusterSize;
0362 clusterSize = 0;
0363 }
0364
0365 channelBuffer->push_back(strip);
0366 size_pos = channelBuffer->size();
0367 channelBuffer->push_back(0);
0368 }
0369 if (!is10Bit) {
0370 channelBuffer->push_back(adc & 0xFF);
0371 } else {
0372 if (clusterSize % 4 == 0) {
0373 channelBuffer->push_back((adc & 0x3FC) >> 2);
0374 adc_pre = ((adc & 0x3) << 6);
0375 } else if (clusterSize % 4 == 1) {
0376 channelBuffer->push_back(adc_pre | ((adc & 0x3F0) >> 4));
0377 adc_pre = ((adc & 0xF) << 4);
0378 } else if (clusterSize % 4 == 2) {
0379 channelBuffer->push_back(adc_pre | ((adc & 0x3C0) >> 6));
0380 adc_pre = ((adc & 0x3F) << 2);
0381 } else if (clusterSize % 4 == 3) {
0382 channelBuffer->push_back(adc_pre | ((adc & 0x300) >> 8));
0383 channelBuffer->push_back(adc & 0xFF);
0384 adc_pre = 0;
0385 }
0386 }
0387 ++clusterSize;
0388 } else if (clusterSize) {
0389 if (is10Bit && (clusterSize % 4)) {
0390 channelBuffer->push_back(adc_pre);
0391 }
0392 (*channelBuffer)[size_pos] = clusterSize;
0393 clusterSize = 0;
0394 }
0395 }
0396 if (clusterSize) {
0397 (*channelBuffer)[size_pos] = clusterSize;
0398 if (is10Bit && (clusterSize % 4)) {
0399 channelBuffer->push_back(adc_pre);
0400 }
0401 }
0402 }
0403
0404 void FEDBufferPayloadCreator::fillClusterDataPreMixMode(std::vector<uint8_t>* channelBuffer,
0405 const FEDStripData::ChannelData& data) const {
0406 uint16_t clusterSize = 0;
0407 const uint16_t nSamples = data.size();
0408 for (uint16_t strip = 0; strip < nSamples; ++strip) {
0409 const uint16_t adc = data.get10BitSample(strip);
0410
0411 if (adc) {
0412 if (clusterSize == 0 || strip == STRIPS_PER_APV) {
0413 if (clusterSize) {
0414 *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
0415 clusterSize = 0;
0416 }
0417 channelBuffer->push_back(strip);
0418 channelBuffer->push_back(0);
0419 }
0420 channelBuffer->push_back(adc & 0xFF);
0421 channelBuffer->push_back((adc & 0x0300) >> 8);
0422
0423 ++clusterSize;
0424 }
0425
0426 else if (clusterSize) {
0427 *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
0428 clusterSize = 0;
0429 }
0430 }
0431 if (clusterSize) {
0432 *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
0433 }
0434 }
0435
0436
0437
0438 FEDBufferGenerator::FEDBufferGenerator(const uint32_t l1ID,
0439 const uint16_t bxID,
0440 const std::vector<bool>& feUnitsEnabled,
0441 const std::vector<bool>& channelsEnabled,
0442 const FEDReadoutMode readoutMode,
0443 const FEDHeaderType headerType,
0444 const FEDBufferFormat bufferFormat,
0445 const FEDDAQEventType evtType)
0446 : defaultDAQHeader_(l1ID, bxID, 0, evtType),
0447 defaultDAQTrailer_(0, 0),
0448 defaultTrackerSpecialHeader_(bufferFormat, readoutMode, headerType),
0449 defaultFEHeader_(FEDFEHeader::newFEHeader(headerType)),
0450 feUnitsEnabled_(feUnitsEnabled),
0451 channelsEnabled_(channelsEnabled) {
0452 if (!defaultFEHeader_.get()) {
0453 std::ostringstream ss;
0454 ss << "Bad header format: " << headerType;
0455 throw cms::Exception("FEDBufferGenerator") << ss.str();
0456 }
0457 }
0458
0459 bool FEDBufferGenerator::getFEUnitEnabled(const uint8_t internalFEUnitNumber) const {
0460 try {
0461 return feUnitsEnabled_.at(internalFEUnitNumber);
0462 } catch (const std::out_of_range&) {
0463 std::ostringstream ss;
0464 ss << "Invalid FE unit number " << internalFEUnitNumber << ". Should be in internal numbering scheme (0-7)";
0465 throw cms::Exception("FEDBufferGenerator") << ss.str();
0466 }
0467 }
0468
0469 bool FEDBufferGenerator::getChannelEnabled(const uint8_t internalFEDChannelNumber) const {
0470 try {
0471 return channelsEnabled_.at(internalFEDChannelNumber);
0472 } catch (const std::out_of_range&) {
0473 std::ostringstream ss;
0474 ss << "Invalid channel number " << internalFEDChannelNumber << ". "
0475 << "Should be in internal numbering scheme (0-95)";
0476 throw cms::Exception("FEDBufferGenerator") << ss.str();
0477 }
0478 }
0479
0480 FEDBufferGenerator& FEDBufferGenerator::setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled) {
0481 try {
0482 feUnitsEnabled_.at(internalFEUnitNumber) = enabled;
0483 } catch (const std::out_of_range&) {
0484 std::ostringstream ss;
0485 ss << "Invalid FE unit number " << internalFEUnitNumber << ". "
0486 << "Should be in internal numbering scheme (0-7)";
0487 throw cms::Exception("FEDBufferGenerator") << ss.str();
0488 }
0489 return *this;
0490 }
0491
0492 FEDBufferGenerator& FEDBufferGenerator::setChannelEnable(const uint8_t internalFEDChannelNumber, const bool enabled) {
0493 try {
0494 channelsEnabled_.at(internalFEDChannelNumber) = enabled;
0495 } catch (const std::out_of_range&) {
0496 std::ostringstream ss;
0497 ss << "Invalid channel number " << internalFEDChannelNumber << ". "
0498 << "Should be in internal numbering scheme (0-95)";
0499 throw cms::Exception("FEDBufferGenerator") << ss.str();
0500 }
0501 return *this;
0502 }
0503
0504 FEDBufferGenerator& FEDBufferGenerator::setFEUnitEnables(const std::vector<bool>& feUnitEnables) {
0505 if (feUnitEnables.size() != FEUNITS_PER_FED) {
0506 std::ostringstream ss;
0507 ss << "Setting FE enable vector with vector which is the wrong size. Size is " << feUnitEnables.size()
0508 << " it must be " << FEUNITS_PER_FED << "." << std::endl;
0509 throw cms::Exception("FEDBufferGenerator") << ss.str();
0510 }
0511 feUnitsEnabled_ = feUnitEnables;
0512 return *this;
0513 }
0514
0515 FEDBufferGenerator& FEDBufferGenerator::setChannelEnables(const std::vector<bool>& channelEnables) {
0516 if (channelEnables.size() != FEDCH_PER_FED) {
0517 std::ostringstream ss;
0518 ss << "Setting FED channel enable vector with vector which is the wrong size. Size is " << channelEnables.size()
0519 << " it must be " << FEDCH_PER_FED << "." << std::endl;
0520 throw cms::Exception("FEDBufferGenerator") << ss.str();
0521 }
0522 channelsEnabled_ = channelEnables;
0523 return *this;
0524 }
0525
0526 void FEDBufferGenerator::generateBuffer(FEDRawData* rawDataObject,
0527 const FEDStripData& data,
0528 uint16_t sourceID,
0529 uint8_t packetCode) const {
0530
0531 TrackerSpecialHeader tkSpecialHeader(defaultTrackerSpecialHeader_);
0532 std::unique_ptr<FEDFEHeader> fedFeHeader(defaultFEHeader_->clone());
0533 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0534 const bool enabled = feUnitsEnabled_[iFE];
0535 tkSpecialHeader.setFEEnableForFEUnit(iFE, enabled);
0536 if (!enabled) {
0537 for (uint8_t iFEUnitChannel = 0; iFEUnitChannel < FEDCH_PER_FEUNIT; iFEUnitChannel++) {
0538 fedFeHeader->setChannelStatus(iFE, iFEUnitChannel, FEDChannelStatus(0));
0539 }
0540 }
0541 }
0542 for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
0543 if (!channelsEnabled_[iCh]) {
0544 fedFeHeader->setChannelStatus(iCh, FEDChannelStatus(0));
0545 }
0546 }
0547
0548 FEDDAQHeader daqHeader(defaultDAQHeader_);
0549 daqHeader.setSourceID(sourceID);
0550
0551 const FEDBufferPayloadCreator payloadPacker(feUnitsEnabled_, channelsEnabled_);
0552 const FEDBufferPayload payload = payloadPacker(getReadoutMode(), packetCode, data);
0553
0554 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0555 fedFeHeader->setFEUnitLength(iFE, payload.getFELength(iFE));
0556 }
0557
0558 rawDataObject->resize(bufferSizeInBytes(*fedFeHeader, payload));
0559
0560 fillBuffer(rawDataObject->data(), daqHeader, defaultDAQTrailer_, tkSpecialHeader, *fedFeHeader, payload);
0561 }
0562
0563 void FEDBufferGenerator::fillBuffer(uint8_t* pointerToStartOfBuffer,
0564 const FEDDAQHeader& daqHeader,
0565 const FEDDAQTrailer& daqTrailer,
0566 const TrackerSpecialHeader& tkSpecialHeader,
0567 const FEDFEHeader& feHeader,
0568 const FEDBufferPayload& payload) {
0569
0570 const size_t lengthInBytes = bufferSizeInBytes(feHeader, payload);
0571 FEDDAQTrailer updatedDAQTrailer(daqTrailer);
0572 updatedDAQTrailer.setEventLengthIn64BitWords(lengthInBytes / 8);
0573
0574 uint8_t* bufferPointer = pointerToStartOfBuffer;
0575 memcpy(bufferPointer, daqHeader.data(), 8);
0576 bufferPointer += 8;
0577 memcpy(bufferPointer, tkSpecialHeader.data(), 8);
0578 bufferPointer += 8;
0579 memcpy(bufferPointer, feHeader.data(), feHeader.lengthInBytes());
0580 bufferPointer += feHeader.lengthInBytes();
0581 memcpy(bufferPointer, payload.data(), payload.lengthInBytes());
0582 bufferPointer += payload.lengthInBytes();
0583 memcpy(bufferPointer, updatedDAQTrailer.data(), 8);
0584
0585 const uint16_t crc = calculateFEDBufferCRC(pointerToStartOfBuffer, lengthInBytes);
0586 updatedDAQTrailer.setCRC(crc);
0587 memcpy(bufferPointer, updatedDAQTrailer.data(), 8);
0588
0589 if (tkSpecialHeader.wasSwapped()) {
0590 for (size_t i = 0; i < 8; i++) {
0591 bufferPointer[i] = bufferPointer[i ^ 4];
0592 }
0593 }
0594 }
0595
0596 }