ATLAS Offline Software
Loading...
Searching...
No Matches
AFP_SiDSensitiveDetectorTool Class Reference

#include <AFP_SiDSensitiveDetectorTool.h>

Inheritance diagram for AFP_SiDSensitiveDetectorTool:
Collaboration diagram for AFP_SiDSensitiveDetectorTool:

Public Member Functions

 AFP_SiDSensitiveDetectorTool (const std::string &type, const std::string &name, const IInterface *parent)
 ~AFP_SiDSensitiveDetectorTool ()
StatusCode SetupEvent () override final
 Beginning of an athena event.
StatusCode Gather () override final
 End of an athena event.
StatusCode initializeSD () override
 Setup an SD in the current thread.
virtual StatusCode SetupEvent (HitCollectionMap &) override
virtual StatusCode Gather (HitCollectionMap &) override

Protected Member Functions

G4VSensitiveDetector * makeSD () const override final
StatusCode assignSD (std::unique_ptr< G4VSensitiveDetector > sd, const std::vector< std::string > &volumes) const
 Assign SD to a list of volumes.
G4VSensitiveDetector * getSD ()
 Retrieve the current SD.
void SetSensitiveDetector (G4LogicalVolume *, G4VSensitiveDetector *) const
 Method stolen from G4VUserDetectorConstruction in G4 10.2.

Protected Attributes

Gaudi::Property< std::vector< std::string > > m_volumeNames {this, "LogicalVolumeNames", {}}
 All the volumes to which this SD is assigned.
Gaudi::Property< std::vector< std::string > > m_outputCollectionNames {this, "OutputCollectionNames", {}}
 Names of all output collections written out by this SD.
Gaudi::Property< bool > m_noVolumes {this, "NoVolumes", false}
 This SensitiveDetector has no volumes associated with it.

Private Member Functions

void setSD (G4VSensitiveDetector *)
 Set the current SD.

Static Private Member Functions

static bool matchStrings (const char *first, const char *second)
 Match two strings with wildcard support.

Private Attributes

G4VSensitiveDetector * m_SD {}
 The sensitive detector to which this thing corresponds.

Detailed Description

Definition at line 16 of file AFP_SiDSensitiveDetectorTool.h.

Constructor & Destructor Documentation

◆ AFP_SiDSensitiveDetectorTool()

AFP_SiDSensitiveDetectorTool::AFP_SiDSensitiveDetectorTool ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 14 of file AFP_SiDSensitiveDetectorTool.cxx.

