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/FEDRawDataCollection.h"
00014
00015
00016 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateMCLegacy.h"
00017 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV35.h"
00018 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV38.h"
00019
00020
00021 #include "EventFilter/GctRawToDigi/src/GctUnpackCollections.h"
00022
00023
00024
00025 using std::cout;
00026 using std::endl;
00027 using std::vector;
00028 using std::string;
00029 using std::dec;
00030 using std::hex;
00031
00032
00033 GctRawToDigi::GctRawToDigi(const edm::ParameterSet& iConfig) :
00034 inputLabel_(iConfig.getParameter<edm::InputTag>("inputLabel")),
00035 fedId_(iConfig.getParameter<int>("gctFedId")),
00036 hltMode_(iConfig.getParameter<bool>("hltMode")),
00037 unpackSharedRegions_(iConfig.getParameter<bool>("unpackSharedRegions")),
00038 formatVersion_(iConfig.getParameter<unsigned>("unpackerVersion")),
00039 verbose_(iConfig.getUntrackedParameter<bool>("verbose",false)),
00040 formatTranslator_(0),
00041 unpackFailures_(0)
00042 {
00043 LogDebug("GCT") << "GctRawToDigi will unpack FED Id " << fedId_;
00044
00045
00046
00047 if(formatVersion_ == 0) { edm::LogInfo("GCT") << "The required GCT Format Translator will be automatically determined from the first S-Link packet header."; }
00048 else if(formatVersion_ == 1)
00049 {
00050 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateMCLegacy";
00051 formatTranslator_ = new GctFormatTranslateMCLegacy(hltMode_, unpackSharedRegions_);
00052 }
00053 else if(formatVersion_ == 2)
00054 {
00055 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV35";
00056 formatTranslator_ = new GctFormatTranslateV35(hltMode_, unpackSharedRegions_);
00057 }
00058 else if(formatVersion_ == 3)
00059 {
00060 edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV38";
00061 formatTranslator_ = new GctFormatTranslateV38(hltMode_, unpackSharedRegions_);
00062 }
00063 else
00064 {
00065 edm::LogWarning("GCT") << "You have requested a version of GctFormatTranslate that does not exist! Will attempt to auto-detect "
00066 "the required GCT Format Translator from the first S-Link packet header instead.";
00067 }
00068
00069 if(hltMode_) { edm::LogInfo("GCT") << "HLT unpack mode selected: HLT unpack optimisations will be used."; }
00070 if(unpackSharedRegions_) { edm::LogInfo("GCT") << "You have selected to unpack shared RCT calo regions - be warned: "
00071 "this is for commissioning purposes only!"; }
00072
00074
00075 produces<L1GctFibreCollection>();
00076 produces<L1CaloEmCollection>();
00077 produces<L1CaloRegionCollection>();
00078
00079
00080 produces<L1GctInternEmCandCollection>();
00081 produces<L1GctInternJetDataCollection>();
00082 produces<L1GctInternEtSumCollection>();
00083
00084
00085 produces<L1GctEmCandCollection>("isoEm");
00086 produces<L1GctEmCandCollection>("nonIsoEm");
00087 produces<L1GctJetCandCollection>("cenJets");
00088 produces<L1GctJetCandCollection>("forJets");
00089 produces<L1GctJetCandCollection>("tauJets");
00090 produces<L1GctHFBitCountsCollection>();
00091 produces<L1GctHFRingEtSumsCollection>();
00092 produces<L1GctEtTotalCollection>();
00093 produces<L1GctEtHadCollection>();
00094 produces<L1GctEtMissCollection>();
00095 produces<L1GctJetCountsCollection>();
00096 }
00097
00098
00099 GctRawToDigi::~GctRawToDigi()
00100 {
00101
00102
00103 delete formatTranslator_;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 void GctRawToDigi::beginJob(const edm::EventSetup&)
00113 {
00114 }
00115
00116
00117
00118 void GctRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00119 {
00120 using namespace edm;
00121
00122
00123 edm::Handle<FEDRawDataCollection> feds;
00124 iEvent.getByLabel(inputLabel_, feds);
00125 const FEDRawData& gctRcd = feds->FEDData(fedId_);
00126
00127 LogDebug("GCT") << "Upacking FEDRawData of size " << std::dec << gctRcd.size();
00128
00129
00130 std::auto_ptr<GctUnpackCollections> colls(new GctUnpackCollections(iEvent, hltMode_));
00131
00132
00133 if(gctRcd.size() < 16)
00134 {
00135 LogDebug("GCT") << "Cannot unpack: empty/invalid GCT raw data (size = "
00136 << gctRcd.size() << "). Returning empty collections!";
00137 ++unpackFailures_;
00138 }
00139 else{ unpack(gctRcd, iEvent, colls.get()); }
00140 }
00141
00142
00143 void GctRawToDigi::unpack(const FEDRawData& d, edm::Event& e, GctUnpackCollections * const colls)
00144 {
00145 const unsigned char * data = d.data();
00146
00147
00148 if(!formatTranslator_)
00149 {
00150
00151
00152 if(!autoDetectRequiredFormatTranslator(data)) { return; }
00153 }
00154
00155
00156 formatTranslator_->setUnpackCollections(colls);
00157
00158
00159
00160
00161 unsigned dPtr = 16;
00162
00163 const unsigned dEnd = d.size() - 8;
00164
00165 GctBlockHeaderCollection bHdrs;
00166
00167
00168 for (unsigned nb=0; dPtr<dEnd; ++nb)
00169 {
00170 if(nb >= MAX_BLOCKS) { LogDebug("GCT") << "Reached block limit - bailing out from this event!"; ++unpackFailures_; break; }
00171
00172
00173 GctBlockHeader blockHeader = formatTranslator_->generateBlockHeader(&data[dPtr]);
00174
00175
00176 if(!formatTranslator_->convertBlock(&data[dPtr+4], blockHeader))
00177 {
00178 LogDebug("GCT") << "Encountered block unpack error - bailing out from this event!";
00179 ++unpackFailures_; break;
00180 }
00181
00182
00183 dPtr += 4*(blockHeader.blockLength()*blockHeader.nSamples()+1);
00184
00185
00186 if(verbose_) { bHdrs.push_back(blockHeader); }
00187 }
00188
00189
00190 if(verbose_) { doVerboseOutput(bHdrs, colls); }
00191 }
00192
00193
00194 bool GctRawToDigi::autoDetectRequiredFormatTranslator(const unsigned char * d)
00195 {
00196 LogDebug("GCT") << "About to auto-detect the required format translator from the firmware version header.";
00197
00198 const uint32_t * p32 = reinterpret_cast<const uint32_t *>(d);
00199 unsigned firmwareHeader = p32[2];
00200
00201
00202 if( firmwareHeader >= 25 && firmwareHeader <= 35 )
00203 {
00204 edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
00205 formatTranslator_ = new GctFormatTranslateV35(hltMode_, unpackSharedRegions_);
00206 return true;
00207 }
00208 else if( firmwareHeader == 38 )
00209 {
00210 edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
00211 formatTranslator_ = new GctFormatTranslateV38(hltMode_, unpackSharedRegions_);
00212 return true;
00213 }
00214 else if( firmwareHeader == 0x00000000 )
00215 {
00216 edm::LogInfo("GCT") << "Legacy Monte-Carlo data detected: GctFormatTranslateMCLegacy will be used to unpack.";
00217 formatTranslator_ = new GctFormatTranslateMCLegacy(hltMode_, unpackSharedRegions_);
00218 return true;
00219 }
00220 else if(firmwareHeader == 0xdeadffff) { }
00221 else if( firmwareHeader == 0xaaaaaaaa) { }
00222 else { }
00223
00224 LogDebug("GCT") << "Failed to determine unpacker to use from the firmware version header! "
00225 "(firmware header = 0x" << hex << firmwareHeader << dec << ")";
00226
00227 ++unpackFailures_;
00228 return false;
00229 }
00230
00231 void GctRawToDigi::doVerboseOutput(const GctBlockHeaderCollection& bHdrs, const GctUnpackCollections * const colls) const
00232 {
00233 std::ostringstream os;
00234 os << "Found " << bHdrs.size() << " GCT block headers" << endl;
00235 for (unsigned i=0, size = bHdrs.size(); i < size; ++i)
00236 {
00237 os << "GCT Raw Data Block : " << formatTranslator_->getBlockDescription(bHdrs[i]) << " : " << bHdrs[i] << endl;
00238 }
00239 os << *colls << endl;
00240 edm::LogVerbatim("GCT") << os.str();
00241 }
00242
00243
00244 void GctRawToDigi::endJob()
00245 {
00246 if(unpackFailures_ > 0)
00247 {
00248 edm::LogError("GCT") << "GCT unpacker encountered " << unpackFailures_
00249 << " unpack errors in total during this job!";
00250 }
00251 }
00252
00254 DEFINE_FWK_MODULE(GctRawToDigi);