22#include "G4EventManager.hh"
23#include "G4GDMLParser.hh"
24#include "G4Navigator.hh"
25#include "G4ParallelWorldPhysics.hh"
26#include "G4PropagatorInField.hh"
27#include "G4RunManagerKernel.hh"
28#include "G4ScoringManager.hh"
29#include "G4StackManager.hh"
30#include "G4StateManager.hh"
31#include "G4TrackingManager.hh"
32#include "G4TransportationManager.hh"
33#include "G4UImanager.hh"
34#include "G4VModularPhysicsList.hh"
35#include "G4VUserPhysicsList.hh"
38#include "CLHEP/Random/RandomEngine.h"
41#include "GaudiKernel/IThreadInitTool.h"
75 if(!m_simplifiedGeoPath.empty()) {
78 if (geoFile.empty()) {
79 ATH_MSG_FATAL(
"Could not find simplified geometry file: " << m_simplifiedGeoPath);
80 return StatusCode::FAILURE;
84 parser.Read(geoFile,
false);
88 if (m_recordFlux) G4ScoringManager::GetScoringManager();
95 catch(
const std::exception& e) {
96 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::initializeOnce: " << e.what());
97 return StatusCode::FAILURE;
107 ATH_CHECK( m_truthRecordSvc.retrieve() );
108 ATH_MSG_INFO(
"- Using ISF TruthRecordSvc : " << m_truthRecordSvc.typeAndName() );
111 ATH_CHECK( m_inputTruthCollectionKey.initialize());
112 ATH_CHECK( m_outputTruthCollectionKey.initialize());
113 ATH_CHECK( m_eventInfoKey.initialize() );
116 if ( not m_truthPreselectionTool.empty() ) {
117 ATH_CHECK(m_truthPreselectionTool.retrieve());
120 if ( not m_qspatcher.empty() ) {
125 return StatusCode::SUCCESS;
135 G4Threading::SetMultithreadedApplication(
m_useMT);
136 ATH_MSG_INFO(
"Multi-threading is " << (G4Threading::IsMultithreadedApplication() ?
"enabled" :
"disabled")
137 <<
"WorkerThread" << G4Threading::IsWorkerThread());
141 throw std::runtime_error(
"Could not initialize ATLAS PhysicsListSvc!");
145 throw std::runtime_error(
"Failed to add action tool "+action_tool.name());
149 ATH_MSG_INFO(
"retrieving the Detector Construction tool" );
151 throw std::runtime_error(
"Could not initialize ATLAS DetectorConstruction!");
156#ifdef G4MULTITHREADED
158 G4AtlasMTRunManager::GetG4AtlasMTRunManager();
159 ATH_MSG_INFO(
"Configuring G4AtlasMTRunManager with " << cardinality() <<
" threads");
161 runMgr->SetNumberOfThreads(cardinality());
167 std::unique_ptr<G4AtlasUserWorkerThreadInitialization> workerInit =
168 std::make_unique<G4AtlasUserWorkerThreadInitialization>();
170 runMgr->SetUserInitialization( workerInit.release() );
171 std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
173 runMgr->SetUserInitialization(actionInitialization.release());
175 throw std::runtime_error(
"Trying to use multi-threading in non-MT build!");
181 G4AtlasRunManager::GetG4AtlasRunManager();
183 runMgr->SetRecordFlux(
m_recordFlux, std::make_unique<G4AtlasFluxRecorder>() );
184 runMgr->SetLogLevel(
int(
msg().level()) );
188 std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
190 runMgr->SetUserInitialization(actionInitialization.release());
194 G4UImanager *ui = G4UImanager::GetUIpointer();
198 ATH_MSG_INFO(
"G4AtlasAlg specific libraries requested ");
200 ui->ApplyCommand(
temp);
206 ui->ApplyCommand(
temp);
213 ui->ApplyCommand(
temp);
214 ui->ApplyCommand(
"/MagneticField/Initialize");
218 ATH_MSG_DEBUG(
"G4 Command: Trying at the end of initializeOnce()");
220 int returnCode = ui->ApplyCommand( g4command );
225 auto* rm = G4RunManager::GetRunManager();
227 throw std::runtime_error(
"Run manager retrieval has failed");
231 if(!
m_useMT && rm->ConfirmBeamOnCondition()) {
232 rm->RunInitialization();
237 if (physicsTool->initializePhysics().isFailure()) {
238 throw std::runtime_error(
"Failed to initialize physics with tool " + physicsTool.name());
243 throw std::runtime_error(
"Could not initialize ATLAS UserLimitsSvc!");
247 G4VModularPhysicsList* thePhysicsList=
dynamic_cast<G4VModularPhysicsList*
>(
m_physListSvc->GetPhysicsList());
248 if (!thePhysicsList) {
249 throw std::runtime_error(
"Failed dynamic_cast!! this is not a G4VModularPhysicsList!");
251#if G4VERSION_NUMBER >= 1010
252 std::vector<std::string>& parallelWorldNames=
m_detConstruction->GetParallelWorldNames();
253 for (
auto& it: parallelWorldNames) {
254 thePhysicsList->RegisterPhysics(
new G4ParallelWorldPhysics(it,
true));
265 G4TransportationManager *tm = G4TransportationManager::GetTransportationManager();
266 G4RunManagerKernel *rmk = G4RunManagerKernel::GetRunManagerKernel();
267 G4EventManager *em = G4EventManager::GetEventManager();
271 tm->GetNavigatorForTracking()->SetVerboseLevel( atof(itr->second.data()) );
274 tm->GetPropagatorInField()->SetVerboseLevel( atof(itr->second.data()) );
277 rmk->GetTrackingManager()->SetVerboseLevel( atof(itr->second.data()) );
280 rmk->GetTrackingManager()->GetSteppingManager()->
281 SetVerboseLevel( atof(itr->second.data()) );
284 rmk->GetStackManager()->SetVerboseLevel( atof(itr->second.data()) );
287 em->SetVerboseLevel( atof(itr->second.data()) );
298 ATH_MSG_DEBUG(
"++++++++++++ G4AtlasAlg finalized ++++++++++++" <<std::endl<<std::endl);
304 catch(
const std::exception& e) {
305 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::finalizeOnce: " << e.what());
306 return StatusCode::FAILURE;
309 return StatusCode::SUCCESS;
316 auto runMgr = G4RunManager::GetRunManager();
317 runMgr->RunTermination();
324 static std::atomic<unsigned int> n_Event=0;
325 ATH_MSG_DEBUG(
"++++++++++++ G4AtlasAlg execute ++++++++++++");
329 if (n_Event<=10 || (n_Event%100) == 0) {
330 ATH_MSG_ALWAYS(
"G4AtlasAlg: Event num. " << n_Event <<
" start processing");
338 catch(
const std::exception& e) {
339 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::releaseGeoModel: " << e.what());
340 return StatusCode::FAILURE;
348 G4Random::setTheEngine(rngWrapper->
getEngine(ctx));
352 auto eventInfo = std::make_unique<AtlasG4EventUserInfo>(ctx);
354 std::shared_ptr<HitCollectionMap> hitCollections = eventInfo->GetHitCollectionMap();
361 if (!inputTruthCollection.
isValid()) {
362 ATH_MSG_FATAL(
"Unable to read input GenEvent collection " << inputTruthCollection.
name() <<
" in store " << inputTruthCollection.
store());
363 return StatusCode::FAILURE;
365 ATH_MSG_DEBUG(
"Found input GenEvent collection " << inputTruthCollection.
name() <<
" in store " << inputTruthCollection.
store());
368 std::unique_ptr<McEventCollection> shadowTruth{};
370 outputTruthCollection = std::make_unique<McEventCollection>();
372 shadowTruth = std::make_unique<McEventCollection>(*inputTruthCollection);
380 outputTruthCollection->push_back(outputEvent.release());
385 outputTruthCollection = std::make_unique<McEventCollection>(*inputTruthCollection);
387 shadowTruth = std::make_unique<McEventCollection>();
396 ATH_MSG_DEBUG(
"Recorded output GenEvent collection " << outputTruthCollection.
name() <<
" in store " << outputTruthCollection.
store());
398 const int largestGeneratedParticleBC = (outputTruthCollection->empty()) ?
HepMC::UNDEFINED_ID
400 const int largestGeneratedVertexBC = (outputTruthCollection->empty()) ?
HepMC::UNDEFINED_ID
409 auto inputEvent = std::make_unique<G4Event>(ctx.eventID().event_number());
410 inputEvent->SetUserInformation(eventInfo.release());
413 *outputTruthCollection, *inputEvent, *shadowTruth));
419#ifdef G4MULTITHREADED
420 auto* workerRM = G4AtlasWorkerRunManager::GetG4AtlasWorkerRunManager();
421 abort = workerRM->ProcessEvent(inputEvent.release());
423 ATH_MSG_ERROR(
"Trying to use multi-threading in non-MT build!");
424 return StatusCode::FAILURE;
428 G4AtlasRunManager::GetG4AtlasRunManager();
429 abort = workerRM->ProcessEvent(inputEvent.release());
443 "Failed to retrieve xAOD::EventInfo while trying to update the "
445 return StatusCode::FAILURE;
467 return StatusCode::SUCCESS;
474 SmartIF<IGeoModelSvc> geoModel{Gaudi::svcLocator()->service(
"GeoModelSvc")};
479 if (geoModel->clear().isFailure()) {
483 ATH_MSG_INFO(
" ----> GeoModelSvc::clear() succeeded " );
493 case 0: {
ATH_MSG_DEBUG(
"G4 Command: " << commandString <<
" - Command Succeeded"); }
break;
494 case 100: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Command Not Found!"); }
break;
496 auto* stateManager = G4StateManager::GetStateManager();
497 ATH_MSG_DEBUG(
"G4 Command: " << commandString <<
" - Illegal Application State (" <<
498 stateManager->GetStateString(stateManager->GetCurrentState()) <<
")!");
500 case 300: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Out of Range!"); }
break;
501 case 400: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Unreadable!"); }
break;
502 case 500: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Out of Candidates!"); }
break;
503 case 600: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Alias Not Found!"); }
break;
504 default: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Unknown Status!"); }
break;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_ALWAYS(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
StatusCode G4AtlasAlg::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
static std::once_flag initializeOnceFlag
static std::once_flag releaseGeoModelOnceFlag
static std::once_flag finalizeOnceFlag
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
A wrapper class for event-slot-local random engines.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
virtual void setFilterPassed(bool state, const EventContext &ctx) const
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< ISF::IInputConverter > m_inputConverter
Service to convert ISF_Particles into a G4Event.
Gaudi::Property< std::string > m_fieldMap
ServiceHandle< ISF::ITruthSvc > m_truthRecordSvc
Central Truth Service.
ServiceHandle< Simulation::IZeroLifetimePatcher > m_qspatcher
Quasi-Stable Particle Simulation Patcher.
void commandLog(int returnCode, const std::string &commandString) const
This command prints a message about a G4Command depending on its returnCode.
std::map< std::string, std::string > m_verbosities
Verbosity settings for Geant4.
Gaudi::Property< std::string > m_physList
Gaudi::Property< bool > m_quietMode
PublicToolHandle< ISensitiveDetectorMasterTool > m_senDetTool
Sensitive Detector Master Tool.
Gaudi::Property< bool > m_useMT
Activate multi-threading configuration.
G4AtlasAlg(const std::string &name, ISvcLocator *pSvcLocator)
Standard algorithm constructor.
ServiceHandle< IAthRNGSvc > m_rndmGenSvc
Random number service.
StatusCode execute(const EventContext &ctx) override
Simulate one Athena event.
StatusCode finalize() override
Finalize the algorithm and invoke G4 run termination.
BooleanProperty m_useShadowEvent
ToolHandle< ISF::IGenEventFilter > m_truthPreselectionTool
PublicToolHandleArray< IPhysicsInitializationTool > m_physicsInitializationTools
Gaudi::Property< std::vector< std::string > > m_g4commands
Commands to send to the G4 UI.
Gaudi::Property< std::string > m_randomStreamName
Random Stream Name.
PublicToolHandle< IFastSimulationMasterTool > m_fastSimTool
Fast Simulation Master Tool.
Gaudi::Property< bool > m_killAbortedEvents
PublicToolHandleArray< G4UA::IUserActionTool > m_actionTools
SG::ReadHandleKey< McEventCollection > m_inputTruthCollectionKey
input hard scatter collection
PublicToolHandle< IDetectorConstructionTool > m_detConstruction
Gaudi::Property< bool > m_activateParallelGeometries
ServiceHandle< G4UA::IUserActionSvc > m_userActionSvc
User Action Service.
ServiceHandle< IUserLimitsSvc > m_userLimitsSvc
Gaudi::Property< std::string > m_libList
void initializeG4()
Poorly named possibly unused method which sets some verbosities.
Gaudi::Property< bool > m_recordFlux
SG::WriteHandleKey< McEventCollection > m_outputTruthCollectionKey
output hard scatter truth collection
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
ServiceHandle< IPhysicsListSvc > m_physListSvc
Physics List Tool.
Gaudi::Property< bool > m_releaseGeoModel
Gaudi::Property< bool > m_flagAbortedEvents
void initializeOnce()
G4 initialization called only by the first alg instance.
void finalizeOnce()
G4 finalization called only by the first alg instance.
void releaseGeoModel()
Releases the GeoModel geometry from memory once it has been used to build the G4 geometry and is no-l...
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
@ Core
Core flags describing the event.
@ Error
The sub-detector issued an error.
int maxGeneratedVertexBarcode(const HepMC::GenEvent *genEvent)
Get the maximal absolute value of barcode of vertex present in the event. Returns a negative number.
constexpr int UNDEFINED_ID
int maxGeneratedParticleBarcode(const HepMC::GenEvent *genEvent)
Get the maximal value of barcode of particle present in the event.
HepMC3::GenEvent GenEvent