88#include "TRestGeant4NeutronTaggingProcess.h"
94TRestGeant4NeutronTaggingProcess::TRestGeant4NeutronTaggingProcess() {
Initialize(); }
96TRestGeant4NeutronTaggingProcess::TRestGeant4NeutronTaggingProcess(
const char* configFilename) {
155 if (volume_name.find(
TrimAndLower(fVetoKeyword)) != string::npos) {
157 }
else if (volume_name.find(
TrimAndLower(fCaptureKeyword)) != string::npos) {
158 fCaptureVolumeIds.push_back(i);
159 }
else if (volume_name.find(
TrimAndLower(fShieldingKeyword)) != string::npos) {
160 fShieldingVolumeIds.push_back(i);
165 for (
unsigned int i = 0; i < fVetoGroupKeywords.size(); i++) {
166 string veto_group_keyword =
TrimAndLower(fVetoGroupKeywords[i]);
167 fVetoGroupVolumeNames[veto_group_keyword] = std::vector<string>{};
171 if (volume_name.find(veto_group_keyword) != string::npos) {
172 fVetoGroupVolumeNames[veto_group_keyword].push_back(
182void TRestGeant4NeutronTaggingProcess::Reset() {
188 fNeutronsCapturedNumber = 0;
190 fNeutronsCapturedPosY.clear();
191 fNeutronsCapturedPosZ.clear();
193 fNeutronsCapturedProductionE.clear();
194 fNeutronsCapturedEDepByNeutron.clear();
195 fNeutronsCapturedEDepByNeutronAndChildren.clear();
196 fNeutronsCapturedEDepByNeutronInVeto.clear();
197 fNeutronsCapturedEDepByNeutronAndChildrenInVeto.clear();
198 fNeutronsCapturedEDepByNeutronAndChildrenInVetoMax.clear();
199 fNeutronsCapturedEDepByNeutronAndChildrenInVetoMin.clear();
201 fGammasNeutronCaptureNumber = 0;
202 fGammasNeutronCapturePosX.clear();
203 fGammasNeutronCapturePosY.clear();
204 fGammasNeutronCapturePosZ.clear();
205 fGammasNeutronCaptureIsCaptureVolume.clear();
206 fGammasNeutronCaptureProductionE.clear();
208 fSecondaryNeutronsShieldingNumber = 0;
209 fSecondaryNeutronsShieldingExitPosX.clear();
210 fSecondaryNeutronsShieldingExitPosY.clear();
211 fSecondaryNeutronsShieldingExitPosZ.clear();
212 fSecondaryNeutronsShieldingIsCaptured.clear();
213 fSecondaryNeutronsShieldingIsCapturedInCaptureVolume.clear();
214 fSecondaryNeutronsShieldingProductionE.clear();
215 fSecondaryNeutronsShieldingExitE.clear();
225 std::map<string, Double_t> volume_energy_map;
232 volume_energy_map[volume_name] = energy;
235 Double_t energy_veto_max = 0;
236 for (
const auto& pair : volume_energy_map) {
237 Double_t veto_energy = pair.second;
239 if (veto_energy > energy_veto_max) {
240 energy_veto_max = veto_energy;
246 for (
const auto& pair : fVetoGroupVolumeNames) {
247 Double_t energy_veto_max_group = 0;
248 for (
unsigned int i = 0; i < pair.second.size(); i++) {
249 string volume_name = pair.second[i];
250 Double_t veto_energy = volume_energy_map[volume_name];
251 if (veto_energy > energy_veto_max_group) {
252 energy_veto_max_group = veto_energy;
257 for (
auto it = pair.first.cbegin(); it != pair.first.cend(); ++it) {
258 if (it == pair.first.cbegin()) {
259 group_name += std::toupper(*it);
261 group_name += std::tolower(*it);
269 for (
const auto& quenching_factor : fQuenchingFactors) {
270 string quenching_factor_string = std::to_string(quenching_factor);
272 quenching_factor_string =
273 quenching_factor_string.replace(quenching_factor_string.find(
"."),
sizeof(
".") - 1,
"_");
274 volume_energy_map.clear();
275 for (
unsigned int i = 0; i <
fOutputG4Event->GetNumberOfTracks(); i++) {
277 string particle_name = (string)track.GetParticleName();
281 if (particle_name ==
"e-" || particle_name ==
"e+" || particle_name ==
"gamma") {
283 volume_energy_map[volume_name] += track.GetEnergyInVolume(
id);
286 volume_energy_map[volume_name] += quenching_factor * track.GetEnergyInVolume(
id);
291 Double_t energy_veto_max = 0;
292 for (
const auto& pair : volume_energy_map) {
293 Double_t veto_energy = pair.second;
294 SetObservableValue(pair.first +
"VolumeEDep" +
"Qf" + quenching_factor_string, veto_energy);
295 if (veto_energy > energy_veto_max) {
296 energy_veto_max = veto_energy;
299 SetObservableValue(
string(
"vetoAllEVetoMax") +
"Qf" + quenching_factor_string, energy_veto_max);
302 for (
const auto& pair : fVetoGroupVolumeNames) {
303 Double_t energy_veto_max_group = 0;
304 for (
unsigned int i = 0; i < pair.second.size(); i++) {
305 string volume_name = pair.second[i];
306 Double_t veto_energy = volume_energy_map[volume_name];
307 if (veto_energy > energy_veto_max_group) {
308 energy_veto_max_group = veto_energy;
313 for (
auto it = pair.first.cbegin(); it != pair.first.cend(); ++it) {
314 if (it == pair.first.cbegin()) {
315 group_name += std::toupper(*it);
317 group_name += std::tolower(*it);
320 SetObservableValue(
"vetoGroup" + group_name +
"EVetoMax" +
"Qf" + quenching_factor_string,
321 energy_veto_max_group);
325 std::set<int> neutronsCaptured = {};
326 for (
unsigned int i = 0; i <
fOutputG4Event->GetNumberOfTracks(); i++) {
328 string particle_name = (string)track.GetParticleName();
329 if (particle_name ==
"neutron") {
330 auto hits = track.GetHits();
331 for (
unsigned int j = 0; j < hits.GetNumberOfHits(); j++) {
332 string process_name = (string)track.GetProcessName(hits.GetProcess(j));
333 if (process_name ==
"nCapture") {
339 neutronsCaptured.insert(track.GetTrackID());
341 fNeutronsCapturedNumber += 1;
343 fNeutronsCapturedPosY.push_back(hits.GetY(j));
344 fNeutronsCapturedPosZ.push_back(hits.GetZ(j));
346 Int_t volumeId = hits.GetVolumeId(j);
347 Int_t isCaptureVolume = 0;
348 for (
const auto&
id : fCaptureVolumeIds) {
349 if (volumeId ==
id) {
355 fNeutronsCapturedProductionE.push_back(track.GetInitialKineticEnergy());
358 double neutronsCapturedEDepByNeutron = 0;
359 double neutronsCapturedEDepByNeutronAndChildren = 0;
360 double neutronsCapturedEDepByNeutronInVeto = 0;
361 double neutronsCapturedEDepByNeutronAndChildrenInVeto = 0;
363 std::set<int> parents = {track.GetTrackID()};
364 std::map<int, double> energyInVeto;
365 for (
unsigned int child = 0; child <
fOutputG4Event->GetNumberOfTracks(); child++) {
367 if ((parents.count(trackChild.GetParentID()) > 0) ||
368 parents.count(trackChild.GetTrackID()) > 0) {
370 parents.insert(trackChild.GetTrackID());
371 neutronsCapturedEDepByNeutronAndChildren += trackChild.GetTotalEnergy();
372 if (trackChild.GetTrackID() == track.GetTrackID()) {
373 neutronsCapturedEDepByNeutron += trackChild.GetTotalEnergy();
376 neutronsCapturedEDepByNeutronAndChildrenInVeto +=
377 trackChild.GetEnergyInVolume(vetoId);
378 energyInVeto[vetoId] += trackChild.GetEnergyInVolume(vetoId);
379 if (trackChild.GetTrackID() == track.GetTrackID()) {
380 neutronsCapturedEDepByNeutronInVeto +=
381 trackChild.GetEnergyInVolume(vetoId);
387 fNeutronsCapturedEDepByNeutron.push_back(neutronsCapturedEDepByNeutron);
388 fNeutronsCapturedEDepByNeutronAndChildren.push_back(
389 neutronsCapturedEDepByNeutronAndChildren);
390 fNeutronsCapturedEDepByNeutronInVeto.push_back(neutronsCapturedEDepByNeutronInVeto);
391 fNeutronsCapturedEDepByNeutronAndChildrenInVeto.push_back(
392 neutronsCapturedEDepByNeutronAndChildrenInVeto);
395 double energyMaxVeto = 0;
396 double energyMinVeto = -1;
397 for (
const auto& pair : energyInVeto) {
398 auto E = pair.second;
399 if (E > energyMaxVeto) energyMaxVeto = E;
400 if (E < energyMaxVeto || energyMinVeto == -1) energyMinVeto = E;
403 fNeutronsCapturedEDepByNeutronAndChildrenInVetoMax.push_back(energyMaxVeto);
404 fNeutronsCapturedEDepByNeutronAndChildrenInVetoMin.push_back(energyMinVeto);
417 SetObservableValue(
"neutronsCapturedEDepByNeutronAndChildren", fNeutronsCapturedEDepByNeutronAndChildren);
418 SetObservableValue(
"neutronsCapturedEDepByNeutronInVeto", fNeutronsCapturedEDepByNeutronInVeto);
420 fNeutronsCapturedEDepByNeutronAndChildrenInVeto);
422 fNeutronsCapturedEDepByNeutronAndChildrenInVetoMax);
424 fNeutronsCapturedEDepByNeutronAndChildrenInVetoMin);
425 for (
unsigned int i = 0; i <
fOutputG4Event->GetNumberOfTracks(); i++) {
427 string particle_name = (string)track.GetParticleName();
428 if (particle_name ==
"gamma") {
430 Int_t parent = track.GetParentID();
431 if (neutronsCaptured.count(parent) > 0) {
432 const auto& hits = track.GetHits();
434 fGammasNeutronCaptureNumber += 1;
435 fGammasNeutronCapturePosX.push_back(hits.GetX(0));
436 fGammasNeutronCapturePosY.push_back(hits.GetY(0));
437 fGammasNeutronCapturePosZ.push_back(hits.GetZ(0));
439 Int_t volumeId = hits.GetVolumeId(0);
440 Int_t isCaptureVolume = 0;
441 for (
const auto&
id : fCaptureVolumeIds) {
442 if (volumeId ==
id) {
447 fGammasNeutronCaptureIsCaptureVolume.push_back(isCaptureVolume);
448 fGammasNeutronCaptureProductionE.push_back(track.GetInitialKineticEnergy());
461 SetObservableValue(
"gammasNeutronCaptureIsCaptureVolume", fGammasNeutronCaptureIsCaptureVolume);
462 SetObservableValue(
"gammasNeutronCaptureProductionE", fGammasNeutronCaptureProductionE);
464 std::set<int> secondaryNeutrons = {};
465 for (
unsigned int i = 0; i <
fOutputG4Event->GetNumberOfTracks(); i++) {
467 string particle_name = (string)track.GetParticleName();
468 if (particle_name ==
"neutron" && track.GetParentID() != 0) {
470 auto hits = track.GetHits();
471 for (
unsigned int j = 0; j < hits.GetNumberOfHits(); j++) {
472 string process_name = (string)track.GetProcessName(hits.GetProcess(j));
473 if (process_name ==
"Transportation") {
474 for (
const auto&
id : fShieldingVolumeIds) {
475 if (hits.GetVolumeId(j) == id) {
477 if (secondaryNeutrons.count(track.GetTrackID()) == 0) {
479 secondaryNeutrons.insert(track.GetTrackID());
483 fSecondaryNeutronsShieldingNumber += 1;
484 fSecondaryNeutronsShieldingExitPosX.push_back(hits.GetX(j));
485 fSecondaryNeutronsShieldingExitPosY.push_back(hits.GetY(j));
486 fSecondaryNeutronsShieldingExitPosZ.push_back(hits.GetZ(j));
488 Int_t volumeId = hits.GetVolumeId(j);
489 Int_t isCaptureVolume = 0;
490 for (
const auto&
id : fCaptureVolumeIds) {
491 if (volumeId ==
id) {
496 Int_t isCaptured = 0;
497 if (neutronsCaptured.count(track.GetTrackID()) > 0) {
500 fSecondaryNeutronsShieldingIsCaptured.push_back(isCaptured);
502 fSecondaryNeutronsShieldingIsCapturedInCaptureVolume.push_back(
505 fSecondaryNeutronsShieldingIsCapturedInCaptureVolume.push_back(0);
508 fSecondaryNeutronsShieldingProductionE.push_back(track.GetInitialKineticEnergy());
509 fSecondaryNeutronsShieldingExitE.push_back(hits.GetKineticEnergy(j));
517 SetObservableValue(
"secondaryNeutronsShieldingNumber", fSecondaryNeutronsShieldingNumber);
518 SetObservableValue(
"secondaryNeutronsShieldingExitPosX", fSecondaryNeutronsShieldingExitPosX);
519 SetObservableValue(
"secondaryNeutronsShieldingExitPosY", fSecondaryNeutronsShieldingExitPosY);
520 SetObservableValue(
"secondaryNeutronsShieldingExitPosZ", fSecondaryNeutronsShieldingExitPosZ);
521 SetObservableValue(
"secondaryNeutronsShieldingIsCaptured", fSecondaryNeutronsShieldingIsCaptured);
523 fSecondaryNeutronsShieldingIsCapturedInCaptureVolume);
524 SetObservableValue(
"secondaryNeutronsShieldingProductionE", fSecondaryNeutronsShieldingProductionE);
525 SetObservableValue(
"secondaryNeutronsShieldingExitE", fSecondaryNeutronsShieldingExitE);
549 string veto_keyword =
GetParameter(
"vetoKeyword",
"veto");
552 string veto_group_keywords =
GetParameter(
"vetoGroupKeywords",
"");
553 stringstream ss(veto_group_keywords);
556 getline(ss, substr,
',');
562 string capture_keyword =
GetParameter(
"captureKeyword",
"sheet");
567 string shielding_keyword =
GetParameter(
"shieldingKeyword",
"shielding");
571 string quenching_factors =
GetParameter(
"vetoQuenchingFactors",
"-1");
572 stringstream ss_qf(quenching_factors);
573 while (ss_qf.good()) {
575 getline(ss_qf, substr,
',');
577 Float_t quenching_factor = (Float_t)std::atof(substr.c_str());
578 if (quenching_factor > 1 || quenching_factor < 0) {
579 cout <<
"ERROR: quenching factor must be between 0 and 1" << endl;
582 fQuenchingFactors.push_back(quenching_factor);
void SetObservableValue(const std::string &name, const T &value)
Set observable value for AnalysisTree.
A base class for any REST event.
An event class to store geant4 generated event information.
std::vector< Int_t > fNeutronsCapturedIsCaptureVolume
If documentation is added perhaps they could be shorter names.
void InitProcess() override
Process initialization.
void Initialize() override
Function to initialize input/output event members and define the section name.
TRestGeant4Event * fInputG4Event
A pointer to the specific TRestGeant4Event input.
void LoadConfig(const std::string &configFilename, const std::string &name="")
Function to load the configuration from an external configuration file.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
void InitFromConfigFile() override
Function to read input parameters from the RML TRestGeant4NeutronTaggingProcess metadata section.
std::vector< int > fVetoVolumeIds
TODO these members should be documented.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
void PrintMetadata() override
It prints out the process parameters stored in the metadata structure.
void EndProcess() override
Function to include required actions after all events have been processed.
std::vector< Double_t > fNeutronsCapturedPosX
TODO it might be simplified using std::vector<TVector3>
TRestGeant4Event * fOutputG4Event
A pointer to the specific TRestGeant4Event output.
~TRestGeant4NeutronTaggingProcess()
Default destructor.
TRestGeant4Metadata * fG4Metadata
A pointer to the simulation metadata information accessible to TRestRun.
std::string TrimAndLower(std::string s)
It trims and lowers the string.