File indexing completed on 2024-04-06 12:10:39
0001 #include "EventFilter/GctRawToDigi/plugins/GctRawToDigi.h"
0002
0003
0004 #include <vector>
0005 #include <sstream>
0006 #include <iostream>
0007
0008
0009 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013
0014
0015 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0016 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0017
0018
0019 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateMCLegacy.h"
0020 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV35.h"
0021 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV38.h"
0022
0023
0024 #include "EventFilter/GctRawToDigi/src/GctUnpackCollections.h"
0025
0026
0027 using std::cout;
0028 using std::dec;
0029 using std::endl;
0030 using std::hex;
0031 using std::string;
0032 using std::vector;
0033
0034 GctRawToDigi::GctRawToDigi(const edm::ParameterSet& iConfig)
0035 : inputLabel_(iConfig.getParameter<edm::InputTag>("inputLabel")),
0036 fedId_(iConfig.getUntrackedParameter<int>("gctFedId", FEDNumbering::MINTriggerGCTFEDID)),
0037 hltMode_(iConfig.getParameter<bool>("hltMode")),
0038 numberOfGctSamplesToUnpack_(iConfig.getParameter<unsigned>("numberOfGctSamplesToUnpack")),
0039 numberOfRctSamplesToUnpack_(iConfig.getParameter<unsigned>("numberOfRctSamplesToUnpack")),
0040 unpackSharedRegions_(iConfig.getParameter<bool>("unpackSharedRegions")),
0041 formatVersion_(iConfig.getParameter<unsigned>("unpackerVersion")),
0042 checkHeaders_(iConfig.getUntrackedParameter<bool>("checkHeaders", false)),
0043 verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)),
0044 formatTranslator_(nullptr),
0045 errors_(nullptr),
0046 errorCounters_(MAX_ERR_CODE + 1),
0047 unpackFailures_(0) {
0048 LogDebug("GCT") << "GctRawToDigi will unpack FED Id " << fedId_;
0049
0050
0051
0052
0053 if (formatVersion_ == 0) {
0054 edm::LogInfo("GCT")
0055 << "The required GCT Format Translator will be automatically determined from the first S-Link packet header.";
0056 } else if (formatVersion_ == 1) {
0057 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateMCLegacy";
0058 formatTranslator_ = new GctFormatTranslateMCLegacy(hltMode_, unpackSharedRegions_);
0059 } else if (formatVersion_ == 2) {
0060 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV35";
0061 formatTranslator_ = new GctFormatTranslateV35(hltMode_, unpackSharedRegions_);
0062 } else if (formatVersion_ == 3) {
0063 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV38";
0064 formatTranslator_ = new GctFormatTranslateV38(
0065 hltMode_, unpackSharedRegions_, numberOfGctSamplesToUnpack_, numberOfRctSamplesToUnpack_);
0066 } else {
0067 edm::LogWarning("GCT")
0068 << "You have requested a version of GctFormatTranslate that does not exist! Will attempt to auto-detect "
0069 "the required GCT Format Translator from the first S-Link packet header instead.";
0070 }
0071
0072 if (hltMode_) {
0073 edm::LogInfo("GCT") << "HLT unpack mode selected: HLT unpack optimisations will be used.";
0074 }
0075 if (unpackSharedRegions_) {
0076 edm::LogInfo("GCT") << "You have selected to unpack shared RCT calo regions - be warned: "
0077 "this is for commissioning purposes only!";
0078 }
0079
0080
0081
0082 produces<L1GctFibreCollection>();
0083 produces<L1CaloEmCollection>();
0084 produces<L1CaloRegionCollection>();
0085
0086
0087 produces<L1GctInternEmCandCollection>();
0088 produces<L1GctInternJetDataCollection>();
0089 produces<L1GctInternEtSumCollection>();
0090 produces<L1GctInternHFDataCollection>();
0091 produces<L1GctInternHtMissCollection>();
0092
0093
0094 produces<L1GctEmCandCollection>("isoEm");
0095 produces<L1GctEmCandCollection>("nonIsoEm");
0096 produces<L1GctJetCandCollection>("cenJets");
0097 produces<L1GctJetCandCollection>("forJets");
0098 produces<L1GctJetCandCollection>("tauJets");
0099 produces<L1GctHFBitCountsCollection>();
0100 produces<L1GctHFRingEtSumsCollection>();
0101 produces<L1GctEtTotalCollection>();
0102 produces<L1GctEtHadCollection>();
0103 produces<L1GctEtMissCollection>();
0104 produces<L1GctHtMissCollection>();
0105 produces<L1GctJetCountsCollection>();
0106
0107
0108 produces<L1TriggerErrorCollection>();
0109 consumes<FEDRawDataCollection>(inputLabel_);
0110 }
0111
0112 GctRawToDigi::~GctRawToDigi() {
0113
0114
0115 delete formatTranslator_;
0116 }
0117
0118 void GctRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0119 edm::ParameterSetDescription desc;
0120 desc.add<bool>("unpackSharedRegions", false);
0121 desc.add<unsigned int>("numberOfGctSamplesToUnpack", 1);
0122 desc.add<unsigned int>("numberOfRctSamplesToUnpack", 1);
0123 desc.add<bool>("hltMode", false);
0124 desc.add<edm::InputTag>("inputLabel", edm::InputTag("rawDataCollector"));
0125 static const char* const kComment =
0126 " \n"
0127 " value | Unpacker/RAW Format Version \n"
0128 "-----------|---------------------------------------------------------------------------- \n"
0129 " 0 | Auto-detects RAW Format in use - the recommended option \n"
0130 " 1 | Force usage of the Monte-Carlo Legacy unpacker (unpacks DigiToRaw events) \n"
0131 " 2 | Force usage of the RAW Format V35 unpacker \n"
0132 " 3 | Force usage of the RAW Format V38 unpacker \n";
0133 desc.add<unsigned int>("unpackerVersion", 0)->setComment(kComment);
0134 desc.addUntracked<int>("gctFedId", 745);
0135 desc.addUntracked<bool>("checkHeaders", false), desc.addUntracked<bool>("verbose", false);
0136 descriptions.add("gctRawToDigi", desc);
0137 }
0138
0139
0140
0141
0142
0143
0144 void GctRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0145 using namespace edm;
0146
0147
0148 std::unique_ptr<GctUnpackCollections> colls(new GctUnpackCollections(iEvent));
0149 errors_ = colls->errors();
0150
0151
0152 edm::Handle<FEDRawDataCollection> feds;
0153 iEvent.getByLabel(inputLabel_, feds);
0154
0155
0156 if (feds.isValid()) {
0157 const FEDRawData& gctRcd = feds->FEDData(fedId_);
0158
0159 LogDebug("GCT") << "Upacking FEDRawData of size " << std::dec << gctRcd.size();
0160
0161
0162 if (gctRcd.size() < 16) {
0163 LogDebug("GCT") << "Cannot unpack: empty/invalid GCT raw data (size = " << gctRcd.size()
0164 << "). Returning empty collections!";
0165 addError(1);
0166 return;
0167 }
0168
0169
0170
0171
0172 if (!formatTranslator_) {
0173 if (!autoDetectRequiredFormatTranslator(gctRcd.data()))
0174 return;
0175 }
0176
0177
0178 blockHeaders_.clear();
0179
0180
0181 unpack(gctRcd, iEvent, colls.get());
0182
0183
0184 if (checkHeaders_)
0185 checkHeaders();
0186
0187
0188 if (verbose_) {
0189 doVerboseOutput(blockHeaders_, colls.get());
0190 }
0191 }
0192 }
0193
0194 void GctRawToDigi::unpack(const FEDRawData& d, edm::Event& e, GctUnpackCollections* const colls) {
0195
0196 formatTranslator_->setUnpackCollections(colls);
0197
0198 const unsigned char* data = d.data();
0199
0200
0201
0202
0203 unsigned dPtr = 16;
0204
0205 const unsigned dEnd = d.size() - 8;
0206
0207
0208 for (unsigned nb = 0; dPtr < dEnd; ++nb) {
0209 if (nb >= MAX_BLOCKS) {
0210 LogDebug("GCT") << "Reached block limit - bailing out from this event!";
0211 addError(6);
0212 break;
0213 }
0214
0215
0216 GctBlockHeader blockHeader = formatTranslator_->generateBlockHeader(&data[dPtr]);
0217
0218
0219 if (!formatTranslator_->convertBlock(&data[dPtr + 4],
0220 blockHeader))
0221 {
0222 LogDebug("GCT") << "Encountered block unpack error - bailing out from this event!";
0223 addError(4);
0224 break;
0225 }
0226
0227
0228 dPtr += 4 * (blockHeader.blockLength() * blockHeader.nSamples() +
0229 1);
0230
0231
0232 if (verbose_ || checkHeaders_)
0233 blockHeaders_.push_back(blockHeader);
0234 }
0235 }
0236
0237
0238 bool GctRawToDigi::autoDetectRequiredFormatTranslator(const unsigned char* d) {
0239 LogDebug("GCT") << "About to auto-detect the required format translator from the firmware version header.";
0240
0241 const uint32_t* p32 = reinterpret_cast<const uint32_t*>(d);
0242 unsigned firmwareHeader = p32[2];
0243
0244
0245
0246
0247 if (firmwareHeader >= 25 && firmwareHeader <= 35) {
0248 edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader
0249 << " will be used to unpack.";
0250 formatTranslator_ = new GctFormatTranslateV35(hltMode_, unpackSharedRegions_);
0251 return true;
0252 } else if (firmwareHeader == 38) {
0253 edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader
0254 << " will be used to unpack.";
0255 formatTranslator_ = new GctFormatTranslateV38(
0256 hltMode_, unpackSharedRegions_, numberOfGctSamplesToUnpack_, numberOfRctSamplesToUnpack_);
0257 return true;
0258 } else if (firmwareHeader == 0x00000000) {
0259 edm::LogInfo("GCT") << "Legacy Monte-Carlo data detected: GctFormatTranslateMCLegacy will be used to unpack.";
0260 formatTranslator_ = new GctFormatTranslateMCLegacy(hltMode_, unpackSharedRegions_);
0261 return true;
0262 }
0263
0264
0265
0266 else {
0267
0268 LogDebug("GCT") << "Failed to determine unpacker to use from the firmware version header! "
0269 "(firmware header = 0x"
0270 << hex << firmwareHeader << dec << ")";
0271 addError(2);
0272 return false;
0273 }
0274 }
0275
0276 void GctRawToDigi::checkHeaders() {
0277
0278 }
0279
0280 void GctRawToDigi::doVerboseOutput(const GctBlockHeaderCollection& bHdrs,
0281 const GctUnpackCollections* const colls) const {
0282 std::ostringstream os;
0283 os << "Found " << bHdrs.size() << " GCT block headers" << endl;
0284 for (unsigned i = 0, size = bHdrs.size(); i < size; ++i) {
0285 os << "GCT Raw Data Block : " << formatTranslator_->getBlockDescription(bHdrs[i]) << " : " << bHdrs[i] << endl;
0286 }
0287 os << *colls << endl;
0288 edm::LogVerbatim("GCT") << os.str();
0289 }
0290
0291 void GctRawToDigi::addError(const unsigned code) {
0292
0293 if (code > MAX_ERR_CODE) {
0294 LogDebug("GCT") << "Unknown error code : " << code;
0295 return;
0296 }
0297
0298
0299 if (errorCounters_.at(code) == 0 && verbose_) {
0300 std::ostringstream os;
0301 switch (code) {
0302 case 0:
0303 os << "Reserved error code - not in use";
0304 break;
0305 case 1:
0306 os << "FED record empty or too short";
0307 break;
0308 case 2:
0309 os << "Unknown raw data version";
0310 break;
0311 case 3:
0312 os << "Detected unknown firmware version";
0313 break;
0314 case 4:
0315 os << "Detected unknown data block";
0316 break;
0317 case 5:
0318 os << "Block headers out of sync";
0319 break;
0320 case 6:
0321 os << "Too many blocks";
0322 break;
0323 default:
0324 os << "Unknown error code";
0325 }
0326 edm::LogError("GCT") << "Unpacking error " << code << " : " << os.str();
0327 }
0328
0329
0330 ++(errorCounters_.at(code));
0331
0332
0333 if (errors_ != nullptr) {
0334 errors_->push_back(L1TriggerError(fedId_, code));
0335 } else
0336 LogDebug("GCT") << "Detected error (code=" << code << ") but no error collection available!";
0337 }
0338
0339
0340 void GctRawToDigi::endJob() {
0341 unsigned total = 0;
0342 std::ostringstream os;
0343
0344 for (unsigned i = 0; i <= MAX_ERR_CODE; ++i) {
0345 total += errorCounters_.at(i);
0346 os << "Error " << i << " (" << errorCounters_.at(i) << ")";
0347 if (i < MAX_ERR_CODE) {
0348 os << ", ";
0349 }
0350 }
0351
0352 if (total > 0 && verbose_) {
0353 edm::LogError("GCT") << "Encountered " << total << " unpacking errors: " << os.str();
0354 }
0355 }
0356
0357
0358 DEFINE_FWK_MODULE(GctRawToDigi);