15 : SensitiveDetectorBase(type,name,parent)
16{
17}
SensitiveDetectorBase(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.

◆ ~AFP_SiDSensitiveDetectorTool()

AFP_SiDSensitiveDetectorTool::~AFP_SiDSensitiveDetectorTool ( )
inline

Definition at line 23 of file AFP_SiDSensitiveDetectorTool.h.

23{}

Member Function Documentation

◆ assignSD()

StatusCode SensitiveDetectorBase::assignSD ( std::unique_ptr< G4VSensitiveDetector > sd,
const std::vector< std::string > & volumes ) const
protectedinherited

Assign SD to a list of volumes.

This method supports wild card matching

Definition at line 64 of file SensitiveDetectorBase.cxx.

66{
67 // Propagate verbosity setting to the SD
68 if(msgLvl(MSG::VERBOSE)) sd->SetVerboseLevel(10);
69 else if(msgLvl(MSG::DEBUG)) sd->SetVerboseLevel(5);
70
71 // Add the sensitive detector to the SD manager in G4 for SDs,
72 // even if it has no volumes associated to it.
73 auto sdMgr = G4SDManager::GetSDMpointer();
74 auto sdPtr = sd.get();
75 // SDManager is now the SD owner
76 sdMgr->AddNewDetector(sd.release());
77
78 if(!volumes.empty()) {
79 bool gotOne = false;
80 auto logicalVolumeStore = G4LogicalVolumeStore::GetInstance();
81 for(const auto& volumeName : volumes) {
82 // Keep track of how many volumes we find with this name string.
83 // We allow for multiple matches.
84 int numFound = 0;
85
86 // Find volumes with this name
87 for(auto* logVol : *logicalVolumeStore) {
88
89 ATH_MSG_VERBOSE("Check whether "<<logVol->GetName()<<" belongs to the set of sensitive detectors "<<volumeName);
90 if( matchStrings( volumeName.data(), logVol->GetName() ) ){
91 ++numFound;
92 SetSensitiveDetector(logVol, sdPtr);
93 }
94
95 }
96 // Warn if no volumes were found
97 if(numFound == 0) {
98 ATH_MSG_WARNING("Volume " << volumeName <<
99 " not found in G4LogicalVolumeStore.");
100 }
101 else {
102 ATH_MSG_VERBOSE("Found " << numFound << " copies of LV " << volumeName <<
103 "; SD " << sd->GetName() << " assigned.");
104 gotOne = true;
105 }
106
107 }
108
109 // Abort if we have failed to assign any volume
110 if(!gotOne) {
111 ATH_MSG_ERROR( "Failed to assign *any* volume to SD " << name() <<
112 " and expected at least one. Size of the volume store "<<G4LogicalVolumeStore::GetInstance()->size() );
113 return StatusCode::FAILURE;
114 }
115 }
116
117 return StatusCode::SUCCESS;
118}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
static bool matchStrings(const char *first, const char *second)
Match two strings with wildcard support.
void SetSensitiveDetector(G4LogicalVolume *, G4VSensitiveDetector *) const
Method stolen from G4VUserDetectorConstruction in G4 10.2.

◆ Gather() [1/2]

StatusCode AFP_SiDSensitiveDetectorTool::Gather ( )
finaloverridevirtual

End of an athena event.

Reimplemented from SensitiveDetectorBase.

Definition at line 44 of file AFP_SiDSensitiveDetectorTool.cxx.

45{
46 ATH_MSG_VERBOSE( "AFP_SiDSensitiveDetectorTool::Gather()" );
47 if(!getSD())
48 {
49 ATH_MSG_ERROR ("Gather: AFP_SiDSensitiveDetector never created!");
50 return StatusCode::FAILURE;
51 }
52 else
53 {
54 AFP_SiDSensitiveDetector *localSD = dynamic_cast<AFP_SiDSensitiveDetector*>(getSD());
55 if(!localSD)
56 {
57 ATH_MSG_ERROR ("Gather: Failed to cast m_SD into AFP_SiDSensitiveDetector.");
58 return StatusCode::FAILURE;
59 }
60 localSD->EndOfAthenaEvent();
61 }
62 return StatusCode::SUCCESS;
63}
G4VSensitiveDetector * getSD()
Retrieve the current SD.

◆ Gather() [2/2]

◆ getSD()

G4VSensitiveDetector * SensitiveDetectorBase::getSD ( )
protectedinherited

Retrieve the current SD.

In AthenaMT, this means the thread-local SD. Otherwise, it is simply the single SD.

Definition at line 120 of file SensitiveDetectorBase.cxx.

121{
122#ifdef G4MULTITHREADED
123 // Get current thread-ID
124 const auto tid = std::this_thread::get_id();
125 // Retrieve it from the SD map
126 auto sdPair = m_sdThreadMap.find(tid);
127 if(sdPair == m_sdThreadMap.end()) return nullptr;
128 return sdPair->second;
129#else
130 return m_SD;
131#endif
132}
G4VSensitiveDetector * m_SD
The sensitive detector to which this thing corresponds.

◆ initializeSD()

StatusCode SensitiveDetectorBase::initializeSD ( )
overrideinherited

Setup an SD in the current thread.

Separate from the AthAlgTool initialize() method because it needs to be called once per worker thread in AthenaMT. Don't confuse this with the G4 SD method Initialize which is called at the beginning of every G4 event.

Definition at line 25 of file SensitiveDetectorBase.cxx.

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 sure SD isn't already registered
39 if(getSD())
40 {
41 ATH_MSG_ERROR("Trying to create a SD which already exists!");
42 return StatusCode::FAILURE;
43 }
44
45 // Make the SD stored by this tool
46 auto sd = std::unique_ptr<G4VSensitiveDetector>(makeSD());
47 if(!sd)
48 {
49 ATH_MSG_ERROR("Failed to create SD!");
50 return StatusCode::FAILURE;
51 }
52 setSD(sd.get());
53
54 // Assign the SD to our list of volumes
55 ATH_CHECK( assignSD( std::move(sd), m_volumeNames.value() ) );
56
57 ATH_MSG_DEBUG( "Initialized and added SD " << name() );
58 return StatusCode::SUCCESS;
59}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
StatusCode assignSD(std::unique_ptr< G4VSensitiveDetector > sd, const std::vector< std::string > &volumes) const
Assign SD to a list of volumes.
Gaudi::Property< std::vector< std::string > > m_volumeNames
All the volumes to which this SD is assigned.
Gaudi::Property< bool > m_noVolumes
This SensitiveDetector has no volumes associated with it.
void setSD(G4VSensitiveDetector *)
Set the current SD.

◆ makeSD()

G4VSensitiveDetector * AFP_SiDSensitiveDetectorTool::makeSD ( ) const
finaloverrideprotected

Definition at line 67 of file AFP_SiDSensitiveDetectorTool.cxx.

68{
69 ATH_MSG_DEBUG( "Initializing SD" );
70 // Create a fresh SD
71 return new AFP_SiDSensitiveDetector(name(), m_outputCollectionNames[0]);
72}
Gaudi::Property< std::vector< std::string > > m_outputCollectionNames
Names of all output collections written out by this SD.

◆ matchStrings()

bool SensitiveDetectorBase::matchStrings ( const char * first,
const char * second )
staticprivateinherited

Match two strings with wildcard support.

Compares two strings character by character with optional * wildcard in the first argument

Definition at line 147 of file SensitiveDetectorBase.cxx.

