Go to the documentation of this file.00001 #include "EventFilter/GctRawToDigi/plugins/GctRawToDigi.h"
00002
00003
00004 #include <vector>
00005 #include <sstream>
00006 #include <iostream>
00007
00008
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "FWCore/Framework/interface/MakerMacros.h"
00011
00012
00013 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00014 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00015
00016
00017 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateMCLegacy.h"
00018 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV35.h"
00019 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV38.h"
00020
00021
00022 #include "EventFilter/GctRawToDigi/src/GctUnpackCollections.h"
00023
00024
00025
00026 using std::cout;
00027 using std::endl;
00028 using std::vector;
00029 using std::string;
00030 using std::dec;
00031 using std::hex;
00032
00033
00034 GctRawToDigi::GctRawToDigi(const edm::ParameterSet& iConfig) :
00035 inputLabel_(iConfig.getParameter<edm::InputTag>("inputLabel")),
00036 fedId_(iConfig.getUntrackedParameter<int>("gctFedId", FEDNumbering::MINTriggerGCTFEDID)),
00037 hltMode_(iConfig.getParameter<bool>("hltMode")),
00038 numberOfGctSamplesToUnpack_(iConfig.getParameter<unsigned>("numberOfGctSamplesToUnpack")),
00039 numberOfRctSamplesToUnpack_(iConfig.getParameter<unsigned>("numberOfRctSamplesToUnpack")),
00040 unpackSharedRegions_(iConfig.getParameter<bool>("unpackSharedRegions")),
00041 formatVersion_(iConfig.getParameter<unsigned>("unpackerVersion")),
00042 checkHeaders_(iConfig.getUntrackedParameter<bool>("checkHeaders",false)),
00043 verbose_(iConfig.getUntrackedParameter<bool>("verbose",false)),
00044 formatTranslator_(0),
00045 errors_(0),
00046 errorCounters_(MAX_ERR_CODE+1),
00047 unpackFailures_(0)
00048 {
00049 LogDebug("GCT") << "GctRawToDigi will unpack FED Id " << fedId_;
00050
00051
00052
00053
00054 if(formatVersion_ == 0) { edm::LogInfo("GCT") << "The required GCT Format Translator will be automatically determined from the first S-Link packet header."; }
00055 else if(formatVersion_ == 1)
00056 {
00057 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateMCLegacy";
00058 formatTranslator_ = new GctFormatTranslateMCLegacy(hltMode_, unpackSharedRegions_);
00059 }
00060 else if(formatVersion_ == 2)
00061 {
00062 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV35";
00063 formatTranslator_ = new GctFormatTranslateV35(hltMode_, unpackSharedRegions_);
00064 }
00065 else if(formatVersion_ == 3)
00066 {
00067 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV38";
00068 formatTranslator_ = new GctFormatTranslateV38(hltMode_, unpackSharedRegions_, numberOfGctSamplesToUnpack_, numberOfRctSamplesToUnpack_);
00069 }
00070 else
00071 {
00072 edm::LogWarning("GCT") << "You have requested a version of GctFormatTranslate that does not exist! Will attempt to auto-detect "
00073 "the required GCT Format Translator from the first S-Link packet header instead.";
00074 }
00075
00076 if(hltMode_) { edm::LogInfo("GCT") << "HLT unpack mode selected: HLT unpack optimisations will be used."; }
00077 if(unpackSharedRegions_) { edm::LogInfo("GCT") << "You have selected to unpack shared RCT calo regions - be warned: "
00078 "this is for commissioning purposes only!"; }
00079
00081
00082 produces<L1GctFibreCollection>();
00083 produces<L1CaloEmCollection>();
00084 produces<L1CaloRegionCollection>();
00085
00086
00087 produces<L1GctInternEmCandCollection>();
00088 produces<L1GctInternJetDataCollection>();
00089 produces<L1GctInternEtSumCollection>();
00090 produces<L1GctInternHFDataCollection>();
00091 produces<L1GctInternHtMissCollection>();
00092
00093
00094 produces<L1GctEmCandCollection>("isoEm");
00095 produces<L1GctEmCandCollection>("nonIsoEm");
00096 produces<L1GctJetCandCollection>("cenJets");
00097 produces<L1GctJetCandCollection>("forJets");
00098 produces<L1GctJetCandCollection>("tauJets");
00099 produces<L1GctHFBitCountsCollection>();
00100 produces<L1GctHFRingEtSumsCollection>();
00101 produces<L1GctEtTotalCollection>();
00102 produces<L1GctEtHadCollection>();
00103 produces<L1GctEtMissCollection>();
00104 produces<L1GctHtMissCollection>();
00105 produces<L1GctJetCountsCollection>();
00106
00107
00108 produces<L1TriggerErrorCollection>();
00109 }
00110
00111
00112 GctRawToDigi::~GctRawToDigi()
00113 {
00114
00115
00116 delete formatTranslator_;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125 void GctRawToDigi::beginJob()
00126 {
00127 }
00128
00129
00130
00131 void GctRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00132 {
00133 using namespace edm;
00134
00135
00136 std::auto_ptr<GctUnpackCollections> colls(new GctUnpackCollections(iEvent));
00137 errors_ = colls->errors();
00138
00139
00140 edm::Handle<FEDRawDataCollection> feds;
00141 iEvent.getByLabel(inputLabel_, feds);
00142
00143
00144 if (feds.isValid()) {
00145
00146 const FEDRawData& gctRcd = feds->FEDData(fedId_);
00147
00148 LogDebug("GCT") << "Upacking FEDRawData of size " << std::dec << gctRcd.size();
00149
00150
00151 if(gctRcd.size() < 16) {
00152 LogDebug("GCT") << "Cannot unpack: empty/invalid GCT raw data (size = "
00153 << gctRcd.size() << "). Returning empty collections!";
00154 addError(1);
00155 return;
00156 }
00157
00158
00159
00160
00161 if(!formatTranslator_) {
00162 if(!autoDetectRequiredFormatTranslator(gctRcd.data())) return;
00163 }
00164
00165
00166 blockHeaders_.clear();
00167
00168
00169 unpack(gctRcd, iEvent, colls.get());
00170
00171
00172 if (checkHeaders_) checkHeaders();
00173
00174
00175 if(verbose_) { doVerboseOutput(blockHeaders_, colls.get()); }
00176
00177 }
00178
00179 }
00180
00181
00182 void GctRawToDigi::unpack(const FEDRawData& d, edm::Event& e, GctUnpackCollections * const colls)
00183 {
00184
00185
00186 formatTranslator_->setUnpackCollections(colls);
00187
00188 const unsigned char * data = d.data();
00189
00190
00191
00192
00193 unsigned dPtr = 16;
00194
00195 const unsigned dEnd = d.size() - 8;
00196
00197
00198 for (unsigned nb=0; dPtr<dEnd; ++nb)
00199 {
00200 if(nb >= MAX_BLOCKS) {
00201 LogDebug("GCT") << "Reached block limit - bailing out from this event!";
00202 addError(6);
00203 break;
00204 }
00205
00206
00207 GctBlockHeader blockHeader = formatTranslator_->generateBlockHeader(&data[dPtr]);
00208
00209
00210 if(!formatTranslator_->convertBlock(&data[dPtr+4], blockHeader))
00211 {
00212 LogDebug("GCT") << "Encountered block unpack error - bailing out from this event!";
00213 addError(4);
00214 break;
00215 }
00216
00217
00218 dPtr += 4*(blockHeader.blockLength()*blockHeader.nSamples()+1);
00219
00220
00221 if (verbose_ || checkHeaders_) blockHeaders_.push_back(blockHeader);
00222
00223 }
00224
00225 }
00226
00227
00228
00229 bool GctRawToDigi::autoDetectRequiredFormatTranslator(const unsigned char * d)
00230 {
00231 LogDebug("GCT") << "About to auto-detect the required format translator from the firmware version header.";
00232
00233 const uint32_t * p32 = reinterpret_cast<const uint32_t *>(d);
00234 unsigned firmwareHeader = p32[2];
00235
00236
00237
00238
00239 if( firmwareHeader >= 25 && firmwareHeader <= 35 )
00240 {
00241 edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
00242 formatTranslator_ = new GctFormatTranslateV35(hltMode_, unpackSharedRegions_);
00243 return true;
00244 }
00245 else if( firmwareHeader == 38 )
00246 {
00247 edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
00248 formatTranslator_ = new GctFormatTranslateV38(hltMode_, unpackSharedRegions_, numberOfGctSamplesToUnpack_, numberOfRctSamplesToUnpack_);
00249 return true;
00250 }
00251 else if( firmwareHeader == 0x00000000 )
00252 {
00253 edm::LogInfo("GCT") << "Legacy Monte-Carlo data detected: GctFormatTranslateMCLegacy will be used to unpack.";
00254 formatTranslator_ = new GctFormatTranslateMCLegacy(hltMode_, unpackSharedRegions_);
00255 return true;
00256 }
00257
00258
00259
00260 else {
00261
00262 LogDebug("GCT") << "Failed to determine unpacker to use from the firmware version header! "
00263 "(firmware header = 0x" << hex << firmwareHeader << dec << ")";
00264 addError(2);
00265 return false;
00266 }
00267
00268 }
00269
00270
00271 void GctRawToDigi::checkHeaders() {
00272
00273
00274
00275 }
00276
00277
00278 void GctRawToDigi::doVerboseOutput(const GctBlockHeaderCollection& bHdrs, const GctUnpackCollections * const colls) const
00279 {
00280 std::ostringstream os;
00281 os << "Found " << bHdrs.size() << " GCT block headers" << endl;
00282 for (unsigned i=0, size = bHdrs.size(); i < size; ++i)
00283 {
00284 os << "GCT Raw Data Block : " << formatTranslator_->getBlockDescription(bHdrs[i]) << " : " << bHdrs[i] << endl;
00285 }
00286 os << *colls << endl;
00287 edm::LogVerbatim("GCT") << os.str();
00288 }
00289
00290
00291
00292 void GctRawToDigi::addError(const unsigned code) {
00293
00294
00295 if (code > MAX_ERR_CODE) {
00296 LogDebug("GCT") << "Unknown error code : " << code;
00297 return;
00298 }
00299
00300
00301 if (errorCounters_.at(code) == 0 && verbose_) {
00302 std::ostringstream os;
00303 switch(code) {
00304 case 0: os << "Reserved error code - not in use"; break;
00305 case 1: os << "FED record empty or too short"; break;
00306 case 2: os << "Unknown raw data version"; break;
00307 case 3: os << "Detected unknown firmware version"; break;
00308 case 4: os << "Detected unknown data block"; break;
00309 case 5: os << "Block headers out of sync"; break;
00310 case 6: os << "Too many blocks"; break;
00311 default: os << "Unknown error code";
00312 }
00313 edm::LogError("GCT") << "Unpacking error " << code << " : " << os.str();
00314 }
00315
00316
00317 ++(errorCounters_.at(code));
00318
00319
00320 if (errors_ != 0) {
00321 errors_->push_back(L1TriggerError(fedId_, code));
00322 }
00323 else LogDebug("GCT") << "Detected error (code=" << code << ") but no error collection available!";
00324
00325 }
00326
00327
00328 void GctRawToDigi::endJob()
00329 {
00330 unsigned total=0;
00331 std::ostringstream os;
00332
00333 for (unsigned i=0 ; i <= MAX_ERR_CODE ; ++i) {
00334 total+=errorCounters_.at(i);
00335 os << "Error " << i << " (" << errorCounters_.at(i) << ")";
00336 if(i < MAX_ERR_CODE) { os << ", "; }
00337 }
00338
00339 if (total>0 && verbose_) {
00340 edm::LogError("GCT") << "Encountered " << total << " unpacking errors: " << os.str();
00341 }
00342 }
00343
00345 DEFINE_FWK_MODULE(GctRawToDigi);