CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/GctRawToDigi/plugins/GctDigiToRaw.cc

Go to the documentation of this file.
00001 #include "EventFilter/GctRawToDigi/plugins/GctDigiToRaw.h"
00002 
00003 // system
00004 #include <vector>
00005 #include <sstream>
00006 #include <iostream>
00007 #include <iomanip>
00008 
00009 // framework
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "FWCore/PluginManager/interface/ModuleDef.h"
00012 #include "FWCore/Framework/interface/MakerMacros.h"
00013 
00014 // Raw data collection
00015 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00016 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00017 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00018 #include "DataFormats/Provenance/interface/EventID.h"
00019 
00020 // Header needed to computer CRCs
00021 #include "FWCore/Utilities/interface/CRC16.h"
00022 
00023 // GCT input data formats
00024 #include "DataFormats/L1CaloTrigger/interface/L1CaloEmCand.h"
00025 #include "DataFormats/L1CaloTrigger/interface/L1CaloRegion.h"
00026 #include "DataFormats/L1CaloTrigger/interface/L1CaloRegionDetId.h"
00027 #include "DataFormats/L1CaloTrigger/interface/L1CaloCollections.h"
00028 
00029 // GCT output data formats
00030 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctCollections.h"
00031 
00032 // Raw data collection
00033 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00034 
00035 using std::cout;
00036 using std::endl;
00037 using std::vector;
00038 
00039 
00040 GctDigiToRaw::GctDigiToRaw(const edm::ParameterSet& iConfig) :
00041   rctInputLabel_(iConfig.getParameter<edm::InputTag>("rctInputLabel")),
00042   gctInputLabel_(iConfig.getParameter<edm::InputTag>("gctInputLabel")),
00043   packRctEm_(iConfig.getUntrackedParameter<bool>("packRctEm", true)),
00044   packRctCalo_(iConfig.getUntrackedParameter<bool>("packRctCalo", true)),
00045   fedId_(iConfig.getParameter<int>("gctFedId")),
00046   verbose_(iConfig.getUntrackedParameter<bool>("verbose",false)),
00047   counter_(0),
00048   formatTranslator_()
00049 {
00050   LogDebug("GCT") << "GctDigiToRaw will pack FED Id " << fedId_;
00051 
00052   //register the products
00053   produces<FEDRawDataCollection>();
00054 }
00055 
00056 
00057 GctDigiToRaw::~GctDigiToRaw()
00058 {
00059    // do anything here that needs to be done at destruction time
00060    // (e.g. close files, deallocate resources etc.)
00061 }
00062 
00063 
00064 //
00065 // member functions
00066 //
00067 
00068 // ------------ method called to produce the data  ------------
00069 void
00070 GctDigiToRaw::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00071 {
00072   using namespace edm;
00073   
00074   counter_++; // To "simulate" bunch crossings for now...
00075   unsigned int bx = counter_ % 3564;  // What's the proper way of doing this?
00076   EventNumber_t eventNumber = iEvent.id().event();
00077   
00078   // Supply bx and EvID to the packer so it can make internal capture block headers.
00079   formatTranslator_.setPackingBxId(bx);
00080   formatTranslator_.setPackingEventId(eventNumber);
00081  
00082   // The GCT and RCT input label strings
00083   const std::string gctInputLabelStr = gctInputLabel_.label();
00084   const std::string rctInputLabelStr = rctInputLabel_.label();
00085   
00086   // get GCT digis
00087   edm::Handle<L1GctEmCandCollection> isoEm;
00088   iEvent.getByLabel(gctInputLabelStr, "isoEm", isoEm);
00089   edm::Handle<L1GctEmCandCollection> nonIsoEm;
00090   iEvent.getByLabel(gctInputLabelStr, "nonIsoEm", nonIsoEm);
00091   edm::Handle<L1GctJetCandCollection> cenJets;
00092   iEvent.getByLabel(gctInputLabelStr, "cenJets", cenJets);
00093   edm::Handle<L1GctJetCandCollection> forJets;
00094   iEvent.getByLabel(gctInputLabelStr, "forJets", forJets);
00095   edm::Handle<L1GctJetCandCollection> tauJets;
00096   iEvent.getByLabel(gctInputLabelStr, "tauJets", tauJets);
00097   edm::Handle<L1GctEtTotalCollection> etTotal;
00098   iEvent.getByLabel(gctInputLabelStr, "", etTotal);
00099   edm::Handle<L1GctEtHadCollection> etHad;
00100   iEvent.getByLabel(gctInputLabelStr, "", etHad);
00101   edm::Handle<L1GctEtMissCollection> etMiss;
00102   iEvent.getByLabel(gctInputLabelStr, "", etMiss);
00103   edm::Handle<L1GctHFRingEtSumsCollection> hfRingSums;
00104   iEvent.getByLabel(gctInputLabelStr, "", hfRingSums);
00105   edm::Handle<L1GctHFBitCountsCollection> hfBitCounts;
00106   iEvent.getByLabel(gctInputLabelStr, "", hfBitCounts);
00107   edm::Handle<L1GctHtMissCollection> htMiss;
00108   iEvent.getByLabel(gctInputLabelStr, "", htMiss);
00109   edm::Handle<L1GctJetCountsCollection> jetCounts;
00110   iEvent.getByLabel(gctInputLabelStr, "", jetCounts);
00111 
00112   // get RCT EM Cand digi
00113   bool packRctEmThisEvent = packRctEm_;
00114   edm::Handle<L1CaloEmCollection> rctEm;
00115   if(packRctEmThisEvent)
00116   {
00117     iEvent.getByLabel(rctInputLabelStr, rctEm);
00118     if(rctEm.failedToGet())
00119     {
00120       packRctEmThisEvent = false;
00121       LogDebug("GCT") << "RCT EM Candidate packing requested, but failed to get them from event!";
00122     }
00123   }
00124 
00125   // get RCT Calo region digi
00126   bool packRctCaloThisEvent = packRctCalo_;
00127   edm::Handle<L1CaloRegionCollection> rctCalo;
00128   if(packRctCaloThisEvent)
00129   {
00130     iEvent.getByLabel(rctInputLabelStr, rctCalo);
00131     if(rctCalo.failedToGet())
00132     {
00133       packRctCaloThisEvent = false;
00134       LogDebug("GCT") << "RCT Calo Region packing requested, but failed to get them from event!";
00135     }
00136   }
00137   
00138   // create the raw data collection
00139   std::auto_ptr<FEDRawDataCollection> rawColl(new FEDRawDataCollection()); 
00140  
00141   // get the GCT buffer
00142   FEDRawData& fedRawData=rawColl->FEDData(fedId_);
00143  
00144   // set the size & make pointers to the header, beginning of payload, and footer.
00145   unsigned int rawSize = 88;  // MUST BE MULTIPLE OF 8! (slink packets are 64 bit, but using 8-bit data struct).
00146   if(packRctEmThisEvent) { rawSize += 232; }  // Space for RCT EM Cands.
00147   if(packRctCaloThisEvent) { rawSize += 800; }  // Space for RCT Calo Regions (plus a 32-bit word of padding to make divisible by 8)
00148   fedRawData.resize(rawSize);
00149   unsigned char * pHeader = fedRawData.data();  
00150   unsigned char * pPayload = pHeader + 16;  //  16 = 8 for slink header + 8 for Greg's versioning header.
00151   unsigned char * pFooter = pHeader + rawSize - 8;
00152  
00153   // Write CDF header (exactly as told by Marco Zanetti)
00154   FEDHeader fedHeader(pHeader);
00155   fedHeader.set(pHeader, 1, eventNumber, bx, fedId_);  // what should the bx_ID be?
00156  
00157   // Pack GCT jet output digis
00158   formatTranslator_.writeGctOutJetBlock(pPayload, 
00159                                         cenJets.product(),
00160                                         forJets.product(),
00161                                         tauJets.product(),
00162                                         hfRingSums.product(), 
00163                                         hfBitCounts.product(),
00164                                         htMiss.product());
00165 
00166   pPayload += 36; //advance payload pointer
00167   
00168   // Pack GCT EM and energy sums digis.
00169   formatTranslator_.writeGctOutEmAndEnergyBlock(pPayload,
00170                                                 isoEm.product(), 
00171                                                 nonIsoEm.product(),
00172                                                 etTotal.product(), 
00173                                                 etHad.product(), 
00174                                                 etMiss.product());
00175 
00176   pPayload += 28; //advance payload pointer
00177 
00178   // Pack RCT EM Cands
00179   if(packRctEmThisEvent)
00180   {
00181     formatTranslator_.writeRctEmCandBlocks(pPayload, rctEm.product());
00182     pPayload+=232;  //advance payload pointer
00183   }
00184 
00185   // Pack RCT Calo Regions
00186   if(packRctCaloThisEvent)
00187   {
00188     formatTranslator_.writeAllRctCaloRegionBlock(pPayload, rctCalo.product());
00189   }
00190   
00191   // Write CDF footer (exactly as told by Marco Zanetti)
00192   FEDTrailer fedTrailer(pFooter);
00193   fedTrailer.set(pFooter, rawSize/8, evf::compute_crc(pHeader, rawSize), 0, 0);
00194  
00195   // Debug output.
00196   if (verbose_) { print(fedRawData); }
00197  
00198   // Put the collection in the event.
00199   iEvent.put(rawColl);
00200 }
00201 
00202 
00203 void GctDigiToRaw::print(FEDRawData& data) {
00204 
00205   const unsigned char * d = data.data();
00206 
00207   for (unsigned int i=0; i<data.size(); i=i+4) {
00208     uint32_t w = (uint32_t)d[i] + (uint32_t)(d[i+1]<<8) + (uint32_t)(d[i+2]<<16) + (uint32_t)(d[i+3]<<24);
00209     cout << std::hex << std::setw(4) << i/4 << " " << std::setw(8) << w << endl;
00210   }
00211 
00212 }
00213 
00214 
00215 // ------------ method called once each job just before starting event loop  ------------
00216 void 
00217 GctDigiToRaw::beginJob()
00218 {
00219 }
00220 
00221 // ------------ method called once each job just after ending the event loop  ------------
00222 void 
00223 GctDigiToRaw::endJob() {
00224 }
00225 
00227 DEFINE_FWK_MODULE(GctDigiToRaw);
00228