CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CalibTracker/SiStripESProducers/plugins/real/SiStripGainESProducerTemplate.h

Go to the documentation of this file.
00001 #ifndef CalibTracker_SiStripESProducers_SiStripGainESProducerTemplate_h
00002 #define CalibTracker_SiStripESProducers_SiStripGainESProducerTemplate_h
00003 
00004 // system include files
00005 #include <memory>
00006 #include "boost/shared_ptr.hpp"
00007 #include <utility>
00008 
00009 // user include files
00010 #include "FWCore/Framework/interface/ModuleFactory.h"
00011 #include "FWCore/Framework/interface/ESProducer.h"
00012 #include "FWCore/ServiceRegistry/interface/Service.h"
00013 
00014 #include "FWCore/Framework/interface/ESHandle.h"
00015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 
00018 #include "CalibFormats/SiStripObjects/interface/SiStripGain.h"
00019 #include "CondFormats/SiStripObjects/interface/SiStripApvGain.h"
00020 #include "CondFormats/DataRecord/interface/SiStripCondDataRecords.h"
00021 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
00022 //
00023 // class declaration
00024 //
00025 template<typename TDependentRecord, typename TInputRecord>
00026 class SiStripGainESProducerTemplate : public edm::ESProducer {
00027  public:
00028   SiStripGainESProducerTemplate(const edm::ParameterSet&);
00029   ~SiStripGainESProducerTemplate(){};
00030   
00031   std::auto_ptr<SiStripGain> produce(const TDependentRecord&);
00032 
00033  private:
00034 
00035   SiStripGain* SiStripGainNormalizationFunction(const TDependentRecord& iRecord);
00036   double getNFactor(const int apvGainIndex);
00037 
00038   std::vector<edm::ParameterSet> apvGainLabels_;
00039   std::vector<std::pair<std::string, std::string> > apvgain_;
00040   std::vector<double> norm_;
00041   bool automaticMode_;
00042   bool  printdebug_;
00043   SiStripGain * gain_;
00044   std::vector<edm::ESHandle<SiStripApvGain> > pDD;
00045 
00046   void fillApvGain( const SiStripGainRcd & a, const std::pair<std::string, std::string> & recordLabelPair, std::vector<edm::ESHandle<SiStripApvGain> >& pDD );
00047 };
00048 
00049 template<typename TDependentRecord, typename TInputRecord>
00050 SiStripGainESProducerTemplate<TDependentRecord,TInputRecord>::SiStripGainESProducerTemplate(const edm::ParameterSet& iConfig)
00051 {
00052   setWhatProduced(this);
00053 
00054   automaticMode_ = iConfig.getParameter<bool>("AutomaticNormalization");
00055   printdebug_ = iConfig.getUntrackedParameter<bool>("printDebug", false);
00056   apvGainLabels_ = iConfig.getParameter<std::vector<edm::ParameterSet> >("APVGain");
00057 
00058   // Fill the vector of apv labels
00059   std::vector<edm::ParameterSet>::const_iterator gainPSetIt = apvGainLabels_.begin();
00060   for( ; gainPSetIt != apvGainLabels_.end(); ++gainPSetIt ) {
00061     apvgain_.push_back( std::make_pair(gainPSetIt->getParameter<std::string>("Record"), gainPSetIt->getUntrackedParameter<std::string>("Label", "")) );
00062     norm_.push_back(gainPSetIt->getUntrackedParameter<double>("NormalizationFactor", 1.));
00063   }
00064   bool badNorm = false;
00065   std::vector<double>::const_iterator it = norm_.begin();
00066   for( ; it != norm_.end(); ++it ) {
00067     if( *it <= 0 ) badNorm = true;
00068   }
00069 
00070   if(!automaticMode_ && badNorm ){
00071     edm::LogError("SiStripGainESProducer") << "[SiStripGainESProducer] - ERROR: negative or zero Normalization factor provided. Assuming 1 for such factor" << std::endl;
00072     norm_ = std::vector<double>(norm_.size(), 1.);
00073   }
00074 }
00075 
00076 template<typename TDependentRecord, typename TInputRecord>
00077 std::auto_ptr<SiStripGain> SiStripGainESProducerTemplate<TDependentRecord,TInputRecord>::produce(const TDependentRecord& iRecord)
00078 {
00079   std::auto_ptr<SiStripGain> ptr(SiStripGainNormalizationFunction(iRecord));
00080   return ptr;
00081 }
00082 
00083 template<typename TDependentRecord, typename TInputRecord>
00084 void SiStripGainESProducerTemplate<TDependentRecord, TInputRecord>::fillApvGain( const SiStripGainRcd & a, const std::pair<std::string, std::string> & recordLabelPair, std::vector<edm::ESHandle<SiStripApvGain> >& pDD )
00085 {
00086   // Put in an empty ApvGain and fill it
00087   pDD.push_back(edm::ESHandle<SiStripApvGain>());
00088   std::string recordName( recordLabelPair.first );
00089   std::string labelName( recordLabelPair.second );
00090   if( recordName == "SiStripApvGainRcd" ) a.getRecord<SiStripApvGainRcd>().get( labelName, pDD.back() );
00091   else if( recordName == "SiStripApvGain2Rcd" ) a.getRecord<SiStripApvGain2Rcd>().get( labelName, pDD.back() );
00092   else if( recordName == "SiStripApvGain3Rcd" ) a.getRecord<SiStripApvGain3Rcd>().get( labelName, pDD.back() );
00093   else edm::LogError("SiStripGainESProducer::SiStripGainNormalizationFunction") << "ERROR: unrecognized record name " << recordName << std::endl
00094                                                                                 << "please specify one of: SiStripApvGainRcd, SiStripApvGain2Rcd, SiStripApvGain3Rcd" << std::endl;
00095 }
00096 
00097 template<typename TDependentRecord, typename TInputRecord>
00098 SiStripGain* SiStripGainESProducerTemplate<TDependentRecord,TInputRecord>::SiStripGainNormalizationFunction(const TDependentRecord& iRecord)
00099 {
00100   // First clean up the pDD vector otherwise it will contain old handles referring to products no more in the es
00101   pDD.clear();
00102 
00103   if(typeid(TDependentRecord)==typeid(SiStripGainRcd) && typeid(TInputRecord)==typeid(SiStripApvGainRcd)){
00104 
00105     const SiStripGainRcd& a = dynamic_cast<const SiStripGainRcd&>(iRecord);
00106 
00107     fillApvGain( a, apvgain_[0], pDD );
00108     // Create a new gain object and insert the ApvGain
00109     SiStripGain * gain = new SiStripGain( *(pDD[0].product()), getNFactor(0), apvgain_[0] );
00110 
00111     if( apvgain_.size() > 1 ) {
00112       for( unsigned int i=1; i<apvgain_.size(); ++i ) {
00113         fillApvGain( a, apvgain_[i], pDD );
00114         // Add the new ApvGain to the gain object
00115         gain->multiply(*(pDD[i].product()), getNFactor(i), apvgain_[i]);
00116       }
00117     }
00118     return gain;
00119 
00120   }else if(typeid(TDependentRecord)==typeid(SiStripGainSimRcd) && typeid(TInputRecord)==typeid(SiStripApvGainSimRcd)){
00121 
00122     const SiStripGainSimRcd& a = dynamic_cast<const SiStripGainSimRcd&>(iRecord);
00123 
00124     pDD.push_back(edm::ESHandle<SiStripApvGain>());
00125     a.getRecord<SiStripApvGainSimRcd>().get(apvgain_[0].second, pDD[0]);
00126     SiStripGain * gain = new SiStripGain( *(pDD[0].product()), getNFactor(0), apvgain_[0] );
00127 
00128     if( apvgain_.size() > 1 ) {
00129       for( unsigned int i=1; i<apvgain_.size(); ++i ) {
00130         pDD.push_back(edm::ESHandle<SiStripApvGain>());
00131         a.getRecord<SiStripApvGainSimRcd>().get(apvgain_[i].second, pDD[i]);
00132         gain->multiply(*(pDD[i].product()), getNFactor(i), apvgain_[i]);
00133       }
00134     }
00135     return gain;
00136   }
00137     
00138   edm::LogError("SiStripGainESProducer") << "[SiStripGainNormalizationFunction] - ERROR: asking for a pair of records different from <SiStripGainRcd,SiStripApvGainRcd> and <SiStripGainSimRcd,SiStripApvGainSimRcd>" << std::endl;
00139   return new SiStripGain();
00140 }
00141 
00142 template<typename TDependentRecord, typename TInputRecord>
00143 double  SiStripGainESProducerTemplate<TDependentRecord,TInputRecord>::getNFactor(const int apvGainIndex){
00144   double NFactor=0.;
00145 
00146   if(automaticMode_ || printdebug_ ){
00147 
00148     std::vector<uint32_t> DetIds;
00149     pDD[apvGainIndex]->getDetIds(DetIds);
00150 
00151     double SumOfGains=0.;
00152     int NGains=0;
00153     
00154     for(std::vector<uint32_t>::const_iterator detit=DetIds.begin(); detit!=DetIds.end(); detit++){
00155       
00156       SiStripApvGain::Range detRange = pDD[apvGainIndex]->getRange(*detit);
00157       
00158       int iComp=0;
00159        
00160       for(std::vector<float>::const_iterator apvit=detRange.first; apvit!=detRange.second; apvit++){
00161          
00162         SumOfGains+=(*apvit);
00163         NGains++;
00164         if (printdebug_)
00165           edm::LogInfo("SiStripGainESProducer::produce()")<< "detid/component: " << *detit <<"/"<<iComp<< "   gain factor " <<*apvit ;
00166         iComp++;
00167       }      
00168     }
00169     
00170     if(automaticMode_){
00171       if(SumOfGains>0 && NGains>0){
00172         NFactor=SumOfGains/NGains;
00173       }
00174       else{
00175         edm::LogError("SiStripGainESProducer::produce() - ERROR: empty set of gain values received. Cannot compute normalization factor. Assuming 1 for such factor") << std::endl;
00176         NFactor=1.;
00177       }
00178     }
00179   }
00180   
00181   if(!automaticMode_){
00182     NFactor=norm_[apvGainIndex];
00183   }
00184 
00185   if (printdebug_)  edm::LogInfo("SiStripGainESProducer")<< " putting A SiStrip Gain object in eventSetup with normalization factor " << NFactor ;
00186   return NFactor;
00187 }  
00188 #endif