gdynamicDigitization
Loading...
Searching...
No Matches
gdynamicdigitization.h
Go to the documentation of this file.
1#pragma once
2
3#include <gemc/gstreamer/sro/gSROData.h>
4
5#include "greadoutSpecs.h"
6#include <gemc/gfactory/gfactory_options.h>
7
8// gemc
9#include <gemc/gfactory/gfactory.h>
10#include <gemc/gtouchable/gtouchable.h>
11#include <gemc/ghit/ghit.h>
12#include <gemc/gdata/gDigitizedData.h>
13#include <gemc/gdata/gTrueInfoData.h>
14#include <gemc/gtranslationTable/gtranslationTable.h>
16
17// c++
18#include <utility>
19#include <vector>
20#include <bitset>
21#include <map>
22#include <string>
23#include <optional>
24
25// geant4
26#include "G4Step.hh"
27
43public:
52 explicit GTouchableModifiers(const std::vector<std::string> &touchableNames);
53
54private:
63 std::map<std::string, std::vector<double> > modifierWeightsMap;
64
73 std::map<std::string, std::vector<double> > modifierWeightsAndTimesMap;
74
75public:
83 void insertIdAndWeight(const std::string &touchableName, int idValue, double weight);
84
93 void insertIdWeightAndTime(const std::string &touchableName, int idValue, double weight, double time);
94
104 void assignOverallWeight(const std::string &touchableName, double totalWeight);
105
115 [[nodiscard]] inline bool isWeightsOnly() const { return !modifierWeightsMap.empty(); }
116
126 inline std::vector<double> getModifierWeightsVector(const std::string &touchableName) {
127 return modifierWeightsMap[touchableName];
128 }
129
139 inline std::vector<double> getModifierWeightsAndTimeVector(const std::string &touchableName) {
140 return modifierWeightsAndTimesMap[touchableName];
141 }
142};
143
149
150inline constexpr const char *to_string(CollectionMode mode) {
151 switch (mode) {
152 case event: return "event";
153 case run: return "run";
154 case frame: return "frame";
155 }
156 return "unknown";
157}
158
175class GDynamicDigitization : public GBase<GDynamicDigitization> {
176public:
182 explicit GDynamicDigitization(const std::shared_ptr<GOptions> &g) : GBase(g, GDIGITIZATION_LOGGER) {
183 recordZeroEdep = g->getSwitch("recordZeroEdep");
184 }
185
187 ~GDynamicDigitization() override = default;
188
189 [[nodiscard]] virtual CollectionMode collection_mode() const { return CollectionMode::event; }
190
201 [[nodiscard]] double processStepTime(const std::shared_ptr<GTouchable> &gTouchID,
202 [[maybe_unused]] G4Step *thisStep) {
204 log->debug(NORMAL, "%1", FUNCTION_NAME);
205 return processStepTimeImpl(gTouchID, thisStep);
206 }
207
217 [[nodiscard]] virtual double processStepTimeImpl(const std::shared_ptr<GTouchable> &gTouchID,
218 [[maybe_unused]] G4Step *thisStep);
219
220 [[nodiscard]] std::vector<std::string> variables_to_normalize() {
222
223 log->debug(NORMAL, "%1", FUNCTION_NAME);
224
226 }
227
228
229 [[nodiscard]] virtual std::vector<std::string> variables_to_normalizeImpl() {
230 std::vector<std::string> variables;
231 return variables;
232 }
233
234
246 [[nodiscard]] std::vector<std::shared_ptr<GTouchable> > processTouchable(
247 std::shared_ptr<GTouchable> gtouchable, G4Step *thisStep) {
249 log->debug(NORMAL, "%1", FUNCTION_NAME);
250 return processTouchableImpl(std::move(gtouchable), thisStep);
251 }
252
260 [[nodiscard]] virtual std::vector<std::shared_ptr<GTouchable> > processTouchableImpl(
261 std::shared_ptr<GTouchable> gtouchable, G4Step *thisStep);
262
273 [[nodiscard]] std::vector<std::shared_ptr<GTouchable> > processGTouchableModifiers(
274 const std::shared_ptr<GTouchable> &gTouchID, const GTouchableModifiers &gmods) {
276 log->debug(NORMAL, "%1", FUNCTION_NAME);
277 return processGTouchableModifiersImpl(gTouchID, gmods);
278 }
279
289 virtual std::vector<std::shared_ptr<GTouchable> > processGTouchableModifiersImpl(
290 [[maybe_unused]] const std::shared_ptr<GTouchable> &gTouchID,
291 [[maybe_unused]] const GTouchableModifiers &gmods);
292
302 [[nodiscard]] std::unique_ptr<GTrueInfoData> collectTrueInformation(GHit *ghit, size_t hitn) {
304 log->info(
305 2, "GDynamicDigitization::collect true information for hit number %1 with size %2 steps", hitn,
306 ghit->nsteps());
307 return collectTrueInformationImpl(ghit, hitn);
308 }
309
317 [[nodiscard]] virtual std::unique_ptr<GTrueInfoData> collectTrueInformationImpl(GHit *ghit, size_t hitn);
318
328 [[nodiscard]] std::unique_ptr<GDigitizedData> digitizeHit(GHit *ghit, [[maybe_unused]] size_t hitn) {
330 log->info(2, "GDynamicDigitization::digitize hit number %1 with size %2 steps", hitn, ghit->nsteps());
331 return digitizeHitImpl(ghit, hitn);
332 }
333
343 [[nodiscard]] virtual std::unique_ptr<GDigitizedData> digitizeHitImpl(
344 [[maybe_unused]] GHit *ghit, [[maybe_unused]] size_t hitn) { return nullptr; }
345
354 virtual void stream_hit([[maybe_unused]] GHit* hit, [[maybe_unused]] std::size_t hit_index,
355 [[maybe_unused]] const GSROEventContext& event,
356 [[maybe_unused]] const GSROEmit& emit) const {}
357
367 [[nodiscard]] bool loadConstants([[maybe_unused]] int runno, [[maybe_unused]] std::string const &variation) {
369 log->debug(NORMAL, "GDynamicDigitization::load constants");
370 return loadConstantsImpl(runno, variation);
371 }
372
382 virtual bool loadConstantsImpl([[maybe_unused]] int runno, [[maybe_unused]] std::string const &variation) {
383 return true;
384 }
385
395 [[nodiscard]] bool loadTT([[maybe_unused]] int runno, [[maybe_unused]] std::string const &variation) {
397 log->debug(
398 NORMAL, "GDynamicDigitization::load Translation Table for run %1 with variation %2", runno,
399 variation);
400 return loadTTImpl(runno, variation);
401 }
402
412 virtual bool loadTTImpl([[maybe_unused]] int runno, [[maybe_unused]] std::string const &variation) { return true; }
413
426 void chargeAndTimeAtHardware(int time, int q, const GHit *ghit, GDigitizedData &gdata);
427
435 [[nodiscard]] bool defineReadoutSpecs() {
437 log->debug(NORMAL, "GDynamicDigitization::define readout specs");
438 return defineReadoutSpecsImpl();
439 };
440
448 virtual bool defineReadoutSpecsImpl() = 0;
449
451 std::shared_ptr<const GReadoutSpecs> readoutSpecs;
452
454 std::shared_ptr<const GTranslationTable> translationTable;
455
465 static GDynamicDigitization *instantiate(const dlhandle h, std::shared_ptr<GOptions> g) {
466 if (!h) return nullptr;
467 using fptr = GDynamicDigitization* (*)(std::shared_ptr<GOptions>);
468
469 auto sym = dlsym(h, "GDynamicDigitizationFactory");
470 if (!sym) return nullptr;
471
472 auto func = reinterpret_cast<fptr>(sym);
473 return func(g);
474 }
475
485 virtual bool decisionToSkipHit(double energy) {
486 if (energy == 0 && !recordZeroEdep) {
487 return true;
488 }
489 return false;
490 }
491
502 virtual bool decisionToSkipHit(double energy, [[maybe_unused]] const G4Step* thisStep) {
503 return decisionToSkipHit(energy);
504 }
505
516 [[nodiscard]] bool shouldStopTrackAfterHit(const G4Step* thisStep) const {
518 return shouldStopTrackAfterHitImpl(thisStep);
519 }
520
527 [[nodiscard]] virtual bool shouldStopTrackAfterHitImpl(
528 [[maybe_unused]] const G4Step* thisStep) const {
529 return false;
530 }
531
540 // TODO: REMOVE THIS EVERYWHERE also remove check_if_log_defined
541 void set_loggers(const std::shared_ptr<GOptions> &g) { gopts = g; }
542
551 void setDigitizationVariation(const std::string &v) { digitization_variation = v; }
552
558 [[nodiscard]] std::string getDigitizationVariation() const { return digitization_variation; }
559
570 void setHitRejectionPolicies(const std::string &systemName);
571
584 [[nodiscard]] bool apply_thresholds(GHit* ghit, GDigitizedData* digitizedData) {
585 if (!applyThresholds_ && !thresholds_are_intrinsic_impl()) { return false; }
586 return apply_thresholds_impl(ghit, digitizedData);
587 }
588
595 [[nodiscard]] virtual bool apply_thresholds_impl([[maybe_unused]] GHit* ghit,
596 [[maybe_unused]] GDigitizedData* digitizedData) {
597 return false;
598 }
599
606 [[nodiscard]] virtual bool thresholds_are_intrinsic_impl() const { return false; }
607
621 [[nodiscard]] bool apply_efficiency(GHit* ghit, GDigitizedData* digitizedData) {
622 if (!applyInefficiencies_ && !efficiencies_are_intrinsic_impl()) { return false; }
623 return apply_efficiency_impl(ghit, digitizedData);
624 }
625
632 [[nodiscard]] virtual bool apply_efficiency_impl([[maybe_unused]] GHit* ghit,
633 [[maybe_unused]] GDigitizedData* digitizedData) {
634 return false;
635 }
636
643 [[nodiscard]] virtual bool efficiencies_are_intrinsic_impl() const { return false; }
644
645private:
647 bool recordZeroEdep = false;
648
651 bool applyThresholds_ = false;
652 bool applyInefficiencies_ = false;
653
656 std::string digitization_variation = "default";
657
658protected:
660 std::shared_ptr<GOptions> gopts;
661
667 void check_if_log_defined() const {
668 if (gopts == nullptr) {
669 std::cerr << guts::KRED
670 << "Fatal Error: GDynamicDigitization: goption is not set for this plugin or one of the loggers is null."
671 << std::endl;
672 std::cerr << "The set_loggers function needs to be called." << std::endl;
673 std::cerr << "For example: dynamicRoutines[\"ctof\"]->set_loggers(gopts);" << std::endl;
674 std::cerr << guts::RST << std::endl;
675 exit(1);
676 }
677 }
678};
679
681 using dRoutinesMap = std::unordered_map<std::string, std::shared_ptr<GDynamicDigitization> >;
682
690 inline std::shared_ptr<GDynamicDigitization> load_dynamicRoutine(const std::string &plugin_name,
691 const std::shared_ptr<GOptions> &gopts) {
692 GManager manager(gopts);
694 }
695
706 inline std::shared_ptr<const dRoutinesMap> dynamicRoutinesMap(const std::vector<std::string> &plugin_names,
707 const std::shared_ptr<GOptions> &gopts) {
708 auto log = std::make_shared<GLogger>(gopts, SFUNCTION_NAME, GDIGITIZATION_LOGGER);
709 GManager manager(gopts);
710
711 auto routines = std::make_shared<dRoutinesMap>();
712
713 for (const auto &plugin: plugin_names) {
714 routines->emplace(plugin, manager.LoadAndRegisterObjectFromLibrary<GDynamicDigitization>(plugin, gopts));
715 log->info(0, "dynamicRoutinesMap[%1]: %2", plugin, (*routines)[plugin]);
716 }
717
718 return routines;
719 }
720} // namespace gdynamicdigitization
GBase(const std::shared_ptr< GOptions > &gopt, std::string logger_name="")
std::shared_ptr< GLogger > log
Abstract base class for dynamically loaded digitization plugins.
bool apply_thresholds(GHit *ghit, GDigitizedData *digitizedData)
Applies this system's ADC-threshold rejection to a digitized hit.
virtual CollectionMode collection_mode() const
std::shared_ptr< GOptions > gopts
Options used by the digitization plugin instance.
virtual bool defineReadoutSpecsImpl()=0
Implementation hook to define readout specs.
std::vector< std::string > variables_to_normalize()
bool loadConstants(int runno, std::string const &variation)
Loads digitization constants (calibration/configuration).
~GDynamicDigitization() override=default
Virtual destructor.
virtual std::unique_ptr< GTrueInfoData > collectTrueInformationImpl(GHit *ghit, size_t hitn)
Implementation hook for true-information collection.
GDynamicDigitization(const std::shared_ptr< GOptions > &g)
Constructs the digitization base object.
bool loadTT(int runno, std::string const &variation)
Loads the translation table (identity -> electronics address).
double processStepTime(const std::shared_ptr< GTouchable > &gTouchID, G4Step *thisStep)
Computes the time associated with a simulation step for electronics binning.
virtual std::vector< std::shared_ptr< GTouchable > > processGTouchableModifiersImpl(const std::shared_ptr< GTouchable > &gTouchID, const GTouchableModifiers &gmods)
Implementation hook for touchable modifier application.
void check_if_log_defined() const
Ensures options/logging are configured before plugin methods run.
void setDigitizationVariation(const std::string &v)
Sets the variation used when this routine loads constants / translation tables.
virtual double processStepTimeImpl(const std::shared_ptr< GTouchable > &gTouchID, G4Step *thisStep)
Implementation hook for step time computation.
std::unique_ptr< GTrueInfoData > collectTrueInformation(GHit *ghit, size_t hitn)
Collects standardized “true hit information” into a GTrueInfoData record.
std::shared_ptr< const GTranslationTable > translationTable
Translation table is typically loaded during initialization and treated as immutable.
std::vector< std::shared_ptr< GTouchable > > processTouchable(std::shared_ptr< GTouchable > gtouchable, G4Step *thisStep)
Processes a touchable based on the current step and readout specs.
virtual bool apply_thresholds_impl(GHit *ghit, GDigitizedData *digitizedData)
Plugin hook: is this digitized hit below the per-channel ADC threshold?
static GDynamicDigitization * instantiate(const dlhandle h, std::shared_ptr< GOptions > g)
Dynamically instantiates a plugin instance from a dynamic library.
virtual std::vector< std::shared_ptr< GTouchable > > processTouchableImpl(std::shared_ptr< GTouchable > gtouchable, G4Step *thisStep)
Implementation hook for touchable processing.
bool apply_efficiency(GHit *ghit, GDigitizedData *digitizedData)
Applies this system's efficiency rejection to a digitized hit.
std::shared_ptr< const GReadoutSpecs > readoutSpecs
Readout specs are created during initialization and treated as immutable.
bool shouldStopTrackAfterHit(const G4Step *thisStep) const
Ask whether Geant4 should terminate the track after recording this step's hit.
virtual std::vector< std::string > variables_to_normalizeImpl()
virtual bool apply_efficiency_impl(GHit *ghit, GDigitizedData *digitizedData)
Plugin hook: does this digitized hit fail the per-channel efficiency draw?
virtual bool loadTTImpl(int runno, std::string const &variation)
Implementation hook for translation table loading.
void set_loggers(const std::shared_ptr< GOptions > &g)
Sets the options pointer required by the digitization base.
virtual bool efficiencies_are_intrinsic_impl() const
Declares that this plugin's efficiency policy is intrinsic to GEMC2 digitization.
virtual std::unique_ptr< GDigitizedData > digitizeHitImpl(GHit *ghit, size_t hitn)
Implementation hook for hit digitization.
std::string getDigitizationVariation() const
Returns the variation passed to loadConstants() / loadTT().
virtual bool decisionToSkipHit(double energy)
Decides whether a hit should be skipped based on deposited energy.
virtual bool thresholds_are_intrinsic_impl() const
Declares that this plugin's threshold is intrinsic to its GEMC2 digitization.
virtual bool shouldStopTrackAfterHitImpl(const G4Step *thisStep) const
Plugin hook controlling post-hit track termination.
void setHitRejectionPolicies(const std::string &systemName)
Resolves this routine's hit-rejection policies from the global options.
std::unique_ptr< GDigitizedData > digitizeHit(GHit *ghit, size_t hitn)
Digitizes a hit into a GDigitizedData record.
void chargeAndTimeAtHardware(int time, int q, const GHit *ghit, GDigitizedData &gdata)
Adds hardware-level time/charge and address fields to a digitized record.
virtual bool loadConstantsImpl(int runno, std::string const &variation)
Implementation hook for constant loading.
std::vector< std::shared_ptr< GTouchable > > processGTouchableModifiers(const std::shared_ptr< GTouchable > &gTouchID, const GTouchableModifiers &gmods)
Applies touchable modifiers.
virtual void stream_hit(GHit *hit, std::size_t hit_index, const GSROEventContext &event, const GSROEmit &emit) const
virtual bool decisionToSkipHit(double energy, const G4Step *thisStep)
Decides whether a step should be skipped before hit creation.
bool defineReadoutSpecs()
Initializes readout specifications.
size_t nsteps() const
std::shared_ptr< T > LoadAndRegisterObjectFromLibrary(std::string_view name, const std::shared_ptr< GOptions > &gopts)
Helper container for representing touchable “modifier” information.
void insertIdAndWeight(const std::string &touchableName, int idValue, double weight)
Inserts a new (id, weight) pair for the specified touchable.
std::vector< double > getModifierWeightsVector(const std::string &touchableName)
Returns the weights vector for a touchable.
std::vector< double > getModifierWeightsAndTimeVector(const std::string &touchableName)
Returns the weights-and-times vector for a touchable.
bool isWeightsOnly() const
Returns whether the container currently reports weights-only modifiers.
void insertIdWeightAndTime(const std::string &touchableName, int idValue, double weight, double time)
Inserts a new (id, weight, time) triplet for the specified touchable.
void assignOverallWeight(const std::string &touchableName, double totalWeight)
Normalizes modifier weights by dividing by a provided total.
GTouchableModifiers(const std::vector< std::string > &touchableNames)
Constructs the container and declares supported touchable names.
std::function< void(GSROCrateId, GSROTime, std::unique_ptr< const GSROData >)> GSROEmit
void * dlhandle
constexpr const char * to_string(CollectionMode mode)
Options for the GDynamicDigitization module.
constexpr const char * GDIGITIZATION_LOGGER
Logger name used by this module.
#define FUNCTION_NAME
#define SFUNCTION_NAME
NORMAL
Readout electronics specifications used by time-binning and hit organization.
const std::string plugin_name
std::shared_ptr< GDynamicDigitization > load_dynamicRoutine(const std::string &plugin_name, const std::shared_ptr< GOptions > &gopts)
Loads a single dynamic routine and returns it.
std::unordered_map< std::string, std::shared_ptr< GDynamicDigitization > > dRoutinesMap
std::shared_ptr< const dRoutinesMap > dynamicRoutinesMap(const std::vector< std::string > &plugin_names, const std::shared_ptr< GOptions > &gopts)
Loads multiple dynamic routines and returns an immutable shared map.
constexpr char RST[]
constexpr char KRED[]