54 #include "G4SystemOfUnits.hh"
55 #include "G4Threading.hh"
56 #include "G4UImanager.hh"
57 #include "G4WorkerThread.hh"
58 #include "G4WorkerRunManagerKernel.hh"
59 #include "G4StateManager.hh"
60 #include "G4TransportationManager.hh"
62 #include "G4FieldManager.hh"
70 #include "tbb/task_arena.h"
77 std::atomic<int> thread_counter{0};
79 int get_new_thread_index() {
return thread_counter++; }
81 thread_local
int s_thread_index = get_new_thread_index();
83 int getThreadIndex() {
return s_thread_index; }
87 std::vector<std::shared_ptr<SimWatcher> >& oWatchers,
88 std::vector<std::shared_ptr<SimProducer> >& oProds) {
89 if (!iP.
exists(
"Watchers")) {
93 std::vector<edm::ParameterSet> watchers = iP.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
95 for (
auto& watcher : watchers) {
96 std::unique_ptr<SimWatcherMakerBase> maker(
98 if (maker ==
nullptr) {
100 <<
"Unable to find the requested Watcher <" << watcher.getParameter<
std::string>(
"type");
102 std::shared_ptr<SimWatcher> watcherTemp;
103 std::shared_ptr<SimProducer> producerTemp;
104 maker->make(watcher, *(iReg), watcherTemp, producerTemp);
105 oWatchers.push_back(watcherTemp);
107 oProds.push_back(producerTemp);
112 std::atomic<int> active_tlsdata{0};
113 std::atomic<bool> tls_shutdown_timeout{
false};
114 std::atomic<int> n_tls_shutdown_task{0};
118 std::unique_ptr<G4RunManagerKernel>
kernel;
125 std::vector<std::shared_ptr<SimWatcher> >
watchers;
154 m_nonBeam(iConfig.getParameter<
bool>(
"NonBeamEvent")),
155 m_pUseMagneticField(iConfig.getParameter<
bool>(
"UseMagneticField")),
156 m_LHCTransport(iConfig.getParameter<
bool>(
"LHCTransport")),
157 m_EvtMgrVerbosity(iConfig.getUntrackedParameter<
int>(
"G4EventManagerVerbosity", 0)),
160 m_pEventAction(iConfig.getParameter<
edm::
ParameterSet>(
"EventAction")),
161 m_pStackingAction(iConfig.getParameter<
edm::
ParameterSet>(
"StackingAction")),
162 m_pTrackingAction(iConfig.getParameter<
edm::
ParameterSet>(
"TrackingAction")),
163 m_pSteppingAction(iConfig.getParameter<
edm::
ParameterSet>(
"SteppingAction")),
164 m_pCustomUIsession(iConfig.getUntrackedParameter<
edm::
ParameterSet>(
"CustomUIsession")),
167 m_sVerbose(nullptr) {
168 std::vector<edm::ParameterSet> watchers = iConfig.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
171 int thisID = getThreadIndex();
175 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker is constructed for the thread " << thisID;
179 ++n_tls_shutdown_task;
187 while (n_tls_shutdown_task != 0) {
188 nanosleep(&
s,
nullptr);
196 if (active_tlsdata != 0 and not tls_shutdown_timeout) {
197 ++n_tls_shutdown_task;
200 tbb::task_arena arena(tbb::task_arena::attach{});
210 while (active_tlsdata.load() != 0 and ++
count < 1000) {
211 nanosleep(&
s,
nullptr);
214 tls_shutdown_timeout =
true;
217 --n_tls_shutdown_task;
221 int thisID = getThreadIndex();
222 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " << thisID;
237 int thisID = getThreadIndex();
242 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. "
243 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
260 int thisID = getThreadIndex();
261 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread " << thisID <<
" is started";
264 G4Threading::G4SetThreadId(thisID);
265 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
267 if (uitype ==
"MessageLogger") {
269 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
271 }
else if (uitype ==
"FilePerThread") {
275 <<
"Invalid value of CustomUIsession.Type '" << uitype
276 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
280 G4WorkerThread::BuildGeometryAndPhysicsVector();
283 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
285 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
289 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler());
294 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
295 tM->SetWorldForTracking(worldPV);
309 tM->SetFieldManager(fieldManager);
310 fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
313 if (!fieldFile.empty()) {
316 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: Dump magnetic field to file " << fieldFile;
331 <<
"RunManagerMTWorker: Sensitive Detectors are built in thread " << thisID <<
" found "
338 <<
"RunManagerMTWorker: start initialisation of PhysicsList for the thread " << thisID;
341 if (!runManagerMaster->
G4Commands().empty()) {
342 G4cout <<
"RunManagerMTWorker: Requested UI commands: " << G4endl;
345 G4UImanager::GetUIpointer()->ApplyCommand(
command);
348 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
350 physicsList->InitializeWorker();
354 const bool kernelInit =
m_tls->
kernel->RunInitialization();
357 <<
"RunManagerMTWorker: Geant4 kernel initialization failed in thread " << thisID;
370 m_sVerbose = std::make_unique<CMSSteppingVerbose>(
sv, elim, ve, vn, vt);
374 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
379 <<
"RunManagerMTWorker::initializeThread done for the thread " << thisID <<
" " << timer;
388 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
394 eventManager->SetUserAction(userEventAction);
398 eventManager->SetUserAction(userTrackingAction);
403 eventManager->SetUserAction(userSteppingAction);
445 int thisID = getThreadIndex();
446 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun " << thisID <<
" is started";
448 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
455 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun ";
459 int thisID = getThreadIndex();
460 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun " << thisID <<
" is started";
489 <<
"RunManagerMTWorker::produce(): stream " << inpevt.
streamID() <<
" thread " << getThreadIndex()
490 <<
" Geant4 initialisation for this thread";
507 auto simEvent = std::make_unique<G4SimEvent>();
514 genVertex->y() / CLHEP::cm,
515 genVertex->z() / CLHEP::cm,
519 std::stringstream
ss;
520 ss <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices \n";
525 std::stringstream
ss;
526 ss <<
"RunManagerMTWorker::produce: "
527 <<
" no G4WorkerRunManagerKernel yet for thread index" << getThreadIndex() <<
", id " << std::hex
528 << std::this_thread::get_id() <<
" \n";
533 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
534 <<
" threadIndex=" << getThreadIndex() <<
" weight=" <<
m_simEvent->
weight() <<
"; "
535 <<
m_tls->
currentEvent->GetNumberOfPrimaryVertex() <<
" vertices for Geant4; generator produced "
547 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
557 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
558 t->SetTrackStatus(fStopAndKill);
566 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
567 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
584 G4Event* evt =
new G4Event(
evtid);
622 <<
" RunManager WARNING : error opening file <" <<
file <<
"> for magnetic field";
625 double rmax = 9000 * mm;
626 double zmax = 24000 * mm;
642 double point[4] = {0.0, 0.0, 0.0, 0.0};
643 double bfield[3] = {0.0, 0.0, 0.0};
645 fout << std::setprecision(6);
646 for (
int i = 0;
i <=
nr; ++
i) {
648 for (
int j = 0;
j <= nz; ++
j) {
652 field->GetFieldValue(
point, bfield);
653 fout <<
"R(mm)= " <<
r / mm <<
" phi(deg)= " <<
phi / degree <<
" Z(mm)= " <<
z / mm
654 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
655 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / tesla << G4endl;