File indexing completed on 2024-04-06 12:26:27
0001 #include "FWCore/Framework/interface/Frameworkfwd.h"
0002 #include "FWCore/Framework/interface/stream/EDProducer.h"
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/Framework/interface/ESWatcher.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006
0007 #include "DataFormats/Common/interface/DetSetVector.h"
0008 #include "DataFormats/Common/interface/DetSetVectorNew.h"
0009
0010 #include "CalibFormats/SiStripObjects/interface/SiStripGain.h"
0011 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
0012 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
0013
0014 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
0015
0016 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
0017 #include <numeric>
0018
0019 class SiStripClusterToDigiProducer : public edm::stream::EDProducer<> {
0020 typedef edmNew::DetSetVector<SiStripCluster> ClusterCollection;
0021 typedef edmNew::DetSet<SiStripCluster> DetClusterCollection;
0022 typedef edmNew::DetSet<SiStripCluster>::const_iterator DetClusIter;
0023
0024 typedef edm::DetSetVector<SiStripDigi> DigiCollection;
0025 typedef edm::DetSet<SiStripDigi> DetDigiCollection;
0026 typedef edm::DetSet<SiStripDigi>::const_iterator DetDigiIter;
0027
0028 public:
0029 explicit SiStripClusterToDigiProducer(const edm::ParameterSet& conf);
0030 void produce(edm::Event&, const edm::EventSetup&) override;
0031
0032 private:
0033 void process(const ClusterCollection& input, std::vector<DetDigiCollection>& output_base);
0034 void setDetId(const uint32_t id);
0035 float gain(const uint16_t& strip) const { return gain_->getStripGain(strip, gainRange); }
0036 uint16_t applyGain(const uint16_t& strip, const uint16_t& adc);
0037
0038 edm::EDGetTokenT<ClusterCollection> token;
0039 SiStripApvGain::Range gainRange;
0040 edm::ESGetToken<SiStripGain, SiStripGainRcd> gainToken_;
0041 edm::ESWatcher<SiStripGainRcd> gainWatcher_;
0042 const SiStripGain* gain_;
0043 uint32_t detId;
0044 };
0045
0046 SiStripClusterToDigiProducer::SiStripClusterToDigiProducer(const edm::ParameterSet& conf) {
0047 token = consumes<ClusterCollection>(conf.getParameter<edm::InputTag>("ClusterProducer"));
0048 gainToken_ = esConsumes();
0049
0050 produces<DigiCollection>("ZeroSuppressed");
0051 produces<DigiCollection>("VirginRaw");
0052 produces<DigiCollection>("ProcessedRaw");
0053 produces<DigiCollection>("ScopeMode");
0054 }
0055
0056 void SiStripClusterToDigiProducer::produce(edm::Event& event, const edm::EventSetup& es) {
0057 if (gainWatcher_.check(es)) {
0058 gain_ = &es.getData(gainToken_);
0059 }
0060
0061 std::vector<DetDigiCollection> output_base;
0062 edm::Handle<ClusterCollection> input;
0063 event.getByToken(token, input);
0064
0065 if (input.isValid())
0066 process(*input, output_base);
0067
0068 auto outputZS = std::make_unique<DigiCollection>(output_base);
0069 auto outputVR = std::make_unique<DigiCollection>();
0070 auto outputPR = std::make_unique<DigiCollection>();
0071 auto outputSM = std::make_unique<DigiCollection>();
0072
0073 event.put(std::move(outputZS), "ZeroSuppressed");
0074 event.put(std::move(outputVR), "VirginRaw");
0075 event.put(std::move(outputPR), "ProcessedRaw");
0076 event.put(std::move(outputSM), "ScopeMode");
0077 }
0078
0079 void SiStripClusterToDigiProducer::process(const ClusterCollection& input,
0080 std::vector<DetDigiCollection>& output_base) {
0081 for (ClusterCollection::const_iterator it = input.begin(); it != input.end(); ++it) {
0082 uint32_t detid = it->detId();
0083
0084 setDetId(detid);
0085 DetDigiCollection detDigis(detid);
0086
0087 DetClusIter clus(it->begin()), endclus(it->end());
0088 for (; clus != endclus; clus++) {
0089 size_t istrip = 0;
0090 size_t width = clus->amplitudes().size();
0091 size_t firstStrip = clus->firstStrip();
0092 uint16_t stripPos = firstStrip;
0093 for (; istrip < width; ++istrip) {
0094 detDigis.data.push_back(SiStripDigi(stripPos, applyGain(stripPos, clus->amplitudes()[istrip])));
0095 stripPos++;
0096 }
0097 }
0098
0099 if (!detDigis.empty())
0100 output_base.push_back(detDigis);
0101 }
0102 }
0103
0104 inline void SiStripClusterToDigiProducer::setDetId(const uint32_t id) {
0105 gainRange = gain_->getRange(id);
0106 detId = id;
0107 }
0108
0109 inline uint16_t SiStripClusterToDigiProducer::applyGain(const uint16_t& strip, const uint16_t& adc) {
0110 if (adc > 255)
0111 throw cms::Exception("Invalid Charge") << " digi at strip " << strip << " has ADC out of range " << adc;
0112 if (adc > 253)
0113 return adc;
0114 uint16_t charge = static_cast<uint16_t>(
0115 adc * gain(strip) +
0116 0.5);
0117 return (charge > 1022 ? 255 : (charge > 253 ? 254 : charge));
0118 }
0119
0120 #include "FWCore/PluginManager/interface/ModuleDef.h"
0121 #include "FWCore/Framework/interface/MakerMacros.h"
0122 DEFINE_FWK_MODULE(SiStripClusterToDigiProducer);