ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Simulation
G4Atlas
G4AtlasTools
src
SensitiveDetectorBase.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
6
7
// Base class
8
#include "
G4AtlasTools/SensitiveDetectorBase.h
"
9
// Geant4 includes used in functions
10
#include "G4LogicalVolumeStore.hh"
11
#include "G4MultiSensitiveDetector.hh"
12
#include "G4SDManager.hh"
13
// STL includes
14
#include <sstream>
15
16
17
SensitiveDetectorBase::SensitiveDetectorBase
(
const
std::string&
type
,
18
const
std::string& name,
19
const
IInterface* parent)
20
: base_class(
type
,name,parent)
21
{
22
}
23
24
// Athena method used to set up the SDs for the current worker thread.
25
StatusCode
SensitiveDetectorBase::initializeSD
()
26
{
27
ATH_MSG_VERBOSE
( name() <<
"::initializeSD()"
);
28
29
// Sanity check for volume configuration problems.
30
// It would be better to have a more robust solution for this.
31
if
(
m_volumeNames
.empty() !=
m_noVolumes
) {
32
ATH_MSG_ERROR
(
"Initializing SD from "
<< name() <<
", NoVolumes = "
33
<< (
m_noVolumes
?
"true"
:
"false"
) <<
", but LogicalVolumeNames = "
34
<<
m_volumeNames
.value());
35
return
StatusCode::FAILURE;
36
}
37
38
// Make the SD stored by this tool
39
auto
sd = std::unique_ptr<G4VSensitiveDetector>(makeSD());
40
if
(!sd)
41
{
42
ATH_MSG_ERROR
(
"Failed to create SD!"
);
43
return
StatusCode::FAILURE;
44
}
45
// Assign the SD to our list of volumes
46
ATH_CHECK
(
assignSD
( std::move(sd),
m_volumeNames
.value() ) );
47
48
ATH_MSG_DEBUG
(
"Initialized and added SD "
<< name() );
49
return
StatusCode::SUCCESS;
50
}
51
52
//-----------------------------------------------------------------------------
53
// Assign an SD to a list of volumes
54
//-----------------------------------------------------------------------------
55
StatusCode
SensitiveDetectorBase::
56
assignSD
(std::unique_ptr<G4VSensitiveDetector> sd,
const
std::vector<std::string>& volumes)
const
57
{
58
// Propagate verbosity setting to the SD
59
if
(msgLvl(MSG::VERBOSE)) sd->SetVerboseLevel(10);
60
else
if
(msgLvl(MSG::DEBUG)) sd->SetVerboseLevel(5);
61
62
// Add the sensitive detector to the SD manager in G4 for SDs,
63
// even if it has no volumes associated to it.
64
auto
sdMgr = G4SDManager::GetSDMpointer();
65
auto
sdPtr = sd.get();
66
// SDManager is now the SD owner
67
//for later use
68
auto
sdName = sd->GetName();
69
sdMgr->AddNewDetector(sd.release());
70
71
if
(!volumes.empty()) {
72
bool
gotOne =
false
;
73
auto
logicalVolumeStore = G4LogicalVolumeStore::GetInstance();
74
for
(
const
auto
& volumeName : volumes) {
75
// Keep track of how many volumes we find with this name string.
76
// We allow for multiple matches.
77
int
numFound = 0;
78
79
// Find volumes with this name
80
for
(
auto
* logVol : *logicalVolumeStore) {
81
82
ATH_MSG_VERBOSE
(
"Check whether "
<<logVol->GetName()<<
" belongs to the set of sensitive detectors "
<<volumeName);
83
if
(
matchStrings
( volumeName.data(), logVol->GetName() ) ){
84
++numFound;
85
SetSensitiveDetector
(logVol, sdPtr);
86
}
87
88
}
89
// Warn if no volumes were found
90
if
(numFound == 0) {
91
ATH_MSG_WARNING
(
"Volume "
<< volumeName <<
92
" not found in G4LogicalVolumeStore."
);
93
}
94
else
{
95
ATH_MSG_VERBOSE
(
"Found "
<< numFound <<
" copies of LV "
<< volumeName <<
96
"; SD "
<< sdName <<
" assigned."
);
97
gotOne =
true
;
98
}
99
100
}
101
102
// Abort if we have failed to assign any volume
103
if
(!gotOne) {
104
ATH_MSG_ERROR
(
"Failed to assign *any* volume to SD "
<< name() <<
105
" and expected at least one. Size of the volume store "
<<G4LogicalVolumeStore::GetInstance()->
size
() );
106
return
StatusCode::FAILURE;
107
}
108
}
109
110
return
StatusCode::SUCCESS;
111
}
112
113
//This function was adapted from the example found at
114
//https://www.geeksforgeeks.org/wildcard-character-matching/
115
bool
SensitiveDetectorBase::matchStrings
(
const
char
*first,
const
char
*second)
116
{
117
// If we reach at the end of both strings, we are done
118
if
(*first ==
'\0'
&& *second ==
'\0'
)
119
return
true
;
120
121
// If there are consecutive '*' present in the first string
122
// advance to the next character
123
if
(*first ==
'*'
&& *(first + 1) ==
'*'
)
124
return
matchStrings
(first + 1, second);
125
126
// Make sure that the characters after '*' are present in second string.
127
if
(*first ==
'*'
&& *(first + 1) !=
'\0'
&& *second ==
'\0'
)
128
return
false
;
129
130
// If the current characters of both strings match
131
if
(*first == *second)
132
return
matchStrings
(first + 1, second + 1);
133
134
// If there is *, then there are two possibilities
135
// a) We consider current character of second string
136
// b) We ignore current character of second string.
137
if
(*first ==
'*'
)
138
return
matchStrings
(first + 1, second) ||
matchStrings
(first, second + 1);
139
return
false
;
140
}
141
142
void
SensitiveDetectorBase::
143
SetSensitiveDetector
(G4LogicalVolume* logVol, G4VSensitiveDetector* aSD)
const
144
{
145
// New Logic: allow for "multiple" SDs being attached to a single LV.
146
// To do that we use a special proxy SD called G4MultiSensitiveDetector
147
148
// Get existing SD if already set and check if it is of the special type
149
G4VSensitiveDetector* originalSD = logVol->GetSensitiveDetector();
150
if
( originalSD ==
nullptr
)
151
{
152
logVol->SetSensitiveDetector(aSD);
153
}
154
else
155
{
156
G4MultiSensitiveDetector* msd =
dynamic_cast<
G4MultiSensitiveDetector*
>
(originalSD);
157
if
( msd !=
nullptr
)
158
{
159
msd->AddSD(aSD);
160
}
161
else
162
{
163
// Construct a unique name using the volume address
164
std::stringstream
ss
;
165
ss << static_cast<const void*>
(logVol);
166
const
G4String msdname =
"/MultiSD_"
+ logVol->GetName() +
ss
.str();
167
msd =
new
G4MultiSensitiveDetector(std::move(msdname));
168
// We need to register the proxy to have correct handling of IDs
169
G4SDManager::GetSDMpointer()->AddNewDetector(msd);
170
msd->AddSD(originalSD);
171
msd->AddSD(aSD);
172
logVol->SetSensitiveDetector(msd);
173
}
174
}
175
}
176
ATH_CHECK
#define ATH_CHECK
Evaluate an expression and check for errors.
Definition
AthCheckMacros.h:40
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition
AthMsgStreamMacros.h:33
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition
AthMsgStreamMacros.h:28
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition
AthMsgStreamMacros.h:32
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition
AthMsgStreamMacros.h:29
ss
static Double_t ss
Definition
LArPhysWaveHECTool.cxx:37
SensitiveDetectorBase.h
size
size_t size() const
Number of registered mappings.
SensitiveDetectorBase::assignSD
StatusCode assignSD(std::unique_ptr< G4VSensitiveDetector > sd, const std::vector< std::string > &volumes) const
Assign SD to a list of volumes.
Definition
SensitiveDetectorBase.cxx:56
SensitiveDetectorBase::m_volumeNames
Gaudi::Property< std::vector< std::string > > m_volumeNames
All the volumes to which this SD is assigned.
Definition
SensitiveDetectorBase.h:78
SensitiveDetectorBase::initializeSD
StatusCode initializeSD() override
Setup an SD in the current thread.
Definition
SensitiveDetectorBase.cxx:25
SensitiveDetectorBase::m_noVolumes
Gaudi::Property< bool > m_noVolumes
This SensitiveDetector has no volumes associated with it.
Definition
SensitiveDetectorBase.h:83
SensitiveDetectorBase::SensitiveDetectorBase
SensitiveDetectorBase(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.
Definition
SensitiveDetectorBase.cxx:17
SensitiveDetectorBase::matchStrings
static bool matchStrings(const char *first, const char *second)
Match two strings with wildcard support.
Definition
SensitiveDetectorBase.cxx:115
SensitiveDetectorBase::SetSensitiveDetector
void SetSensitiveDetector(G4LogicalVolume *, G4VSensitiveDetector *) const
Method stolen from G4VUserDetectorConstruction in G4 10.2.
Definition
SensitiveDetectorBase.cxx:143
type
Generated on
for ATLAS Offline Software by
1.17.0