REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestGeant4AnalysisProcess.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
280
281#include "TRestGeant4AnalysisProcess.h"
282
283#include <algorithm>
284#include <tuple>
285
286using namespace std;
287
289
294
308 Initialize();
309
310 if (LoadConfigFromFile(configFilename)) LoadDefaultConfig();
311}
312
317
321void TRestGeant4AnalysisProcess::LoadDefaultConfig() { SetTitle("Default config"); }
322
328 fG4Metadata = nullptr;
329 SetSectionName(this->ClassName());
330 SetLibraryVersion(LIBRARY_VERSION);
331
332 fInputG4Event = nullptr;
334}
335
348void TRestGeant4AnalysisProcess::LoadConfig(const string& configFilename, const string& name) {
349 if (LoadConfigFromFile(configFilename, name)) LoadDefaultConfig();
350}
351
352namespace {
353string CapitalizeFirst(string name) {
354 if (!name.empty()) {
355 name[0] = toupper(name[0]);
356 }
357 return name;
358}
359
360bool EndsWith(const string& text, const string& suffix) {
361 return text.size() >= suffix.size() &&
362 text.compare(text.size() - suffix.size(), suffix.size(), suffix) == 0;
363}
364
365bool StartsWith(const string& text, const string& prefix) { return text.rfind(prefix, 0) == 0; }
366} // namespace
367
373 static const map<string, string> processNameMap = {
374 // electromagnetic, photons
375 {"Photoelectric", "phot"},
376 {"Compton", "compt"},
377 {"Rayleigh", "Rayl"},
378 {"Conversion", "conv"},
379 {"PhotonNuclear", "photonNuclear"},
380 // electromagnetic, charged particles
381 {"Bremsstrahlung", "eBrem"},
382 {"Bremstralung", "eBrem"}, // legacy misspelling
383 {"Annihilation", "annihil"},
384 {"EIoni", "eIoni"},
385 {"HIoni", "hIoni"},
386 {"IonIoni", "ionIoni"},
387 {"MuIoni", "muIoni"},
388 {"Msc", "msc"},
389 {"CoulombScat", "CoulombScat"},
390 // hadronic
391 {"HadElastic", "hadElastic"},
392 {"NeutronInelastic", "neutronInelastic"},
393 {"NInelastic", "neutronInelastic"}, // legacy name
394 {"ProtonInelastic", "protonInelastic"},
395 {"NCapture", "nCapture"},
396 // decay
397 {"RadioactiveDecay", "RadioactiveDecay"},
398 {"RadiactiveDecay", "RadioactiveDecay"}, // legacy misspelling
399 {"Decay", "Decay"},
400 };
401 return processNameMap;
402}
403
411string TRestGeant4AnalysisProcess::GetGeant4ProcessName(const string& name) const {
412 if (name.empty()) {
413 return "";
414 }
415
416 const auto& processNameMap = GetRestToGeant4ProcessNameMap();
417 const auto it = processNameMap.find(name);
418 if (it != processNameMap.end()) {
419 return it->second;
420 }
421
422 for (const auto& [restName, geant4Name] : processNameMap) {
423 if (CapitalizeFirst(geant4Name) == name) {
424 return geant4Name;
425 }
426 }
427
428 if (fG4Metadata != nullptr) {
429 for (const auto& geant4Name : fG4Metadata->GetGeant4PhysicsInfo().GetAllProcesses()) {
430 if (CapitalizeFirst(geant4Name.Data()) == name) {
431 return geant4Name.Data();
432 }
433 }
434 }
435
436 return "";
437}
438
443 cout << endl;
444 cout << "??????????????????????????????????????????????????" << endl;
445 cout << "REST warning : TRestGeant4AnalysisProcess." << endl;
446 cout << "------------------------------------------" << endl;
447 cout << endl;
448 cout << " Volume " << volumeName << " is not an active volume" << endl;
449 cout << endl;
450 cout << "List of active volumes : " << endl;
451 cout << "------------------------ " << endl;
452
453 for (unsigned int n = 0; n < fG4Metadata->GetNumberOfActiveVolumes(); n++)
454 cout << "Volume " << n << " : " << fG4Metadata->GetActiveVolumeName(n) << endl;
455 cout << "??????????????????????????????????????????????????" << endl;
456 cout << endl;
457}
458
466 fG4Metadata = GetMetadata<TRestGeant4Metadata>();
467
468 // InitProcess may be called more than once
469 fEnergyInObservables.clear();
470 fVolumeID.clear();
471 fVolumeName.clear();
472 fMeanPosObservables.clear();
473 fVolumeID2.clear();
474 fDirID.clear();
475 fProcessObservables.clear();
476 fVolumeID3.clear();
477 fProcessVolumeName.clear();
478 fProcessName.clear();
480 fParticleTrackCounter.clear();
482 fParticleTrackEdep.clear();
486 fPerProcessG4Names.clear();
487 fPerProcessParticle.clear();
488
489 std::vector<string> fObservables;
490 fObservables = TRestEventProcess::ReadObservables();
491 std::map<std::string, std::string> aliasObsToVol = GetAliasObservableNameToVolume();
492
493 const auto& physicsInfo = fG4Metadata->GetGeant4PhysicsInfo();
494 const auto availableProcesses = physicsInfo.GetAllProcesses();
495
496 // containsProcessPhot and containsProcessCompt are always evaluated (historical behaviour)
497 fContainsProcessObservables = {"containsProcessPhot", "containsProcessCompt"};
498 fContainsProcessG4Name = {"phot", "compt"};
499
501 // {observable name, particle (empty for any), Geant4 processes}
502 const vector<tuple<string, string, vector<string>>> perProcessDefinitions = {
503 {"PerProcessPhotoelectric", "", {"phot"}},
504 {"PerProcessCompton", "", {"compt"}},
505 {"PerProcessElectronicIoni", "", {"eIoni"}},
506 {"PerProcessAlphaIoni", "alpha", {"ionIoni", "alphaIoni"}},
507 {"PerProcessIonIoni", "", {"ionIoni"}},
508 {"PerProcessHadronicIoni", "", {"hIoni"}},
509 {"PerProcessProtonIoni", "proton", {"hIoni"}},
510 {"PerProcessMsc", "", {"msc"}},
511 {"PerProcessHadronElastic", "", {"hadElastic"}},
512 {"PerProcessNeutronElastic", "neutron", {"hadElastic"}},
513 };
514 for (const auto& [obsName, particle, processes] : perProcessDefinitions) {
515 fPerProcessObservables.push_back(obsName);
516 fPerProcessParticle.push_back(particle);
517 fPerProcessG4Names.push_back(processes);
518 if (fAnalysisTree != nullptr) {
519 fAnalysisTree->AddObservable((string)GetName() + "_" + obsName, "double",
520 "Energy deposited in the sensitive volume by a given process");
521 }
522 }
523 }
524
525 for (unsigned int i = 0; i < fObservables.size(); i++) {
526 if (fObservables[i].find("VolumeEDep") != string::npos) {
527 TString volName = fObservables[i].substr(0, fObservables[i].length() - 10).c_str();
528 if (aliasObsToVol.find(fObservables[i]) != aliasObsToVol.end()) {
529 volName = aliasObsToVol[fObservables[i]].c_str();
530 }
531
532 Int_t volId = fG4Metadata->GetActiveVolumeID(volName);
533 if (volId >= 0) {
534 fEnergyInObservables.push_back(fObservables[i]);
535 fVolumeID.push_back(volId);
536 fVolumeName.push_back(volName.Data());
537 }
538
539 if (volId == -1) {
541 }
542 }
543
544 if (fObservables[i].find("MeanPos") != string::npos) {
545 TString volName2 = fObservables[i].substr(0, fObservables[i].length() - 8).c_str();
546 if (aliasObsToVol.find(fObservables[i]) != aliasObsToVol.end()) {
547 volName2 = aliasObsToVol[fObservables[i]].c_str();
548 }
549 std::string dirId = fObservables[i].substr(fObservables[i].length() - 1, 1);
550
551 Int_t volId2 = fG4Metadata->GetActiveVolumeID(volName2);
552 if (volId2 >= 0) {
553 fMeanPosObservables.push_back(fObservables[i]);
554 fVolumeID2.push_back(volId2);
555 fDirID.push_back(dirId);
556 }
557
558 if (volId2 == -1) {
560 }
561
562 if ((dirId != "X") && (dirId != "Y") && (dirId != "Z")) {
563 cout << endl;
564 cout << "??????????????????????????????????????????????????" << endl;
565 cout << "REST warning : TRestGeant4AnalysisProcess." << endl;
566 cout << "------------------------------------------" << endl;
567 cout << endl;
568 cout << " Direction " << dirId << " is not valid" << endl;
569 cout << " Only X, Y or Z accepted" << endl;
570 cout << endl;
571 }
572 }
573
574 if (StartsWith(fObservables[i], "containsProcess")) {
575 const string processSuffix = fObservables[i].substr(string("containsProcess").length());
576 if (std::find(fContainsProcessObservables.begin(), fContainsProcessObservables.end(),
577 fObservables[i]) != fContainsProcessObservables.end()) {
578 continue;
579 }
580 const string geant4Name = GetGeant4ProcessName(processSuffix);
581 if (geant4Name.empty()) {
582 RESTWarning << "TRestGeant4AnalysisProcess: unknown process '" << processSuffix
583 << "' in observable '" << fObservables[i] << "'. It will not be filled."
584 << RESTendl;
585 continue;
586 }
587 if (availableProcesses.count(geant4Name) == 0) {
588 RESTWarning << "TRestGeant4AnalysisProcess: Geant4 process '" << geant4Name
589 << "' (observable '" << fObservables[i]
590 << "') is not registered in the physics info of this simulation. "
591 << "Its value will always be 0 (processes sharing type and subtype, e.g. "
592 << "eIoni and ionIoni, are registered only once)" << RESTendl;
593 }
594 fContainsProcessObservables.push_back(fObservables[i]);
595 fContainsProcessG4Name.push_back(geant4Name);
596 continue;
597 }
598
599 // <volume><Process>Process observables. Other observables ending in "Process" are excluded.
600 if (EndsWith(fObservables[i], "Process") && !StartsWith(fObservables[i], "firstTrackInSensitive")) {
601 const string nameWithoutSuffix =
602 fObservables[i].substr(0, fObservables[i].length() - string("Process").length());
603 const bool hasAlias = aliasObsToVol.find(fObservables[i]) != aliasObsToVol.end();
604
605 // find the longest trailing substring which is a known process name
606 string processName;
607 string geant4Name;
608 for (size_t length = 1; length <= nameWithoutSuffix.length(); length++) {
609 // the volume name may only be empty if it is given through the `volume` attribute
610 if (length == nameWithoutSuffix.length() && !hasAlias) {
611 break;
612 }
613 const string candidate = nameWithoutSuffix.substr(nameWithoutSuffix.length() - length);
614 const string candidateGeant4Name = GetGeant4ProcessName(candidate);
615 if (!candidateGeant4Name.empty()) {
616 processName = candidate;
617 geant4Name = candidateGeant4Name;
618 }
619 }
620
621 if (geant4Name.empty()) {
622 RESTWarning << "TRestGeant4AnalysisProcess: no known process name found in observable '"
623 << fObservables[i] << "'. It will not be filled." << RESTendl;
624 RESTWarning << "Valid process names are:";
625 for (const auto& [restName, g4Name] : GetRestToGeant4ProcessNameMap()) {
626 RESTWarning << " " << restName;
627 }
628 RESTWarning << " (or a Geant4 process name with the first letter capitalized)" << RESTendl;
629 continue;
630 }
631
632 TString volName3 = nameWithoutSuffix.substr(0, nameWithoutSuffix.length() - processName.length());
633 if (hasAlias) {
634 volName3 = aliasObsToVol[fObservables[i]].c_str();
635 }
636 Int_t volId3 = fG4Metadata->GetActiveVolumeID(volName3);
637
638 if (volId3 >= 0) {
639 fProcessObservables.push_back(fObservables[i]);
640 fVolumeID3.push_back(volId3);
641 fProcessVolumeName.emplace_back(volName3.Data());
642 fProcessName.push_back(geant4Name);
643 if (availableProcesses.count(geant4Name) == 0) {
644 RESTWarning << "TRestGeant4AnalysisProcess: Geant4 process '" << geant4Name
645 << "' (observable '" << fObservables[i]
646 << "') is not registered in the physics info of this simulation. "
647 << "It will be 0 unless energy is deposited under this process name "
648 << "(processes sharing type and subtype, e.g. eIoni and ionIoni, are "
649 << "registered only once)" << RESTendl;
650 }
651 } else {
653 }
654 }
655
656 if (fObservables[i].find("TracksCounter") != string::npos) {
657 TString particleName = fObservables[i].substr(0, fObservables[i].length() - 13).c_str();
658 fTrackCounterObservables.push_back(fObservables[i]);
659 fParticleTrackCounter.emplace_back(particleName.Data());
660 }
661
662 if (fObservables[i].find("TracksEDep") != string::npos) {
663 TString particleName = fObservables[i].substr(0, fObservables[i].length() - 10).c_str();
664 fTracksEDepObservables.push_back(fObservables[i]);
665 fParticleTrackEdep.emplace_back(particleName.Data());
666 }
667 }
668}
669
674 fInputG4Event = (TRestGeant4Event*)inputEvent;
675 *fOutputG4Event = *((TRestGeant4Event*)inputEvent);
676
677 const auto sensitiveVolumeName = fG4Metadata->GetSensitiveVolume();
678
679 Double_t sensitiveVolumeEnergy = fOutputG4Event->GetEnergyInVolume(sensitiveVolumeName.Data());
680 // Get time of the first hit in the sensitive volume
681 double hitTime = std::numeric_limits<double>::infinity();
682 std::set<int> trackIdsInSensitiveVolume;
683
684 for (const auto& track : fOutputG4Event->GetTracks()) {
685 const auto& hits = track.GetHits();
686 for (size_t hitIndex = 0; hitIndex < hits.GetNumberOfHits(); hitIndex++) {
687 const auto volumeName = hits.GetVolumeName(hitIndex);
688 if (volumeName != sensitiveVolumeName) {
689 continue;
690 }
691 const double energy = hits.GetEnergy(hitIndex);
692 if (energy <= 0) {
693 continue;
694 }
695
696 const double time = hits.GetTime(hitIndex);
697 if (time < hitTime) {
698 hitTime = time;
699 }
700
701 trackIdsInSensitiveVolume.insert(track.GetTrackID());
702 }
703 }
704
705 SetObservableValue("sensitiveVolumeFirstHitTime", hitTime);
706
707 std::set<int> trackParentsOfInterest;
708 for (const auto& trackIdInSensitiveVolume : trackIdsInSensitiveVolume) {
709 const auto track = fOutputG4Event->GetTrackByID(trackIdInSensitiveVolume);
710 TRestGeant4Track* parent = track;
711 bool found = false;
712 while (parent != nullptr && !found) {
713 // iterate over hits
714 const auto& hits = parent->GetHits();
715 if (hits.GetVolumeName(0) != sensitiveVolumeName) {
716 for (size_t hitIndex = 0; hitIndex < hits.GetNumberOfHits(); hitIndex++) {
717 const auto volumeName = hits.GetVolumeName(hitIndex);
718 if (volumeName != sensitiveVolumeName) {
719 found = true;
720 trackParentsOfInterest.insert(parent->GetTrackID());
721 break;
722 }
723 }
724 }
725
726 parent = parent->GetParentTrack();
727 }
728 }
729
730 if (!trackParentsOfInterest.empty()) {
731 const auto track = fOutputG4Event->GetTrackByID(*trackParentsOfInterest.begin());
732
733 const auto position = track->GetInitialPosition();
734 SetObservableValue("firstTrackInSensitivePositionX", position.X());
735 SetObservableValue("firstTrackInSensitivePositionY", position.Y());
736 SetObservableValue("firstTrackInSensitivePositionZ", position.Z());
737
738 const auto energy = track->GetInitialKineticEnergy();
739 SetObservableValue("firstTrackInSensitiveEnergy", energy);
740
741 const string particleName = track->GetParticleName().Data();
742 SetObservableValue("firstTrackInSensitiveParticle", particleName);
743
744 string parentParticleName;
745 if (track->GetParentTrack() != nullptr) {
746 parentParticleName = track->GetParentTrack()->GetParticleName().Data();
747 }
748 SetObservableValue("firstTrackInSensitiveParentParticle", parentParticleName);
749
750 const string creatorProcess = track->GetCreatorProcess().Data();
751 SetObservableValue("firstTrackInSensitiveCreatorProcess", creatorProcess);
752
753 const string volumeName = track->GetHits().GetVolumeName(0).Data();
754 SetObservableValue("firstTrackInSensitiveVolumeName", volumeName);
755 }
756
757 SetObservableValue("firstTrackInSensitiveOk", trackParentsOfInterest.size() == 1);
758
760 cout << "----------------------------" << endl;
761 cout << "TRestGeant4Event : " << fOutputG4Event->GetID() << endl;
762 cout << "Sensitive volume Energy : " << sensitiveVolumeEnergy << endl;
763 cout << "Total energy : " << fOutputG4Event->GetTotalDepositedEnergy() << endl;
764 }
765
766 SetObservableValue("sensitiveVolumeEnergy", sensitiveVolumeEnergy);
767
768 Double_t xOrigin = fOutputG4Event->GetPrimaryEventOrigin().X();
769 SetObservableValue("xOriginPrimary", xOrigin);
770
771 Double_t yOrigin = fOutputG4Event->GetPrimaryEventOrigin().Y();
772 SetObservableValue("yOriginPrimary", yOrigin);
773
774 Double_t zOrigin = fOutputG4Event->GetPrimaryEventOrigin().Z();
775 SetObservableValue("zOriginPrimary", zOrigin);
776
777 Double_t xDirection = fOutputG4Event->GetPrimaryEventDirection(0).X();
778 SetObservableValue("xDirectionPrimary", xDirection);
779
780 Double_t yDirection = fOutputG4Event->GetPrimaryEventDirection(0).Y();
781 SetObservableValue("yDirectionPrimary", yDirection);
782
783 Double_t zDirection = fOutputG4Event->GetPrimaryEventDirection(0).Z();
784 SetObservableValue("zDirectionPrimary", zDirection);
785
786 SetObservableValue("eventPrimaryParticleName", fOutputG4Event->GetPrimaryEventParticleName(0));
787 string subEventPrimaryParticleName;
788 if (fOutputG4Event->GetSubID() != 0) {
789 subEventPrimaryParticleName = fOutputG4Event->GetSubEventPrimaryEventParticleName();
790 } else {
791 subEventPrimaryParticleName = "generator";
792 }
793 SetObservableValue("subEventPrimaryParticleName", subEventPrimaryParticleName);
794
795 TVector3 primaryDirection(xDirection, yDirection, zDirection);
796 primaryDirection = primaryDirection.Unit();
797 SetObservableValue("thetaPrimary", primaryDirection.Theta());
798 SetObservableValue("phiPrimary", primaryDirection.Phi());
799 SetObservableValue("zenithYDegrees", TMath::ACos(-1 * yDirection) * TMath::RadToDeg());
800 TVector3 sourceDirection = fG4Metadata->GetParticleSource(0)->GetDirection();
801 sourceDirection = sourceDirection.Unit();
802 SetObservableValue("zenithSourceDegrees",
803 TMath::ACos(primaryDirection.Dot(sourceDirection)) * TMath::RadToDeg());
804
805 Double_t energyPrimary = fOutputG4Event->GetPrimaryEventEnergy(0);
806 SetObservableValue("energyPrimary", energyPrimary);
807
808 Double_t energyTotal = fOutputG4Event->GetTotalDepositedEnergy();
809 SetObservableValue("totalEdep", energyTotal);
810
811 Double_t size = fOutputG4Event->GetBoundingBoxSize();
812 SetObservableValue("boundingSize", size);
813
814 // containsProcessXxx observables: 1 if the event contains the Geant4 process, 0 otherwise
815 const auto& physicsInfo = fG4Metadata->GetGeant4PhysicsInfo();
816 for (unsigned int n = 0; n < fContainsProcessObservables.size(); n++) {
817 const auto& processName = fContainsProcessG4Name[n];
818 const Int_t processID = physicsInfo.GetProcessID(processName);
819 // GetProcessID returns a default id (0) for unknown processes, which may be a valid id
820 const bool processIsRegistered = physicsInfo.GetProcessName(processID) == processName;
821 Int_t containsProcess = 0;
822 if (processIsRegistered && fOutputG4Event->ContainsProcess(processID)) {
823 containsProcess = 1;
824 }
826 }
827
828 if (!fProcessObservables.empty()) {
829 const auto energyInVolumePerProcess = fOutputG4Event->GetEnergyInVolumePerProcessMap();
830 for (unsigned int n = 0; n < fProcessObservables.size(); n++) {
831 Double_t energy = 0;
832 const auto volume = energyInVolumePerProcess.find(fProcessVolumeName[n]);
833 if (volume != energyInVolumePerProcess.end()) {
834 const auto process = volume->second.find(fProcessName[n]);
835 if (process != volume->second.end()) {
836 energy = process->second;
837 }
838 }
840 }
841 }
842
843 if (!fPerProcessObservables.empty()) {
844 const auto energyInVolumePerParticlePerProcess =
845 fOutputG4Event->GetEnergyInVolumePerParticlePerProcessMap();
846 const auto sensitiveVolume = energyInVolumePerParticlePerProcess.find(sensitiveVolumeName.Data());
847 for (unsigned int n = 0; n < fPerProcessObservables.size(); n++) {
848 Double_t energy = 0;
849 if (sensitiveVolume != energyInVolumePerParticlePerProcess.end()) {
850 for (const auto& [particle, energyPerProcess] : sensitiveVolume->second) {
851 if (!fPerProcessParticle[n].empty() && particle != fPerProcessParticle[n]) {
852 continue;
853 }
854 for (const auto& processName : fPerProcessG4Names[n]) {
855 const auto process = energyPerProcess.find(processName);
856 if (process != energyPerProcess.end()) {
857 energy += process->second;
858 }
859 }
860 }
861 }
863 energy = sensitiveVolumeEnergy > 0 ? energy / sensitiveVolumeEnergy : 0;
864 }
866 }
867 }
868
869 for (unsigned int n = 0; n < fParticleTrackCounter.size(); n++) {
870 Int_t nT = fOutputG4Event->GetNumberOfTracksForParticle(fParticleTrackCounter[n]);
871 string obsName = fTrackCounterObservables[n];
872 SetObservableValue(obsName, nT);
873 }
874
875 for (unsigned int n = 0; n < fTracksEDepObservables.size(); n++) {
876 Double_t energy = fOutputG4Event->GetEnergyDepositedByParticle(fParticleTrackEdep[n]);
877 string obsName = fTracksEDepObservables[n];
878 SetObservableValue(obsName, energy);
879 }
880
881 for (unsigned int n = 0; n < fEnergyInObservables.size(); n++) {
882 Double_t en = fOutputG4Event->GetEnergyInVolume(fVolumeName[n]);
883 string obsName = fEnergyInObservables[n];
884 SetObservableValue(obsName, en);
885 }
886
887 for (unsigned int n = 0; n < fMeanPosObservables.size(); n++) {
888 string obsName = fMeanPosObservables[n];
889
890 Double_t mpos = 0;
891 if (fDirID[n] == (TString) "X")
892 mpos = fOutputG4Event->GetMeanPositionInVolume(fVolumeID2[n]).X();
893
894 else if (fDirID[n] == (TString) "Y")
895 mpos = fOutputG4Event->GetMeanPositionInVolume(fVolumeID2[n]).Y();
896
897 else if (fDirID[n] == (TString) "Z")
898 mpos = fOutputG4Event->GetMeanPositionInVolume(fVolumeID2[n]).Z();
899
900 SetObservableValue(obsName, mpos);
901 }
902
904 cout << "G4 Tracks : " << fOutputG4Event->GetNumberOfTracks() << endl;
905 cout << "----------------------------" << endl;
906 }
907
908 return fOutputG4Event;
909}
910
911std::map<std::string, std::string> TRestGeant4AnalysisProcess::GetAliasObservableNameToVolume() {
912 TiXmlElement* e = GetElement("observable");
913 std::map<std::string, std::string> obsNamesToVolumes;
914
915 while (e != nullptr) {
916 const char* obschr = e->Attribute("name");
917 const char* _value = e->Attribute("value");
918 const char* _vol = e->Attribute("volume");
919
920 string value;
921 if (_value == nullptr)
922 value = "ON";
923 else
924 value = _value;
925
926 if (ToUpper(value) == "ON") {
927 if (obschr != nullptr) {
928 string volume;
929 if (_vol) {
930 volume = _vol;
931 obsNamesToVolumes[(string)obschr] = volume;
932 }
933 }
934 }
935
936 e = e->NextSiblingElement("observable");
937 }
938
939 return obsNamesToVolumes;
940}
941
TRestAnalysisTree * fAnalysisTree
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
A pure analysis process to extract information from a TRestGeant4Event.
std::vector< std::string > fPerProcessParticle
The particle restriction of each PerProcessXxx observable (empty means any particle).
void Initialize() override
Function to initialize input/output event members and define the section name.
std::vector< std::string > fEnergyInObservables
It stores the name of observables xxxVolumeEDep related to the energy deposition in volume xxx.
std::vector< std::string > fDirID
std::string GetGeant4ProcessName(const std::string &name) const
It returns the Geant4 process name corresponding to name.
void InitProcess() override
Process initialization. Observable names are interpreted and auxiliar observable members,...
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.
TRestGeant4Metadata * fG4Metadata
A pointer to the simulation metadata information accessible to TRestRun.
~TRestGeant4AnalysisProcess()
Default destructor.
std::vector< std::string > fTracksEDepObservables
A std::vector storing the observable name xxxTracksEDep for a given xxx particle.
std::vector< std::string > fParticleTrackCounter
A std::vector storing the xxx particle name extracted from xxxTracksCounter.
std::vector< std::string > fProcessObservables
std::vector< Int_t > fVolumeID2
A std::vector storing the active volume ids corresponding mean position observable xxxMeanPosX,...
Bool_t fPerProcessSensitiveEnergyNorm
If true, PerProcessXxx observables are normalized to the total energy in the sensitive volume.
std::vector< std::string > fProcessVolumeName
A std::vector storing the volume name corresponding to each process observable.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
std::vector< std::string > fPerProcessObservables
A std::vector storing the observable names PerProcessXxx (only if fPerProcessSensitiveEnergy).
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
std::vector< std::string > fContainsProcessObservables
A std::vector storing the observable names containsProcessXxx.
std::vector< Int_t > fVolumeID
A std::vector storing the active volume ids of observables xxxVolumeEDep.
TRestGeant4Event * fOutputG4Event
A pointer to the specific TRestGeant4Event output.
std::vector< std::string > fTrackCounterObservables
A std::vector storing the observable name xxxTracksCounter for a given xxx particle.
std::vector< std::vector< std::string > > fPerProcessG4Names
The Geant4 process names contributing to each PerProcessXxx observable.
std::vector< Int_t > fVolumeID3
A std::vector storing the active volume ids corresponding process observable .
static const std::map< std::string, std::string > & GetRestToGeant4ProcessNameMap()
It returns the map between the process names used in REST observables (<volume><Process>Process) and ...
TRestGeant4AnalysisProcess()
Default constructor.
std::vector< std::string > fMeanPosObservables
A std::vector storing the name of active volumes.
std::vector< std::string > fProcessName
A std::vector storing the Geant4 name of the process corresponding to each process observable.
void EndProcess() override
Function to include required actions after all events have been processed.
std::vector< std::string > fContainsProcessG4Name
A std::vector storing the Geant4 process name corresponding to each containsProcessXxx observable.
std::vector< std::string > fParticleTrackEdep
A std::vector storing the xxx particle name extracted from xxxTracksEDep.
void PrintNotActiveVolumeWarning(const TString &volumeName)
It prints a warning when the volume used by an observable is not an active volume.
An event class to store geant4 generated event information.
Double_t GetBoundingBoxSize()
This method returns the event size as the size of the bounding box enclosing all hits.
const TRestGeant4PhysicsInfo & GetGeant4PhysicsInfo() const
Returns an immutable reference to the physics info.
TString GetSensitiveVolume(int n=0) const
Returns a std::string with the name of the sensitive volume.
Int_t GetActiveVolumeID(const TString &name)
Returns the id of an active volume giving as parameter its name.
unsigned int GetNumberOfActiveVolumes() const
Returns the number of active volumes, or geometry volumes that have been selected for data storage.
TString GetActiveVolumeName(Int_t n) const
Returns a std::string with the name of the active volume with index n.
TRestGeant4ParticleSource * GetParticleSource(size_t n=0) const
Returns the name of the particle source with index n (Geant4 based names).
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.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
void SetSectionName(std::string sName)
set the section name, clear the section content
@ REST_Debug
+show the defined debug messages
std::string ToUpper(std::string in)
Convert string to its upper case. Alternative of TString::ToUpper.