CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoLocalTracker/SiStripClusterizer/plugins/SiStripClusterToDigiProducer.cc

Go to the documentation of this file.
00001 #include "FWCore/Framework/interface/Frameworkfwd.h"
00002 #include "FWCore/Framework/interface/EDProducer.h"
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/Framework/interface/ESHandle.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 
00007 #include "DataFormats/Common/interface/DetSetVector.h"
00008 #include "DataFormats/Common/interface/DetSetVectorNew.h"
00009 
00010 #include "CalibFormats/SiStripObjects/interface/SiStripGain.h"
00011 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
00012 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
00013 
00014 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
00015 
00016 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
00017 #include "boost/foreach.hpp"
00018 #include <numeric>
00019 
00020 class SiStripClusterToDigiProducer : public edm::EDProducer  {
00021 
00022   typedef   edmNew::DetSetVector<SiStripCluster> ClusterCollection;
00023   typedef   edmNew::DetSet<SiStripCluster> DetClusterCollection;
00024   typedef   edmNew::DetSet<SiStripCluster>::const_iterator DetClusIter;
00025 
00026 
00027   typedef   edm::DetSetVector<SiStripDigi> DigiCollection;
00028   typedef   edm::DetSet<SiStripDigi> DetDigiCollection;
00029   typedef   edm::DetSet<SiStripDigi>::const_iterator DetDigiIter;
00030 
00031 
00032 public:
00033 
00034   explicit SiStripClusterToDigiProducer(const edm::ParameterSet& conf);
00035   void produce(edm::Event&, const edm::EventSetup&);
00036 
00037 private:
00038 
00039   void process(const ClusterCollection& input, std::vector<DetDigiCollection>& output_base);
00040   void initialize(const edm::EventSetup& es);
00041   void setDetId(const uint32_t id); 
00042   float gain(const uint16_t& strip)  const { return gainHandle->getStripGain( strip, gainRange ); }
00043   uint16_t applyGain(const uint16_t& strip,const uint16_t& adc );
00044 
00045   const edm::InputTag _inputTag;
00046   SiStripApvGain::Range gainRange;
00047   edm::ESHandle<SiStripGain> gainHandle;
00048   uint32_t gain_cache_id, detId;
00049   
00050 };
00051 
00052 
00053 SiStripClusterToDigiProducer::
00054 SiStripClusterToDigiProducer(const edm::ParameterSet& conf) 
00055   : _inputTag( conf.getParameter<edm::InputTag>("ClusterProducer") ){
00056   
00057   produces< DigiCollection > ("ZeroSuppressed");
00058   produces< DigiCollection > ("VirginRaw"     );
00059   produces< DigiCollection > ("ProcessedRaw"  );
00060   produces< DigiCollection > ("ScopeMode"     );
00061   
00062 }
00063 
00064 void SiStripClusterToDigiProducer::
00065 produce(edm::Event& event, const edm::EventSetup& es)  {
00066   
00067   initialize(es);
00068   
00069   std::vector<DetDigiCollection> output_base; 
00070   edm::Handle<ClusterCollection> input ;
00071   event.getByLabel(_inputTag,input);
00072 
00073   if(input.isValid())
00074     process(*input, output_base);
00075 
00076 
00077   std::auto_ptr< DigiCollection > outputZS(new DigiCollection(output_base) );
00078   std::auto_ptr< DigiCollection > outputVR(new DigiCollection() );
00079   std::auto_ptr< DigiCollection > outputPR(new DigiCollection() );
00080   std::auto_ptr< DigiCollection > outputSM(new DigiCollection() );
00081 
00082   event.put( outputZS, "ZeroSuppressed");
00083   event.put( outputVR, "VirginRaw"     );
00084   event.put( outputPR, "ProcessedRaw"  );
00085   event.put( outputSM, "ScopeMode"     );
00086 }
00087 
00088 void SiStripClusterToDigiProducer::
00089 process(const ClusterCollection& input, std::vector<DetDigiCollection>& output_base)  {
00090  
00091   for(ClusterCollection::const_iterator it = input.begin(); it!=input.end(); ++it) {
00092 
00093     uint32_t detid=it->detId();
00094 
00095     setDetId(detid);
00096     DetDigiCollection detDigis(detid);
00097 
00098     DetClusIter clus(it->begin()), endclus(it->end());
00099     for(;clus!=endclus;clus++){
00100       size_t istrip     = 0;
00101       size_t width      = clus->amplitudes().size();
00102       size_t firstStrip = clus->firstStrip();
00103       uint16_t stripPos=firstStrip;
00104       for(;istrip<width;++istrip){
00105         detDigis.data.push_back( SiStripDigi( stripPos, applyGain(stripPos,clus->amplitudes()[istrip]) ) );
00106         stripPos++;
00107       }
00108     }
00109     
00110     if (detDigis.size()) 
00111       output_base.push_back(detDigis); 
00112   }
00113 }
00114 
00115 void SiStripClusterToDigiProducer::
00116 initialize(const edm::EventSetup& es) {
00117   uint32_t g_cache_id = es.get<SiStripGainRcd>().cacheIdentifier();
00118 
00119   if(g_cache_id != gain_cache_id) {
00120     es.get<SiStripGainRcd>().get( gainHandle );
00121     gain_cache_id = g_cache_id;
00122   }
00123 }
00124 
00125 
00126 inline 
00127 void SiStripClusterToDigiProducer::
00128 setDetId(const uint32_t id) {
00129   gainRange =  gainHandle->getRange(id); 
00130   detId = id;
00131 }
00132 
00133 inline
00134 uint16_t SiStripClusterToDigiProducer::
00135 applyGain(const uint16_t& strip,const uint16_t& adc ) {
00136 
00137   if(adc > 255) throw cms::Exception("Invalid Charge") << " digi at strip " << strip << " has ADC out of range " << adc;
00138   if(adc > 253) return adc; //saturated, do not scale
00139   uint16_t charge = static_cast<uint16_t>( adc*gain(strip) + 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
00140   return ( charge > 1022 ? 255 : 
00141           ( charge >  253 ? 254 : charge ));
00142 }
00143 
00144 
00145 
00146 #include "FWCore/PluginManager/interface/ModuleDef.h"
00147 #include "FWCore/Framework/interface/MakerMacros.h"
00148 DEFINE_FWK_MODULE(SiStripClusterToDigiProducer);