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