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;
140 throw std::runtime_error(
"Could not initialize ATLAS PhysicsListSvc!");
144 throw std::runtime_error(
"Failed to add action tool "+action_tool.name());
148 ATH_MSG_INFO(
"retrieving the Detector Construction tool" );
150 throw std::runtime_error(
"Could not initialize ATLAS DetectorConstruction!");
155#ifdef G4MULTITHREADED
157 G4AtlasMTRunManager::GetG4AtlasMTRunManager();
163 std::unique_ptr<G4AtlasUserWorkerThreadInitialization> workerInit =
164 std::make_unique<G4AtlasUserWorkerThreadInitialization>();
166 runMgr->SetUserInitialization( workerInit.release() );
167 std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
169 runMgr->SetUserInitialization(actionInitialization.release());
171 throw std::runtime_error(
"Trying to use multi-threading in non-MT build!");
177 G4AtlasRunManager::GetG4AtlasRunManager();
179 runMgr->SetRecordFlux(
m_recordFlux, std::make_unique<G4AtlasFluxRecorder>() );
180 runMgr->SetLogLevel(
int(
msg().level()) );
184 std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
186 runMgr->SetUserInitialization(actionInitialization.release());
190 G4UImanager *ui = G4UImanager::GetUIpointer();
194 ATH_MSG_INFO(
"G4AtlasAlg specific libraries requested ");
196 ui->ApplyCommand(temp);
201 std::string temp=
"/Physics/GetPhysicsList "+
m_physList;
202 ui->ApplyCommand(temp);
208 std::string temp=
"/MagneticField/Select "+
m_fieldMap;
209 ui->ApplyCommand(temp);
210 ui->ApplyCommand(
"/MagneticField/Initialize");
214 ATH_MSG_DEBUG(
"G4 Command: Trying at the end of initializeOnce()");
216 int returnCode = ui->ApplyCommand( g4command );
221 auto* rm = G4RunManager::GetRunManager();
223 throw std::runtime_error(
"Run manager retrieval has failed");
227 if(!
m_useMT && rm->ConfirmBeamOnCondition()) {
228 rm->RunInitialization();
233 if (physicsTool->initializePhysics().isFailure()) {
234 throw std::runtime_error(
"Failed to initialize physics with tool " + physicsTool.name());
239 throw std::runtime_error(
"Could not initialize ATLAS UserLimitsSvc!");
243 G4VModularPhysicsList* thePhysicsList=
dynamic_cast<G4VModularPhysicsList*
>(
m_physListSvc->GetPhysicsList());
244 if (!thePhysicsList) {
245 throw std::runtime_error(
"Failed dynamic_cast!! this is not a G4VModularPhysicsList!");
247#if G4VERSION_NUMBER >= 1010
248 std::vector<std::string>& parallelWorldNames=
m_detConstruction->GetParallelWorldNames();
249 for (
auto& it: parallelWorldNames) {
250 thePhysicsList->RegisterPhysics(
new G4ParallelWorldPhysics(it,
true));
261 G4TransportationManager *tm = G4TransportationManager::GetTransportationManager();
262 G4RunManagerKernel *rmk = G4RunManagerKernel::GetRunManagerKernel();
263 G4EventManager *em = G4EventManager::GetEventManager();
267 tm->GetNavigatorForTracking()->SetVerboseLevel( atof(itr->second.data()) );
270 tm->GetPropagatorInField()->SetVerboseLevel( atof(itr->second.data()) );
273 rmk->GetTrackingManager()->SetVerboseLevel( atof(itr->second.data()) );
276 rmk->GetTrackingManager()->GetSteppingManager()->
277 SetVerboseLevel( atof(itr->second.data()) );
280 rmk->GetStackManager()->SetVerboseLevel( atof(itr->second.data()) );
283 em->SetVerboseLevel( atof(itr->second.data()) );
294 ATH_MSG_DEBUG(
"++++++++++++ G4AtlasAlg finalized ++++++++++++" <<std::endl<<std::endl);
300 catch(
const std::exception& e) {
301 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::finalizeOnce: " << e.what());
302 return StatusCode::FAILURE;
305 return StatusCode::SUCCESS;
312 auto runMgr = G4RunManager::GetRunManager();
313 runMgr->RunTermination();
320 static std::atomic<unsigned int> n_Event=0;
321 ATH_MSG_DEBUG(
"++++++++++++ G4AtlasAlg execute ++++++++++++");
325 if (n_Event<=10 || (n_Event%100) == 0) {
326 ATH_MSG_ALWAYS(
"G4AtlasAlg: Event num. " << n_Event <<
" start processing");
334 catch(
const std::exception& e) {
335 ATH_MSG_ERROR(
"Failure in G4AtlasAlg::releaseGeoModel: " << e.what());
336 return StatusCode::FAILURE;
340 const EventContext& ctx = Gaudi::Hive::currentContext();
345 G4Random::setTheEngine(*rngWrapper);
349 auto eventInfo = std::make_unique<AtlasG4EventUserInfo>(ctx);
351 std::shared_ptr<HitCollectionMap> hitCollections = eventInfo->GetHitCollectionMap();
358 if (!inputTruthCollection.
isValid()) {
359 ATH_MSG_FATAL(
"Unable to read input GenEvent collection " << inputTruthCollection.
name() <<
" in store " << inputTruthCollection.
store());
360 return StatusCode::FAILURE;
362 ATH_MSG_DEBUG(
"Found input GenEvent collection " << inputTruthCollection.
name() <<
" in store " << inputTruthCollection.
store());
365 std::unique_ptr<McEventCollection> shadowTruth{};
367 outputTruthCollection = std::make_unique<McEventCollection>();
369 shadowTruth = std::make_unique<McEventCollection>(*inputTruthCollection);
370 for (HepMC::GenEvent* currentGenEvent : *shadowTruth ) {
377 outputTruthCollection->push_back(outputEvent.release());
382 outputTruthCollection = std::make_unique<McEventCollection>(*inputTruthCollection);
384 shadowTruth = std::make_unique<McEventCollection>();
387 for (HepMC::GenEvent* currentGenEvent : *outputTruthCollection ) {
393 ATH_MSG_DEBUG(
"Recorded output GenEvent collection " << outputTruthCollection.
name() <<
" in store " << outputTruthCollection.
store());
395 const int largestGeneratedParticleBC = (outputTruthCollection->empty()) ?
HepMC::UNDEFINED_ID
397 const int largestGeneratedVertexBC = (outputTruthCollection->empty()) ?
HepMC::UNDEFINED_ID
406 auto inputEvent = std::make_unique<G4Event>(ctx.eventID().event_number());
407 inputEvent->SetUserInformation(eventInfo.release());
410 *outputTruthCollection, *inputEvent, *shadowTruth));
416#ifdef G4MULTITHREADED
417 auto* workerRM = G4AtlasWorkerRunManager::GetG4AtlasWorkerRunManager();
418 abort = workerRM->ProcessEvent(inputEvent.release());
420 ATH_MSG_ERROR(
"Trying to use multi-threading in non-MT build!");
421 return StatusCode::FAILURE;
425 G4AtlasRunManager::GetG4AtlasRunManager();
426 abort = workerRM->ProcessEvent(inputEvent.release());
434 setFilterPassed(
false);
440 "Failed to retrieve xAOD::EventInfo while trying to update the "
442 return StatusCode::FAILURE;
459 for (HepMC::GenEvent* currentGenEvent : *outputTruthCollection ) {
464 return StatusCode::SUCCESS;
471 SmartIF<IGeoModelSvc> geoModel{Gaudi::svcLocator()->service(
"GeoModelSvc")};
476 if (geoModel->clear().isFailure()) {
480 ATH_MSG_INFO(
" ----> GeoModelSvc::clear() succeeded " );
490 case 0: {
ATH_MSG_DEBUG(
"G4 Command: " << commandString <<
" - Command Succeeded"); }
break;
491 case 100: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Command Not Found!"); }
break;
493 auto* stateManager = G4StateManager::GetStateManager();
494 ATH_MSG_DEBUG(
"G4 Command: " << commandString <<
" - Illegal Application State (" <<
495 stateManager->GetStateString(stateManager->GetCurrentState()) <<
")!");
497 case 300: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Out of Range!"); }
break;
498 case 400: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Unreadable!"); }
break;
499 case 500: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Parameter Out of Candidates!"); }
break;
500 case 600: {
ATH_MSG_ERROR(
"G4 Command: " << commandString <<
" - Alias Not Found!"); }
break;
501 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.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
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.
StatusCode execute() override
Simulate one Athena event.
ServiceHandle< IAthRNGSvc > m_rndmGenSvc
Random number service.
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.