ATLAS Offline Software
Loading...
Searching...
No Matches
TestActionEHist.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// TestActionEHist.cxx //
8// Code for ROOT output (filename selected in code) //
9// of histograms of the initial kinetic energy //
10// (from truth) of specified particles, by volume. //
11// //
12// Written by Kevin Sapp //
13// University of Pittsburgh //
14// kcs34@pitt.edu //
15// Last update 07.09.09 //
16// //
18
19#include "TestActionEHist.h"
20
21#include "G4Track.hh"
22#include "G4Electron.hh"
23#include "G4Gamma.hh"
24#include "G4Positron.hh"
25#include "G4ParticleDefinition.hh"
26#include "G4TouchableHistory.hh"
27#include "G4VPhysicalVolume.hh"
28#include "G4LogicalVolume.hh"
29#include "G4VProcess.hh"
30#include "TFile.h"
31#include "TH1F.h"
32
33#include <cstdlib>
34
35using std::string;
36using std::stringstream;
37using std::vector;
38
39// #define _myDebug
40
41namespace G4UA
42{
43
48
49
50 void TestActionEHist::PreUserTrackingAction(const G4Track* aTrack)
51 {
52 if (aTrack) {
53
54 // Set Particle label and empty trajectory
55 G4ParticleDefinition* pDef = aTrack->GetDefinition();
56 const G4String& pName = pDef->GetParticleName();
57 const G4String& pSubType = pDef->GetParticleSubType();
58 if (pName == "neutron" || pName == "proton" ) { m_p_tag = pName; }
59 else if (pSubType =="e" || pSubType == "pi" ) { m_p_tag = pSubType; }
60 else { m_p_tag = pDef->GetParticleType(); }
61 if (!m_trajectory.empty()) m_trajectory.clear();
62 }
63 }
64
65 void TestActionEHist::PostUserTrackingAction(const G4Track* aTrack)
66 {
67 if (aTrack) {
68 m_trajectory.clear();
69 }
70 }
71
73 {
74 // initialize histogramming file (DON'T USE GAUDI) & directories
75 delete m_world;
76 m_world = new TFile(m_config.name.c_str(), "RECREATE");
77 G4cout<<m_config.name<<" initialized, in directory "<<gDirectory->GetPath()<<G4endl;
78 }
79
81 {
82 m_world->Write();
83 m_world->Close();
84 delete m_world;
85 G4cout<<m_config.name<<" saved & closed."<<G4endl;
86 }
87
88 void TestActionEHist::UserSteppingAction(const G4Step* aStep)
89 {
90 if (aStep) {
91
92 // Create tree structure for current step
93 VolumeTreeNavigator currentTree( aStep );
94
95 // check for processes which don't need to be histogrammed
96 //if ( currentTree.KillProcesses( 2, "nKiller", "G4FastSimulationManagerProcess" ) ) return;
97
98 // Stores a list of the names of leaf-node volumes which the track has entered
99 // and checks it for earlier occurences of the same volume
100 m_firstStep = true;
101 if (currentTree.GetStepNumber() > 1) {
102 for ( vector<string>::const_iterator it = m_trajectory.begin();
103 it != m_trajectory.end(); ++it ) {
104 if ( *it == stringify( currentTree.GetVolume()->GetName() ) ) {
105 m_firstStep = false;
106 break;
107 }
108 }
109 }
110
111 // For particles' first step in the current volume
112 if (m_firstStep) {
113 // push_back trajectory element
114 m_trajectory.push_back( stringify( currentTree.GetVolume()->GetName() ) );
115
116 // set depth cut (MUST implement Simple if Detail is used)
117 currentTree.SetDepthCutSimple(m_config.dCALO, m_config.dBeam, m_config.dIDET, m_config.dMUON);
118 // Detailed depth cut format: /Atlas::Atlas/[level 1]/[level 2]/.../[last directory level]
119 if ( !m_config.dDetail.empty() ) {
120 currentTree.SetDepthCutDetail( m_config.dDetail.c_str() );
121 }
122
123 //for( auto histelement : currentTree.GetHistory())
124 // std::cout<<histelement.first->GetName()<< std::endl;
125 //std::cout<<"end dump tree "<<std::endl;
126 //std::cout<<"before ascending "<<currentTree.GetVolume()->GetName()<<std::endl;
127
128 // go to ATLAS::ATLAS
129 currentTree.Ascend( currentTree.GetCurrentDepth() );
130
131 while ( true ) {
132 // collect naming info for histogram
133 G4VPhysicalVolume* pv = currentTree.GetVolume();
134 string thPV = cleanstr(pv->GetName());
135 string thNoDau = stringify(pv->GetLogicalVolume()->GetNoDaughters());
136 int thRep = currentTree.GetCopyNumber();
137
138 // construct keyname & directory title
139 string v_name = (thRep == 16969 ? std::move(thPV) : thPV+"_"+stringify(thRep));
140 string p_name = m_p_tag + ( currentTree.GetStepNumber() != 1 ? "_entred" : "_madein" );
141 string title = thNoDau+" daughters, "+stringify(currentTree.GetCurrentDepth())+" from base";
142
143 // Build and fill histogram at bottom of tree, then build dir and cd to it
144 if ( currentTree.GetStepNumber() == 1 || currentTree.GetCurrentDepth() == currentTree.GetFullDepth() ) {
145 BuildHists(v_name, p_name, m_config.maxhists, currentTree.GetPreStepPoint()->GetKineticEnergy());
146 }
147 if ( !currentTree.Descend() ) break;
148 if ( !BuildDirs(v_name, title, m_config.maxdirs) ) break;
149 }
150
151 // Return to world to get ready for next step... FINALLY
152 m_world->cd();
153 }
154 }
155 }
156
157 // Call or create histogram & fill it; returns fill status
158 void TestActionEHist::BuildHists(const string& vol_tag, const string& part_tag, int& hLeft,
159 double xfill, double weight, const int nbins,
160 const int binsize)
161 {
162 TH1F* hExists =
163 (TH1F*)gDirectory->FindObjectAny((part_tag+"_"+vol_tag+"_hist").c_str());
164 if (!hLeft && !hExists) { return; }
165 else if (!hExists) {
166 hExists = new TH1F((part_tag+"_"+vol_tag+"_hist").c_str(),
167 (part_tag+" KE in "+vol_tag).c_str(),
168 nbins,0,nbins*binsize);
169 hLeft--;
170 //G4cout<<"Histogram "<<gDirectory->GetPath()<<"/"<<hExists->GetName()<<" created"<<G4endl;
171 if (!hLeft) G4cout<<"Last histogram reached"<<G4endl;
172 }
173
174 if (xfill >= 0 && weight >= 0) { hExists->Fill(xfill,weight); }
175 else if (xfill >= 0) { hExists->Fill(xfill); }
176 else { return; }
177 }
178
179 // Call or create directory & cd into it; returns directory-change status
180 bool TestActionEHist::BuildDirs(const string& vol_tag, const string& dirTitle, int& dLeft)
181 {
182 bool enter = false;
183 TDirectory* dExists = (TDirectory*)gDirectory->FindObjectAny(vol_tag.c_str());
184 if (!dLeft && !dExists) { return enter; }
185 if (!dExists) {
186 dExists = new TDirectoryFile(vol_tag.c_str(),
187 dirTitle.c_str());
188 dLeft--;
189
190 if (!dLeft) G4cout<<"Last directory created"<<G4endl;
191 }
192
193 if (dExists) enter = (bool)dExists->cd();
194 // if (enter) ATH_MSG_DEBUG("Current directory: "<<gDirectory->GetPath());
195 return enter;
196 }
197
198} // namespace G4UA
std::string cleanstr(T obj)
std::string stringify(T obj)
TestActionEHist(const Config &config)
Config m_config
holds the python configuration
void BuildHists(const std::string &vol_tag, const std::string &part_tag, int &hLeft, double xfill=-1, double yfill=-1, const int nbins=3000, const int binsize=1)
Size of bins in histogram, in MeV.
virtual void EndOfRunAction(const G4Run *) override
bool BuildDirs(const std::string &vol_tag, const std::string &dirTitle, int &dLeft)
Remaining directories to create.
virtual void PreUserTrackingAction(const G4Track *) override
std::string m_p_tag
Used to specify current particle in tracking.
bool m_firstStep
Flag indicating whether step is first in current volume.
TFile * m_world
File in which to store neutron & electron info.
std::vector< std::string > m_trajectory
Used to store volume names which the current track has entered.
virtual void UserSteppingAction(const G4Step *) override
virtual void PostUserTrackingAction(const G4Track *) override
virtual void BeginOfRunAction(const G4Run *) override
int GetStepNumber() const
bool Ascend(int levels=1)
G4VPhysicalVolume * GetVolume(int rel=0) const
int GetCopyNumber(int rel=0) const
void SetDepthCutDetail(const char *)
bool Descend(int levels=1)
void SetDepthCutSimple(const int, const int, const int, const int)
const G4StepPoint * GetPreStepPoint() const
int GetFullDepth() const