/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
SimFastTiming/FastTimingCommon/interface/MTDDigitizer.h
265 строк
10 KB
Shahzad Malik Muzaffar
[SIMULATION] Drop Geometry/CommonDetUnit package
28 май 2026, 12:59
28 май 2026, 12:59
3cef132
Код
Авторство
О чём код?
#ifndef FastTimingSimProducers_FastTimingCommon_MTDDigitizer_h #define FastTimingSimProducers_FastTimingCommon_MTDDigitizer_h #include "SimFastTiming/FastTimingCommon/interface/MTDDigitizerBase.h" #include "SimFastTiming/FastTimingCommon/interface/MTDDigitizerTraits.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/ForwardDetId/interface/BTLDetId.h" #include "DataFormats/ForwardDetId/interface/ETLDetId.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/ProducesCollector.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "Geometry/Records/interface/MTDDigiGeometryRecord.h" #include "Geometry/MTDGeometryBuilder/interface/MTDGeometry.h" #include "Geometry/CommonTopologies/interface/GeomDetType.h" #include "Geometry/CommonTopologies/interface/PixelTopology.h" #include "Geometry/MTDGeometryBuilder/interface/ProxyMTDTopology.h" #include "Geometry/MTDGeometryBuilder/interface/RectangularMTDTopology.h" #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h" #include "DataFormats/Math/interface/liblogintpack.h" #include <vector> #include <unordered_map> #include <unordered_set> #include <memory> #include <tuple> namespace mtd_digitizer { namespace MTDHelpers { // index , det id, time typedef std::tuple<int, uint32_t, float> MTDCaloHitTuple_t; inline bool orderByDetIdThenTime(const MTDCaloHitTuple_t& a, const MTDCaloHitTuple_t& b) { unsigned int detId_a(std::get<1>(a)), detId_b(std::get<1>(b)); if (detId_a < detId_b) return true; if (detId_a > detId_b) return false; double time_a(std::get<2>(a)), time_b(std::get<2>(b)); if (time_a < time_b) return true; return false; } } // namespace MTDHelpers inline void saveSimHitAccumulator(PMTDSimAccumulator& simResult, const MTDSimHitDataAccumulator& simData, const float minCharge, const float maxCharge) { constexpr auto nEnergies = std::tuple_size<decltype(MTDCellInfo().hit_info)>::value; static_assert(nEnergies == PMTDSimAccumulator::Data::energyMask + 1, "PMTDSimAccumulator bit pattern needs to be updated"); static_assert(nSamples == PMTDSimAccumulator::Data::sampleMask, "PMTDSimAccumulator bit pattern needs to be updated"); const float minPackChargeLog = minCharge > 0.f ? std::log(minCharge) : -2; const float maxPackChargeLog = std::log(maxCharge); constexpr uint16_t base = PMTDSimAccumulator::Data::dataMask; simResult.reserve(simData.size()); // mimicking the digitization for (const auto& elem : simData) { // store only non-zero for (size_t iEn = 0; iEn < nEnergies; ++iEn) { const auto& samples = elem.second.hit_info[iEn]; for (size_t iSample = 0; iSample < nSamples; ++iSample) { if (samples[iSample] > minCharge) { unsigned short packed; if (iEn == 1 || iEn == 3) { // assuming linear range for tof of 0..25 packed = samples[iSample] / PREMIX_MAX_TOF * base; } else { packed = logintpack::pack16log(samples[iSample], minPackChargeLog, maxPackChargeLog, base); } simResult.emplace_back(elem.first.detid_, elem.first.row_, elem.first.column_, iEn, iSample, packed); } } } } } inline void loadSimHitAccumulator(MTDSimHitDataAccumulator& simData, const PMTDSimAccumulator& simAccumulator, const float minCharge, const float maxCharge) { const float minPackChargeLog = minCharge > 0.f ? std::log(minCharge) : -2; const float maxPackChargeLog = std::log(maxCharge); constexpr uint16_t base = PMTDSimAccumulator::Data::dataMask; for (const auto& detIdIndexHitInfo : simAccumulator) { auto foo = simData.emplace( MTDCellId(detIdIndexHitInfo.detId(), detIdIndexHitInfo.row(), detIdIndexHitInfo.column()), MTDCellInfo()); auto simIt = foo.first; auto& hit_info = simIt->second.hit_info; size_t iEn = detIdIndexHitInfo.energyIndex(); size_t iSample = detIdIndexHitInfo.sampleIndex(); if (iEn > PMTDSimAccumulator::Data::energyMask + 1 || iSample > PMTDSimAccumulator::Data::sampleMask) throw cms::Exception("MTDDigitixer::loadSimHitAccumulator") << "Index out of range: iEn = " << iEn << " iSample = " << iSample << std::endl; float value; if (iEn == 1 || iEn == 3) { value = static_cast<float>(detIdIndexHitInfo.data()) / base * PREMIX_MAX_TOF; } else { value = logintpack::unpack16log(detIdIndexHitInfo.data(), minPackChargeLog, maxPackChargeLog, base); } if (iEn == 0 || iEn == 2) { hit_info[iEn][iSample] += value; } else if (hit_info[iEn][iSample] == 0 || value < hit_info[iEn][iSample]) { // For iEn==1 the digitizers just set the TOF of the first SimHit hit_info[iEn][iSample] = value; } } } template <class Traits> class MTDDigitizer : public MTDDigitizerBase { public: typedef typename Traits::DeviceSim DeviceSim; typedef typename Traits::ElectronicsSim ElectronicsSim; typedef typename Traits::DigiCollection DigiCollection; MTDDigitizer(const edm::ParameterSet& config, edm::ProducesCollector producesCollector, edm::ConsumesCollector& iC) : MTDDigitizerBase(config, producesCollector, iC), geomToken_(iC.esConsumes()), geom_(nullptr), deviceSim_(config.getParameterSet("DeviceSimulation"), iC), electronicsSim_(config.getParameterSet("ElectronicsSimulation"), iC), maxSimHitsAccTime_(config.getParameter<uint32_t>("maxSimHitsAccTime")) {} ~MTDDigitizer() override {} /** @short handle SimHit accumulation */ void accumulate(edm::Event const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) override; void accumulate(PileUpEventPrincipal const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) override; void accumulate(edm::Handle<edm::PSimHitContainer> const& hits, int bxCrossing, CLHEP::HepRandomEngine* hre) override; // for premixing void accumulate(const PMTDSimAccumulator& simAccumulator) override; /** @short actions at the start/end of event */ void initializeEvent(edm::Event const& e, edm::EventSetup const& c) override; void finalizeEvent(edm::Event& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) override; private: void resetSimHitDataAccumulator() { MTDSimHitDataAccumulator().swap(simHitAccumulator_); } const edm::ESGetToken<MTDGeometry, MTDDigiGeometryRecord> geomToken_; const MTDGeometry* geom_; // implementations DeviceSim deviceSim_; // processes a given simhit into an entry in a MTDSimHitDataAccumulator ElectronicsSim electronicsSim_; // processes a MTDSimHitDataAccumulator into a BTLDigiCollection/ETLDigiCollection //handle sim hits const int maxSimHitsAccTime_; MTDSimHitDataAccumulator simHitAccumulator_; }; template <class Traits> void MTDDigitizer<Traits>::accumulate(edm::Event const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) { edm::Handle<edm::PSimHitContainer> simHits; e.getByLabel(inputSimHits_, simHits); if (simHits.isValid()) accumulate(simHits, 0, hre); else edm::LogWarning("MTDMix") << "MTDDigitizer:: Cannot find hits for " << inputSimHits_; } template <class Traits> void MTDDigitizer<Traits>::accumulate(PileUpEventPrincipal const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) { edm::Handle<edm::PSimHitContainer> simHits; e.getByLabel(inputSimHits_, simHits); if (simHits.isValid()) accumulate(simHits, e.bunchCrossing(), hre); else edm::LogWarning("MTDMix") << "MTDDigitizer:: Cannot find hits for " << inputSimHits_; } template <class Traits> void MTDDigitizer<Traits>::accumulate(edm::Handle<edm::PSimHitContainer> const& hits, int bxCrossing, CLHEP::HepRandomEngine* hre) { using namespace MTDHelpers; //create list of tuples (pos in container, RECO DetId, time) to be sorted first int nchits = (int)hits->size(); std::vector<MTDCaloHitTuple_t> hitRefs; hitRefs.reserve(nchits); for (int i = 0; i < nchits; ++i) { const auto& the_hit = hits->at(i); DetId id = the_hit.detUnitId(); if (verbosity_ > 0) { edm::LogInfo("MTDDigitizer") << " i/p " << std::hex << the_hit.detUnitId() << std::dec << " o/p " << id.rawId() << std::endl; } if (0 != id.rawId()) { hitRefs.emplace_back(i, id.rawId(), the_hit.tof()); } } std::sort(hitRefs.begin(), hitRefs.end(), MTDHelpers::orderByDetIdThenTime); deviceSim_.getHitsResponse(hitRefs, hits, &simHitAccumulator_, hre); hitRefs.clear(); } template <class Traits> void MTDDigitizer<Traits>::accumulate(const PMTDSimAccumulator& simAccumulator) { loadSimHitAccumulator(simHitAccumulator_, simAccumulator, premixStage1MinCharge_, premixStage1MaxCharge_); } template <class Traits> void MTDDigitizer<Traits>::initializeEvent(edm::Event const& e, edm::EventSetup const& c) { geom_ = &c.getData(geomToken_); deviceSim_.getEvent(e); deviceSim_.getEventSetup(c); if (not premixStage1_) { electronicsSim_.getEvent(e); electronicsSim_.getEventSetup(c); } } template <class Traits> void MTDDigitizer<Traits>::finalizeEvent(edm::Event& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) { if (premixStage1_) { auto simResult = std::make_unique<PMTDSimAccumulator>(); saveSimHitAccumulator(*simResult, simHitAccumulator_, premixStage1MinCharge_, premixStage1MaxCharge_); e.put(std::move(simResult), digiCollection_); } else { auto digiCollection = std::make_unique<DigiCollection>(); electronicsSim_.run(simHitAccumulator_, *digiCollection, hre); e.put(std::move(digiCollection), digiCollection_); } //release memory for next event resetSimHitDataAccumulator(); } } // namespace mtd_digitizer #endif