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
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
0049 const FEDRawData& rawData = rawColl.FEDData(fedId);
0050
0051
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
0081
0082
0083
0084
0085
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
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;
0136 std::atomic<int> detReady;
0137 std::atomic<int> detSet;
0138 std::atomic<int> detAct;
0139 std::atomic<int> detNoZ;
0140 std::atomic<int> detAbrt;
0141 std::atomic<int> totClus;
0142 };
0143
0144 mutable Stat stat;
0145
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 }
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
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
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
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 }
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 }
0328
0329 void ClusterFiller::fill(StripClusterizerAlgorithm::output_t::TSFastFiller& record) const {
0330 try {
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
0345 for (auto const conn : conditions.currentConnection(det)) {
0346 if UNLIKELY (!conn)
0347 continue;
0348
0349 const uint16_t fedId = conn->fedId();
0350
0351
0352 if UNLIKELY (!fedId || !conn->isConnected()) {
0353 continue;
0354 }
0355
0356
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
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
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
0430 uint32_t id = conn->detId();
0431 edm::DetSet<SiStripDigi> zsdigis(id);
0432
0433
0434
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
0446 uint32_t id = conn->detId();
0447 edm::DetSet<SiStripDigi> zsdigis(id);
0448
0449
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 }
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 }