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"
76 if(!m_simplifiedGeoPath.empty()) {
79 if (geoFile.empty()) {
80 ATH_MSG_FATAL(
"Could not find simplified geometry file: " << m_simplifiedGeoPath);
81 return StatusCode::FAILURE;
85 parser.Read(geoFile,
false);
89 if (m_recordFlux) G4ScoringManager::GetScoringManager();
96 catch(
const std::exception& e) {
97 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::initializeOnce: " << e.what());
98 return StatusCode::FAILURE;
108 ATH_CHECK( m_truthRecordSvc.retrieve() );
109 ATH_MSG_INFO(
"- Using ISF TruthRecordSvc : " << m_truthRecordSvc.typeAndName() );
111 ATH_MSG_INFO(
"- Using ISF GeoIDSvc : " << m_geoIDSvc.typeAndName() );
118 ATH_CHECK( m_inputTruthCollectionKey.initialize());
119 ATH_CHECK( m_outputTruthCollectionKey.initialize());
120 ATH_CHECK( m_eventInfoKey.initialize() );
123 if ( not m_truthPreselectionTool.empty() ) {
124 ATH_CHECK(m_truthPreselectionTool.retrieve());
127 if ( not m_qspatcher.empty() ) {
132 return StatusCode::SUCCESS;
142 G4Threading::SetMultithreadedApplication(
m_useMT);
143 ATH_MSG_INFO(
"Multi-threading is " << (G4Threading::IsMultithreadedApplication() ?
"enabled" :
"disabled")
144 <<
"WorkerThread" << G4Threading::IsWorkerThread());
148 throw std::runtime_error(
"Could not initialize ATLAS PhysicsListSvc!");
152 throw std::runtime_error(
"Failed to add action tool "+action_tool.name());
156 ATH_MSG_INFO(
"retrieving the Detector Construction tool" );
158 throw std::runtime_error(
"Could not initialize ATLAS DetectorConstruction!");
163#ifdef G4MULTITHREADED
165 G4AtlasMTRunManager::GetG4AtlasMTRunManager();
166 ATH_MSG_INFO(
"Configuring G4AtlasMTRunManager with " << cardinality() <<
" threads");
168 runMgr->SetNumberOfThreads(cardinality());
174 std::unique_ptr<G4AtlasUserWorkerThreadInitialization> workerInit =
175 std::make_unique<G4AtlasUserWorkerThreadInitialization>();
177 runMgr->SetUserInitialization( workerInit.release() );
178 std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
180 runMgr->SetUserInitialization(actionInitialization.release());
182 throw std::runtime_error(
"Trying to use multi-threading in non-MT build!");
188 G4AtlasRunManager::GetG4AtlasRunManager();
190 runMgr->SetRecordFlux(
m_recordFlux, std::make_unique<G4AtlasFluxRecorder>() );
191 runMgr->SetLogLevel(
int(
msg().level()) );
195 std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
197 runMgr->SetUserInitialization(actionInitialization.release());
201 G4UImanager *ui = G4UImanager::GetUIpointer();
205 ATH_MSG_INFO(
"G4AtlasAlg specific libraries requested ");
207 ui->ApplyCommand(temp);
212 std::string temp=
"/Physics/GetPhysicsList "+
m_physList;
213 ui->ApplyCommand(temp);
219 std::string temp=
"/MagneticField/Select "+
m_fieldMap;
220 ui->ApplyCommand(temp);
221 ui->ApplyCommand(
"/MagneticField/Initialize");
225 ATH_MSG_DEBUG(
"G4 Command: Trying at the end of initializeOnce()");
227 int returnCode = ui->ApplyCommand( g4command );
232 auto* rm = G4RunManager::GetRunManager();
234 throw std::runtime_error(
"Run manager retrieval has failed");
238 if(!
m_useMT && rm->ConfirmBeamOnCondition()) {
239 rm->RunInitialization();
244 if (physicsTool->initializePhysics().isFailure()) {
245 throw std::runtime_error(
"Failed to initialize physics with tool " + physicsTool.name());
250 throw std::runtime_error(
"Could not initialize ATLAS UserLimitsSvc!");
254 G4VModularPhysicsList* thePhysicsList=
dynamic_cast<G4VModularPhysicsList*
>(
m_physListSvc->GetPhysicsList());
255 if (!thePhysicsList) {
256 throw std::runtime_error(
"Failed dynamic_cast!! this is not a G4VModularPhysicsList!");
258#if G4VERSION_NUMBER >= 1010
259 std::vector<std::string>& parallelWorldNames=
m_detConstruction->GetParallelWorldNames();
260 for (
auto& it: parallelWorldNames) {
261 thePhysicsList->RegisterPhysics(
new G4ParallelWorldPhysics(it,
true));
272 G4TransportationManager *tm = G4TransportationManager::GetTransportationManager();
273 G4RunManagerKernel *rmk = G4RunManagerKernel::GetRunManagerKernel();
274 G4EventManager *em = G4EventManager::GetEventManager();
278 tm->GetNavigatorForTracking()->SetVerboseLevel( atof(itr->second.data()) );
281 tm->GetPropagatorInField()->SetVerboseLevel( atof(itr->second.data()) );
284 rmk->GetTrackingManager()->SetVerboseLevel( atof(itr->second.data()) );
287 rmk->GetTrackingManager()->GetSteppingManager()->
288 SetVerboseLevel( atof(itr->second.data()) );
291 rmk->GetStackManager()->SetVerboseLevel( atof(itr->second.data()) );
294 em->SetVerboseLevel( atof(itr->second.data()) );
305 ATH_MSG_DEBUG(
"++++++++++++ G4AtlasAlg finalized ++++++++++++" <<std::endl<<std::endl);
311 catch(
const std::exception& e) {
312 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::finalizeOnce: " << e.what());
313 return StatusCode::FAILURE;
316 return StatusCode::SUCCESS;
323 auto runMgr = G4RunManager::GetRunManager();
324 runMgr->RunTermination();
331 static std::atomic<unsigned int> n_Event=0;
332 ATH_MSG_DEBUG(
"++++++++++++ G4AtlasAlg execute ++++++++++++");
336 if (n_Event<=10 || (n_Event%100) == 0) {
337 ATH_MSG_ALWAYS(
"G4AtlasAlg: Event num. " << n_Event <<
" start processing");
345 catch(
const std::exception& e) {
346 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::releaseGeoModel: " << e.what());
347 return StatusCode::FAILURE;
355 G4Random::setTheEngine(rngWrapper->
getEngine(ctx));
359 auto eventInfo = std::make_unique<AtlasG4EventUserInfo>(ctx);
361 std::shared_ptr<HitCollectionMap> hitCollections = eventInfo->GetHitCollectionMap();
368 if (!inputTruthCollection.
isValid()) {
369 ATH_MSG_FATAL(
"Unable to read input GenEvent collection " << inputTruthCollection.
name() <<
" in store " << inputTruthCollection.
store());
370 return StatusCode::FAILURE;
372 ATH_MSG_DEBUG(
"Found input GenEvent collection " << inputTruthCollection.
name() <<
" in store " << inputTruthCollection.
store());
375 std::unique_ptr<McEventCollection> shadowTruth{};
377 outputTruthCollection = std::make_unique<McEventCollection>();
379 shadowTruth = std::make_unique<McEventCollection>(*inputTruthCollection);
387 outputTruthCollection->push_back(outputEvent.release());
392 outputTruthCollection = std::make_unique<McEventCollection>(*inputTruthCollection);
394 shadowTruth = std::make_unique<McEventCollection>();
403 ATH_MSG_DEBUG(
"Recorded output GenEvent collection " << outputTruthCollection.
name() <<
" in store " << outputTruthCollection.
store());
405 const int largestGeneratedParticleBC = (outputTruthCollection->empty()) ?
HepMC::UNDEFINED_ID
407 const int largestGeneratedVertexBC = (outputTruthCollection->empty()) ?
HepMC::UNDEFINED_ID
416 auto inputEvent = std::make_unique<G4Event>(ctx.eventID().event_number());
417 inputEvent->SetUserInformation(eventInfo.release());
420 *outputTruthCollection, *inputEvent, *shadowTruth));
426#ifdef G4MULTITHREADED
427 auto* workerRM = G4AtlasWorkerRunManager::GetG4AtlasWorkerRunManager();
428 abort = workerRM->ProcessEvent(inputEvent.release());
430 ATH_MSG_ERROR(
"Trying to use multi-threading in non-MT build!");
431 return StatusCode::FAILURE;
435 G4AtlasRunManager::GetG4AtlasRunManager();
436 abort = workerRM->ProcessEvent(inputEvent.release());
450 "Failed to retrieve xAOD::EventInfo while trying to update the "
452 return StatusCode::FAILURE;
474 return StatusCode::SUCCESS;
481 SmartIF<IGeoModelSvc> geoModel{Gaudi::svcLocator()->service(
"GeoModelSvc")};
486 if (geoModel->clear().isFailure()) {
490 ATH_MSG_INFO(
" ----> GeoModelSvc::clear() succeeded " );
500 case 0: {
ATH_MSG_DEBUG(
"G4 Command: " << commandString <<
" - Command Succeeded"); }
break;
501 case 100: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Command Not Found!"); }
break;
503 auto* stateManager = G4StateManager::GetStateManager();
504 ATH_MSG_DEBUG(
"G4 Command: " << commandString <<
" - Illegal Application State (" <<
505 stateManager->GetStateString(stateManager->GetCurrentState()) <<
")!");
507 case 300: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Out of Range!"); }
break;
508 case 400: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Unreadable!"); }
break;
509 case 500: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Out of Candidates!"); }
break;
510 case 600: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Alias Not Found!"); }
break;
511 default: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Unknown Status!"); }
break;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ALWAYS(x)
#define ATH_MSG_WARNING(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.
Singleton class for creating truth incidents.
void SetISFGeoIDSvc(ISF::IGeoIDSvc *geoIDSvc)
Define which ISF GeoIDSvc to use.
void SetISFTruthSvc(ISF::ITruthSvc *truthSvc)
Define which ISF TruthService to use.
@ 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