148{
149 // If we reach at the end of both strings, we are done
150 if (*first == '\0' && *second == '\0')
151 return true;
152
153 // If there are consecutive '*' present in the first string
154 // advance to the next character
155 if(*first == '*' && *(first + 1) == '*')
156 return matchStrings(first + 1, second);
157
158 // Make sure that the characters after '*' are present in second string.
159 if (*first == '*' && *(first + 1) != '\0' && *second == '\0')
160 return false;
161
162 // If the current characters of both strings match
163 if (*first == *second)
164 return matchStrings(first + 1, second + 1);
165
166 // If there is *, then there are two possibilities
167 // a) We consider current character of second string
168 // b) We ignore current character of second string.
169 if (*first == '*')
170 return matchStrings(first + 1, second) || matchStrings(first, second + 1);
171 return false;
172}

◆ setSD()

void SensitiveDetectorBase::setSD ( G4VSensitiveDetector * sd)
privateinherited

Set the current SD.

In hive, this gets assigned as the thread-local SD.

Definition at line 134 of file SensitiveDetectorBase.cxx.

135{
136#ifdef G4MULTITHREADED
137 const auto tid = std::this_thread::get_id();
138 ATH_MSG_DEBUG("Creating and registering SD " << sd << " in thread " << tid);
139 m_sdThreadMap.insert( std::make_pair(tid, sd) );
140#else
141 m_SD = sd;
142#endif
143}

◆ SetSensitiveDetector()

void SensitiveDetectorBase::SetSensitiveDetector ( G4LogicalVolume * logVol,
G4VSensitiveDetector * aSD ) const
protectedinherited

Method stolen from G4VUserDetectorConstruction in G4 10.2.

Definition at line 174 of file SensitiveDetectorBase.cxx.

176{
177 // New Logic: allow for "multiple" SDs being attached to a single LV.
178 // To do that we use a special proxy SD called G4MultiSensitiveDetector
179
180 // Get existing SD if already set and check if it is of the special type
181 G4VSensitiveDetector* originalSD = logVol->GetSensitiveDetector();
182 if ( originalSD == nullptr )
183 {
184 logVol->SetSensitiveDetector(aSD);
185 }
186 else
187 {
188 G4MultiSensitiveDetector* msd = dynamic_cast<G4MultiSensitiveDetector*>(originalSD);
189 if ( msd != nullptr )
190 {
191 msd->AddSD(aSD);
192 }
193 else
194 {
195 // Construct a unique name using the volume address
196 std::stringstream ss;
198 const G4String msdname = "/MultiSD_" + logVol->GetName() + ss.str();
199 msd = new G4MultiSensitiveDetector(std::move(msdname));
200 // We need to register the proxy to have correct handling of IDs
201 G4SDManager::GetSDMpointer()->AddNewDetector(msd);
202 msd->AddSD(originalSD);
203 msd->AddSD(aSD);
204 logVol->SetSensitiveDetector(msd);
205 }
206 }
207}
static Double_t ss

◆ SetupEvent() [1/2]

StatusCode AFP_SiDSensitiveDetectorTool::SetupEvent ( )
finaloverridevirtual

Beginning of an athena event.

This is where collection initialization should happen.

Reimplemented from SensitiveDetectorBase.

Definition at line 21 of file AFP_SiDSensitiveDetectorTool.cxx.

22{
23 ATH_MSG_VERBOSE( "AFP_SiDSensitiveDetectorTool::SetupEvent()" );
24 if(!getSD())
25 {
26 ATH_MSG_ERROR ("SetupEvent: AFP_SiDSensitiveDetector never created!");
27 return StatusCode::FAILURE;
28 }
29 else
30 {
31 AFP_SiDSensitiveDetector *localSD = dynamic_cast<AFP_SiDSensitiveDetector*>(getSD());
32 if(!localSD)
33 {
34 ATH_MSG_ERROR ("SetupEvent: Failed to cast m_SD into AFP_SiDSensitiveDetector.");
35 return StatusCode::FAILURE;
36 }
37 localSD->StartOfAthenaEvent();
38 }
39 return StatusCode::SUCCESS;
40}

◆ SetupEvent() [2/2]

Member Data Documentation

◆ m_noVolumes

Gaudi::Property<bool> SensitiveDetectorBase::m_noVolumes {this, "NoVolumes", false}
protectedinherited

This SensitiveDetector has no volumes associated with it.

Definition at line 101 of file SensitiveDetectorBase.h.

101{this, "NoVolumes", false};

◆ m_outputCollectionNames

Gaudi::Property<std::vector<std::string> > SensitiveDetectorBase::m_outputCollectionNames {this, "OutputCollectionNames", {}}
protectedinherited

Names of all output collections written out by this SD.

Definition at line 98 of file SensitiveDetectorBase.h.

98{this, "OutputCollectionNames", {}};

◆ m_SD

G4VSensitiveDetector* SensitiveDetectorBase::m_SD {}
privateinherited

The sensitive detector to which this thing corresponds.

Definition at line 125 of file SensitiveDetectorBase.h.

125{};

◆ m_volumeNames

Gaudi::Property<std::vector<std::string> > SensitiveDetectorBase::m_volumeNames {this, "LogicalVolumeNames", {}}
protectedinherited

All the volumes to which this SD is assigned.

Definition at line 96 of file SensitiveDetectorBase.h.

96{this, "LogicalVolumeNames", {}};

The documentation for this class was generated from the following files: