REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestGeant4QuenchingProcess.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
46
47#include "TRestGeant4QuenchingProcess.h"
48
49using namespace std;
50
52
57
71 Initialize();
72
73 if (LoadConfigFromFile(configFilename)) {
75 }
76}
77
82
86void TRestGeant4QuenchingProcess::LoadDefaultConfig() { SetTitle("Default config"); }
87
93 fGeant4Metadata = nullptr;
94 SetSectionName(this->ClassName());
95 SetLibraryVersion(LIBRARY_VERSION);
96
97 fInputG4Event = nullptr;
99}
100
113void TRestGeant4QuenchingProcess::LoadConfig(const string& configFilename, const string& name) {
114 if (LoadConfigFromFile(configFilename, name)) {
116 }
117}
118
120 TiXmlElement* volumeElement = GetElement("volume");
121 while (volumeElement) {
122 const string volumeName = GetParameter("name", volumeElement, "");
123 if (volumeName.empty()) {
124 cerr << "TRestGeant4QuenchingProcess: No volume expression specified" << endl;
125 exit(1);
126 }
127 fUserVolumeExpressions.insert(volumeName);
128 volumeElement = GetNextElement(volumeElement);
129 }
130}
131
135 fGeant4Metadata = GetMetadata<TRestGeant4Metadata>();
136 if (fGeant4Metadata == nullptr) {
137 cerr << "TRestGeant4QuenchingProcess: No TRestGeant4Metadata found" << endl;
138 exit(1);
139 }
140
141 const auto geometryInfo = fGeant4Metadata->GetGeant4GeometryInfo();
142 // check all the user volume expressions are valid and correspond to at least a volume
143 for (const auto& userVolume : fUserVolumeExpressions) {
144 set<string> physicalVolumes = {};
145 for (const auto& volume : geometryInfo.GetAllPhysicalVolumesMatchingExpression(userVolume)) {
146 physicalVolumes.insert(volume.Data());
147 }
148 if (!physicalVolumes.empty()) {
149 continue;
150 }
151 // maybe it refers to a logical volume
152 for (const auto& logicalVolume : geometryInfo.GetAllLogicalVolumesMatchingExpression(userVolume)) {
153 for (const auto& volume : geometryInfo.GetAllPhysicalVolumesFromLogical(logicalVolume.Data())) {
154 physicalVolumes.insert(volume.Data());
155 }
156 }
157
158 if (physicalVolumes.empty()) {
159 RESTWarning << "TRestGeant4QuenchingProcess: No volume found matching expression: " << userVolume
160 << RESTendl;
161 }
162
163 for (const auto& physicalVolume : physicalVolumes) {
164 const auto volumeName = geometryInfo.GetAlternativeNameFromGeant4PhysicalName(physicalVolume);
165 fVolumes.insert(volumeName.Data());
166 }
167 }
168
169 RESTDebug << "TRestGeant4QuenchingProcess initialized with volumes" << RESTendl;
170 for (const auto& volume : fVolumes) {
171 RESTDebug << " " << volume << RESTendl;
172 }
173}
174
175double QuenchingFactor(double recoilEnergy, int A, int Z) {
176 // Lindhard formula
177 double gamma = 11.5 * recoilEnergy * TMath::Power(Z, -7.0 / 3.0);
178 double g = 3 * TMath::Power(gamma, 0.15) + 0.7 * TMath::Power(gamma, 0.6) + gamma;
179 double k = 0.133 * TMath::Power(Z, 2.0 / 3.0) * TMath::Power(A, -1.0 / 2.0);
180 return k * g / (1 + k * g);
181}
186 fInputG4Event = (TRestGeant4Event*)inputEvent;
187 *fOutputG4Event = *((TRestGeant4Event*)inputEvent);
188
189 const double sensitiveVolumeEnergyBefore = fOutputG4Event->GetSensitiveVolumeEnergy();
190
192 fOutputG4Event->fEnergyInVolumePerParticlePerProcess.clear();
193
194 // loop over all tracks
195 for (int trackIndex = 0; trackIndex < int(fOutputG4Event->GetNumberOfTracks()); trackIndex++) {
196 // get the track
197 TRestGeant4Track* track = fOutputG4Event->GetTrackPointer(trackIndex);
198 const auto& particleName = track->GetParticleName();
199
200 auto hits = track->GetHitsPointer();
201 if (!hits->GetHadronicOk()) {
202 cerr << "TRestGeant4QuenchingProcess: Hadronic information not available. Use the "
203 "'storeHadronicTargetInfo' parameter in the restG4 configuration"
204 << endl;
205 exit(1);
206 }
207 auto& energy = hits->GetEnergyRef();
208 for (int hitIndex = 0; hitIndex < int(hits->GetNumberOfHits()); hitIndex++) {
209 const auto& volumeName = hits->GetVolumeName(hitIndex);
210
211 const string isotopeName = hits->GetHadronicTargetIsotopeName(hitIndex);
212 const int isotopeA = hits->GetHadronicTargetIsotopeA(hitIndex);
213 const int isotopeZ = hits->GetHadronicTargetIsotopeZ(hitIndex);
214
215 double recoilEnergy = hits->GetEnergy(hitIndex);
216
217 double quenchingFactor = 1.0;
218 if (fVolumes.count(volumeName.Data()) && recoilEnergy > 0 && !isotopeName.empty()) {
219 quenchingFactor = QuenchingFactor(recoilEnergy, isotopeA, isotopeZ);
220 }
221
222 const auto processName = hits->GetProcessName(hitIndex);
223
224 if (energy[hitIndex] > 0) {
225 fOutputG4Event->fEnergyInVolumePerParticlePerProcess[volumeName.Data()][particleName.Data()]
226 [processName.Data()] +=
227 energy[hitIndex] * quenchingFactor;
228 }
229 }
230 }
231
232 const double sensitiveVolumeEnergyAfter =
233 fOutputG4Event->GetEnergyInVolume(fGeant4Metadata->GetSensitiveVolume().Data());
234
235 bool sensitiveQuenched = TMath::Abs(sensitiveVolumeEnergyAfter - sensitiveVolumeEnergyBefore) > 1e-2;
236 SetObservableValue("sensitiveQuenched", sensitiveQuenched);
237 SetObservableValue("sensitiveVolumeEnergyBefore", sensitiveVolumeEnergyBefore);
238 SetObservableValue("sensitiveVolumeEnergyAfter", sensitiveVolumeEnergyAfter);
239
240 return fOutputG4Event;
241}
242
244
247 for (auto const& volume : fVolumes) {
248 RESTMetadata << "Volume: " << volume << RESTendl;
249 }
250 EndPrintProcess();
251}
252
253std::set<std::string> TRestGeant4QuenchingProcess::GetVolumes() const { return fVolumes; }
254
255std::set<std::string> TRestGeant4QuenchingProcess::GetUserVolumeExpressions() const {
256 return fUserVolumeExpressions;
257}
TRestRun * GetRunInfo() const
Return the pointer of the hosting TRestRun object.
void BeginPrintProcess()
[name, cut range]
void SetObservableValue(const std::string &name, const T &value)
Set observable value for AnalysisTree.
A base class for any REST event.
Definition: TRestEvent.h:38
An event class to store geant4 generated event information.
void InitializeReferences(TRestRun *run) override
Initialize dynamical references when loading the event from a root file.
TString GetSensitiveVolume(int n=0) const
Returns a std::string with the name of the sensitive volume.
const TRestGeant4GeometryInfo & GetGeant4GeometryInfo() const
Returns an immutable reference to the geometry info.
Recomputes the energy of every hit based on quenching factor for each particle and volume.
TRestGeant4Event * fOutputG4Event
A pointer to the specific TRestGeant4Event output.
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.
TRestGeant4Metadata * fGeant4Metadata
A pointer to the simulation metadata information accessible to TRestRun.
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
TRestGeant4Event * fInputG4Event
A pointer to the specific TRestGeant4Event input.
void EndProcess() override
To be executed at the end of the run (outside event loop)
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.
endl_t RESTendl
Termination flag object for TRestStringOutput.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
void SetSectionName(std::string sName)
set the section name, clear the section content
TiXmlElement * GetNextElement(TiXmlElement *e)
Get the next sibling xml element of this element, with same eleDeclare.
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.