47 #include "TRestGeant4QuenchingProcess.h"
73 if (LoadConfigFromFile(configFilename)) {
93 fGeant4Metadata =
nullptr;
94 SetSectionName(this->ClassName());
95 SetLibraryVersion(LIBRARY_VERSION);
97 fInputG4Event =
nullptr;
114 if (LoadConfigFromFile(configFilename, name)) {
120 TiXmlElement* volumeElement = GetElement(
"volume");
121 while (volumeElement) {
122 TiXmlElement* particleElement = GetElement(
"particle", volumeElement);
123 const string volumeName = GetParameter(
"name", volumeElement,
"");
124 if (volumeName.empty()) {
125 cerr <<
"TRestGeant4QuenchingProcess: No volume expression specified" << endl;
128 while (particleElement) {
129 const string particleName = GetParameter(
"name", particleElement,
"");
130 if (particleName.empty()) {
131 cerr <<
"TRestGeant4QuenchingProcess: No particle name specified" << endl;
134 const auto quenchingFactor = stof(GetParameter(
"quenchingFactor", particleElement, -1.0));
136 if (quenchingFactor < 0.0 || quenchingFactor > 1.0) {
137 cerr <<
"TRestGeant4QuenchingProcess: Quenching factor must be between 0 and 1" << endl;
140 fUserVolumeParticleQuenchingFactor[volumeName][particleName] = quenchingFactor;
141 particleElement = GetNextElement(particleElement);
143 volumeElement = GetNextElement(volumeElement);
150 fGeant4Metadata = GetMetadata<TRestGeant4Metadata>();
151 if (fGeant4Metadata ==
nullptr) {
152 cerr <<
"TRestGeant4QuenchingProcess: No TRestGeant4Metadata found" << endl;
156 const auto geometryInfo = fGeant4Metadata->GetGeant4GeometryInfo();
158 for (
const auto& [userVolume, particleToQuenchingMap] : fUserVolumeParticleQuenchingFactor) {
159 set<string> physicalVolumes = {};
160 for (
const auto& volume : geometryInfo.GetAllPhysicalVolumesMatchingExpression(userVolume)) {
161 physicalVolumes.insert(volume.Data());
163 if (!physicalVolumes.empty()) {
167 for (
const auto& logicalVolume : geometryInfo.GetAllLogicalVolumesMatchingExpression(userVolume)) {
168 for (
const auto& volume : geometryInfo.GetAllPhysicalVolumesFromLogical(logicalVolume.Data())) {
169 physicalVolumes.insert(volume.Data());
173 if (physicalVolumes.empty()) {
174 cerr <<
"TRestGeant4QuenchingProcess: No volume found matching expression " << userVolume << endl;
178 for (
const auto& physicalVolume : physicalVolumes) {
179 const auto volumeName = geometryInfo.GetAlternativeNameFromGeant4PhysicalName(physicalVolume);
180 fVolumeParticleQuenchingFactor[volumeName.Data()] = particleToQuenchingMap;
184 RESTDebug <<
"TRestGeant4QuenchingProcess initialized with volumes" << RESTendl;
185 for (
const auto& [volume, particleToQuenchingMap] : fVolumeParticleQuenchingFactor) {
186 RESTDebug << volume << RESTendl;
187 for (
const auto& [particle, quenchingFactor] : particleToQuenchingMap) {
188 RESTDebug <<
"\t" << particle <<
" " << quenchingFactor << RESTendl;
201 fOutputG4Event->fEnergyInVolumePerParticlePerProcess.clear();
204 for (
int trackIndex = 0; trackIndex < int(fOutputG4Event->GetNumberOfTracks()); trackIndex++) {
207 const auto& particleName = track->GetParticleName();
209 auto hits = track->GetHitsPointer();
210 auto& energy = hits->GetEnergyRef();
211 for (
int hitIndex = 0; hitIndex < int(hits->GetNumberOfHits()); hitIndex++) {
212 const auto& volumeName = hits->GetVolumeName(hitIndex);
213 const float_t quenchingFactor =
214 GetQuenchingFactorForVolumeAndParticle(volumeName.Data(), particleName.Data());
216 energy[hitIndex] *= quenchingFactor;
221 const string processName = hits->GetProcessName(hitIndex).Data();
223 if (energy[hitIndex] > 0) {
224 fOutputG4Event->fEnergyInVolumePerParticlePerProcess[volumeName.Data()][particleName.Data()]
225 [processName] += energy[hitIndex];
232 return fOutputG4Event;
239 vector<string> TRestGeant4QuenchingProcess::GetUserVolumeExpressions()
const {
240 vector<string> userVolumeExpressions;
241 userVolumeExpressions.reserve(fUserVolumeParticleQuenchingFactor.size());
242 for (
auto const& x : fUserVolumeParticleQuenchingFactor) {
243 userVolumeExpressions.push_back(x.first);
245 return userVolumeExpressions;
248 float_t TRestGeant4QuenchingProcess::GetQuenchingFactorForVolumeAndParticle(
249 const string& volumeName,
const string& particleName)
const {
250 float_t quenchingFactor = 1.0;
252 if (fVolumeParticleQuenchingFactor.find(volumeName) != fVolumeParticleQuenchingFactor.end()) {
254 if (fVolumeParticleQuenchingFactor.at(volumeName).find(particleName) !=
255 fVolumeParticleQuenchingFactor.at(volumeName).end()) {
256 quenchingFactor = fVolumeParticleQuenchingFactor.at(volumeName).at(particleName);
259 return quenchingFactor;
264 cout <<
"Printing TRestGeant4QuenchingProcess user configuration" << endl;
265 for (
auto const& [volume, particleQuenchingFactorMap] : fUserVolumeParticleQuenchingFactor) {
266 cout <<
"Volume: " << volume << endl;
267 for (
auto const& [particle, quenchingFactor] : particleQuenchingFactorMap) {
268 cout <<
" - Particle: " << particle <<
" Quenching factor: " << quenchingFactor << endl;
272 if (!fVolumeParticleQuenchingFactor.empty()) {
273 cout <<
"Printing TRestGeant4QuenchingProcess configuration with actual volumes" << endl;
274 for (
auto const& [volume, particleQuenchingFactorMap] : fVolumeParticleQuenchingFactor) {
275 cout <<
"Volume: " << volume << endl;
276 for (
auto const& [particle, quenchingFactor] : particleQuenchingFactorMap) {
277 cout <<
" - Particle: " << particle <<
" Quenching factor: " << quenchingFactor << endl;
A base class for any REST event.
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
An event class to store geant4 generated event information.
Recomputes the energy of every hit based on quenching factor for each particle and volume.
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
void EndProcess() override
Function to include required actions after all events have been processed.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
void LoadConfig(const std::string &configFilename, const std::string &name="")
Function to load the configuration from an external configuration file.
TRestGeant4QuenchingProcess()
Default constructor.
void Initialize() override
Function to initialize input/output event members and define the section name.
~TRestGeant4QuenchingProcess() override
Default destructor.
void InitProcess() override
Process initialization. User volume expressions are matched to physical volumes.