Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:25:10

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