ATLAS Offline Software
Loading...
Searching...
No Matches
VolumeTreeNavigator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// VolumeTreeNavigator.cxx //
8// Class containing functions to allow a general //
9// navigation of uniquely specified GEANT4 volumes //
10// and collection of their tree patterns and locations. //
11// //
12// Written by Kevin Sapp //
13// University of Pittsburgh //
14// kcs34@pitt.edu //
15// Last update 02.03.10 //
16// //
18
19#include "VolumeTreeNavigator.h"
20
21#include <string>
22#include <vector>
23#include <utility>
24
25#include "G4Track.hh"
26#include "G4StepPoint.hh"
27#include "G4VProcess.hh"
28#include "G4TouchableHistory.hh"
29#include "G4VPhysicalVolume.hh"
30#include "G4LogicalVolume.hh"
31
32using std::string; using std::vector;
33using std::pair; using std::make_pair;
34
36 AthMessaging("VolumeTreeNavigator"),
38
39{
40 // collect full set of volume tree data
41 m_track = aStep->GetTrack();
42 m_preStepPoint = aStep->GetPreStepPoint();
43 m_postStepPoint = aStep->GetPostStepPoint();
44 m_preHistory = dynamic_cast<const G4TouchableHistory*>(m_preStepPoint->GetTouchable());
45 if (not m_preHistory){
46 ATH_MSG_ERROR("Dynamic cast failed in VolumeTreeNavigator::VolumeTreeNavigator");
47 return;
48 }
49 m_preDepth = m_preHistory->GetHistoryDepth();
50 m_stepNo = m_track->GetCurrentStepNumber();
51
52 if (!m_history.empty()) m_history.clear();
53
54 // consolidate volume data into a vector
55 for (G4int c = m_preDepth; c + 1 != 0; c--) {
56 G4VPhysicalVolume* thPV = m_preHistory->GetVolume(c);
57 int thPVRep = (int)(thPV->GetCopyNo());
58 pair<G4VPhysicalVolume*, int> thPVID = make_pair(thPV, thPVRep);
59 m_history.push_back(thPVID);
60 }
61 ATH_MSG_DEBUG("history size: "<< m_history.size());
62
63 // Set h_end to specify full history unless otherwise chosen by DepthCut functions, and
64 // set h_nav to start at the lowest accessible level, h_end - 1.
65 m_h_end = m_history.end();
66 m_h_nav = m_h_end-1;
67}
68
69void VolumeTreeNavigator::SetDepthCutSimple(const int CALO, const int BeamPipe, const int IDET, const int MUONQ02)
70{
71 unsigned int cut = m_history.size();
72 if ( m_history.size() > 1 ) {
73 const string name = stringify(m_history[1].first->GetName());
74 if (name == "CALO::CALO") cut = CALO+1;
75 else if (name == "BeamPipe::BeamPipe") cut = BeamPipe+1;
76 else if (name == "IDET::IDET" || name == "ITK::ITK") cut = IDET+1;
77 else if (name == "MUONQ02::MUONQ02") cut = MUONQ02+1;
78 else { ATH_MSG_INFO("Level 1 volume not found, output default depth"); }
79 }
80 else if ( m_history.empty() ) {
81 ATH_MSG_FATAL("No volumes in history, run will terminate!");
82 }
83
84 if ( cut > m_history.size() ) cut = m_history.size();
85 m_h_end = m_history.begin();
86 advance(m_h_end, cut);
87 m_h_nav = m_h_end-1;
88 ATH_MSG_DEBUG("VolumeTreeNavigator::SetDepthCutSimple at "<< m_h_nav->first->GetName());
89 return;
90}
91
93{
94 static const vector<string> volumes = [&]() {
95 vector<string> v;
96 msg() << MSG::INFO <<"SetDepthCutDetail path parsed as ";
97 string path = stringify(cpath);
98 string::size_type slash = 0;
99 string::size_type start = path.find_first_not_of( '/' );
100 while ( slash != string::npos ) {
101 start = slash+1;
102 slash = path.find_first_of( '/', start );
103 v.push_back( path.substr(start, slash-start) );
104 msg() << MSG::INFO <<"/"<<volumes.back();
105 }
106 msg() << endmsg;
107 return v;
108 }();
109
111 vector<string>::const_iterator v_nav = volumes.begin();
112 advance( v_nav, distance( m_history.begin(), m_h_nav ) );
113 while ( v_nav != volumes.end() && m_h_nav != m_history.end() ) {
114 if ( *v_nav == stringify( m_h_nav->first->GetName() ) ) {
115 ++m_h_nav;
116 ++v_nav; }
117 else {
118 break; }
119 }
121 m_h_nav = m_h_end-1;
122 ATH_MSG_INFO("VolumeTreeNavigator::SetDepthCutDetail at "<< m_h_nav->first->GetName());
123 return;
124}
125
127{
128 // Derive a permanent VolTree object from the current volume and its history
129 VolTree ret;
130 for (VolNav t = m_history.begin(); t != m_h_nav+1; ++t) {
131 ret.push_back(*t);
132 }
133 ATH_MSG_DEBUG("VolumeTreeNavigator::Extract succeeded for "<< m_h_nav->first->GetName() <<".");
134 return ret;
135}
136
138 // Move up # of levels given in the navigable history, stop at Atlas::Atlas
139 if ( !m_history.empty() )
140 {
141 if ( distance( m_history.begin(), m_h_nav ) == 0 || levels == 0 ) return 0;
142 else if ( abs(levels) > abs(distance( m_history.begin(), m_h_nav )) )
143 levels = abs(distance( m_history.begin(), m_h_nav ));
144 advance(m_h_nav, -abs(levels));
145 return 1;
146 }
147 else return 0;
148}
149
151{
152 // Move down # of levels given in the navigable history
153 if ( !m_history.empty() )
154 {
155 if ( distance(m_h_nav, m_h_end) == 1 || levels == 0 ) return 0;
156 else if ( abs(levels) > abs(distance( m_h_nav, m_h_end-1 )) )
157 levels = abs(distance( m_h_nav, m_h_end-1 ));
158 advance(m_h_nav, abs(levels));
159 return 1;
160 }
161 else return 0;
162}
163
164bool VolumeTreeNavigator::KillProcesses(const int numProc, const char* pr1, ...)
165{
166 // Checks for disallowed processes, and if found returns true; accepts arbitrary number
167 // of process names.
168 const G4VProcess* pds = m_postStepPoint->GetProcessDefinedStep();
169 va_list procs;
170
171 if ( pds ) {
172 std::string name_string = stringify( pds->GetProcessName() );
173 const char* name = name_string.c_str();
174 va_start(procs, pr1);
175 for ( int i = 0; i != numProc; i++ ) {
176 if ( name == va_arg(procs, const char*) ) {
177 ATH_MSG_DEBUG(name <<" process triggered - return");
178 va_end(procs);
179 return 1;
180 }
181 }
182 va_end(procs);
183 }
184 return 0;
185}
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
std::vector< VolID > VolTree
VolTree::iterator VolNav
std::string stringify(T obj)
MsgStream & msg() const
The standard message stream.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
bool KillProcesses(const int, const char *,...)
int m_stepNo
depth of volume tree, step number
bool Ascend(int levels=1)
VolNav m_h_end
specifies cut termination in history
VolTree m_history
full volume history, cast as const after preparation
void SetDepthCutDetail(const char *)
bool Descend(int levels=1)
G4Track * m_track
current track
const G4TouchableHistory * m_preHistory
touchable history containing current volume's history
void SetDepthCutSimple(const int, const int, const int, const int)
VolumeTreeNavigator(const G4Step *)
G4StepPoint * m_preStepPoint
volume/process/etc.
G4StepPoint * m_postStepPoint
volume/process/etc.
VolNav m_h_nav
VolTree iterator with no access below cut.