Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-19 23:20:17

0001 /*
0002  */
0003 #include "RecoLocalTracker/SiStripClusterizer/interface/StripClusterizerAlgorithmFactory.h"
0004 #include "RecoLocalTracker/SiStripZeroSuppression/interface/SiStripRawProcessingFactory.h"
0005 
0006 #include "RecoLocalTracker/SiStripClusterizer/interface/StripClusterizerAlgorithm.h"
0007 #include "RecoLocalTracker/SiStripZeroSuppression/interface/SiStripRawProcessingAlgorithms.h"
0008 
0009 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
0010 #include "DataFormats/Common/interface/DetSetVectorNew.h"
0011 
0012 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0013 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
0014 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
0015 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
0016 
0017 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
0018 
0019 #include "FWCore/Framework/interface/stream/EDProducer.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0022 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0023 #include "FWCore/Utilities/interface/InputTag.h"
0024 #include "FWCore/Framework/interface/Event.h"
0025 #include "FWCore/Framework/interface/EventSetup.h"
0026 #include "FWCore/Framework/interface/ESHandle.h"
0027 #include "FWCore/Utilities/interface/Likely.h"
0028 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0029 
0030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0031 #include <sstream>
0032 #include <memory>
0033 #include <atomic>
0034 #include <mutex>
0035 
0036 // #define VIDEBUG
0037 #ifdef VIDEBUG
0038 #include <iostream>
0039 #define COUT std::cout << "VI "
0040 #else
0041 #define COUT LogDebug("")
0042 #endif
0043 
0044 namespace {
0045   std::unique_ptr<sistrip::FEDBuffer> fillBuffer(int fedId, const FEDRawDataCollection& rawColl) {
0046     std::unique_ptr<sistrip::FEDBuffer> buffer;
0047 
0048     // Retrieve FED raw data for given FED
0049     const FEDRawData& rawData = rawColl.FEDData(fedId);
0050 
0051     // Check on FEDRawData pointer
0052     const auto st_buffer = sistrip::preconstructCheckFEDBuffer(rawData);
0053     if UNLIKELY (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
0054       if (edm::isDebugEnabled()) {
0055         edm::LogWarning(sistrip::mlRawToCluster_)
0056             << "[ClustersFromRawProducer::" << __func__ << "]" << st_buffer << " for FED ID " << fedId;
0057       }
0058       return buffer;
0059     }
0060     buffer = std::make_unique<sistrip::FEDBuffer>(rawData);
0061     const auto st_chan = buffer->findChannels();
0062     if UNLIKELY (sistrip::FEDBufferStatusCode::SUCCESS != st_chan) {
0063       if (edm::isDebugEnabled()) {
0064         edm::LogWarning(sistrip::mlRawToCluster_)
0065             << "Exception caught when creating FEDBuffer object for FED " << fedId << ": " << st_chan;
0066       }
0067       buffer.reset();
0068       return buffer;
0069     }
0070     if UNLIKELY (!buffer->doChecks(false)) {
0071       if (edm::isDebugEnabled()) {
0072         edm::LogWarning(sistrip::mlRawToCluster_)
0073             << "Exception caught when creating FEDBuffer object for FED " << fedId << ": FED Buffer check fails";
0074       }
0075       buffer.reset();
0076       return buffer;
0077     }
0078 
0079     /*
0080     // dump of FEDRawData to stdout
0081     if ( dump_ ) {
0082     std::stringstream ss;
0083     RawToDigiUnpacker::dumpRawData( fedId, rawData, ss );
0084     LogTrace(mlRawToDigi_) 
0085     << ss.str();
0086     }
0087     */
0088 
0089     return buffer;
0090   }
0091 
0092   class ClusterFiller final : public StripClusterizerAlgorithm::output_t::Getter {
0093   public:
0094     ClusterFiller(const FEDRawDataCollection& irawColl,
0095                   StripClusterizerAlgorithm& iclusterizer,
0096                   SiStripRawProcessingAlgorithms& irawAlgos,
0097                   bool idoAPVEmulatorCheck,
0098                   bool legacy,
0099                   bool hybridZeroSuppressed)
0100         : rawColl(irawColl),
0101           clusterizer(iclusterizer),
0102           conditions(iclusterizer.conditions()),
0103           rawAlgos(irawAlgos),
0104           doAPVEmulatorCheck(idoAPVEmulatorCheck),
0105           legacy_(legacy),
0106           hybridZeroSuppressed_(hybridZeroSuppressed) {
0107       incTot(clusterizer.conditions().allDetIds().size());
0108       for (auto& d : done)
0109         d = nullptr;
0110     }
0111 
0112     ~ClusterFiller() override { printStat(); }
0113 
0114     void fill(StripClusterizerAlgorithm::output_t::TSFastFiller& record) const override;
0115 
0116   private:
0117     CMS_THREAD_GUARD(done) mutable std::unique_ptr<sistrip::FEDBuffer> buffers[1024];
0118     mutable std::atomic<sistrip::FEDBuffer*> done[1024];
0119 
0120     const FEDRawDataCollection& rawColl;
0121 
0122     StripClusterizerAlgorithm& clusterizer;
0123     const SiStripClusterizerConditions& conditions;
0124     SiStripRawProcessingAlgorithms& rawAlgos;
0125 
0126     // March 2012: add flag for disabling APVe check in configuration
0127     bool doAPVEmulatorCheck;
0128 
0129     bool legacy_;
0130     bool hybridZeroSuppressed_;
0131 
0132 #ifdef VIDEBUG
0133     struct Stat {
0134       Stat() : totDet(0), detReady(0), detSet(0), detAct(0), detNoZ(0), detAbrt(0), totClus(0) {}
0135       std::atomic<int> totDet;    // all dets
0136       std::atomic<int> detReady;  // dets "updated"
0137       std::atomic<int> detSet;    // det actually set not empty
0138       std::atomic<int> detAct;    // det actually set with content
0139       std::atomic<int> detNoZ;    // det actually set with content
0140       std::atomic<int> detAbrt;   // det aborted
0141       std::atomic<int> totClus;   // total number of clusters
0142     };
0143 
0144     mutable Stat stat;
0145     // void zeroStat() const { stat = std::move(Stat()); }
0146     void incTot(int n) const { stat.totDet = n; }
0147     void incReady() const { stat.detReady++; }
0148     void incSet() const { stat.detSet++; }
0149     void incAct() const { stat.detAct++; }
0150     void incNoZ() const { stat.detNoZ++; }
0151     void incAbrt() const { stat.detAbrt++; }
0152     void incClus(int n) const { stat.totClus += n; }
0153     void printStat() const {
0154       COUT << "VI clusters " << stat.totDet << ',' << stat.detReady << ',' << stat.detSet << ',' << stat.detAct << ','
0155            << stat.detNoZ << ',' << stat.detAbrt << ',' << stat.totClus << std::endl;
0156     }
0157 
0158 #else
0159     static void zeroStat() {}
0160     static void incTot(int) {}
0161     static void incReady() {}
0162     static void incSet() {}
0163     static void incAct() {}
0164     static void incNoZ() {}
0165     static void incAbrt() {}
0166     static void incClus(int) {}
0167     static void printStat() {}
0168 #endif
0169   };
0170 }  // namespace
0171 
0172 class SiStripClusterizerFromRaw final : public edm::stream::EDProducer<> {
0173 public:
0174   explicit SiStripClusterizerFromRaw(const edm::ParameterSet& conf)
0175       : onDemand(conf.getParameter<bool>("onDemand")),
0176         clusterizer_(StripClusterizerAlgorithmFactory::create(consumesCollector(),
0177                                                               conf.getParameter<edm::ParameterSet>("Clusterizer"))),
0178         rawAlgos_(SiStripRawProcessingFactory::create(conf.getParameter<edm::ParameterSet>("Algorithms"),
0179                                                       consumesCollector())),
0180         doAPVEmulatorCheck_(conf.getParameter<bool>("DoAPVEmulatorCheck")),
0181         legacy_(conf.getParameter<bool>("LegacyUnpacker")),
0182         hybridZeroSuppressed_(conf.getParameter<bool>("HybridZeroSuppressed")) {
0183     productToken_ = consumes<FEDRawDataCollection>(conf.getParameter<edm::InputTag>("ProductLabel"));
0184     produces<edmNew::DetSetVector<SiStripCluster> >();
0185     assert(clusterizer_.get());
0186     assert(rawAlgos_.get());
0187   }
0188 
0189   void produce(edm::Event& ev, const edm::EventSetup& es) override {
0190     initialize(es);
0191 
0192     // get raw data
0193     edm::Handle<FEDRawDataCollection> rawData;
0194     ev.getByToken(productToken_, rawData);
0195 
0196     std::unique_ptr<edmNew::DetSetVector<SiStripCluster> > output(
0197         onDemand ? new edmNew::DetSetVector<SiStripCluster>(
0198                        std::shared_ptr<edmNew::DetSetVector<SiStripCluster>::Getter>(std::make_shared<ClusterFiller>(
0199                            *rawData, *clusterizer_, *rawAlgos_, doAPVEmulatorCheck_, legacy_, hybridZeroSuppressed_)),
0200                        clusterizer_->conditions().allDetIds())
0201                  : new edmNew::DetSetVector<SiStripCluster>());
0202 
0203     if (onDemand)
0204       assert(output->onDemand());
0205 
0206     output->reserve(15000, 24 * 10000);
0207 
0208     if (!onDemand) {
0209       run(*rawData, *output);
0210       output->shrink_to_fit();
0211       COUT << output->dataSize() << " clusters from " << output->size() << " modules" << std::endl;
0212     }
0213 
0214     ev.put(std::move(output));
0215   }
0216 
0217   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0218 
0219 private:
0220   void initialize(const edm::EventSetup& es);
0221 
0222   void run(const FEDRawDataCollection& rawColl, edmNew::DetSetVector<SiStripCluster>& output);
0223 
0224 private:
0225   bool onDemand;
0226 
0227   edm::EDGetTokenT<FEDRawDataCollection> productToken_;
0228 
0229   std::unique_ptr<StripClusterizerAlgorithm> clusterizer_;
0230   std::unique_ptr<SiStripRawProcessingAlgorithms> rawAlgos_;
0231 
0232   // March 2012: add flag for disabling APVe check in configuration
0233   bool doAPVEmulatorCheck_;
0234 
0235   bool legacy_;
0236   bool hybridZeroSuppressed_;
0237 };
0238 
0239 void SiStripClusterizerFromRaw::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0240   edm::ParameterSetDescription desc;
0241 
0242   desc.add("ProductLabel", edm::InputTag("rawDataCollector"));
0243   desc.add<std::string>("ConditionsLabel", "");
0244   desc.add("onDemand", true);
0245   desc.add("DoAPVEmulatorCheck", true);
0246   desc.add("LegacyUnpacker", false);
0247   desc.add("HybridZeroSuppressed", false);
0248 
0249   edm::ParameterSetDescription clusterizer;
0250   StripClusterizerAlgorithmFactory::fillDescriptions(clusterizer);
0251   desc.add("Clusterizer", clusterizer);
0252 
0253   edm::ParameterSetDescription algorithms;
0254   SiStripRawProcessingFactory::fillDescriptions(algorithms);
0255   desc.add("Algorithms", algorithms);
0256 
0257   descriptions.addWithDefaultLabel(desc);
0258 }
0259 
0260 #include "FWCore/Framework/interface/MakerMacros.h"
0261 DEFINE_FWK_MODULE(SiStripClusterizerFromRaw);
0262 
0263 void SiStripClusterizerFromRaw::initialize(const edm::EventSetup& es) {
0264   (*clusterizer_).initialize(es);
0265   (*rawAlgos_).initialize(es);
0266 }
0267 
0268 void SiStripClusterizerFromRaw::run(const FEDRawDataCollection& rawColl, edmNew::DetSetVector<SiStripCluster>& output) {
0269   ClusterFiller filler(rawColl, *clusterizer_, *rawAlgos_, doAPVEmulatorCheck_, legacy_, hybridZeroSuppressed_);
0270 
0271   // loop over good det in cabling
0272   for (auto idet : clusterizer_->conditions().allDetIds()) {
0273     StripClusterizerAlgorithm::output_t::TSFastFiller record(output, idet);
0274 
0275     filler.fill(record);
0276 
0277     if (record.empty())
0278       record.abort();
0279   }  // end loop over dets
0280 }
0281 
0282 namespace {
0283   class StripByStripAdder {
0284   public:
0285     typedef std::output_iterator_tag iterator_category;
0286     typedef void value_type;
0287     typedef void difference_type;
0288     typedef void pointer;
0289     typedef void reference;
0290 
0291     StripByStripAdder(StripClusterizerAlgorithm& clusterizer,
0292                       StripClusterizerAlgorithm::State& state,
0293                       StripClusterizerAlgorithm::output_t::TSFastFiller& record)
0294         : clusterizer_(clusterizer), state_(state), record_(record) {}
0295 
0296     StripByStripAdder& operator=(SiStripDigi digi) {
0297       clusterizer_.stripByStripAdd(state_, digi.strip(), digi.adc(), record_);
0298       return *this;
0299     }
0300 
0301     StripByStripAdder& operator*() { return *this; }
0302     StripByStripAdder& operator++() { return *this; }
0303     StripByStripAdder& operator++(int) { return *this; }
0304 
0305   private:
0306     StripClusterizerAlgorithm& clusterizer_;
0307     StripClusterizerAlgorithm::State& state_;
0308     StripClusterizerAlgorithm::output_t::TSFastFiller& record_;
0309   };
0310 
0311   template <typename Container>
0312   class ADC_back_inserter {
0313   public:
0314     ADC_back_inserter(Container& c) : c_(c) {}
0315 
0316     ADC_back_inserter& operator=(SiStripRawDigi digi) {
0317       c_.push_back(digi.adc());
0318       return *this;
0319     }
0320     ADC_back_inserter& operator*() { return *this; }
0321     ADC_back_inserter& operator++() { return *this; }
0322     ADC_back_inserter& operator++(int) { return *this; }
0323 
0324   private:
0325     Container& c_;
0326   };
0327 }  // namespace
0328 
0329 void ClusterFiller::fill(StripClusterizerAlgorithm::output_t::TSFastFiller& record) const {
0330   try {  // edmNew::CapacityExaustedException
0331     incReady();
0332 
0333     auto idet = record.id();
0334 
0335     COUT << "filling " << idet << std::endl;
0336 
0337     auto const& det = clusterizer.stripByStripBegin(idet);
0338     if (!det.valid())
0339       return;
0340     StripClusterizerAlgorithm::State state(det);
0341 
0342     incSet();
0343     record.reserve(16);
0344     // Loop over apv-pairs of det
0345     for (auto const conn : conditions.currentConnection(det)) {
0346       if UNLIKELY (!conn)
0347         continue;
0348 
0349       const uint16_t fedId = conn->fedId();
0350 
0351       // If fed id is null or connection is invalid continue
0352       if UNLIKELY (!fedId || !conn->isConnected()) {
0353         continue;
0354       }
0355 
0356       // If Fed hasnt already been initialised, extract data and initialise
0357       sistrip::FEDBuffer* buffer = done[fedId];
0358       if (!buffer) {
0359         buffer = fillBuffer(fedId, rawColl).release();
0360         if (!buffer) {
0361           continue;
0362         }
0363         sistrip::FEDBuffer* exp = nullptr;
0364         if (done[fedId].compare_exchange_strong(exp, buffer))
0365           buffers[fedId].reset(buffer);
0366         else {
0367           delete buffer;
0368           buffer = done[fedId];
0369         }
0370       }
0371       assert(buffer);
0372 
0373       buffer->setLegacyMode(legacy_);
0374 
0375       // check channel
0376       const uint8_t fedCh = conn->fedCh();
0377 
0378       if UNLIKELY (!buffer->channelGood(fedCh, doAPVEmulatorCheck)) {
0379         if (edm::isDebugEnabled()) {
0380           std::ostringstream ss;
0381           ss << "Problem unpacking channel " << fedCh << " on FED " << fedId;
0382           edm::LogWarning(sistrip::mlRawToCluster_) << ss.str();
0383         }
0384         continue;
0385       }
0386 
0387       // Determine APV std::pair number
0388       uint16_t ipair = conn->apvPairNumber();
0389 
0390       const sistrip::FEDReadoutMode mode = buffer->readoutMode();
0391       const sistrip::FEDLegacyReadoutMode lmode =
0392           legacy_ ? buffer->legacyReadoutMode() : sistrip::READOUT_MODE_LEGACY_INVALID;
0393 
0394       using namespace sistrip;
0395       if LIKELY (fedchannelunpacker::isZeroSuppressed(mode, legacy_, lmode)) {
0396         auto perStripAdder = StripByStripAdder(clusterizer, state, record);
0397         const auto isNonLite = fedchannelunpacker::isNonLiteZS(mode, legacy_, lmode);
0398         const uint8_t pCode = (isNonLite ? buffer->packetCode(legacy_, fedCh) : 0);
0399         auto st_ch = fedchannelunpacker::StatusCode::SUCCESS;
0400         if LIKELY (!hybridZeroSuppressed_) {
0401           st_ch = fedchannelunpacker::unpackZeroSuppressed(
0402               buffer->channel(fedCh), perStripAdder, ipair * 256, isNonLite, mode, legacy_, lmode, pCode);
0403         } else {
0404           const uint32_t id = conn->detId();
0405           edm::DetSet<SiStripDigi> unpDigis{id};
0406           unpDigis.reserve(256);
0407           st_ch = fedchannelunpacker::unpackZeroSuppressed(
0408               buffer->channel(fedCh), std::back_inserter(unpDigis), ipair * 256, isNonLite, mode, legacy_, lmode, pCode);
0409           if (fedchannelunpacker::StatusCode::SUCCESS == st_ch) {
0410             edm::DetSet<SiStripDigi> suppDigis{id};
0411             unsigned int detId = suppDigis.id;
0412             uint16_t maxNStrips = SiStripDetId(detId).numberOfAPVs() * 128;
0413             rawAlgos.suppressHybridData(maxNStrips, unpDigis, suppDigis, ipair * 2);
0414             std::copy(std::begin(suppDigis), std::end(suppDigis), perStripAdder);
0415           }
0416         }
0417         if (fedchannelunpacker::StatusCode::SUCCESS != st_ch && edm::isDebugEnabled()) {
0418           edm::LogWarning(sistrip::mlRawToCluster_)
0419               << "Unordered clusters for channel " << fedCh << " on FED " << fedId << ": " << toString(st_ch);
0420           continue;
0421         }
0422       } else {
0423         auto st_ch = fedchannelunpacker::StatusCode::SUCCESS;
0424         if (fedchannelunpacker::isVirginRaw(mode, legacy_, lmode)) {
0425           std::vector<int16_t> digis;
0426           st_ch = fedchannelunpacker::unpackVirginRaw(
0427               buffer->channel(fedCh), ADC_back_inserter(digis), buffer->channel(fedCh).packetCode());
0428           if (fedchannelunpacker::StatusCode::SUCCESS == st_ch) {
0429             //process raw
0430             uint32_t id = conn->detId();
0431             edm::DetSet<SiStripDigi> zsdigis(id);
0432             //rawAlgos_->subtractorPed->subtract( id, ipair*256, digis);
0433             //rawAlgos_->subtractorCMN->subtract( id, digis);
0434             //rawAlgos_->suppressor->suppress( digis, zsdigis);
0435             uint16_t firstAPV = ipair * 2;
0436             rawAlgos.suppressVirginRawData(id, firstAPV, digis, zsdigis);
0437             for (const auto digi : zsdigis) {
0438               clusterizer.stripByStripAdd(state, digi.strip(), digi.adc(), record);
0439             }
0440           }
0441         } else if (fedchannelunpacker::isProcessedRaw(mode, legacy_, lmode)) {
0442           std::vector<int16_t> digis;
0443           st_ch = fedchannelunpacker::unpackProcessedRaw(buffer->channel(fedCh), ADC_back_inserter(digis));
0444           if (fedchannelunpacker::StatusCode::SUCCESS == st_ch) {
0445             //process raw
0446             uint32_t id = conn->detId();
0447             edm::DetSet<SiStripDigi> zsdigis(id);
0448             //rawAlgos_->subtractorCMN->subtract( id, digis);
0449             //rawAlgos_->suppressor->suppress( digis, zsdigis);
0450             uint16_t firstAPV = ipair * 2;
0451             rawAlgos.suppressProcessedRawData(id, firstAPV, digis, zsdigis);
0452             for (edm::DetSet<SiStripDigi>::const_iterator it = zsdigis.begin(); it != zsdigis.end(); it++) {
0453               clusterizer.stripByStripAdd(state, it->strip(), it->adc(), record);
0454             }
0455           }
0456         } else {
0457           edm::LogWarning(sistrip::mlRawToCluster_)
0458               << "[ClustersFromRawProducer::" << __func__ << "]"
0459               << " FEDRawData readout mode " << mode << " from FED id " << fedId << " not supported.";
0460         }
0461         if (fedchannelunpacker::StatusCode::SUCCESS != st_ch && edm::isDebugEnabled()) {
0462           edm::LogWarning(sistrip::mlRawToCluster_)
0463               << "[ClustersFromRawProducer::" << __func__ << "]" << toString(st_ch) << " from FED id " << fedId
0464               << " channel " << fedCh;
0465         }
0466       }
0467     }  // end loop over conn
0468 
0469     clusterizer.stripByStripEnd(state, record);
0470 
0471     incAct();
0472 
0473     if (record.full()) {
0474       edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand for "
0475                                               << record.id() << ' ' << record.size();
0476       record.abort();
0477       incAbrt();
0478     }
0479 
0480     if (!record.empty())
0481       incNoZ();
0482 
0483     COUT << "filled " << record.size() << std::endl;
0484     for (auto const& cl : record)
0485       COUT << cl.firstStrip() << ',' << cl.amplitudes().size() << std::endl;
0486     incClus(record.size());
0487   } catch (edmNew::CapacityExaustedException const&) {
0488     edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand";
0489   }
0490 }