Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:56

0001 #include "CondFormats/DataRecord/interface/Phase2TrackerCablingRcd.h"
0002 #include "CondFormats/SiStripObjects/interface/Phase2TrackerCabling.h"
0003 #include "DataFormats/Common/interface/DetSet.h"
0004 #include "DataFormats/Common/interface/DetSetVector.h"
0005 #include "DataFormats/Common/interface/Handle.h"
0006 #include "DataFormats/DetId/interface/DetIdCollection.h"
0007 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0008 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0009 #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h"
0010 #include "EventFilter/Phase2TrackerRawToDigi/interface/Phase2TrackerFEDBuffer.h"
0011 #include "EventFilter/Phase2TrackerRawToDigi/interface/Phase2TrackerFEDChannel.h"
0012 #include "EventFilter/Phase2TrackerRawToDigi/interface/Phase2TrackerFEDHeader.h"
0013 #include "EventFilter/Phase2TrackerRawToDigi/interface/Phase2TrackerFEDRawChannelUnpacker.h"
0014 #include "EventFilter/Phase2TrackerRawToDigi/interface/Phase2TrackerFEDZSChannelUnpacker.h"
0015 #include "EventFilter/Phase2TrackerRawToDigi/interface/utils.h"
0016 #include "FWCore/Framework/interface/global/EDProducer.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/EventSetup.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 #include "FWCore/Utilities/interface/Exception.h"
0022 
0023 namespace Phase2Tracker {
0024 
0025   class Phase2TrackerDigiProducer : public edm::global::EDProducer<> {
0026   public:
0027     /// constructor
0028     Phase2TrackerDigiProducer(const edm::ParameterSet& pset);
0029     /// default constructor
0030     ~Phase2TrackerDigiProducer() override = default;
0031     void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0032 
0033   private:
0034     const edm::ESGetToken<Phase2TrackerCabling, Phase2TrackerCablingRcd> ph2CablingESToken_;
0035 
0036     const edm::EDGetTokenT<FEDRawDataCollection> token_;
0037     const edm::EDPutTokenT<edm::DetSetVector<Phase2TrackerDigi>> putToken_;
0038     class Registry {
0039     public:
0040       /// constructor
0041       Registry(uint32_t aDetid, uint16_t firstStrip, size_t indexInVector, uint16_t numberOfDigis)
0042           : detid(aDetid), first(firstStrip), index(indexInVector), length(numberOfDigis) {}
0043       /// < operator to sort registries
0044       bool operator<(const Registry& other) const {
0045         return (detid != other.detid ? detid < other.detid : first < other.first);
0046       }
0047       /// public data members
0048       uint32_t detid;
0049       uint16_t first;
0050       size_t index;
0051       uint16_t length;
0052     };
0053   };
0054 }  // namespace Phase2Tracker
0055 
0056 #include "FWCore/Framework/interface/MakerMacros.h"
0057 typedef Phase2Tracker::Phase2TrackerDigiProducer Phase2TrackerDigiProducer;
0058 DEFINE_FWK_MODULE(Phase2TrackerDigiProducer);
0059 
0060 using namespace std;
0061 
0062 namespace Phase2Tracker {
0063 
0064   Phase2TrackerDigiProducer::Phase2TrackerDigiProducer(const edm::ParameterSet& pset)
0065       : ph2CablingESToken_(esConsumes()),
0066         token_(consumes<FEDRawDataCollection>(pset.getParameter<edm::InputTag>("ProductLabel"))),
0067         putToken_(produces<edm::DetSetVector<Phase2TrackerDigi>>("ProcessedRaw")) {}
0068 
0069   void Phase2TrackerDigiProducer::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& es) const {
0070     // fetch cabling from event setup
0071     auto const& cabling = es.getData(ph2CablingESToken_);
0072 
0073     // Retrieve FEDRawData collection
0074     edm::Handle<FEDRawDataCollection> buffers;
0075     event.getByToken(token_, buffers);
0076 
0077     //reserve enough working memory
0078     std::vector<Registry> proc_work_registry;
0079     std::vector<Phase2TrackerDigi> proc_work_digis;
0080     {
0081       size_t reserve_count = 0;
0082       size_t reserve_digis = 0;
0083       for (size_t fedIndex = Phase2Tracker::FED_ID_MIN; fedIndex <= Phase2Tracker::CMS_FED_ID_MAX; ++fedIndex) {
0084         const FEDRawData& fed = buffers->FEDData(fedIndex);
0085         if (fed.size() != 0) {
0086           // construct buffer
0087           Phase2Tracker::Phase2TrackerFEDBuffer buffer(fed.data(), fed.size());
0088           int ichan = 0;
0089           for (int ife = 0; ife < MAX_FE_PER_FED; ife++) {
0090             for (int icbc = 0; icbc < MAX_CBC_PER_FE; icbc++) {
0091               if (buffer.channel(ichan).length() > 0) {
0092                 ++reserve_count;
0093                 //calculation from Phase2TrackerFEDRawChannelUnpacker.h
0094                 reserve_digis += buffer.channel(ichan).length() * 8 - STRIPS_PADDING;
0095                 ++ichan;
0096               }
0097             }
0098           }
0099         }
0100       }
0101       proc_work_registry.reserve(2 * reserve_count);
0102       proc_work_digis.reserve(reserve_digis);
0103     }
0104     // Analyze strip tracker FED buffers in data
0105     for (size_t fedIndex = Phase2Tracker::FED_ID_MIN; fedIndex <= Phase2Tracker::CMS_FED_ID_MAX; ++fedIndex) {
0106       const FEDRawData& fed = buffers->FEDData(fedIndex);
0107       if (fed.size() != 0) {
0108         // construct buffer
0109         Phase2Tracker::Phase2TrackerFEDBuffer buffer(fed.data(), fed.size());
0110 
0111 #ifdef EDM_ML_DEBUG
0112         std::ostringstream ss;
0113         ss << " -------------------------------------------- " << endl;
0114         ss << " buffer debug ------------------------------- " << endl;
0115         ss << " -------------------------------------------- " << endl;
0116         ss << " buffer size : " << buffer.bufferSize() << endl;
0117         ss << " fed id      : " << fedIndex << endl;
0118         ss << " -------------------------------------------- " << endl;
0119         ss << " tracker header debug ------------------------" << endl;
0120         ss << " -------------------------------------------- " << endl;
0121         LogTrace("Phase2TrackerDigiProducer") << ss.str();
0122         ss.clear();
0123         ss.str("");
0124 
0125         Phase2TrackerFEDHeader tr_header = buffer.trackerHeader();
0126         ss << " Version  : " << hex << setw(2) << (int)tr_header.getDataFormatVersion() << endl;
0127         ss << " Mode     : " << hex << setw(2) << tr_header.getDebugMode() << endl;
0128         ss << " Type     : " << hex << setw(2) << (int)tr_header.getEventType() << endl;
0129         ss << " Readout  : " << hex << setw(2) << tr_header.getReadoutMode() << endl;
0130         ss << " Condition Data : " << (tr_header.getConditionData() ? "Present" : "Absent") << "\n";
0131         ss << " Data Type      : " << (tr_header.getDataType() ? "Real" : "Fake") << "\n";
0132         ss << " Status   : " << hex << setw(16) << (int)tr_header.getGlibStatusCode() << endl;
0133         ss << " FE stat  : ";
0134         for (int i = 15; i >= 0; i--) {
0135           if ((tr_header.frontendStatus())[i]) {
0136             ss << "1";
0137           } else {
0138             ss << "0";
0139           }
0140         }
0141         ss << endl;
0142         ss << " Nr CBC   : " << hex << setw(16) << (int)tr_header.getNumberOfCBC() << endl;
0143         ss << " CBC stat : ";
0144         for (int i = 0; i < tr_header.getNumberOfCBC(); i++) {
0145           ss << hex << setw(2) << (int)tr_header.CBCStatus()[i] << " ";
0146         }
0147         ss << endl;
0148         LogTrace("Phase2TrackerDigiProducer") << ss.str();
0149         ss.clear();
0150         ss.str("");
0151         ss << " -------------------------------------------- " << endl;
0152         ss << " Payload  ----------------------------------- " << endl;
0153         ss << " -------------------------------------------- " << endl;
0154 #endif
0155 
0156         // loop channels
0157         int ichan = 0;
0158         for (int ife = 0; ife < MAX_FE_PER_FED; ife++) {
0159           for (int icbc = 0; icbc < MAX_CBC_PER_FE; icbc++) {
0160             const Phase2TrackerFEDChannel& channel = buffer.channel(ichan);
0161             if (channel.length() > 0) {
0162               // get fedid from cabling
0163               const Phase2TrackerModule mod = cabling.findFedCh(std::make_pair(fedIndex, ife));
0164               uint32_t detid = mod.getDetid();
0165 #ifdef EDM_ML_DEBUG
0166               ss << dec << " id from cabling : " << detid << endl;
0167               ss << dec << " reading channel : " << icbc << " on FE " << ife;
0168               ss << dec << " with length  : " << (int)channel.length() << endl;
0169 #endif
0170 
0171               // container for this channel's digis
0172               std::vector<Phase2TrackerDigi> stripsTop;
0173               std::vector<Phase2TrackerDigi> stripsBottom;
0174 
0175               // unpacking data
0176               Phase2TrackerFEDRawChannelUnpacker unpacker = Phase2TrackerFEDRawChannelUnpacker(channel);
0177               while (unpacker.hasData()) {
0178                 if (unpacker.stripOn()) {
0179                   if (unpacker.stripIndex() % 2) {
0180                     stripsTop.push_back(Phase2TrackerDigi((int)(STRIPS_PER_CBC * icbc + unpacker.stripIndex()) / 2, 0));
0181 #ifdef EDM_ML_DEBUG
0182                     ss << "t";
0183 #endif
0184                   } else {
0185                     stripsBottom.push_back(
0186                         Phase2TrackerDigi((int)(STRIPS_PER_CBC * icbc + unpacker.stripIndex()) / 2, 0));
0187 #ifdef EDM_ML_DEBUG
0188                     ss << "b";
0189 #endif
0190                   }
0191                 } else {
0192 #ifdef EDM_ML_DEBUG
0193                   ss << "_";
0194 #endif
0195                 }
0196                 unpacker++;
0197               }
0198 #ifdef EDM_ML_DEBUG
0199               ss << endl;
0200               LogTrace("Phase2TrackerDigiProducer") << ss.str();
0201               ss.clear();
0202               ss.str("");
0203 #endif
0204 
0205               // store beginning and end of this digis for this detid and add this registry to the list
0206               // and store data
0207               proc_work_registry.emplace_back(
0208                   detid + 1, STRIPS_PER_CBC * icbc / 2, proc_work_digis.size(), stripsTop.size());
0209               proc_work_digis.insert(proc_work_digis.end(), stripsTop.begin(), stripsTop.end());
0210               proc_work_registry.emplace_back(
0211                   detid + 2, STRIPS_PER_CBC * icbc / 2, proc_work_digis.size(), stripsBottom.size());
0212               proc_work_digis.insert(proc_work_digis.end(), stripsBottom.begin(), stripsBottom.end());
0213             }
0214             ichan++;
0215           }
0216         }  // end loop on channels
0217       }
0218     }
0219 
0220     // store digis in edm collections
0221     std::sort(proc_work_registry.begin(), proc_work_registry.end());
0222     std::vector<edm::DetSet<Phase2TrackerDigi>> sorted_and_merged;
0223 
0224     std::vector<Registry>::iterator it = proc_work_registry.begin(), it2 = it + 1, end = proc_work_registry.end();
0225     while (it < end) {
0226       sorted_and_merged.push_back(edm::DetSet<Phase2TrackerDigi>(it->detid));
0227       std::vector<Phase2TrackerDigi>& digis = sorted_and_merged.back().data;
0228       // first count how many digis we have
0229       size_t len = it->length;
0230       for (it2 = it + 1; (it2 != end) && (it2->detid == it->detid); ++it2) {
0231         len += it2->length;
0232       }
0233       // reserve memory
0234       digis.reserve(len);
0235       // push them in
0236       for (it2 = it + 0; (it2 != end) && (it2->detid == it->detid); ++it2) {
0237         digis.insert(digis.end(), &proc_work_digis[it2->index], &proc_work_digis[it2->index + it2->length]);
0238       }
0239       it = it2;
0240     }
0241     event.emplace(putToken_, sorted_and_merged, true);
0242   }
0243 }  // namespace Phase2Tracker