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

#include <CaloCellContainerSDTool.h>

Inheritance diagram for CaloCellContainerSDTool:
Collaboration diagram for CaloCellContainerSDTool:

Public Member Functions

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

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.
void SetSensitiveDetector (G4LogicalVolume *, G4VSensitiveDetector *) const
 Method stolen from G4VUserDetectorConstruction in G4 10.2.

Protected Attributes

PublicToolHandle< ICaloCellMakerToolm_EmptyCellBuilderTool
PublicToolHandle< ICaloCellMakerToolm_FastHitConvertTool
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.

Static Private Member Functions

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

Detailed Description

Definition at line 16 of file CaloCellContainerSDTool.h.

Constructor & Destructor Documentation

◆ CaloCellContainerSDTool()

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

Definition at line 18 of file CaloCellContainerSDTool.cxx.

19 : SensitiveDetectorBase( type , name , parent ),
20 m_EmptyCellBuilderTool("EmptyCellBuilderTool/EmptyCellBuilderTool"),
21 m_FastHitConvertTool ("FastHitConvertTool/FastHitConvertTool")
22{
23 declareProperty ("EmptyCellBuilderTool", m_EmptyCellBuilderTool, "EmptyCellBuilderTool");
24 declareProperty ("FastHitConvertTool", m_FastHitConvertTool, "FastHitConvertTool");
25}
PublicToolHandle< ICaloCellMakerTool > m_EmptyCellBuilderTool
PublicToolHandle< ICaloCellMakerTool > m_FastHitConvertTool
SensitiveDetectorBase(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.

◆ ~CaloCellContainerSDTool()

CaloCellContainerSDTool::~CaloCellContainerSDTool ( )
inline

Definition at line 22 of file CaloCellContainerSDTool.h.

22{}

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 55 of file SensitiveDetectorBase.cxx.

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}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
size_t size() const
Number of registered mappings.
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()

StatusCode CaloCellContainerSDTool::Gather ( HitCollectionMap & hitCollections)
finaloverridevirtual

End of an athena event.

Reimplemented from SensitiveDetectorBase.

Definition at line 56 of file CaloCellContainerSDTool.cxx.

57{
58 // Get current event context
59 const EventContext& ctx = Gaudi::Hive::currentContext();
60
61 const std::string& collectionName = m_outputCollectionNames[0];
62 std::unique_ptr<CaloCellContainerBuilder> builder =
63 hitCollections.Extract<CaloCellContainerBuilder>(collectionName);
64 if (!builder || !builder->container) {
65 ATH_MSG_ERROR("Gather: Failed to retrieve CaloCellContainerBuilder.");
66 return StatusCode::FAILURE;
67 }
68
69 // Update the calo iterators of the calo cell container.
70 builder->container->updateCaloIterators();
71
72 // Convert FastCaloSim hits into HitCollections, taking into account sampling fractions.
73 if(m_FastHitConvertTool->process(builder->container.get(), ctx).isFailure()){
74 ATH_MSG_ERROR("Gather: Failed to process calo cell container with the fast hit convert tool.");
75 return StatusCode::FAILURE;
76 }
77
78 SG::WriteHandle<CaloCellContainer> handle{collectionName, ctx};
79 ATH_CHECK(handle.record(std::move(builder->container)));
80 return StatusCode::SUCCESS;
81}
#define ATH_CHECK
Evaluate an expression and check for errors.
std::unique_ptr< T > Extract(std::string const &hitCollectionName)
Extract the hit collection for a given SDs downcasted to the template parameter.
Gaudi::Property< std::vector< std::string > > m_outputCollectionNames
Names of all output collections written out by this SD.
virtual void handle(const Incident &inc)
Handle end of run incidents to save the metadata at that point.

◆ initialize()

StatusCode CaloCellContainerSDTool::initialize ( )
finaloverride

Definition at line 27 of file CaloCellContainerSDTool.cxx.

28{
31 return StatusCode::SUCCESS;
32}

◆ 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 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}
#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.

◆ makeSD()

G4VSensitiveDetector * CaloCellContainerSDTool::makeSD ( ) const
finaloverrideprotected

Definition at line 83 of file CaloCellContainerSDTool.cxx.

84{
85 ATH_MSG_DEBUG( "Initializing SD" );
86
87 // Create a fresh SD
88 return new CaloCellContainerSD(name(), m_outputCollectionNames[0]);
89}

◆ 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 115 of file SensitiveDetectorBase.cxx.

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}

◆ SetSensitiveDetector()

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

Method stolen from G4VUserDetectorConstruction in G4 10.2.

Definition at line 142 of file SensitiveDetectorBase.cxx.

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;
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}
static Double_t ss

◆ SetupEvent()

StatusCode CaloCellContainerSDTool::SetupEvent ( HitCollectionMap & hitCollections)
finaloverridevirtual

Beginning of an athena event.

This is where collection initialization should happen.

Reimplemented from SensitiveDetectorBase.

Definition at line 34 of file CaloCellContainerSDTool.cxx.

35{
36 // Get current event context
37 const EventContext& ctx = Gaudi::Hive::currentContext();
38
39 const std::string& collectionName = m_outputCollectionNames[0];
40 hitCollections.Emplace<CaloCellContainerBuilder>(collectionName);
41 auto* builder = hitCollections.Find<CaloCellContainerBuilder>(collectionName);
42 if (!builder) {
43 ATH_MSG_ERROR("SetupEvent: Failed to create CaloCellContainerBuilder.");
44 return StatusCode::FAILURE;
45 }
46
47 // Initialize cell container with empty cells.
48 if(m_EmptyCellBuilderTool->process(builder->container.get(), ctx).isFailure()){
49 ATH_MSG_ERROR("SetupEvent: Failed to process calo cell container with the empty cell builder tool.");
50 return StatusCode::FAILURE;
51 }
52
53 return StatusCode::SUCCESS;
54}
T * Find(std::string const &hitCollectionName)
Get the hit collection for a given SDs.
std::pair< StorageIterator, bool > Emplace(std::string const &hitCollectionName, CollectionArgs &&... args)
Insert a container in the map with in-place construction.

Member Data Documentation

◆ m_EmptyCellBuilderTool

PublicToolHandle<ICaloCellMakerTool> CaloCellContainerSDTool::m_EmptyCellBuilderTool
protected

Definition at line 33 of file CaloCellContainerSDTool.h.

◆ m_FastHitConvertTool

PublicToolHandle<ICaloCellMakerTool> CaloCellContainerSDTool::m_FastHitConvertTool
protected

Definition at line 34 of file CaloCellContainerSDTool.h.

◆ m_noVolumes

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

This SensitiveDetector has no volumes associated with it.

Definition at line 83 of file SensitiveDetectorBase.h.

83{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 80 of file SensitiveDetectorBase.h.

80{this, "OutputCollectionNames", {}};

◆ 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 78 of file SensitiveDetectorBase.h.

78{this, "LogicalVolumeNames", {}};

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