ATLAS Offline Software
Loading...
Searching...
No Matches
VolumeTreeNavigator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 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 m_preDepth = m_preHistory->GetHistoryDepth();
46 m_stepNo = m_track->GetCurrentStepNumber();
47
48 if (!m_history.empty()) m_history.clear();
49
50 // consolidate volume data into a vector
51 for (G4int c = m_preDepth; c + 1 != 0; c--) {
52 G4VPhysicalVolume* thPV = m_preHistory->GetVolume(c);
53 int thPVRep = (int)(thPV->GetCopyNo());
54 pair<G4VPhysicalVolume*, int> thPVID = make_pair(thPV, thPVRep);
55 m_history.push_back(thPVID);
56 }
57 ATH_MSG_DEBUG("history size: "<< m_history.size());
58
59 // Set h_end to specify full history unless otherwise chosen by DepthCut functions, and
60 // set h_nav to start at the lowest accessible level, h_end - 1.
61 m_h_end = m_history.end();
62 m_h_nav = m_h_end-1;
63}
64
65void VolumeTreeNavigator::SetDepthCutSimple(const int CALO, const int BeamPipe, const int IDET, const int MUONQ02)
66{
67 unsigned int cut = m_history.size();
68 if ( m_history.size() > 1 ) {
69 const string name = stringify(m_history[1].first->GetName());
70 if (name == "CALO::CALO") cut = CALO+1;
71 else if (name == "BeamPipe::BeamPipe") cut = BeamPipe+1;
72 else if (name == "IDET::IDET" || name == "ITK::ITK") cut = IDET+1;
73 else if (name == "MUONQ02::MUONQ02") cut = MUONQ02+1;
74 else { ATH_MSG_INFO("Level 1 volume not found, output default depth"); }
75 }
76 else if ( m_history.empty() ) {
77 ATH_MSG_FATAL("No volumes in history, run will terminate!");
78 }
79
80 if ( cut > m_history.size() ) cut = m_history.size();
81 m_h_end = m_history.begin();
82 advance(m_h_end, cut);
83 m_h_nav = m_h_end-1;
84 ATH_MSG_DEBUG("VolumeTreeNavigator::SetDepthCutSimple at "<< m_h_nav->first->GetName());
85 return;
86}
87
89{
90 static const vector<string> volumes = [&]() {
91 vector<string> v;
92 msg() << MSG::INFO <<"SetDepthCutDetail path parsed as ";
93 string path = stringify(cpath);
94 string::size_type slash = 0;
95 string::size_type start = path.find_first_not_of( '/' );
96 while ( slash != string::npos ) {
97 start = slash+1;
98 slash = path.find_first_of( '/', start );
99 v.push_back( path.substr(start, slash-start) );
100 msg() << MSG::INFO <<"/"<<volumes.back();
101 }
102 msg() << endmsg;
103 return v;
104 }();
105
107 vector<string>::const_iterator v_nav = volumes.begin();
108 advance( v_nav, distance( m_history.begin(), m_h_nav ) );
109 while ( v_nav != volumes.end() && m_h_nav != m_history.end() ) {
110 if ( *v_nav == stringify( m_h_nav->first->GetName() ) ) {
111 ++m_h_nav;
112 ++v_nav; }
113 else {
114 break; }
115 }
117 m_h_nav = m_h_end-1;
118 ATH_MSG_INFO("VolumeTreeNavigator::SetDepthCutDetail at "<< m_h_nav->first->GetName());
119 return;
120}
121
123{
124 // Derive a permanent VolTree object from the current volume and its history
125 VolTree ret;
126 for (VolNav t = m_history.begin(); t != m_h_nav+1; ++t) {
127 ret.push_back(*t);
128 }
129 ATH_MSG_DEBUG("VolumeTreeNavigator::Extract succeeded for "<< m_h_nav->first->GetName() <<".");
130 return ret;
131}
132
134 // Move up # of levels given in the navigable history, stop at Atlas::Atlas
135 if ( !m_history.empty() )
136 {
137 if ( distance( m_history.begin(), m_h_nav ) == 0 || levels == 0 ) return 0;
138 else if ( abs(levels) > abs(distance( m_history.begin(), m_h_nav )) )
139 levels = abs(distance( m_history.begin(), m_h_nav ));
140 advance(m_h_nav, -abs(levels));
141 return 1;
142 }
143 else return 0;
144}
145
147{
148 // Move down # of levels given in the navigable history
149 if ( !m_history.empty() )
150 {
151 if ( distance(m_h_nav, m_h_end) == 1 || levels == 0 ) return 0;
152 else if ( abs(levels) > abs(distance( m_h_nav, m_h_end-1 )) )
153 levels = abs(distance( m_h_nav, m_h_end-1 ));
154 advance(m_h_nav, abs(levels));
155 return 1;
156 }
157 else return 0;
158}
159
160bool VolumeTreeNavigator::KillProcesses(const int numProc, const char* pr1, ...)
161{
162 // Checks for disallowed processes, and if found returns true; accepts arbitrary number
163 // of process names.
164 const G4VProcess* pds = m_postStepPoint->GetProcessDefinedStep();
165 va_list procs;
166
167 if ( pds ) {
168 std::string name_string = stringify( pds->GetProcessName() );
169 const char* name = name_string.c_str();
170 va_start(procs, pr1);
171 for ( int i = 0; i != numProc; i++ ) {
172 if ( name == va_arg(procs, const char*) ) {
173 ATH_MSG_DEBUG(name <<" process triggered - return");
174 va_end(procs);
175 return 1;
176 }
177 }
178 va_end(procs);
179 }
180 return 0;
181}
#define endmsg
#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.