Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-04 02:53:15

0001 #include "CalibFormats/CastorObjects/interface/CastorDbRecord.h"
0002 #include "CalibFormats/CastorObjects/interface/CastorDbService.h"
0003 #include "DataFormats/Common/interface/Handle.h"
0004 #include "DataFormats/HcalDetId/interface/HcalCastorDetId.h"
0005 #include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"
0006 #include "FWCore/Framework/interface/ConsumesCollector.h"
0007 #include "FWCore/Framework/interface/Event.h"
0008 #include "FWCore/Framework/interface/EventSetup.h"
0009 #include "FWCore/Framework/interface/ESWatcher.h"
0010 #include "FWCore/Framework/interface/FrameworkfwdMostUsed.h"
0011 #include "FWCore/Framework/interface/ProducesCollector.h"
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/ServiceRegistry/interface/Service.h"
0015 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0016 #include "FWCore/Utilities/interface/StreamID.h"
0017 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0018 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0019 #include "SimCalorimetry/CaloSimAlgos/interface/CaloShapeIntegrator.h"
0020 #include "SimCalorimetry/CaloSimAlgos/interface/CaloTDigitizer.h"
0021 #include "SimCalorimetry/CaloSimAlgos/interface/CaloHitResponse.h"
0022 #include "SimCalorimetry/CaloSimAlgos/interface/CaloTDigitizer.h"
0023 #include "SimCalorimetry/CastorSim/interface/CastorAmplifier.h"
0024 #include "SimCalorimetry/CastorSim/interface/CastorCoderFactory.h"
0025 #include "SimCalorimetry/CastorSim/interface/CastorDigitizerTraits.h"
0026 #include "SimCalorimetry/CastorSim/interface/CastorElectronicsSim.h"
0027 #include "SimCalorimetry/CastorSim/interface/CastorHitCorrection.h"
0028 #include "SimCalorimetry/CastorSim/interface/CastorHitFilter.h"
0029 #include "SimCalorimetry/CastorSim/interface/CastorShape.h"
0030 #include "SimCalorimetry/CastorSim/interface/CastorSimParameterMap.h"
0031 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
0032 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
0033 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixMod.h"
0034 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
0035 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0036 
0037 #include <vector>
0038 
0039 namespace CLHEP {
0040   class HepRandomEngine;
0041 }
0042 
0043 class CastorDigiProducer : public DigiAccumulatorMixMod {
0044 public:
0045   explicit CastorDigiProducer(const edm::ParameterSet &ps, edm::ProducesCollector, edm::ConsumesCollector &iC);
0046   ~CastorDigiProducer() override;
0047 
0048   void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override;
0049   void accumulate(edm::Event const &e, edm::EventSetup const &c) override;
0050   void accumulate(PileUpEventPrincipal const &e, edm::EventSetup const &c, edm::StreamID const &) override;
0051   void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override;
0052 
0053 private:
0054   void accumulateCaloHits(std::vector<PCaloHit> const &, int bunchCrossing);
0055 
0056   /// fills the vectors for each subdetector
0057   void sortHits(const edm::PCaloHitContainer &hits);
0058   /// some hits in each subdetector, just for testing purposes
0059   void fillFakeHits();
0060   /// make sure the digitizer has the correct list of all cells that
0061   /// exist in the geometry
0062   void checkGeometry(const edm::EventSetup &eventSetup);
0063 
0064   const edm::ESGetToken<CastorDbService, CastorDbRecord> theConditionsToken;
0065   const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> theGeometryToken;
0066   edm::ESWatcher<CaloGeometryRecord> theGeometryWatcher;
0067   const edm::InputTag theHitsProducerTag;
0068   const edm::EDGetTokenT<std::vector<PCaloHit>> hitToken_;
0069 
0070   /** Reconstruction algorithm*/
0071   typedef CaloTDigitizer<CastorDigitizerTraits> CastorDigitizer;
0072 
0073   CastorSimParameterMap *theParameterMap;
0074   CaloVShape *theCastorShape;
0075   CaloVShape *theCastorIntegratedShape;
0076 
0077   CaloHitResponse *theCastorResponse;
0078 
0079   CastorAmplifier *theAmplifier;
0080   CastorCoderFactory *theCoderFactory;
0081   CastorElectronicsSim *theElectronicsSim;
0082 
0083   CastorHitFilter theCastorHitFilter;
0084 
0085   CastorHitCorrection *theHitCorrection;
0086 
0087   CastorDigitizer *theCastorDigitizer;
0088 
0089   std::vector<PCaloHit> theCastorHits;
0090 
0091   CLHEP::HepRandomEngine *randomEngine_ = nullptr;
0092 };
0093 
0094 CastorDigiProducer::CastorDigiProducer(const edm::ParameterSet &ps,
0095                                        edm::ProducesCollector producesCollector,
0096                                        edm::ConsumesCollector &iC)
0097     : theConditionsToken(iC.esConsumes()),
0098       theGeometryToken(iC.esConsumes()),
0099       theHitsProducerTag(ps.getParameter<edm::InputTag>("hitsProducer")),
0100       hitToken_(iC.consumes<std::vector<PCaloHit>>(theHitsProducerTag)),
0101       theParameterMap(new CastorSimParameterMap(ps)),
0102       theCastorShape(new CastorShape()),
0103       theCastorIntegratedShape(new CaloShapeIntegrator(theCastorShape)),
0104       theCastorResponse(new CaloHitResponse(theParameterMap, theCastorIntegratedShape)),
0105       theAmplifier(nullptr),
0106       theCoderFactory(nullptr),
0107       theElectronicsSim(nullptr),
0108       theHitCorrection(nullptr),
0109       theCastorDigitizer(nullptr),
0110       theCastorHits() {
0111   producesCollector.produces<CastorDigiCollection>();
0112 
0113   theCastorResponse->setHitFilter(&theCastorHitFilter);
0114 
0115   bool doTimeSlew = ps.getParameter<bool>("doTimeSlew");
0116   if (doTimeSlew) {
0117     // no time slewing for HF
0118     theCastorResponse->setHitCorrection(theHitCorrection);
0119   }
0120 
0121   bool doNoise = ps.getParameter<bool>("doNoise");
0122   theAmplifier = new CastorAmplifier(theParameterMap, doNoise);
0123   theCoderFactory = new CastorCoderFactory(CastorCoderFactory::DB);
0124   theElectronicsSim = new CastorElectronicsSim(theAmplifier, theCoderFactory);
0125 
0126   theCastorDigitizer = new CastorDigitizer(theCastorResponse, theElectronicsSim, doNoise);
0127 
0128   edm::Service<edm::RandomNumberGenerator> rng;
0129   if (!rng.isAvailable()) {
0130     throw cms::Exception("Configuration") << "CastorDigiProducer requires the RandomNumberGeneratorService\n"
0131                                              "which is not present in the configuration file.  You must add the "
0132                                              "service\n"
0133                                              "in the configuration file or remove the modules that require it.";
0134   }
0135 }
0136 
0137 CastorDigiProducer::~CastorDigiProducer() {
0138   delete theCastorDigitizer;
0139   delete theParameterMap;
0140   delete theCastorShape;
0141   delete theCastorIntegratedShape;
0142   delete theCastorResponse;
0143   delete theElectronicsSim;
0144   delete theAmplifier;
0145   delete theCoderFactory;
0146   delete theHitCorrection;
0147 }
0148 
0149 void CastorDigiProducer::initializeEvent(edm::Event const &event, edm::EventSetup const &eventSetup) {
0150   // get the appropriate gains, noises, & widths for this event
0151   const CastorDbService *conditions = &eventSetup.getData(theConditionsToken);
0152   theAmplifier->setDbService(conditions);
0153   theCoderFactory->setDbService(conditions);
0154   theParameterMap->setDbService(conditions);
0155 
0156   // Cache random number engine
0157   edm::Service<edm::RandomNumberGenerator> rng;
0158   randomEngine_ = &rng->getEngine(event.streamID());
0159 
0160   edm::LogInfo("CastorDigiProducer") << "checking the geometry...";
0161 
0162   // get the correct geometry
0163   checkGeometry(eventSetup);
0164 
0165   theCastorHits.clear();
0166 
0167   theCastorDigitizer->initializeHits();
0168 }
0169 
0170 void CastorDigiProducer::accumulateCaloHits(std::vector<PCaloHit> const &hcalHits, int bunchCrossing) {
0171   // fillFakeHits();
0172 
0173   if (theHitCorrection != nullptr) {
0174     theHitCorrection->fillChargeSums(hcalHits);
0175   }
0176   theCastorDigitizer->add(hcalHits, bunchCrossing, randomEngine_);
0177 }
0178 
0179 void CastorDigiProducer::accumulate(edm::Event const &e, edm::EventSetup const &) {
0180   // Step A: Get and accumulate digitized hits
0181   const edm::Handle<std::vector<PCaloHit>> &castorHandle = e.getHandle(hitToken_);
0182 
0183   accumulateCaloHits(*castorHandle.product(), 0);
0184 }
0185 
0186 void CastorDigiProducer::accumulate(PileUpEventPrincipal const &e,
0187                                     edm::EventSetup const &,
0188                                     edm::StreamID const &streamID) {
0189   // Step A: Get and accumulate digitized hits
0190   edm::Handle<std::vector<PCaloHit>> castorHandle;
0191   e.getByLabel(theHitsProducerTag, castorHandle);
0192 
0193   accumulateCaloHits(*castorHandle.product(), e.bunchCrossing());
0194 }
0195 
0196 void CastorDigiProducer::finalizeEvent(edm::Event &e, const edm::EventSetup &eventSetup) {
0197   // Step B: Create empty output
0198 
0199   std::unique_ptr<CastorDigiCollection> castorResult(new CastorDigiCollection());
0200 
0201   // Step C: Invoke the algorithm, getting back outputs.
0202   theCastorDigitizer->run(*castorResult, randomEngine_);
0203 
0204   edm::LogInfo("CastorDigiProducer") << "HCAL/Castor digis   : " << castorResult->size();
0205 
0206   // Step D: Put outputs into event
0207   e.put(std::move(castorResult));
0208 
0209   randomEngine_ = nullptr;  // to prevent access outside event
0210 }
0211 
0212 void CastorDigiProducer::sortHits(const edm::PCaloHitContainer &hits) {
0213   for (edm::PCaloHitContainer::const_iterator hitItr = hits.begin(); hitItr != hits.end(); ++hitItr) {
0214     DetId detId = hitItr->id();
0215     if (detId.det() == DetId::Calo && detId.subdetId() == HcalCastorDetId::SubdetectorId) {
0216       theCastorHits.push_back(*hitItr);
0217     } else {
0218       edm::LogError("CastorDigiProducer") << "Bad Hit subdetector " << detId.subdetId();
0219     }
0220   }
0221 }
0222 
0223 void CastorDigiProducer::fillFakeHits() {
0224   HcalCastorDetId castorDetId(HcalCastorDetId::Section(2), true, 1, 1);
0225 
0226   theCastorHits.emplace_back(castorDetId.rawId(), 50.0, 0.);
0227 }
0228 
0229 void CastorDigiProducer::checkGeometry(const edm::EventSetup &eventSetup) {
0230   if (theGeometryWatcher.check(eventSetup)) {
0231     const CaloGeometry *geometry = &eventSetup.getData(theGeometryToken);
0232     theCastorResponse->setGeometry(geometry);
0233 
0234     const std::vector<DetId> &castorCells = geometry->getValidDetIds(DetId::Calo, HcalCastorDetId::SubdetectorId);
0235 
0236     // // edm::LogInfo("CastorDigiProducer") << "CastorDigiProducer::CheckGeometry number of cells:" << castorCells.size()
0237     ;
0238     theCastorDigitizer->setDetIds(castorCells);
0239   }
0240 }
0241 
0242 #include "FWCore/Framework/interface/MakerMacros.h"
0243 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixModFactory.h"
0244 
0245 DEFINE_DIGI_ACCUMULATOR(CastorDigiProducer);