Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-24 23:45:59

0001 // -*- C++ -*-
0002 //
0003 // Package:    Calibration/EcalCalibAlgos
0004 // Class:      EcalPhiSymRecHitProducer
0005 //
0006 //
0007 // Original Author:  Simone Pigazzini
0008 //         Created:  Wed, 16 Mar 2022 15:52:48 GMT
0009 //
0010 //
0011 #include "FWCore/Framework/interface/ESHandle.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 #include "FWCore/Framework/interface/global/EDProducer.h"
0014 #include "FWCore/Framework/interface/Event.h"
0015 #include "FWCore/Framework/interface/EventSetup.h"
0016 #include "FWCore/Framework/interface/LuminosityBlock.h"
0017 #include "FWCore/Framework/interface/ConsumesCollector.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0020 #include "FWCore/ServiceRegistry/interface/Service.h"
0021 
0022 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
0023 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0024 #include "DataFormats/EcalDetId/interface/EEDetId.h"
0025 
0026 #include "Calibration/Tools/interface/EcalRingCalibrationTools.h"
0027 #include "CalibCalorimetry/EcalLaserCorrection/interface/EcalLaserDbService.h"
0028 #include "CalibCalorimetry/EcalLaserCorrection/interface/EcalLaserDbRecord.h"
0029 
0030 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0031 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0032 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
0033 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0034 
0035 #include "CondFormats/EcalObjects/interface/EcalChannelStatus.h"
0036 #include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h"
0037 #include "CondFormats/EcalObjects/interface/EcalChannelStatusCode.h"
0038 #include "CondFormats/RunInfo/interface/LHCInfo.h"
0039 #include "CondFormats/DataRecord/interface/LHCInfoRcd.h"
0040 
0041 #include "Calibration/EcalCalibAlgos/interface/EcalPhiSymRecHit.h"
0042 #include "Calibration/EcalCalibAlgos/interface/EcalPhiSymInfo.h"
0043 
0044 //---Wrapper to handle stream data
0045 struct PhiSymCache {
0046   EcalPhiSymInfo ecalLumiInfo;
0047   EcalPhiSymRecHitCollection recHitCollEB;
0048   EcalPhiSymRecHitCollection recHitCollEE;
0049 
0050   void clear() {
0051     ecalLumiInfo = EcalPhiSymInfo();
0052     recHitCollEB.clear();
0053     recHitCollEE.clear();
0054   }
0055 };
0056 
0057 // cache structure for LuminosityBlock/Run Cache
0058 struct ConfigCache {
0059   float etCutsEB[EcalRingCalibrationTools::N_RING_BARREL];
0060   float etCutsEE[EcalRingCalibrationTools::N_RING_ENDCAP];
0061   std::vector<DetId> barrelDetIds;
0062   std::vector<DetId> endcapDetIds;
0063 };
0064 
0065 //****************************************************************************************
0066 // - EcalPhiSymRecHitProducerBase: base class implementing the main algorithm
0067 // - EcalPhiSymRecHitProducerLumi: produces reduced collections per LuminosityBlock
0068 // - EcalPhiSymRecHitProducerRun: produces reduced collections per Run
0069 class EcalPhiSymRecHitProducerBase {
0070 public:
0071   explicit EcalPhiSymRecHitProducerBase(const edm::ParameterSet& pSet, edm::ConsumesCollector&& cc);
0072   ~EcalPhiSymRecHitProducerBase(){};
0073 
0074   //---methods
0075   // job
0076   void initializeJob();
0077   // event
0078   void processEvent(edm::Event const& event,
0079                     edm::EventSetup const& setup,
0080                     ConfigCache const* config,
0081                     PhiSymCache* cache) const;
0082   // helpers
0083   void initializeStreamCache(ConfigCache const* config, PhiSymCache* cache) const;
0084   void initializePhiSymCache(edm::EventSetup const& setup,
0085                              edm::ESGetToken<EcalChannelStatus, EcalChannelStatusRcd> const& chStatusToken,
0086                              ConfigCache const* config,
0087                              std::shared_ptr<PhiSymCache>& cache) const;
0088   void initializeConfigCache(edm::EventSetup const& setup,
0089                              edm::ESGetToken<CaloGeometry, CaloGeometryRecord> const& geoToken,
0090                              std::shared_ptr<ConfigCache>& cache) const;
0091   void sumCache(PhiSymCache* summaryc, PhiSymCache* streamc) const;
0092 
0093   //---data memebers
0094   // available to derived classes
0095 protected:
0096   edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geoToken_;
0097   edm::ESGetToken<EcalLaserDbService, EcalLaserDbRecord> laserDbToken_;
0098   edm::EDGetTokenT<EBRecHitCollection> ebToken_;
0099   edm::EDGetTokenT<EBRecHitCollection> eeToken_;
0100   float etCutEB_;
0101   std::vector<double> eThresholdsEB_;
0102   float etCutEE_;
0103   std::vector<double> A_;
0104   std::vector<double> B_;
0105   float thrEEmod_;
0106   int nMisCalib_;
0107   int nSumEtValues_;
0108   std::vector<double> misCalibRangeEB_;
0109   std::vector<float> misCalibStepsEB_;
0110   std::vector<double> misCalibRangeEE_;
0111   std::vector<float> misCalibStepsEE_;
0112   //---geometry
0113   EcalRingCalibrationTools calibRing_;
0114   static const short kNRingsEB = EcalRingCalibrationTools::N_RING_BARREL;
0115   static const short kNRingsEE = EcalRingCalibrationTools::N_RING_ENDCAP;
0116   static const short ringsInOneEE = kNRingsEE / 2;
0117   float eThresholdsEE_[kNRingsEE];
0118 };
0119 
0120 //----------IMPLEMENTATION----------------------------------------------------------------
0121 EcalPhiSymRecHitProducerBase::EcalPhiSymRecHitProducerBase(const edm::ParameterSet& pSet, edm::ConsumesCollector&& cc)
0122     : geoToken_(cc.esConsumes()),
0123       laserDbToken_(cc.esConsumes()),
0124       ebToken_(cc.consumes<EBRecHitCollection>(pSet.getParameter<edm::InputTag>("barrelHitCollection"))),
0125       eeToken_(cc.consumes<EBRecHitCollection>(pSet.getParameter<edm::InputTag>("endcapHitCollection"))),
0126       etCutEB_(pSet.getParameter<double>("etCut_barrel")),
0127       eThresholdsEB_(pSet.getParameter<std::vector<double> >("eThresholds_barrel")),
0128       etCutEE_(pSet.getParameter<double>("etCut_endcap")),
0129       A_(pSet.getParameter<std::vector<double> >("A")),
0130       B_(pSet.getParameter<std::vector<double> >("B")),
0131       thrEEmod_(pSet.getParameter<double>("thrEEmod")),
0132       nMisCalib_(pSet.getParameter<int>("nMisCalib") / 2),
0133       nSumEtValues_(nMisCalib_ * 2 + 1),
0134       misCalibRangeEB_(pSet.getParameter<std::vector<double> >("misCalibRangeEB")),
0135       misCalibRangeEE_(pSet.getParameter<std::vector<double> >("misCalibRangeEE")) {}
0136 
0137 void EcalPhiSymRecHitProducerBase::initializeJob() {
0138   //---Compute the endcap thresholds using the provived parametric formula
0139   for (int iRing = 0; iRing < ringsInOneEE; ++iRing) {
0140     if (iRing < 30)
0141       eThresholdsEE_[iRing] = thrEEmod_ * (B_[0] + A_[0] * iRing) / 1000;
0142     else
0143       eThresholdsEE_[iRing] = thrEEmod_ * (B_[1] + A_[1] * iRing) / 1000;
0144     eThresholdsEE_[iRing + ringsInOneEE] = eThresholdsEE_[iRing];
0145   }
0146 
0147   //---misCalib value init (nMisCalib is half of the correct value!)
0148   float misCalibStepEB = std::abs(misCalibRangeEB_[1] - misCalibRangeEB_[0]) / (nMisCalib_ * 2);
0149   float misCalibStepEE = std::abs(misCalibRangeEE_[1] - misCalibRangeEE_[0]) / (nMisCalib_ * 2);
0150   misCalibStepsEB_.resize(nSumEtValues_);
0151   misCalibStepsEE_.resize(nSumEtValues_);
0152   for (int iMis = -nMisCalib_; iMis <= nMisCalib_; ++iMis) {
0153     //--- 0 -> 0; -i -> [1...n/2]; +i -> [n/2+1...n]
0154     int index = iMis > 0 ? iMis + nMisCalib_ : iMis == 0 ? 0 : iMis + nMisCalib_ + 1;
0155     misCalibStepsEB_[index] = iMis * misCalibStepEB;
0156     misCalibStepsEE_[index] = iMis * misCalibStepEE;
0157   }
0158 }
0159 
0160 void EcalPhiSymRecHitProducerBase::processEvent(edm::Event const& event,
0161                                                 edm::EventSetup const& setup,
0162                                                 ConfigCache const* configCache,
0163                                                 PhiSymCache* streamCache) const {
0164   uint64_t totHitsEB = 0;
0165   uint64_t totHitsEE = 0;
0166 
0167   //---get recHits collections
0168   auto barrelRecHits = event.get(ebToken_);
0169   auto endcapRecHits = event.get(eeToken_);
0170 
0171   //---get the laser corrections
0172   edm::Timestamp evtTimeStamp(event.time().value());
0173   auto const& laser = setup.getData(laserDbToken_);
0174 
0175   //---get the geometry
0176   auto const& geometry = setup.getData(geoToken_);
0177   auto barrelGeometry = geometry.getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
0178   auto endcapGeometry = geometry.getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
0179 
0180   //---EB---
0181   for (auto& recHit : barrelRecHits) {
0182     float energy = recHit.energy();
0183     EBDetId ebHit = EBDetId(recHit.id());
0184     int ring = calibRing_.getRingIndex(ebHit);
0185     //---if recHit energy is below thr even with the highest miscalib skip this recHit
0186     if (energy * misCalibRangeEB_[1] < eThresholdsEB_[ring])
0187       continue;
0188     float eta = barrelGeometry->getGeometry(ebHit)->getPosition().eta();
0189 
0190     //---compute et + miscalibration
0191     std::vector<float> etValues(nSumEtValues_, 0);
0192     //---one can do this in one for loop from -nMis to +nMis but in this way the
0193     //---program is faster
0194     //---NOTE: nMisCalib is half on the value set in the cfg python
0195     etValues[0] = recHit.energy() / cosh(eta);
0196     for (int iMis = -nMisCalib_; iMis < 0; ++iMis) {
0197       //--- 0 -> 0; -i -> [1...n/2]; +i -> [n/2+1...n]
0198       int index = iMis + nMisCalib_ + 1;
0199       etValues[index] = etValues[0] * (1 + misCalibStepsEB_[index]);
0200       //---set et to zero if out of range [e_thr, et_thr+1]
0201       if (etValues[index] * cosh(eta) < eThresholdsEB_[ring] || etValues[index] > configCache->etCutsEB[ring])
0202         etValues[index] = 0;
0203     }
0204     for (int iMis = 1; iMis <= nMisCalib_; ++iMis) {
0205       //--- 0 -> 0; -i -> [1...n/2]; +i -> [n/2+1...n]
0206       int index = iMis + nMisCalib_;
0207       etValues[index] = etValues[0] * (1 + misCalibStepsEB_[index]);
0208       //---set et to zero if out of range [e_thr, et_thr+1]
0209       if (etValues[index] * cosh(eta) < eThresholdsEB_[ring] || etValues[index] > configCache->etCutsEB[ring])
0210         etValues[index] = 0;
0211     }
0212     //---set et to zero if out of range [e_thr, et_thr+1]
0213     if (energy < eThresholdsEB_[ring] || etValues[0] > configCache->etCutsEB[ring])
0214       etValues[0] = 0;
0215     else
0216       ++totHitsEB;
0217     //---update the rechHit sumEt
0218     streamCache->recHitCollEB.at(ebHit.denseIndex())
0219         .addHit(etValues, laser.getLaserCorrection(recHit.id(), evtTimeStamp));
0220   }
0221 
0222   //---EE---
0223   for (auto& recHit : endcapRecHits) {
0224     EEDetId eeHit = EEDetId(recHit.id());
0225     int ring = calibRing_.getRingIndex(eeHit) - kNRingsEB;
0226     float energy = recHit.energy();
0227     //---if recHit energy is below thr even with the highest miscalib skip this recHit
0228     if (energy * misCalibRangeEE_[1] < eThresholdsEE_[ring])
0229       continue;
0230     float eta = endcapGeometry->getGeometry(eeHit)->getPosition().eta();
0231 
0232     //---compute et + miscalibration
0233     std::vector<float> etValues(nSumEtValues_, 0);
0234     //---one can do this in one for loop from -nMis to +nMis but in this way the
0235     //---program is faster
0236     //---NOTE: nMisCalib is half on the value set in the cfg python
0237     etValues[0] = recHit.energy() / cosh(eta);
0238     for (int iMis = -nMisCalib_; iMis < 0; ++iMis) {
0239       //--- 0 -> 0; -i -> [1...n/2]; +i -> [n/2+1...n]
0240       int index = iMis + nMisCalib_ + 1;
0241       etValues[index] = etValues[0] * (1 + misCalibStepsEE_[index]);
0242       //---set et to zero if out of range [e_thr, et_thr+1]
0243       if (etValues[index] * cosh(eta) < eThresholdsEE_[ring] || etValues[index] > configCache->etCutsEE[ring])
0244         etValues[index] = 0;
0245     }
0246     for (int iMis = 1; iMis <= nMisCalib_; ++iMis) {
0247       //--- 0 -> 0; -i -> [1...n/2]; +i -> [n/2+1...n]
0248       int index = iMis + nMisCalib_;
0249       etValues[index] = etValues[0] * (1 + misCalibStepsEE_[index]);
0250       //---set et to zero if out of range [e_thr, et_thr+1]
0251       if (etValues[index] * cosh(eta) < eThresholdsEE_[ring] || etValues[index] > configCache->etCutsEE[ring])
0252         etValues[index] = 0;
0253     }
0254     //---set et to zero if out of range [e_thr, et_thr+1]
0255     if (energy < eThresholdsEE_[ring] || etValues[0] > configCache->etCutsEE[ring])
0256       etValues[0] = 0;
0257     else
0258       ++totHitsEE;
0259     //---update the rechHit sumEt
0260     streamCache->recHitCollEE.at(eeHit.denseIndex())
0261         .addHit(etValues, laser.getLaserCorrection(recHit.id(), evtTimeStamp));
0262   }
0263 
0264   //---update the lumi info
0265   EcalPhiSymInfo thisEvent(totHitsEB, totHitsEE, 1, 0, 0, 0, 0);
0266   streamCache->ecalLumiInfo += thisEvent;
0267 }
0268 
0269 void EcalPhiSymRecHitProducerBase::initializeStreamCache(ConfigCache const* config, PhiSymCache* cache) const {
0270   //---Initialize the per-stream RecHitCollection
0271   //   both collections are initialized to contain the total
0272   //   number of crystals, ordered accrodingly to the hashedIndex.
0273   cache->clear();
0274   cache->recHitCollEB.resize(config->barrelDetIds.size());
0275   cache->recHitCollEE.resize(config->endcapDetIds.size());
0276   for (auto& ebDetId : config->barrelDetIds) {
0277     EBDetId id(ebDetId);
0278     cache->recHitCollEB.at(id.denseIndex()) = EcalPhiSymRecHit(id.rawId(), nSumEtValues_);
0279   }
0280   for (auto& eeDetId : config->endcapDetIds) {
0281     EEDetId id(eeDetId);
0282     cache->recHitCollEE.at(id.denseIndex()) = EcalPhiSymRecHit(id.rawId(), nSumEtValues_);
0283   }
0284 }
0285 
0286 void EcalPhiSymRecHitProducerBase::initializePhiSymCache(
0287     edm::EventSetup const& setup,
0288     edm::ESGetToken<EcalChannelStatus, EcalChannelStatusRcd> const& chStatusToken,
0289     ConfigCache const* config,
0290     std::shared_ptr<PhiSymCache>& cache) const {
0291   cache->clear();
0292 
0293   //---get the channels status
0294   auto const& chStatus = setup.getData(chStatusToken);
0295 
0296   cache->recHitCollEB.resize(config->barrelDetIds.size());
0297   cache->recHitCollEE.resize(config->endcapDetIds.size());
0298   for (auto& ebDetId : config->barrelDetIds) {
0299     EBDetId id(ebDetId);
0300     cache->recHitCollEB.at(id.denseIndex()) =
0301         EcalPhiSymRecHit(ebDetId.rawId(), nSumEtValues_, chStatus[id].getStatusCode());
0302   }
0303   for (auto& eeDetId : config->endcapDetIds) {
0304     EEDetId id(eeDetId);
0305     int ring = calibRing_.getRingIndex(id) - kNRingsEB;
0306     cache->recHitCollEE.at(id.denseIndex()) =
0307         EcalPhiSymRecHit(eeDetId.rawId(), nSumEtValues_, chStatus[id].getStatusCode());
0308     cache->recHitCollEE.at(id.denseIndex())
0309         .setEERing(ring < kNRingsEE / 2 ? ring - kNRingsEE / 2 : ring - kNRingsEE / 2 + 1);
0310   }
0311 }
0312 
0313 void EcalPhiSymRecHitProducerBase::initializeConfigCache(
0314     edm::EventSetup const& setup,
0315     edm::ESGetToken<CaloGeometry, CaloGeometryRecord> const& geoToken,
0316     std::shared_ptr<ConfigCache>& cache) const {
0317   //---get the ecal geometry
0318   const auto* geometry = &setup.getData(geoToken);
0319   calibRing_.setCaloGeometry(geometry);
0320 
0321   const auto* barrelGeometry = geometry->getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
0322   const auto* endcapGeometry = geometry->getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
0323   cache->barrelDetIds = barrelGeometry->getValidDetIds(DetId::Ecal, EcalBarrel);
0324   cache->endcapDetIds = endcapGeometry->getValidDetIds(DetId::Ecal, EcalEndcap);
0325 
0326   for (auto& ebDetId : cache->barrelDetIds) {
0327     EBDetId id(ebDetId);
0328     int ring = calibRing_.getRingIndex(id);
0329     //---set etCut if first pass
0330     if (id.iphi() == 1) {
0331       auto cellGeometry = barrelGeometry->getGeometry(id);
0332       float eta = cellGeometry->getPosition().eta();
0333       cache->etCutsEB[ring] = eThresholdsEB_[ring] / cosh(eta) + etCutEB_;
0334     }
0335   }
0336   for (auto& eeDetId : cache->endcapDetIds) {
0337     EEDetId id(eeDetId);
0338     int ring = calibRing_.getRingIndex(id) - kNRingsEB;
0339     //---set eCutEE if first pass
0340     if (ring < ringsInOneEE && id.ix() == EEDetId::IX_MAX / 2) {
0341       auto cellGeometry = endcapGeometry->getGeometry(id);
0342       cache->etCutsEE[ring] = eThresholdsEE_[ring] / cosh(cellGeometry->getPosition().eta()) + etCutEE_;
0343       cache->etCutsEE[ring + ringsInOneEE] = cache->etCutsEE[ring];
0344     }
0345   }
0346 }
0347 
0348 void EcalPhiSymRecHitProducerBase::sumCache(PhiSymCache* summaryc, PhiSymCache* streamc) const {
0349   //---The first argument is the summary cache that
0350   //   contains the lumi/run summary information.
0351   //   The stream partial sums are passed as second argument
0352   summaryc->ecalLumiInfo += streamc->ecalLumiInfo;
0353   for (unsigned int i = 0; i < summaryc->recHitCollEB.size(); ++i)
0354     summaryc->recHitCollEB[i] += streamc->recHitCollEB[i];
0355   for (unsigned int i = 0; i < summaryc->recHitCollEE.size(); ++i)
0356     summaryc->recHitCollEE[i] += streamc->recHitCollEE[i];
0357 }
0358 
0359 //****************************************************************************************
0360 // Lumi producer
0361 // The StreamCache and LuminosityBlockSummaryCache contain the rec hit data, summed per
0362 // stream, in the stream cache, and per lumi in the summary cache.
0363 // The LuminosityBlockCache contains a set of information (detIds and thresholds)
0364 // that requires access to the geometry record to be created. Not using the LuminosityBlockCache
0365 // would require making the objects contained in it mutable class members which is
0366 // discouraged.
0367 class EcalPhiSymRecHitProducerLumi : public edm::global::EDProducer<edm::StreamCache<PhiSymCache>,
0368                                                                     edm::LuminosityBlockCache<ConfigCache>,
0369                                                                     edm::LuminosityBlockSummaryCache<PhiSymCache>,
0370                                                                     edm::EndLuminosityBlockProducer,
0371                                                                     edm::Accumulator>,
0372                                      public EcalPhiSymRecHitProducerBase {
0373 public:
0374   explicit EcalPhiSymRecHitProducerLumi(const edm::ParameterSet& pSet);
0375   ~EcalPhiSymRecHitProducerLumi() override{};
0376 
0377 private:
0378   //---methods
0379   // job
0380   void beginJob() override { initializeJob(); };
0381   // lumi
0382   std::shared_ptr<ConfigCache> globalBeginLuminosityBlock(edm::LuminosityBlock const& lumi,
0383                                                           edm::EventSetup const& setup) const override;
0384   void globalEndLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) const override{};
0385   std::shared_ptr<PhiSymCache> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const& lumi,
0386                                                                  edm::EventSetup const& setup) const override;
0387   void globalEndLuminosityBlockSummary(edm::LuminosityBlock const& lumi,
0388                                        edm::EventSetup const& setup,
0389                                        PhiSymCache* cache) const override{};
0390   void globalEndLuminosityBlockProduce(edm::LuminosityBlock& lumi,
0391                                        edm::EventSetup const& setup,
0392                                        PhiSymCache const* cache) const override;
0393   // stream
0394   std::unique_ptr<PhiSymCache> beginStream(edm::StreamID stream) const override;
0395   void streamBeginLuminosityBlock(edm::StreamID stream,
0396                                   edm::LuminosityBlock const& lumi,
0397                                   edm::EventSetup const& setup) const override;
0398   void streamEndLuminosityBlockSummary(edm::StreamID stream,
0399                                        edm::LuminosityBlock const& lumi,
0400                                        edm::EventSetup const& setup,
0401                                        PhiSymCache* cache) const override;
0402 
0403   // event
0404   void accumulate(edm::StreamID stream, edm::Event const& event, edm::EventSetup const& setup) const override;
0405 
0406   // data members
0407   edm::ESGetToken<LHCInfo, LHCInfoRcd> lhcInfoTokenLumi_;
0408   edm::ESGetToken<EcalChannelStatus, EcalChannelStatusRcd> chStatusTokenLumi_;
0409   edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geoTokenLumi_;
0410 };
0411 
0412 //----------IMPLEMENTATION----------------------------------------------------------------
0413 EcalPhiSymRecHitProducerLumi::EcalPhiSymRecHitProducerLumi(const edm::ParameterSet& pSet)
0414     : EcalPhiSymRecHitProducerBase(pSet, consumesCollector()),
0415       lhcInfoTokenLumi_(esConsumes<edm::Transition::BeginLuminosityBlock>()),
0416       chStatusTokenLumi_(esConsumes<edm::Transition::BeginLuminosityBlock>()),
0417       geoTokenLumi_(esConsumes<edm::Transition::BeginLuminosityBlock>()) {
0418   produces<EcalPhiSymInfo, edm::Transition::EndLuminosityBlock>();
0419   produces<EcalPhiSymRecHitCollection, edm::Transition::EndLuminosityBlock>("EB");
0420   produces<EcalPhiSymRecHitCollection, edm::Transition::EndLuminosityBlock>("EE");
0421 }
0422 
0423 std::shared_ptr<ConfigCache> EcalPhiSymRecHitProducerLumi::globalBeginLuminosityBlock(
0424     edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) const {
0425   auto cache = std::make_shared<ConfigCache>();
0426 
0427   //---Reset cache with config values
0428   initializeConfigCache(setup, geoTokenLumi_, cache);
0429 
0430   return cache;
0431 }
0432 
0433 std::shared_ptr<PhiSymCache> EcalPhiSymRecHitProducerLumi::globalBeginLuminosityBlockSummary(
0434     edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) const {
0435   auto cache = std::make_shared<PhiSymCache>();
0436 
0437   //---Get LHC info
0438   const auto& lhcinfo = setup.getData(lhcInfoTokenLumi_);
0439   EcalPhiSymInfo thisLumi(0, 0, 0, 1, lhcinfo.fillNumber(), lhcinfo.delivLumi(), lhcinfo.recLumi());
0440 
0441   //---Reset global cache
0442   initializePhiSymCache(setup, chStatusTokenLumi_, luminosityBlockCache(lumi.index()), cache);
0443   cache->ecalLumiInfo = thisLumi;
0444 
0445   return cache;
0446 }
0447 
0448 void EcalPhiSymRecHitProducerLumi::globalEndLuminosityBlockProduce(edm::LuminosityBlock& lumi,
0449                                                                    edm::EventSetup const& setup,
0450                                                                    PhiSymCache const* cache) const {
0451   //---put the collections in the LuminosityBlocks tree
0452   auto ecalLumiInfo = std::make_unique<EcalPhiSymInfo>(cache->ecalLumiInfo);
0453   ecalLumiInfo->setMiscalibInfo(
0454       nMisCalib_ * 2, misCalibRangeEB_[0], misCalibRangeEB_[1], misCalibRangeEE_[0], misCalibRangeEE_[1]);
0455   auto recHitCollEB =
0456       std::make_unique<EcalPhiSymRecHitCollection>(cache->recHitCollEB.begin(), cache->recHitCollEB.end());
0457   auto recHitCollEE =
0458       std::make_unique<EcalPhiSymRecHitCollection>(cache->recHitCollEE.begin(), cache->recHitCollEE.end());
0459 
0460   lumi.put(std::move(ecalLumiInfo));
0461   lumi.put(std::move(recHitCollEB), "EB");
0462   lumi.put(std::move(recHitCollEE), "EE");
0463 }
0464 
0465 std::unique_ptr<PhiSymCache> EcalPhiSymRecHitProducerLumi::beginStream(edm::StreamID stream) const {
0466   //---create stream cache
0467   return std::make_unique<PhiSymCache>();
0468 }
0469 
0470 void EcalPhiSymRecHitProducerLumi::streamBeginLuminosityBlock(edm::StreamID stream,
0471                                                               edm::LuminosityBlock const& lumi,
0472                                                               edm::EventSetup const& setup) const {
0473   //---Reset stream cache
0474   initializeStreamCache(luminosityBlockCache(lumi.index()), streamCache(stream));
0475 }
0476 
0477 void EcalPhiSymRecHitProducerLumi::streamEndLuminosityBlockSummary(edm::StreamID stream,
0478                                                                    edm::LuminosityBlock const& lumi,
0479                                                                    edm::EventSetup const& setup,
0480                                                                    PhiSymCache* scache) const {
0481   //---sum stream cache to summary cache
0482   sumCache(scache, streamCache(stream));
0483 }
0484 
0485 void EcalPhiSymRecHitProducerLumi::accumulate(edm::StreamID stream,
0486                                               edm::Event const& event,
0487                                               edm::EventSetup const& setup) const {
0488   processEvent(event, setup, luminosityBlockCache(event.getLuminosityBlock().index()), streamCache(stream));
0489 }
0490 
0491 //****************************************************************************************
0492 // Run producer
0493 // The StreamCache and RunSummaryCache contain the rec hit data, summed per
0494 // stream, in the stream cache, and per run in the summary cache.
0495 // The RunCache contains a set of information (detIds and thresholds)
0496 // that requires access to the geometry record to be created. Not using the RunCache
0497 // would require making the objects contained in it mutable class members which is
0498 // discouraged.
0499 class EcalPhiSymRecHitProducerRun : public edm::global::EDProducer<edm::StreamCache<PhiSymCache>,
0500                                                                    edm::RunCache<ConfigCache>,
0501                                                                    edm::RunSummaryCache<PhiSymCache>,
0502                                                                    edm::EndRunProducer,
0503                                                                    edm::Accumulator>,
0504                                     public EcalPhiSymRecHitProducerBase {
0505 public:
0506   explicit EcalPhiSymRecHitProducerRun(const edm::ParameterSet& pSet);
0507   ~EcalPhiSymRecHitProducerRun() override{};
0508 
0509 private:
0510   //---methods
0511   // job
0512   void beginJob() override { initializeJob(); };
0513   // run
0514   std::shared_ptr<ConfigCache> globalBeginRun(edm::Run const& run, edm::EventSetup const& setup) const override;
0515   std::shared_ptr<PhiSymCache> globalBeginRunSummary(edm::Run const& run, edm::EventSetup const& setup) const override;
0516   void globalEndRun(edm::Run const& run, edm::EventSetup const& setup) const override{};
0517   void globalEndRunSummary(edm::Run const& run, edm::EventSetup const& setup, PhiSymCache* cache) const override{};
0518   void globalEndRunProduce(edm::Run& run, edm::EventSetup const& setup, PhiSymCache const* cache) const override;
0519   // stream
0520   std::unique_ptr<PhiSymCache> beginStream(edm::StreamID stream) const override;
0521   void streamBeginLuminosityBlock(edm::StreamID stream,
0522                                   edm::LuminosityBlock const& lumi,
0523                                   edm::EventSetup const& setup) const override;
0524   void streamBeginRun(edm::StreamID stream, edm::Run const& run, edm::EventSetup const& setup) const override;
0525   void streamEndRunSummary(edm::StreamID stream,
0526                            edm::Run const& run,
0527                            edm::EventSetup const& setup,
0528                            PhiSymCache* cache) const override;
0529   // event
0530   void accumulate(edm::StreamID stream, edm::Event const& event, edm::EventSetup const& setup) const override;
0531 
0532   // data members
0533   edm::ESGetToken<LHCInfo, LHCInfoRcd> lhcInfoTokenLumi_;
0534   edm::ESGetToken<EcalChannelStatus, EcalChannelStatusRcd> chStatusTokenRun_;
0535   edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geoTokenRun_;
0536 };
0537 
0538 //----------IMPLEMENTATION----------------------------------------------------------------
0539 EcalPhiSymRecHitProducerRun::EcalPhiSymRecHitProducerRun(const edm::ParameterSet& pSet)
0540     : EcalPhiSymRecHitProducerBase(pSet, consumesCollector()),
0541       lhcInfoTokenLumi_(esConsumes<edm::Transition::BeginLuminosityBlock>()),
0542       chStatusTokenRun_(esConsumes<edm::Transition::BeginRun>()),
0543       geoTokenRun_(esConsumes<edm::Transition::BeginRun>()) {
0544   produces<EcalPhiSymInfo, edm::Transition::EndRun>();
0545   produces<EcalPhiSymRecHitCollection, edm::Transition::EndRun>("EB");
0546   produces<EcalPhiSymRecHitCollection, edm::Transition::EndRun>("EE");
0547 }
0548 
0549 std::shared_ptr<ConfigCache> EcalPhiSymRecHitProducerRun::globalBeginRun(edm::Run const& run,
0550                                                                          edm::EventSetup const& setup) const {
0551   auto cache = std::make_shared<ConfigCache>();
0552 
0553   //---Reset cache with config values
0554   initializeConfigCache(setup, geoTokenRun_, cache);
0555 
0556   return cache;
0557 }
0558 
0559 std::shared_ptr<PhiSymCache> EcalPhiSymRecHitProducerRun::globalBeginRunSummary(edm::Run const& run,
0560                                                                                 edm::EventSetup const& setup) const {
0561   auto cache = std::make_shared<PhiSymCache>();
0562   initializePhiSymCache(setup, chStatusTokenRun_, runCache(run.index()), cache);
0563   return cache;
0564 }
0565 
0566 void EcalPhiSymRecHitProducerRun::globalEndRunProduce(edm::Run& run,
0567                                                       edm::EventSetup const& setup,
0568                                                       PhiSymCache const* cache) const {
0569   //---put the collections in the Runs tree
0570   auto ecalLumiInfo = std::make_unique<EcalPhiSymInfo>(cache->ecalLumiInfo);
0571   ecalLumiInfo->setMiscalibInfo(
0572       nMisCalib_ * 2, misCalibRangeEB_[0], misCalibRangeEB_[1], misCalibRangeEE_[0], misCalibRangeEE_[1]);
0573   auto recHitCollEB =
0574       std::make_unique<EcalPhiSymRecHitCollection>(cache->recHitCollEB.begin(), cache->recHitCollEB.end());
0575   auto recHitCollEE =
0576       std::make_unique<EcalPhiSymRecHitCollection>(cache->recHitCollEE.begin(), cache->recHitCollEE.end());
0577 
0578   run.put(std::move(ecalLumiInfo));
0579   run.put(std::move(recHitCollEB), "EB");
0580   run.put(std::move(recHitCollEE), "EE");
0581 }
0582 
0583 std::unique_ptr<PhiSymCache> EcalPhiSymRecHitProducerRun::beginStream(edm::StreamID stream) const {
0584   //---create stream cache
0585   return std::make_unique<PhiSymCache>();
0586 }
0587 
0588 void EcalPhiSymRecHitProducerRun::streamBeginRun(edm::StreamID stream,
0589                                                  edm::Run const& run,
0590                                                  edm::EventSetup const& setup) const {
0591   //---Reset stream cache
0592   initializeStreamCache(runCache(run.index()), streamCache(stream));
0593 }
0594 
0595 void EcalPhiSymRecHitProducerRun::streamBeginLuminosityBlock(edm::StreamID stream,
0596                                                              edm::LuminosityBlock const& lumi,
0597                                                              edm::EventSetup const& setup) const {
0598   //---Get LHC info
0599   //   LHCInfo only returns the correct luminosity information
0600   //   for each lumisection, accessing LHCInfo at the beginning
0601   //   of each run would return only the luminosity info of the
0602   //   first LS.
0603   //   Therefore the LHCInfo is accessed only by the first stream
0604   //   each time a new LS is processed
0605   if (stream.value() == 0) {
0606     const auto& lhcinfo = setup.getData(lhcInfoTokenLumi_);
0607     EcalPhiSymInfo thisLumi(0, 0, 0, 1, lhcinfo.fillNumber(), lhcinfo.delivLumi(), lhcinfo.recLumi());
0608 
0609     streamCache(stream)->ecalLumiInfo += thisLumi;
0610   }
0611 }
0612 
0613 void EcalPhiSymRecHitProducerRun::streamEndRunSummary(edm::StreamID stream,
0614                                                       edm::Run const& run,
0615                                                       edm::EventSetup const& setup,
0616                                                       PhiSymCache* scache) const {
0617   //---sum stream cache to run cache
0618   sumCache(scache, streamCache(stream));
0619 }
0620 
0621 void EcalPhiSymRecHitProducerRun::accumulate(edm::StreamID stream,
0622                                              edm::Event const& event,
0623                                              edm::EventSetup const& setup) const {
0624   processEvent(event, setup, runCache(event.getRun().index()), streamCache(stream));
0625 }
0626 
0627 DEFINE_FWK_MODULE(EcalPhiSymRecHitProducerLumi);
0628 DEFINE_FWK_MODULE(EcalPhiSymRecHitProducerRun);