File indexing completed on 2024-04-06 12:29:21
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
0057 void sortHits(const edm::PCaloHitContainer &hits);
0058
0059 void fillFakeHits();
0060
0061
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
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
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
0151 const CastorDbService *conditions = &eventSetup.getData(theConditionsToken);
0152 theAmplifier->setDbService(conditions);
0153 theCoderFactory->setDbService(conditions);
0154 theParameterMap->setDbService(conditions);
0155
0156
0157 edm::Service<edm::RandomNumberGenerator> rng;
0158 randomEngine_ = &rng->getEngine(event.streamID());
0159
0160 edm::LogInfo("CastorDigiProducer") << "checking the geometry...";
0161
0162
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
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
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
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
0198
0199 std::unique_ptr<CastorDigiCollection> castorResult(new CastorDigiCollection());
0200
0201
0202 theCastorDigitizer->run(*castorResult, randomEngine_);
0203
0204 edm::LogInfo("CastorDigiProducer") << "HCAL/Castor digis : " << castorResult->size();
0205
0206
0207 e.put(std::move(castorResult));
0208
0209 randomEngine_ = nullptr;
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
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);