Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:00:12

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