Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-05-12 02:41:29

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;  //saturated, do not scale
0114   uint16_t charge = static_cast<uint16_t>(
0115       adc * gain(strip) +
0116       0.5);  //NB: here we revert the gain applied at the clusterizer level. for this reason the adc counts are multiplied by gain and not divided
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);