Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-13 01:43:24

0001 // -*- C++ -*-
0002 //
0003 // Package:    CondTools/SiStrip
0004 // Class:      SiStripApvGainRescaler
0005 //
0006 /**\class SiStripApvGainRescaler SiStripApvGainRescaler.cc CondTools/SiStrip/plugins/SiStripApvGainRescaler.cc
0007 
0008  Description: Utility class to rescale the values of SiStrip G2 by the ratio of G1_old/G1_new: this is useful in the case in which a Gain2 payload needs to recycled after a G1 update to keep the G1*G2 product constant
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Marco Musich
0015 //         Created:  Tue, 03 Oct 2017 12:57:34 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 #include <iostream>
0022 
0023 // user include files
0024 #include "FWCore/Framework/interface/Frameworkfwd.h"
0025 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0026 
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/MakerMacros.h"
0029 
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 
0032 #include "CondFormats/SiStripObjects/interface/SiStripApvGain.h"
0033 #include "CondFormats/DataRecord/interface/SiStripApvGainRcd.h"
0034 #include "CalibFormats/SiStripObjects/interface/SiStripGain.h"
0035 #include "CalibTracker/Records/interface/SiStripGainRcd.h"
0036 
0037 #include "FWCore/ServiceRegistry/interface/Service.h"
0038 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0039 #include "FWCore/Framework/interface/EventSetup.h"
0040 
0041 //
0042 // class declaration
0043 //
0044 
0045 class SiStripApvGainRescaler : public edm::one::EDAnalyzer<> {
0046 public:
0047   explicit SiStripApvGainRescaler(const edm::ParameterSet&);
0048   ~SiStripApvGainRescaler() override;
0049 
0050   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0051 
0052 private:
0053   void analyze(const edm::Event&, const edm::EventSetup&) override;
0054   std::unique_ptr<SiStripApvGain> getNewObject(const std::map<std::pair<uint32_t, int>, float>& theMap);
0055 
0056   // ----------member data ---------------------------
0057   const uint32_t m_printdebug;
0058   const std::string m_Record;
0059 
0060   // take G2_old and G1_old from the regular gain handle
0061   const edm::ESGetToken<SiStripGain, SiStripGainRcd> g1g2Token_;
0062   // take the additional G1_new from the Gain3Rcd (dirty trick)
0063   const edm::ESGetToken<SiStripApvGain, SiStripApvGain3Rcd> g3Token_;
0064 };
0065 
0066 //
0067 // constructors and destructor
0068 //
0069 SiStripApvGainRescaler::SiStripApvGainRescaler(const edm::ParameterSet& iConfig)
0070     : m_printdebug{iConfig.getUntrackedParameter<uint32_t>("printDebug", 1)},
0071       m_Record(iConfig.getParameter<std::string>("Record")),
0072       g1g2Token_(esConsumes()),
0073       g3Token_(esConsumes()) {}
0074 
0075 SiStripApvGainRescaler::~SiStripApvGainRescaler() = default;
0076 //
0077 // member functions
0078 //
0079 
0080 // ------------ method called for each event  ------------
0081 void SiStripApvGainRescaler::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0082   using namespace edm;
0083 
0084   const auto& g1g2 = iSetup.getData(g1g2Token_);
0085   const auto& g3 = iSetup.getData(g3Token_);
0086 
0087   std::map<std::pair<uint32_t, int>, float> theMap;
0088 
0089   std::vector<uint32_t> detid;
0090   g1g2.getDetIds(detid);
0091   for (const auto& d : detid) {
0092     SiStripApvGain::Range rangeG1_old = g1g2.getRange(d, 0);
0093     SiStripApvGain::Range rangeG2_old = g1g2.getRange(d, 1);
0094     SiStripApvGain::Range rangeG1_new = g3.getRange(d);
0095 
0096     int nAPV = 0;
0097     for (int it = 0; it < rangeG1_old.second - rangeG1_old.first; it++) {
0098       nAPV++;
0099 
0100       std::pair<uint32_t, int> index = std::make_pair(d, nAPV);
0101 
0102       float G1_old = g1g2.getApvGain(it, rangeG1_old);
0103       float G2_old = g1g2.getApvGain(it, rangeG2_old);
0104       float G1G2_old = G1_old * G2_old;
0105       float G1_new = g3.getApvGain(it, rangeG1_new);
0106 
0107       // this is based on G1_old*G2_old = G1_new * G2_new ==> G2_new = (G1_old*G2_old)/G1_new
0108 
0109       float NewGain = G1G2_old / G1_new;
0110 
0111       // DO NOT RESCALE APVs set to the default value
0112       if (G2_old != 1.) {
0113         theMap[index] = NewGain;
0114       } else {
0115         theMap[index] = 1.;
0116       }
0117 
0118     }  // loop over APVs
0119   }    // loop over DetIds
0120 
0121   std::unique_ptr<SiStripApvGain> theAPVGains = this->getNewObject(theMap);
0122 
0123   // write out the APVGains record
0124   edm::Service<cond::service::PoolDBOutputService> poolDbService;
0125 
0126   if (poolDbService.isAvailable())
0127     poolDbService->writeOneIOV(*theAPVGains, poolDbService->currentTime(), m_Record);
0128   else
0129     throw std::runtime_error("PoolDBService required.");
0130 }
0131 
0132 //********************************************************************************//
0133 std::unique_ptr<SiStripApvGain> SiStripApvGainRescaler::getNewObject(
0134     const std::map<std::pair<uint32_t, int>, float>& theMap) {
0135   std::unique_ptr<SiStripApvGain> obj = std::make_unique<SiStripApvGain>();
0136 
0137   std::vector<float> theSiStripVector;
0138   uint32_t PreviousDetId = 0;
0139   unsigned int countDetIds(0);  // count DetIds to print
0140   for (const auto& element : theMap) {
0141     uint32_t DetId = element.first.first;
0142     if (DetId != PreviousDetId) {
0143       if (!theSiStripVector.empty()) {
0144         SiStripApvGain::Range range(theSiStripVector.begin(), theSiStripVector.end());
0145         if (!obj->put(PreviousDetId, range))
0146           edm::LogError("SiStripApvGainRescaler") << "Bug to put detId = " << PreviousDetId << "\n";
0147       }
0148       theSiStripVector.clear();
0149       PreviousDetId = DetId;
0150       countDetIds++;
0151     }
0152     theSiStripVector.push_back(element.second);
0153 
0154     if (countDetIds <= m_printdebug) {
0155       edm::LogInfo("SiStripApvGainRescaler")
0156           << __FUNCTION__ << " DetId: " << DetId << " APV:   " << element.first.second << " Gain:  " << element.second;
0157     }
0158   }
0159 
0160   if (!theSiStripVector.empty()) {
0161     SiStripApvGain::Range range(theSiStripVector.begin(), theSiStripVector.end());
0162     if (!obj->put(PreviousDetId, range))
0163       edm::LogError("SiStripApvGainRescaler") << "Bug to put detId = " << PreviousDetId << "\n";
0164   }
0165 
0166   return obj;
0167 }
0168 
0169 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0170 void SiStripApvGainRescaler::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0171   edm::ParameterSetDescription desc;
0172 
0173   desc.setComment(
0174       " Utility class to rescale the values of SiStrip G2 by the ratio of G1_old/G1_new: this is useful in the case in "
0175       "which a Gain2 payload needs to recycled after a G1 update to keep the G1*G2 product constant."
0176       "PoolDBOutputService must be set up for 'SiStripApvGainRcd'.");
0177 
0178   desc.add<std::string>("Record", "SiStripApvGainRcd");
0179   desc.addUntracked<unsigned int>("printDebug", 1);
0180   descriptions.add("rescaleGain2byGain1", desc);
0181 }
0182 
0183 //define this as a plug-in
0184 DEFINE_FWK_MODULE(SiStripApvGainRescaler);