Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparison of cosmic generator with disk #129

Merged
merged 15 commits into from
Sep 28, 2024
12 changes: 2 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,8 @@ set_library_version(LibraryVersion)
add_definitions(-DLIBRARY_VERSION="${LibraryVersion}")

if (${REST_DECAY0} MATCHES "ON")
add_definitions(-DUSE_Decay0)
# TODO Issue #6 at rest-framework
# ----------------------------------------------------------------------------
# Find package Decay0 and ROOT find_package(BxDecay0 1.0.9 CONFIG COMPONENTS
# manager REQUIRED)
#
# find_package was not working properly for me in 1.0.9. So I was using
# bxdecay0-config. But in case Decay0 flag is enabled and we do not have a
# bxdecay0 installation we might run into problems
#
add_definitions(-DUSE_Decay0
)# https://github.com/rest-for-physics/framework/issues/6

execute_process(
COMMAND bxdecay0-config --version
Expand Down
10 changes: 9 additions & 1 deletion inc/TRestGeant4Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class TRestGeant4Event : public TRestEvent {
Double_t fTotalDepositedEnergy = 0;
Double_t fSensitiveVolumeEnergy = 0;

double fEventTimeWall = 0;
double fEventTimeWallPrimaryGeneration = 0;

Int_t fNVolumes;
std::vector<Int_t> fVolumeStored;
std::vector<std::string> fVolumeStoredNames;
Expand Down Expand Up @@ -150,6 +153,9 @@ class TRestGeant4Event : public TRestEvent {
size_t GetNumberOfHits(Int_t volID = -1) const;
size_t GetNumberOfPhysicalHits(Int_t volID = -1) const;

double GetEventTimeWall() const { return fEventTimeWall; }
double GetEventTimeWallPrimaryGeneration() const { return fEventTimeWallPrimaryGeneration; }

inline const std::vector<TRestGeant4Track>& GetTracks() const { return fTracks; }
inline size_t GetNumberOfTracks() const { return fTracks.size(); }
inline Int_t GetNumberOfActiveVolumes() const { return fNVolumes; }
Expand Down Expand Up @@ -180,6 +186,8 @@ class TRestGeant4Event : public TRestEvent {
return energyMap[volumeName];
}

inline void ClearTracks() { fTracks.clear(); }

TRestHits GetHits(Int_t volID = -1) const;
inline TRestHits GetHitsInVolume(Int_t volID) const { return GetHits(volID); }

Expand Down Expand Up @@ -244,7 +252,7 @@ class TRestGeant4Event : public TRestEvent {
// Destructor
virtual ~TRestGeant4Event();

ClassDefOverride(TRestGeant4Event, 8); // REST event superclass
ClassDefOverride(TRestGeant4Event, 9); // REST event superclass

// restG4
public:
Expand Down
20 changes: 15 additions & 5 deletions inc/TRestGeant4Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class TRestGeant4Metadata : public TRestMetadata {
/// \brief Time before simulation is ended and saved
Double_t fSimulationMaxTimeSeconds = 0;

/// \brief The time, in seconds, that the simulation took to complete.
/// \brief The time, in seconds, that the simulation took to complete (wall time)
Double_t fSimulationTime = 0;

/// \brief The seed value used for Geant4 random event generator.
Expand All @@ -153,6 +153,9 @@ class TRestGeant4Metadata : public TRestMetadata {
/// \brief If activated will remove tracks not present in volumes marked as "keep" or "sensitive".
Bool_t fRemoveUnwantedTracks = false;

/// \brief Store event tracks (default is true)
Bool_t fStoreTracks = false;

/// \brief Option for 'removeUnwantedTracks', if enabled tracks with hits in volumes will be kept event if
/// they deposit zero energy (such as neutron captures)
Bool_t fRemoveUnwantedTracksKeepZeroEnergyTracks = false;
Expand Down Expand Up @@ -269,8 +272,6 @@ class TRestGeant4Metadata : public TRestMetadata {

inline Double_t GetSimulationMaxTimeSeconds() const { return fSimulationMaxTimeSeconds; }

inline Double_t GetSimulationTime() const { return fSimulationTime; }

// Direct access to sources definition in primary generator
///////////////////////////////////////////////////////////
/// Returns the number of primary event sources defined in the generator.
Expand Down Expand Up @@ -369,17 +370,26 @@ class TRestGeant4Metadata : public TRestMetadata {
return result;
}

double GetGeneratorSurfaceCm2() const;

Double_t GetCosmicFluxInCountsPerCm2PerSecond() const;
Double_t GetCosmicIntensityInCountsPerSecond() const;

/// Returns the equivalent simulated time in seconds (physical time simulated)
Double_t GetEquivalentSimulatedTime() const;

/// Returns the total time of the simulation in seconds (wall time)
inline Double_t GetSimulationWallTime() const { return fSimulationTime; }

/// Returns a std::string with the name of the active volume with index n
inline TString GetActiveVolumeName(Int_t n) const { return fActiveVolumes[n]; }

inline std::vector<TString> GetActiveVolumes() const { return fActiveVolumes; }

inline bool GetRemoveUnwantedTracks() const { return fRemoveUnwantedTracks; }

bool GetStoreTracks() const { return fStoreTracks; }

inline bool GetRemoveUnwantedTracksKeepZeroEnergyTracks() const {
return fRemoveUnwantedTracksKeepZeroEnergyTracks;
}
Expand All @@ -393,7 +403,7 @@ class TRestGeant4Metadata : public TRestMetadata {

void SetActiveVolume(const TString& name, Double_t chance, Double_t maxStep = 0);

void SetSimulationTime(Double_t time) { fSimulationTime = time; }
void SetSimulationWallTime(Double_t time) { fSimulationTime = time; }

void PrintMetadata() override;

Expand All @@ -407,7 +417,7 @@ class TRestGeant4Metadata : public TRestMetadata {
TRestGeant4Metadata(const TRestGeant4Metadata& metadata);
TRestGeant4Metadata& operator=(const TRestGeant4Metadata& metadata);

ClassDefOverride(TRestGeant4Metadata, 18);
ClassDefOverride(TRestGeant4Metadata, 19);

// Allow modification of otherwise inaccessible / immutable members that shouldn't be modified by the user
friend class SteppingAction;
Expand Down
1 change: 1 addition & 0 deletions inc/TRestGeant4ParticleSourceCosmics.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class TRestGeant4ParticleSourceCosmics : public TRestGeant4ParticleSource {
const char* GetName() const override { return "TRestGeant4ParticleSourceCosmics"; }

std::map<std::string, TH2D*> GetHistogramsTransformed() const { return fHistogramsTransformed; }
std::set<std::string> GetParticleNames() const { return fParticleNames; }

ClassDefOverride(TRestGeant4ParticleSourceCosmics, 2);
};
Expand Down
4 changes: 2 additions & 2 deletions inc/TRestGeant4PrimaryGeneratorInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ class TRestGeant4PrimaryGeneratorInfo {

/// \brief Returns cosmic surface term (cm2) for simulation time computation
inline Double_t GetSpatialGeneratorCosmicSurfaceTermCm2() const {
const auto radius = GetSpatialGeneratorCosmicRadius() / 10.;
return M_PI * radius * radius;
const auto radius = GetSpatialGeneratorCosmicRadius();
return M_PI * radius * radius * 0.01; // cm2
}

/// \brief Returns the density function of the generator
Expand Down
30 changes: 15 additions & 15 deletions macros/REST_Geant4_MergeRestG4Files.C
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ void REST_Geant4_MergeRestG4Files(const char* outputFilename, const char* inputF
// open the first file
TRestGeant4Metadata mergeMetadata;

auto mergeRun = new TRestRun();
mergeRun->SetName("run");
mergeRun->SetOutputFileName(outputFilename);
mergeRun->FormOutputFile();
mergeRun->GetOutputFile()->cd();
mergeRun->SetRunType("restG4");
TRestRun mergeRun;
mergeRun.SetName("run");
mergeRun.SetOutputFileName(outputFilename);
mergeRun.FormOutputFile();
mergeRun.GetOutputFile()->cd();
mergeRun.SetRunType("restG4");

TRestGeant4Event* mergeEvent = nullptr;
auto mergeEventTree = mergeRun->GetEventTree();
auto mergeEventTree = mergeRun.GetEventTree();
mergeEventTree->Branch("TRestGeant4EventBranch", "TRestGeant4Event", &mergeEvent);

set<Int_t> eventIds; // std::set is sorted from lower to higher automatically
Expand All @@ -71,8 +71,8 @@ void REST_Geant4_MergeRestG4Files(const char* outputFilename, const char* inputF
map<Int_t, Int_t>
eventIdUpdates; // repeatedId -> newId. Make sure if there are repeated event ids in a file
// (because of sub-events) they keep the same event id after modification
auto run = TRestRun(inputFiles[i].c_str());
auto metadata = (TRestGeant4Metadata*)run.GetMetadataClass("TRestGeant4Metadata");
TRestRun run(inputFiles[i].c_str());
auto metadata = dynamic_cast<TRestGeant4Metadata*>(run.GetMetadataClass("TRestGeant4Metadata"));
if (i == 0) {
mergeMetadata = *metadata;
} else {
Expand Down Expand Up @@ -106,23 +106,23 @@ void REST_Geant4_MergeRestG4Files(const char* outputFilename, const char* inputF
eventIds.insert(mergeEvent->GetID());

mergeEventTree->Fill();
mergeRun->GetAnalysisTree()->Fill();
mergeRun.GetAnalysisTree()->Fill();

eventCounter++;
}
}

cout << "Output filename: " << mergeRun->GetOutputFileName() << endl;
cout << "Output file: " << mergeRun->GetOutputFile() << endl;
cout << "Output filename: " << mergeRun.GetOutputFileName() << endl;
cout << "Output file: " << mergeRun.GetOutputFile() << endl;

mergeRun->GetOutputFile()->cd();
mergeRun.GetOutputFile()->cd();

gGeoManager->Write("Geometry", TObject::kOverwrite);

mergeMetadata.SetName("geant4Metadata");
mergeMetadata.Write();
mergeRun->UpdateOutputFile();
mergeRun->CloseFile();
mergeRun.UpdateOutputFile();
mergeRun.CloseFile();

// Open the file again to check the number of events
TRestRun runCheck(outputFilename);
Expand Down
8 changes: 5 additions & 3 deletions src/TRestGeant4Event.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,11 @@ TVector3 TRestGeant4Event::GetFirstPositionInVolume(Int_t volID) const {
/// \param volID Int_t specifying volume ID
///
TVector3 TRestGeant4Event::GetLastPositionInVolume(Int_t volID) const {
for (int t = GetNumberOfTracks() - 1; t >= 0; t--)
if (GetTrack(t).GetEnergyInVolume(volID) > 0) return GetTrack(t).GetLastPositionInVolume(volID);

for (int t = GetNumberOfTracks() - 1; t >= 0; t--) {
if (GetTrack(t).GetEnergyInVolume(volID) > 0) {
return GetTrack(t).GetLastPositionInVolume(volID);
}
}
Double_t nan = TMath::QuietNaN();
return {nan, nan, nan};
}
Expand Down
111 changes: 77 additions & 34 deletions src/TRestGeant4Metadata.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,9 @@ void TRestGeant4Metadata::InitFromConfigFile() {
}
fNEvents = nEventsString == PARAMETER_NOT_FOUND_STR ? 0 : StringToInteger(nEventsString);

fStoreTracks = ToUpper(GetParameter("storeTracks", "true")) == "TRUE" ||
ToUpper(GetParameter("storeTracks", "on")) == "ON";

const auto fNRequestedEntriesString = GetParameter("nRequestedEntries");
fNRequestedEntries =
fNRequestedEntriesString == PARAMETER_NOT_FOUND_STR ? 0 : StringToInteger(fNRequestedEntriesString);
Expand Down Expand Up @@ -921,44 +924,59 @@ void TRestGeant4Metadata::InitFromConfigFile() {
///

Double_t TRestGeant4Metadata::GetCosmicFluxInCountsPerCm2PerSecond() const {
if (TRestGeant4PrimaryGeneratorTypes::StringToSpatialGeneratorTypes(
fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorType().Data()) !=
TRestGeant4PrimaryGeneratorTypes::SpatialGeneratorTypes::COSMIC) {
RESTError
<< "TRestGeant4Metadata::GetEquivalentSimulatedTime can only be called for 'cosmic' generator"
<< RESTendl;
exit(1);
}
const auto source = GetParticleSource();

double countsPerSecondPerCm2 = 0;
if (TRestGeant4PrimaryGeneratorTypes::StringToEnergyDistributionTypes(
source->GetEnergyDistributionType().Data()) !=
TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::FORMULA2) {
RESTError << "TRestGeant4Metadata::GetEquivalentSimulatedTime can only be called for 'formula2' "
"energy distribution"
<< RESTendl;
exit(1);
source->GetEnergyDistributionType().Data()) ==
TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::FORMULA2 &&
TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
source->GetAngularDistributionType().Data()) ==
TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::FORMULA2) {
const auto energyRange = source->GetEnergyDistributionRange();
const auto angularRange = source->GetAngularDistributionRange();
auto function = (TF2*)source->GetEnergyAndAngularDistributionFunction()->Clone();
// counts per second per cm2 (distribution is already integrated over uniform phi)
countsPerSecondPerCm2 =
function->Integral(energyRange.X(), energyRange.Y(), angularRange.X(), angularRange.Y(), 1E-9);
}
if (TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
source->GetAngularDistributionType().Data()) !=
TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::FORMULA2) {
RESTError << "TRestGeant4Metadata::GetEquivalentSimulatedTime can only be called for 'formula' "
"angular distribution"
<< RESTendl;
exit(1);

else if (std::string(source->GetName()) == "TRestGeant4ParticleSourceCosmics") {
auto cosmicSource = dynamic_cast<TRestGeant4ParticleSourceCosmics*>(source);
const auto names = cosmicSource->GetParticleNames();
const auto histograms = cosmicSource->GetHistogramsTransformed();
for (const auto& name : names) {
countsPerSecondPerCm2 += histograms.at(name)->Integral();
}
} else if (TRestGeant4PrimaryGeneratorTypes::StringToEnergyDistributionTypes(
source->GetEnergyDistributionType().Data()) ==
TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::TH2D &&
TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
source->GetAngularDistributionType().Data()) ==
TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::TH2D) {
const auto filename = source->GetEnergyDistributionFilename();
const auto name = source->GetEnergyDistributionNameInFile();
TFile* file = TFile::Open(filename);
auto energyAndAngularDistributionHistogram =
file->Get<TH2D>(name); // it's the same for both angular and energy
if (energyAndAngularDistributionHistogram == nullptr) {
throw std::runtime_error("Histogram not found in file");
}
countsPerSecondPerCm2 = energyAndAngularDistributionHistogram->Integral();
file->Close();
delete file;
}

else {
throw std::runtime_error("Cosmic flux calculation is only supported for TFormula2 or TH2D sources");
}

const auto energyRange = source->GetEnergyDistributionRange();
const auto angularRange = source->GetAngularDistributionRange();
auto function = (TF2*)source->GetEnergyAndAngularDistributionFunction()->Clone();
// counts per second per cm2 (distribution is already integrated over uniform phi)
const auto countsPerSecondPerCm2 =
function->Integral(energyRange.X(), energyRange.Y(), angularRange.X(), angularRange.Y(), 1E-9);
return countsPerSecondPerCm2;
}

Double_t TRestGeant4Metadata::GetCosmicIntensityInCountsPerSecond() const {
const auto countsPerSecondPerCm2 = GetCosmicFluxInCountsPerCm2PerSecond();
const auto surface = fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorCosmicSurfaceTermCm2();
const auto surface = GetGeneratorSurfaceCm2();
const auto countsPerSecond = countsPerSecondPerCm2 * surface;
return countsPerSecond;
}
Expand Down Expand Up @@ -1565,13 +1583,32 @@ void TRestGeant4Metadata::SetActiveVolume(const TString& name, Double_t chance,
fActiveVolumesSet.insert(name.Data());
}

double TRestGeant4Metadata::GetGeneratorSurfaceCm2() const {
const auto type = ToLower(fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorType());
const auto shape = ToLower(fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorShape());

if (type == "surface" && shape == "circle") {
const auto radius = fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorSize().X();
return TMath::Pi() * radius * radius * 0.01; // cm2
} else if (type == "cosmic") {
return fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorCosmicSurfaceTermCm2();
}

throw std::runtime_error(
"TRestGeant4Metadata::GetGeneratorSurfaceCm2: Can only be called for 'cosmic' and 'surface/circle' "
"generators");
}

///////////////////////////////////////////////
/// \brief Returns true if the volume named *volName* has been registered for
/// data storage.
///
Bool_t TRestGeant4Metadata::isVolumeStored(const TString& volume) const {
for (unsigned int n = 0; n < GetNumberOfActiveVolumes(); n++)
if (GetActiveVolumeName(n) == volume) return true;
for (unsigned int n = 0; n < GetNumberOfActiveVolumes(); n++) {
if (GetActiveVolumeName(n) == volume) {
return true;
}
}

return false;
}
Expand All @@ -1580,9 +1617,12 @@ Bool_t TRestGeant4Metadata::isVolumeStored(const TString& volume) const {
/// \brief Returns the probability of an active volume being stored
///
Double_t TRestGeant4Metadata::GetStorageChance(const TString& volume) {
Int_t id;
for (id = 0; id < (Int_t)fActiveVolumes.size(); id++) {
if (fActiveVolumes[id] == volume) return fChance[id];
for (auto id = 0; id < (Int_t)fActiveVolumes.size(); id++) {
{
if (fActiveVolumes[id] == volume) {
return fChance[id];
}
}
}
RESTWarning << "TRestGeant4Metadata::GetStorageChance. Volume " << volume << " not found" << RESTendl;

Expand Down Expand Up @@ -1624,7 +1664,9 @@ void TRestGeant4Metadata::Merge(const TRestGeant4Metadata& metadata) {
fSimulationTime += metadata.fSimulationTime;
}

TRestGeant4Metadata::TRestGeant4Metadata(const TRestGeant4Metadata& metadata) { *this = metadata; }
TRestGeant4Metadata::TRestGeant4Metadata(const TRestGeant4Metadata& metadata) : TRestMetadata(metadata) {
*this = metadata;
}

TRestGeant4Metadata& TRestGeant4Metadata::operator=(const TRestGeant4Metadata& metadata) {
fIsMerge = metadata.fIsMerge;
Expand All @@ -1647,6 +1689,7 @@ TRestGeant4Metadata& TRestGeant4Metadata::operator=(const TRestGeant4Metadata& m
fSensitiveVolumes = metadata.fSensitiveVolumes;
fNEvents = metadata.fNEvents;
fNRequestedEntries = metadata.fNRequestedEntries;
fStoreTracks = metadata.fStoreTracks;
fSimulationMaxTimeSeconds = metadata.fSimulationMaxTimeSeconds;
fSeed = metadata.fSeed;
fSaveAllEvents = metadata.fSaveAllEvents;
Expand Down
Loading