gdynamicDigitization
Loading...
Searching...
No Matches
gDosimeterDigitization.cc
Go to the documentation of this file.
1
27#include <fstream>
28
29
40 double timeWindow = 10; // electronic readout time-window of the detector
41 double gridStartTime = 0; // defines the windows grid
42 auto hitBitSet = HitBitSet("000001"); // defines what information to be stored in the hit
43
44 // Create a new GReadoutSpecs object with the specified parameters.
45 readoutSpecs = std::make_shared<GReadoutSpecs>(timeWindow, gridStartTime, hitBitSet, log);
46
47 return true;
48}
49
64std::unique_ptr<GDigitizedData> GDosimeterDigitization::digitizeHitImpl(GHit* ghit, size_t hitn) {
65 // Ensure that required loggers and options are defined.
67
68 // ghit->getGID() must have a single entry.
69 GIdentifier identity = ghit->getGID().front();
70
71 // Create a new GDigitizedData object for this hit.
72 auto gdata = std::make_unique<GDigitizedData>(gopts, ghit);
73
74 // Include basic hit variables.
75 gdata->includeVariable(identity.getName(), identity.getValue());
76 gdata->includeVariable("hitn", static_cast<int>(hitn));
77 gdata->includeVariable("eTot", ghit->getTotalEnergyDeposited());
78 gdata->includeVariable("time", ghit->getAverageTime());
79
80 // Retrieve per-step particle IDs and energies.
81 auto pids = ghit->getPids();
82 auto pEnergies = ghit->getEs();
83
84 double nielWeight = 0;
85 // Loop over each step.
86 for (size_t stepIndex = 0; stepIndex < pids.size(); stepIndex++) {
87 // Use absolute value so negative particle IDs (e.g. -11) are handled.
88 int pid = std::abs(pids[stepIndex]);
89
90 // Process only for specific particle types.
91 if (pid == 11 || pid == 211 || pid == 2212 || pid == 2112) {
92 // Compute effective energy by subtracting the particle mass.
93 double E = pEnergies[stepIndex] - pMassMeV[pid];
94 // Accumulate NIEL weight using linear interpolation of the NIEL factor.
95 nielWeight += getNielFactorForParticleAtEnergy(pid, E);
96 }
97 }
98
99 // Include the computed NIEL weight in the digitized data.
100 gdata->includeVariable("nielWeight", nielWeight);
101
102 return gdata;
103}
104
117bool GDosimeterDigitization::loadConstantsImpl([[maybe_unused]] int runno, [[maybe_unused]] std::string const& variation) {
118 // NIEL Data: map from particle ID (PID) to file name.
119 std::map<int, std::string> nielDataFiles;
120 nielDataFiles[11] = "niel_electron.txt";
121 nielDataFiles[211] = "niel_pion.txt";
122 nielDataFiles[2112] = "niel_neutron.txt";
123 nielDataFiles[2212] = "niel_proton.txt";
124
125 // Construct plugin path from the GEMC environment variable.
126 std::filesystem::path gemcRoot = gutilities::gemc_root();
127 std::string pluginPath = gemcRoot.string() + "/dosimeterData/";
128
129 // Loop over each particle type and load its NIEL data.
130 for (const auto& [pid, filename] : nielDataFiles) {
131 std::string dataFileWithPath = pluginPath + "/dosimeterData/Niel/" + filename;
132
133 std::ifstream inputfile(dataFileWithPath);
134 if (!inputfile) { log->error(EC__FILENOTFOUND, "Error loading dosimeter data for pid <", pid, "> from file ", dataFileWithPath); }
135
136 log->info(0, " Loading dosimeter data for pid <", pid, "> from file ", dataFileWithPath);
137
138 double p0, p1;
139 // Use proper loop condition to read pairs until failure.
140 while (inputfile >> p0 >> p1) {
141 nielfactorMap[pid].push_back(p0);
142 E_nielfactorMap[pid].push_back(p1);
143 }
144 inputfile.close();
145 }
146
147 // Load particle masses (in MeV) for calibration.
148 pMassMeV[11] = 0.510;
149 pMassMeV[211] = 139.570;
150 pMassMeV[2112] = 939.565;
151 pMassMeV[2212] = 938.272;
152
153 return true;
154}
155
168double GDosimeterDigitization::getNielFactorForParticleAtEnergy(int pid, double energyMeV) {
169 // Number of NIEL data points available for this particle.
170 auto niel_N = nielfactorMap[pid].size();
171 auto j = niel_N;
172
173 // Find the first index for which the energy is below the threshold.
174 for (size_t i = 0; i < niel_N; i++) {
175 if (energyMeV < E_nielfactorMap[pid][i]) {
176 j = i;
177 break;
178 }
179 }
180
181 double value;
182 if (j > 0 && j < niel_N) {
183 // Perform linear interpolation between indices j-1 and j.
184 auto nielfactor_low = nielfactorMap[pid][j - 1];
185 auto nielfactor_high = nielfactorMap[pid][j];
186 auto energy_low = E_nielfactorMap[pid][j - 1];
187 auto energy_high = E_nielfactorMap[pid][j];
188 value = nielfactor_low + (nielfactor_high - nielfactor_low) / (energy_high - energy_low) * (energyMeV - energy_low);
189 }
190 else if (j == 0) {
191 // Energy is below the first threshold.
192 value = nielfactorMap[pid].front();
193 }
194 else {
195 // Energy is above the last threshold.
196 value = nielfactorMap[pid].back();
197 }
198
199 log->debug(NORMAL, " pid: ", pid, ", j: ", j, ", value: ", value, ", energy: ", energyMeV);
200
201 return value;
202}
bool defineReadoutSpecsImpl() override
Defines readout specifications for dosimeter digitization.
std::unique_ptr< GDigitizedData > digitizeHitImpl(GHit *ghit, size_t hitn) override
Digitizes a hit for dosimeter detectors.
bool loadConstantsImpl(int runno, std::string const &variation) override
Loads digitization constants for dosimeter digitization.
std::shared_ptr< GOptions > gopts
Optional pointer to GOptions.
void check_if_log_defined() const
Checks that all required loggers and options are defined.
std::shared_ptr< const GReadoutSpecs > readoutSpecs
After init, we never mutate these:
Declares internal digitization classes for various detector types.