From fcbee47ce6bb3fc3706e21aff0f09b7886e54bae Mon Sep 17 00:00:00 2001 From: Matti Kortelainen Date: Fri, 16 Mar 2018 11:29:35 +0100 Subject: [PATCH] Enable HGCal in phase2 premixing --- .../python/SimL1EmulatorDM_cff.py | 3 + .../HGCDigi/interface/PHGCSimAccumulator.h | 156 ++++++++++++++++++ DataFormats/HGCDigi/src/classes.h | 9 + DataFormats/HGCDigi/src/classes_def.xml | 7 + .../Configuration/python/SimL1Emulator_cff.py | 4 + .../python/HGCalUncalibRecHit_cfi.py | 7 + .../interface/HGCDigitizer.h | 11 ++ .../HGCalSimProducers/plugins/BuildFile.xml | 1 + .../plugins/HGCDigiProducer.cc | 17 +- .../plugins/PreMixingHGCalWorker.cc | 83 ++++++++++ .../python/hgcalDigitizer_cfi.py | 12 ++ .../HGCalSimProducers/src/HGCDigitizer.cc | 95 ++++++++++- .../python/SimGeneral_EventContent_cff.py | 17 +- .../MixingModule/python/digitizers_cfi.py | 7 +- .../interface/PreMixingWorker.h | 1 + .../plugins/PreMixingModule.cc | 3 + .../python/mixOne_premix_on_sim_cfi.py | 30 +++- .../plugins/HGCalDigiValidation.cc | 2 +- .../python/digiValidation_cff.py | 4 + .../python/hgcalDigiValidationEE_cfi.py | 6 + 20 files changed, 454 insertions(+), 21 deletions(-) create mode 100644 DataFormats/HGCDigi/interface/PHGCSimAccumulator.h create mode 100644 SimCalorimetry/HGCalSimProducers/plugins/PreMixingHGCalWorker.cc create mode 100644 Validation/HGCalValidation/python/hgcalDigiValidationEE_cfi.py diff --git a/Configuration/StandardSequences/python/SimL1EmulatorDM_cff.py b/Configuration/StandardSequences/python/SimL1EmulatorDM_cff.py index bbcaf50f5c816..cd6377573bb18 100644 --- a/Configuration/StandardSequences/python/SimL1EmulatorDM_cff.py +++ b/Configuration/StandardSequences/python/SimL1EmulatorDM_cff.py @@ -12,6 +12,9 @@ # simHcalTechTrigDigis.ttpDigiCollection = "DMHcalTTPDigis" # +hgcalTriggerPrimitiveDigiProducer.eeDigis.setModuleLabel("mixData") +hgcalTriggerPrimitiveDigiProducer.fhDigis.setModuleLabel("mixData") +hgcalTriggerPrimitiveDigiProducer.bhDigis.setModuleLabel("mixData") from Configuration.Eras.Modifier_stage2L1Trigger_cff import stage2L1Trigger if not stage2L1Trigger.isChosen(): diff --git a/DataFormats/HGCDigi/interface/PHGCSimAccumulator.h b/DataFormats/HGCDigi/interface/PHGCSimAccumulator.h new file mode 100644 index 0000000000000..ab4b6c479660f --- /dev/null +++ b/DataFormats/HGCDigi/interface/PHGCSimAccumulator.h @@ -0,0 +1,156 @@ +#ifndef DataFormats_HGCDigi_PHGCSimAccumulator_h +#define DataFormats_HGCDigi_PHGCSimAccumulator_h + +#include "DataFormats/DetId/interface/DetId.h" + +#include +#include + +class PHGCSimAccumulator { +public: + // These two structs are public only because of dictionary generation + class DetIdSize { + public: + // Use top 27 bits to hold the details of the DetId + constexpr static unsigned detIdOffset = 5; + constexpr static unsigned detIdMask = 0x7ffffff; + // Use the last 5 bits to index 2x15 elements + constexpr static unsigned sizeOffset = 27; + constexpr static unsigned sizeMask = 0x1f; + // With this arrangement increasing the size component is faster + + DetIdSize(): detIdSize_(0) {} + DetIdSize(unsigned int detId): detIdSize_(detId << detIdOffset) {} + + void increaseSize() { + assert(size()+1 < 1<> detIdOffset; } + unsigned int size() const { return detIdSize_ & sizeMask; } + + private: + unsigned int detIdSize_; + }; + class Data { + public: + constexpr static unsigned energyOffset = 15; + constexpr static unsigned energyMask = 0x1; + constexpr static unsigned sampleOffset = 11; + constexpr static unsigned sampleMask = 0xf; + constexpr static unsigned dataOffset = 0; + constexpr static unsigned dataMask = 0x7ff; + + Data(): data_(0) {} + Data(unsigned short ei, unsigned short si, unsigned short d): + data_((ei << energyOffset) | (si << sampleOffset) | d) + {} + + unsigned int energyIndex() const { return data_ >> energyOffset; } + unsigned int sampleIndex() const { return (data_ >> sampleOffset) & sampleMask; } + unsigned int data() const { return data_ & dataMask; } + + private: + unsigned short data_; + }; + + PHGCSimAccumulator() = default; + PHGCSimAccumulator(unsigned int detId): detSubdetId_(detId >> DetId::kSubdetOffset) {} + ~PHGCSimAccumulator() = default; + + void reserve(size_t size) { + detIdSize_.reserve(size); + data_.reserve(size); + } + + void shrink_to_fit() { + detIdSize_.shrink_to_fit(); + data_.shrink_to_fit(); + } + + void emplace_back(unsigned int detId, unsigned short energyIndex, unsigned short sampleIndex, unsigned short data) { + assert( (detId >> DetId::kSubdetOffset) == detSubdetId_ ); + + // TODO: add checks + if(detIdSize_.empty() || detIdSize_.back().detIdDetails() != (detId & DetIdSize::detIdMask)) { + detIdSize_.emplace_back(detId); + } + data_.emplace_back(energyIndex, sampleIndex, data); + detIdSize_.back().increaseSize(); + } + + class TmpElem { + public: + TmpElem(unsigned int detId, Data data): detId_(detId), data_(data) {} + + unsigned int detId() const { return detId_; } + unsigned short energyIndex() const { return data_.energyIndex(); } + unsigned short sampleIndex() const { return data_.sampleIndex(); } + unsigned short data() const { return data_.data(); } + private: + unsigned int detId_; + Data data_; + }; + + class const_iterator { + public: + // begin + const_iterator(const PHGCSimAccumulator *acc): + acc_(acc), iDet_(0), iData_(0), + endData_(acc->detIdSize_.empty() ? 0 : acc->detIdSize_.front().size()) + {} + + // end + const_iterator(const PHGCSimAccumulator *acc, unsigned int detSize, unsigned int dataSize): + acc_(acc), iDet_(detSize), iData_(dataSize), endData_(0) + {} + + bool operator==(const const_iterator& other) const { + return iDet_ == other.iDet_ && iData_ == other.iData_; + } + bool operator!=(const const_iterator& other) const { + return !operator==(other); + } + const_iterator& operator++() { + ++iData_; + if(iData_ == endData_) { + ++iDet_; + endData_ += (iDet_ == acc_->detIdSize_.size()) ? 0 : acc_->detIdSize_[iDet_].size(); + } + return *this; + } + const_iterator operator++(int) { + auto tmp = *this; + ++(*this); + return tmp; + } + TmpElem operator*() { + return TmpElem((acc_->detSubdetId_ << DetId::kSubdetOffset) | acc_->detIdSize_[iDet_].detIdDetails(), + acc_->data_[iData_]); + } + + private: + const PHGCSimAccumulator *acc_; + unsigned int iDet_; + unsigned int iData_; + unsigned int endData_; + }; + + TmpElem back() const { + return TmpElem((detSubdetId_ << DetId::kSubdetOffset) | detIdSize_.back().detIdDetails(), + data_.back()); + } + + const_iterator cbegin() const { return const_iterator(this); } + const_iterator begin() const { return cbegin(); } + const_iterator cend() const { return const_iterator(this, detIdSize_.size(), data_.size()); } + const_iterator end() const { return cend(); } + +private: + std::vector detIdSize_; + std::vector data_; + unsigned short detSubdetId_ = 0; +}; + +#endif diff --git a/DataFormats/HGCDigi/src/classes.h b/DataFormats/HGCDigi/src/classes.h index 6ed753a87920e..76593960a9ec6 100644 --- a/DataFormats/HGCDigi/src/classes.h +++ b/DataFormats/HGCDigi/src/classes.h @@ -1,5 +1,6 @@ #include #include "DataFormats/HGCDigi/interface/HGCDigiCollections.h" +#include "DataFormats/HGCDigi/interface/PHGCSimAccumulator.h" namespace DataFormats_HGCDigi { struct dictionary { @@ -33,6 +34,14 @@ namespace DataFormats_HGCDigi { edm::Wrapper< edm::SortedCollection< HGCDataFrame > > prodHGCHEDataFrames; HGCHEDigiCollection dcHGCHE; edm::Wrapper wdcHGCHE; + + // Sim cell accumulator (for premixing) + PHGCSimAccumulator saHGC; + PHGCSimAccumulator::Data saHGCdata; + PHGCSimAccumulator::DetIdSize saHGCdis; + std::vector vsaHGCdata; + std::vector vsaHGCdis; + edm::Wrapper wsaHGC; }; } diff --git a/DataFormats/HGCDigi/src/classes_def.xml b/DataFormats/HGCDigi/src/classes_def.xml index 27a3e1a6ddbed..9d879f9d3fab3 100644 --- a/DataFormats/HGCDigi/src/classes_def.xml +++ b/DataFormats/HGCDigi/src/classes_def.xml @@ -27,4 +27,11 @@ + + + + + + + diff --git a/L1Trigger/Configuration/python/SimL1Emulator_cff.py b/L1Trigger/Configuration/python/SimL1Emulator_cff.py index 2c9a4bacf5387..e5ecef2b88ce6 100644 --- a/L1Trigger/Configuration/python/SimL1Emulator_cff.py +++ b/L1Trigger/Configuration/python/SimL1Emulator_cff.py @@ -65,9 +65,13 @@ phase2_hgcal.toReplaceWith( SimL1Emulator , _phase2_siml1emulator ) # If PreMixing, don't run these modules during first step +# TODO: Do we actually need anything from here run in stage1? from Configuration.ProcessModifiers.premix_stage1_cff import premix_stage1 premix_stage1.toReplaceWith(SimL1Emulator, SimL1Emulator.copyAndExclude([ SimL1TCalorimeter, SimL1TechnicalTriggers, SimL1TGlobal ])) +(premix_stage1 & phase2_hgcal).toReplaceWith(SimL1Emulator, SimL1Emulator.copyAndExclude([ + hgcalTriggerPrimitives +])) diff --git a/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py b/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py index 88452c3f558e8..8e9203dd81845 100644 --- a/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py +++ b/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py @@ -47,3 +47,10 @@ algo = cms.string("HGCalUncalibRecHitWorkerWeights") ) + +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(HGCalUncalibRecHit, + HGCEEdigiCollection = 'mixData:HGCDigisEE', + HGCHEFdigiCollection = 'mixData:HGCDigisHEfront', + HGCHEBdigiCollection = 'mixData:HGCDigisHEback', +) diff --git a/SimCalorimetry/HGCalSimProducers/interface/HGCDigitizer.h b/SimCalorimetry/HGCalSimProducers/interface/HGCDigitizer.h index 97c4189e5f890..38757297cd988 100644 --- a/SimCalorimetry/HGCalSimProducers/interface/HGCDigitizer.h +++ b/SimCalorimetry/HGCalSimProducers/interface/HGCDigitizer.h @@ -12,6 +12,7 @@ #include "SimCalorimetry/HGCalSimProducers/interface/HGCHEfrontDigitizer.h" #include "SimCalorimetry/HGCalSimProducers/interface/HGCHEbackDigitizer.h" #include "DataFormats/HGCDigi/interface/HGCDigiCollections.h" +#include "DataFormats/HGCDigi/interface/PHGCSimAccumulator.h" #include "FWCore/Framework/interface/ESHandle.h" #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h" @@ -55,6 +56,8 @@ class HGCDigitizer void accumulate(PileUpEventPrincipal const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre); template void accumulate(edm::Handle const &hits, int bxCrossing,const GEOM *geom, CLHEP::HepRandomEngine* hre); + // for premixing + void accumulate(const PHGCSimAccumulator& simAccumulator); /** @short actions at the start/end of event @@ -83,6 +86,14 @@ private : //digitization type (it's up to the specializations to decide it's meaning) int digitizationType_; + // if true, we're running mixing in premixing stage1 and have to produce the output differently + bool premixStage1_; + + // Minimum charge threshold for premixing stage1 + double premixStage1MinCharge_; + // Maximum charge for packing in premixing stage1 + double premixStage1MaxCharge_; + //handle sim hits int maxSimHitsAccTime_; double bxTime_, ev_per_eh_pair_; diff --git a/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml b/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml index 5d7f01363c6a1..f98156c2d4f18 100644 --- a/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml +++ b/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml @@ -11,6 +11,7 @@ + diff --git a/SimCalorimetry/HGCalSimProducers/plugins/HGCDigiProducer.cc b/SimCalorimetry/HGCalSimProducers/plugins/HGCDigiProducer.cc index 69ba7c63db1b5..2950cb47c06f2 100644 --- a/SimCalorimetry/HGCalSimProducers/plugins/HGCDigiProducer.cc +++ b/SimCalorimetry/HGCalSimProducers/plugins/HGCDigiProducer.cc @@ -12,12 +12,17 @@ HGCDigiProducer::HGCDigiProducer(edm::ParameterSet const& pset, edm::ProducerBas edm::ConsumesCollector& iC) : HGCDigiProducer(pset, iC) { - if( theDigitizer_.producesEEDigis() ) - mixMod.produces(theDigitizer_.digiCollection()); - if( theDigitizer_.producesHEfrontDigis() ) - mixMod.produces(theDigitizer_.digiCollection()); - if( theDigitizer_.producesHEbackDigis() ) - mixMod.produces(theDigitizer_.digiCollection()); + if(pset.getParameter("premixStage1")) { + mixMod.produces(theDigitizer_.digiCollection()); + } + else { + if( theDigitizer_.producesEEDigis() ) + mixMod.produces(theDigitizer_.digiCollection()); + if( theDigitizer_.producesHEfrontDigis() ) + mixMod.produces(theDigitizer_.digiCollection()); + if( theDigitizer_.producesHEbackDigis() ) + mixMod.produces(theDigitizer_.digiCollection()); + } } HGCDigiProducer::HGCDigiProducer(edm::ParameterSet const& pset, edm::ConsumesCollector& iC) : diff --git a/SimCalorimetry/HGCalSimProducers/plugins/PreMixingHGCalWorker.cc b/SimCalorimetry/HGCalSimProducers/plugins/PreMixingHGCalWorker.cc new file mode 100644 index 0000000000000..8e5a44c97744c --- /dev/null +++ b/SimCalorimetry/HGCalSimProducers/plugins/PreMixingHGCalWorker.cc @@ -0,0 +1,83 @@ +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/ProducerBase.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h" + +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Utilities/interface/RandomNumberGenerator.h" + +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/HGCDigi/interface/PHGCSimAccumulator.h" +#include "SimCalorimetry/HGCalSimProducers/interface/HGCDigitizer.h" + +#include "SimGeneral/PreMixingModule/interface/PreMixingWorker.h" +#include "SimGeneral/PreMixingModule/interface/PreMixingWorkerFactory.h" + +class PreMixingHGCalWorker: public PreMixingWorker { +public: + PreMixingHGCalWorker(const edm::ParameterSet& ps, edm::ProducerBase& producer, edm::ConsumesCollector&& iC); + ~PreMixingHGCalWorker() override = default; + + PreMixingHGCalWorker(const PreMixingHGCalWorker&) = delete; + PreMixingHGCalWorker& operator=(const PreMixingHGCalWorker&) = delete; + + void beginRun(const edm::Run& run, const edm::EventSetup& ES) override; + void endRun() override; + void initializeEvent(const edm::Event &e, const edm::EventSetup& ES) override {} + void addSignals(const edm::Event &e, const edm::EventSetup& ES) override; + void addPileups(const PileUpEventPrincipal&, const edm::EventSetup& ES) override; + void put(edm::Event &e,const edm::EventSetup& ES, std::vector const& ps, int bs) override; + +private: + edm::EDGetTokenT signalToken_; + + edm::InputTag pileInputTag_; + + HGCDigitizer digitizer_; +}; + +PreMixingHGCalWorker::PreMixingHGCalWorker(const edm::ParameterSet& ps, edm::ProducerBase& producer, edm::ConsumesCollector&& iC): + signalToken_(iC.consumes(ps.getParameter("digiTagSig"))), + pileInputTag_(ps.getParameter("pileInputTag")), + digitizer_(ps, iC) +{ + if(digitizer_.producesEEDigis()) { + producer.produces(digitizer_.digiCollection()); + } + if(digitizer_.producesHEfrontDigis()) { + producer.produces(digitizer_.digiCollection()); + } + if(digitizer_.producesHEbackDigis()) { + producer.produces(digitizer_.digiCollection()); + } +} + +void PreMixingHGCalWorker::beginRun(const edm::Run& run, const edm::EventSetup& ES) { + digitizer_.beginRun(ES); +} + +void PreMixingHGCalWorker::endRun() { + digitizer_.endRun(); +} + +void PreMixingHGCalWorker::addSignals(const edm::Event &e,const edm::EventSetup& ES) { + edm::Handle handle; + e.getByToken(signalToken_, handle); + digitizer_.accumulate(*handle); +} + +void PreMixingHGCalWorker::addPileups(const PileUpEventPrincipal& pep, const edm::EventSetup& ES) { + edm::Handle handle; + pep.getByLabel(pileInputTag_, handle); + digitizer_.accumulate(*handle); +} + +void PreMixingHGCalWorker::put(edm::Event &e,const edm::EventSetup& ES, std::vector const& ps, int bs) { + edm::Service rng; + digitizer_.finalizeEvent(e, ES, &rng->getEngine(e.streamID())); +} + +DEFINE_EDM_PLUGIN(PreMixingWorkerFactory, PreMixingHGCalWorker, "PreMixingHGCalWorker"); diff --git a/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py b/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py index 3f2a478ac4d7c..2aadd1662b410 100644 --- a/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py +++ b/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py @@ -34,6 +34,9 @@ tofDelay = cms.double(5), digitizationType = cms.uint32(0), makeDigiSimLinks = cms.bool(False), + premixStage1 = cms.bool(False), + premixStage1MinCharge = cms.double(0), + premixStage1MaxCharge = cms.double(1e6), useAllChannels = cms.bool(True), verbosity = cms.untracked.uint32(0), digiCfg = cms.PSet( @@ -95,6 +98,9 @@ tofDelay = cms.double(5), digitizationType = cms.uint32(0), makeDigiSimLinks = cms.bool(False), + premixStage1 = cms.bool(False), + premixStage1MinCharge = cms.double(0), + premixStage1MaxCharge = cms.double(1e6), useAllChannels = cms.bool(True), verbosity = cms.untracked.uint32(0), digiCfg = cms.PSet( @@ -155,6 +161,9 @@ tofDelay = cms.double(1), digitizationType = cms.uint32(1), makeDigiSimLinks = cms.bool(False), + premixStage1 = cms.bool(False), + premixStage1MinCharge = cms.double(0), + premixStage1MaxCharge = cms.double(1e6), useAllChannels = cms.bool(True), verbosity = cms.untracked.uint32(0), digiCfg = cms.PSet( @@ -178,6 +187,9 @@ ) ) ) +from Configuration.ProcessModifiers.premix_stage1_cff import premix_stage1 +for _m in [hgceeDigitizer, hgchefrontDigitizer, hgchebackDigitizer]: + premix_stage1.toModify(_m, premixStage1 = True) #function to set noise to aged HGCal endOfLifeCCEs = [0.5, 0.5, 0.7] diff --git a/SimCalorimetry/HGCalSimProducers/src/HGCDigitizer.cc b/SimCalorimetry/HGCalSimProducers/src/HGCDigitizer.cc index a752714d9ac5f..c6b5519b9afb7 100644 --- a/SimCalorimetry/HGCalSimProducers/src/HGCDigitizer.cc +++ b/SimCalorimetry/HGCalSimProducers/src/HGCDigitizer.cc @@ -15,6 +15,7 @@ #include "Geometry/Records/interface/CaloGeometryRecord.h" #include "Geometry/HGCalCommonData/interface/HGCalGeometryMode.h" #include "Geometry/HcalCommonData/interface/HcalHitRelabeller.h" +#include "DataFormats/Math/interface/liblogintpack.h" #include #include @@ -125,6 +126,59 @@ namespace { return 1.f; } + // Dumps the internals of the SimHit accumulator to the digis for premixing + void saveSimHitAccumulator(PHGCSimAccumulator& simResult, const hgc::HGCSimHitDataAccumulator& simData, const std::unordered_set& validIds, const float minCharge, const float maxCharge) { + constexpr auto nEnergies = std::tuple_size::value; + static_assert(nEnergies <= PHGCSimAccumulator::Data::energyMask+1, "PHGCSimAccumulator bit pattern needs to updated"); + static_assert(hgc_digi::nSamples <= PHGCSimAccumulator::Data::sampleMask+1, "PHGCSimAccumulator bit pattern needs to updated"); + + const float minPackChargeLog = minCharge > 0.f ? std::log(minCharge) : -2; + const float maxPackChargeLog = std::log(maxCharge); + constexpr uint16_t base = 1<second.hit_info[iEn]; + for(size_t iSample = 0; iSample < hgc_digi::nSamples; ++iSample) { + if(samples[iSample] > minCharge) { + const auto packed = logintpack::pack16log(samples[iSample], minPackChargeLog, maxPackChargeLog, base); + simResult.emplace_back(id.rawId(), iEn, iSample, packed); + } + } + } + } + simResult.shrink_to_fit(); + } + + // Loads the internals of the SimHit accumulator from the digis for premixing + void loadSimHitAccumulator(hgc::HGCSimHitDataAccumulator& simData, const PHGCSimAccumulator& simAccumulator, const float minCharge, const float maxCharge, bool setIfZero) { + const float minPackChargeLog = minCharge > 0.f ? std::log(minCharge) : -2; + const float maxPackChargeLog = std::log(maxCharge); + constexpr uint16_t base = 1<second.hit_info; + + size_t iEn = detIdIndexHitInfo.energyIndex(); + size_t iSample = detIdIndexHitInfo.sampleIndex(); + + float value = logintpack::unpack16log(detIdIndexHitInfo.data(), minPackChargeLog, maxPackChargeLog, base); + + if(iEn == 0 || !setIfZero) { + hit_info[iEn][iSample] += value; + } + else if(hit_info[iEn][iSample] == 0) { + hit_info[iEn][iSample] = value; + } + } + } } // @@ -144,6 +198,9 @@ HGCDigitizer::HGCDigitizer(const edm::ParameterSet& ps, digitizationType_ = ps.getParameter< uint32_t >("digitizationType"); verbosity_ = ps.getUntrackedParameter< uint32_t >("verbosity",0); tofDelay_ = ps.getParameter< double >("tofDelay"); + premixStage1_ = ps.getParameter("premixStage1"); + premixStage1MinCharge_ = ps.getParameter("premixStage1MinCharge"); + premixStage1MaxCharge_ = ps.getParameter("premixStage1MaxCharge"); std::unordered_set().swap(validIds_); @@ -229,27 +286,34 @@ void HGCDigitizer::finalizeEvent(edm::Event& e, edm::EventSetup const& es, CLHEP const double thisOcc = simHitAccumulator_->size()/((double)validIds_.size()); averageOccupancies_[idx] = (averageOccupancies_[idx]*(nEvents_-1) + thisOcc)/nEvents_; - if( producesEEDigis() ) - { + if(premixStage1_) { + std::unique_ptr simResult; + if(!simHitAccumulator_->empty()) { + simResult = std::make_unique(simHitAccumulator_->begin()->first); + saveSimHitAccumulator(*simResult, *simHitAccumulator_, validIds_, premixStage1MinCharge_, premixStage1MaxCharge_); + } + e.put(std::move(simResult), digiCollection()); + } + else { + if( producesEEDigis() ) { std::unique_ptr digiResult(new HGCEEDigiCollection() ); theHGCEEDigitizer_->run(digiResult,*simHitAccumulator_,theGeom,validIds_,digitizationType_, hre); edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " EE hits"; e.put(std::move(digiResult),digiCollection()); } - if( producesHEfrontDigis()) - { + if( producesHEfrontDigis()) { std::unique_ptr digiResult(new HGCHEDigiCollection() ); theHGCHEfrontDigitizer_->run(digiResult,*simHitAccumulator_,theGeom,validIds_,digitizationType_, hre); edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " HE front hits"; e.put(std::move(digiResult),digiCollection()); } - if( producesHEbackDigis() ) - { + if( producesHEbackDigis() ) { std::unique_ptr digiResult(new HGCBHDigiCollection() ); theHGCHEbackDigitizer_->run(digiResult,*simHitAccumulator_,theGeom,validIds_,digitizationType_, hre); edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " HE back hits"; e.put(std::move(digiResult),digiCollection()); } + } hgc::HGCSimHitDataAccumulator().swap(*simHitAccumulator_); } @@ -453,6 +517,25 @@ void HGCDigitizer::accumulate(edm::Handle const &hits, hitRefs.clear(); } +void HGCDigitizer::accumulate(const PHGCSimAccumulator& simAccumulator) { + //configuration to apply for the computation of time-of-flight + bool weightToAbyEnergy(false); + switch( mySubDet_ ) { + case ForwardSubdetector::HGCEE: + weightToAbyEnergy = theHGCEEDigitizer_->toaModeByEnergy(); + break; + case ForwardSubdetector::HGCHEF: + weightToAbyEnergy = theHGCHEfrontDigitizer_->toaModeByEnergy(); + break; + case ForwardSubdetector::HGCHEB: + weightToAbyEnergy = theHGCHEbackDigitizer_->toaModeByEnergy(); + break; + default: + break; + } + loadSimHitAccumulator(*simHitAccumulator_, simAccumulator, premixStage1MinCharge_, premixStage1MaxCharge_, !weightToAbyEnergy); +} + // void HGCDigitizer::beginRun(const edm::EventSetup & es) { diff --git a/SimGeneral/Configuration/python/SimGeneral_EventContent_cff.py b/SimGeneral/Configuration/python/SimGeneral_EventContent_cff.py index 45c6093454167..4bc8e70f233c6 100644 --- a/SimGeneral/Configuration/python/SimGeneral_EventContent_cff.py +++ b/SimGeneral/Configuration/python/SimGeneral_EventContent_cff.py @@ -30,12 +30,19 @@ ) # mods for HGCAL -_phase2_hgc_extraCommands = [ 'keep *_mix_HGCDigisEE_*', 'keep *_mix_HGCDigisHEfront_*', 'keep *_mix_HGCDigisHEback_*', - 'keep *_mix_MergedCaloTruth_*' ] +_phase2_hgc_extraCommands = cms.PSet( # using PSet in order to customize with Modifier + digis = cms.vstring('keep *_mix_HGCDigisEE_*', 'keep *_mix_HGCDigisHEfront_*', 'keep *_mix_HGCDigisHEback_*'), + truth = cms.vstring('keep *_mix_MergedCaloTruth_*'), +) +# For phase2 premixing switch the sim digi collections to the ones including pileup +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(_phase2_hgc_extraCommands, + digis = ['keep *_mixData_HGCDigisEE_*', 'keep *_mixData_HGCDigisHEfront_*', 'keep *_mixData_HGCDigisHEback_*'] +) from Configuration.Eras.Modifier_phase2_hgcal_cff import phase2_hgcal -phase2_hgcal.toModify( SimGeneralRAW, outputCommands = SimGeneralRAW.outputCommands + _phase2_hgc_extraCommands ) -phase2_hgcal.toModify( SimGeneralFEVTDEBUG, outputCommands = SimGeneralFEVTDEBUG.outputCommands + _phase2_hgc_extraCommands ) -phase2_hgcal.toModify( SimGeneralRECO, outputCommands = SimGeneralRECO.outputCommands + _phase2_hgc_extraCommands ) +phase2_hgcal.toModify( SimGeneralRAW, outputCommands = SimGeneralRAW.outputCommands + _phase2_hgc_extraCommands.digis + _phase2_hgc_extraCommands.truth ) +phase2_hgcal.toModify( SimGeneralFEVTDEBUG, outputCommands = SimGeneralFEVTDEBUG.outputCommands + _phase2_hgc_extraCommands.digis + _phase2_hgc_extraCommands.truth ) +phase2_hgcal.toModify( SimGeneralRECO, outputCommands = SimGeneralRECO.outputCommands + _phase2_hgc_extraCommands.digis + _phase2_hgc_extraCommands.truth ) _phase2_timing_extraCommands = [ 'keep *_mix_FTLBarrel_*','keep *_mix_FTLEndcap_*','keep *_mix_InitialVertices_*' ] from Configuration.Eras.Modifier_phase2_timing_cff import phase2_timing diff --git a/SimGeneral/MixingModule/python/digitizers_cfi.py b/SimGeneral/MixingModule/python/digitizers_cfi.py index fa688752bcd29..2b41c90410f37 100644 --- a/SimGeneral/MixingModule/python/digitizers_cfi.py +++ b/SimGeneral/MixingModule/python/digitizers_cfi.py @@ -76,9 +76,12 @@ premix_stage2.toModify(theDigitizers, ecal = None, hcal = None, - # TODO: what to do with hgcal? ) - +(premix_stage2 & phase2_hgcal).toModify(theDigitizers, + hgceeDigitizer = dict(premixStage1 = True), + hgchebackDigitizer = dict(premixStage1 = True), + hgchefrontDigitizer = dict(premixStage1 = True), +) theDigitizersValid = cms.PSet(theDigitizers) theDigitizers.mergedtruth.select.signalOnlyTP = True diff --git a/SimGeneral/PreMixingModule/interface/PreMixingWorker.h b/SimGeneral/PreMixingModule/interface/PreMixingWorker.h index 45dbc4b260640..aaa437100d79b 100644 --- a/SimGeneral/PreMixingModule/interface/PreMixingWorker.h +++ b/SimGeneral/PreMixingModule/interface/PreMixingWorker.h @@ -17,6 +17,7 @@ class PreMixingWorker { virtual ~PreMixingWorker() = default; virtual void beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {} + virtual void endRun() {} virtual void beginLuminosityBlock(edm::LuminosityBlock const& iLumi, edm::EventSetup const& iSetup) {} virtual void initializeBunchCrossing(edm::Event const& iEvent, edm::EventSetup const& iSetup, int bunchCrossing) {} virtual void finalizeBunchCrossing(edm::Event& iEvent, edm::EventSetup const& iSetup, int bunchCrossing) {} diff --git a/SimGeneral/PreMixingModule/plugins/PreMixingModule.cc b/SimGeneral/PreMixingModule/plugins/PreMixingModule.cc index 751d4d20291be..5c78e63ffa4f9 100644 --- a/SimGeneral/PreMixingModule/plugins/PreMixingModule.cc +++ b/SimGeneral/PreMixingModule/plugins/PreMixingModule.cc @@ -111,6 +111,9 @@ namespace edm { } void PreMixingModule::endRun(edm::Run const& run, const edm::EventSetup& ES) { + for(auto& w: workers_) { + w->endRun(); + } BMixingModule::endRun( run, ES); } diff --git a/SimGeneral/PreMixingModule/python/mixOne_premix_on_sim_cfi.py b/SimGeneral/PreMixingModule/python/mixOne_premix_on_sim_cfi.py index 828276f137d87..13116caae1271 100644 --- a/SimGeneral/PreMixingModule/python/mixOne_premix_on_sim_cfi.py +++ b/SimGeneral/PreMixingModule/python/mixOne_premix_on_sim_cfi.py @@ -11,6 +11,7 @@ from SimGeneral.MixingModule.SiStripSimParameters_cfi import SiStripSimBlock from SimGeneral.MixingModule.SiPixelSimParameters_cfi import SiPixelSimBlock from SimGeneral.MixingModule.ecalDigitizer_cfi import ecalDigitizer +from SimCalorimetry.HGCalSimProducers.hgcalDigitizer_cfi import hgceeDigitizer, hgchebackDigitizer, hgchefrontDigitizer import EventFilter.EcalRawToDigi.EcalUnpackerData_cfi import EventFilter.ESRawToDigi.esRawToDigi_cfi @@ -307,7 +308,34 @@ ) ) -# TODO: Add HGCAL, but needs code first +phase2_hgcal.toModify(mixData, + workers = dict( + hgcee = cms.PSet( + hgceeDigitizer, + # + workerType = cms.string("PreMixingHGCalWorker"), + # + digiTagSig = cms.InputTag("mix", "HGCDigisEE"), + pileInputTag = cms.InputTag("mix", "HGCDigisEE"), + ), + hgchefront = cms.PSet( + hgchefrontDigitizer, + # + workerType = cms.string("PreMixingHGCalWorker"), + # + digiTagSig = cms.InputTag("mix", "HGCDigisHEfront"), + pileInputTag = cms.InputTag("mix", "HGCDigisHEfront"), + ), + hgcheback = cms.PSet( + hgchebackDigitizer, + # + workerType = cms.string("PreMixingHGCalWorker"), + # + digiTagSig = cms.InputTag("mix", "HGCDigisHEback"), + pileInputTag = cms.InputTag("mix", "HGCDigisHEback"), + ), + ) +) # Muon phase2_muon.toModify(mixData, diff --git a/Validation/HGCalValidation/plugins/HGCalDigiValidation.cc b/Validation/HGCalValidation/plugins/HGCalDigiValidation.cc index f01a053378870..66c4f41c5c5e3 100644 --- a/Validation/HGCalValidation/plugins/HGCalDigiValidation.cc +++ b/Validation/HGCalValidation/plugins/HGCalDigiValidation.cc @@ -124,7 +124,7 @@ void HGCalDigiValidation::fillDescriptions(edm::ConfigurationDescriptions& descr desc.add("ifHCAL",false); desc.addUntracked("Verbosity",0); desc.addUntracked("SampleIndx",0); - descriptions.add("hgcalDigiValidationEE",desc); + descriptions.add("hgcalDigiValidationEEDefault",desc); } void HGCalDigiValidation::analyze(const edm::Event& iEvent, diff --git a/Validation/HGCalValidation/python/digiValidation_cff.py b/Validation/HGCalValidation/python/digiValidation_cff.py index d7d4faea4f3ee..9d1b1cd27aa7f 100644 --- a/Validation/HGCalValidation/python/digiValidation_cff.py +++ b/Validation/HGCalValidation/python/digiValidation_cff.py @@ -9,3 +9,7 @@ hgcalDigiValidationHEB = hgcalDigiValidationEE.clone( DetectorName = cms.string("HCal"), DigiSource = cms.InputTag("mix","HGCDigisHEback")) + +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(hgcalDigiValidationHEF, DigiSource = "mixData:HGCDigisHEfront") +premix_stage2.toModify(hgcalDigiValidationHEB, DigiSource = "mixData:HGCDigisHEback") diff --git a/Validation/HGCalValidation/python/hgcalDigiValidationEE_cfi.py b/Validation/HGCalValidation/python/hgcalDigiValidationEE_cfi.py new file mode 100644 index 0000000000000..faa5ed472b0fe --- /dev/null +++ b/Validation/HGCalValidation/python/hgcalDigiValidationEE_cfi.py @@ -0,0 +1,6 @@ +import FWCore.ParameterSet.Config as cms +from Validation.HGCalValidation.hgcalDigiValidationEEDefault_cfi import hgcalDigiValidationEEDefault as _hgcalDigiValidationEEDefault +hgcalDigiValidationEE = _hgcalDigiValidationEEDefault.clone() + +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(hgcalDigiValidationEE, DigiSource = "mixData:HGCDigisEE")