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"
74 std::atomic<int> thread_counter{0};
76 int get_new_thread_index() {
return thread_counter++; }
78 thread_local
int s_thread_index = get_new_thread_index();
80 int getThreadIndex() {
return s_thread_index; }
84 std::vector<std::shared_ptr<SimWatcher> >& oWatchers,
85 std::vector<std::shared_ptr<SimProducer> >& oProds) {
86 if (!iP.
exists(
"Watchers")) {
90 std::vector<edm::ParameterSet> watchers = iP.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
92 for (
auto& watcher : watchers) {
93 std::unique_ptr<SimWatcherMakerBase> maker(
95 if (maker ==
nullptr) {
97 <<
"Unable to find the requested Watcher <" << watcher.getParameter<
std::string>(
"type");
99 std::shared_ptr<SimWatcher> watcherTemp;
100 std::shared_ptr<SimProducer> producerTemp;
101 maker->make(watcher, *(iReg), watcherTemp, producerTemp);
102 oWatchers.push_back(watcherTemp);
104 oProds.push_back(producerTemp);
109 std::atomic<int> active_tlsdata{0};
110 std::atomic<bool> tls_shutdown_timeout{
false};
111 std::atomic<int> n_tls_shutdown_task{0};
115 std::unique_ptr<G4RunManagerKernel>
kernel;
122 std::vector<std::shared_ptr<SimWatcher> >
watchers;
151 m_nonBeam(iConfig.getParameter<
bool>(
"NonBeamEvent")),
152 m_pUseMagneticField(iConfig.getParameter<
bool>(
"UseMagneticField")),
153 m_EvtMgrVerbosity(iConfig.getUntrackedParameter<
int>(
"G4EventManagerVerbosity", 0)),
156 m_pEventAction(iConfig.getParameter<
edm::
ParameterSet>(
"EventAction")),
157 m_pStackingAction(iConfig.getParameter<
edm::
ParameterSet>(
"StackingAction")),
158 m_pTrackingAction(iConfig.getParameter<
edm::
ParameterSet>(
"TrackingAction")),
159 m_pSteppingAction(iConfig.getParameter<
edm::
ParameterSet>(
"SteppingAction")),
160 m_pCustomUIsession(iConfig.getUntrackedParameter<
edm::
ParameterSet>(
"CustomUIsession")),
163 m_sVerbose(nullptr) {
164 std::vector<edm::ParameterSet> watchers = iConfig.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
174 ++n_tls_shutdown_task;
182 while (n_tls_shutdown_task != 0) {
183 nanosleep(&
s,
nullptr);
192 if (active_tlsdata != 0 and not tls_shutdown_timeout) {
193 ++n_tls_shutdown_task;
196 tbb::task::enqueue(*
task);
204 while (active_tlsdata.load() != 0 and ++
count < 1000) {
205 nanosleep(&
s,
nullptr);
208 tls_shutdown_timeout =
true;
211 --n_tls_shutdown_task;
227 int thisID = getThreadIndex();
232 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. "
233 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
245 int thisID = getThreadIndex();
247 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread " << thisID;
250 G4Threading::G4SetThreadId(thisID);
251 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
253 if (uitype ==
"MessageLogger") {
255 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
257 }
else if (uitype ==
"FilePerThread") {
261 <<
"Invalid value of CustomUIsession.Type '" << uitype
262 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
266 G4WorkerThread::BuildGeometryAndPhysicsVector();
269 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
271 m_tls->
kernel.reset(
new G4WorkerRunManagerKernel());
275 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler());
280 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
281 tM->SetWorldForTracking(worldPV);
295 tM->SetFieldManager(fieldManager);
296 fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
299 if (!fieldFile.empty()) {
302 edm::LogVerbatim(
"SimG4CoreApplication") <<
" RunManagerMTWorker: Dump magnetic field to file " << fieldFile;
317 <<
" RunManagerMTWorker: Sensitive Detector building finished; found " <<
m_tls->
sensTkDets.size()
318 <<
" Tk type Producers, and " <<
m_tls->
sensCaloDets.size() <<
" Calo type producers ";
323 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: start initialisation of PhysicsList for the thread";
327 G4cout <<
"RunManagerMTWorker: Requested UI commands: " << G4endl;
330 G4UImanager::GetUIpointer()->ApplyCommand(
command);
333 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
335 physicsList->InitializeWorker();
339 const bool kernelInit =
m_tls->
kernel->RunInitialization();
358 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread done for the thread " << thisID;
360 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
369 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
375 eventManager->SetUserAction(userEventAction);
379 eventManager->SetUserAction(userTrackingAction);
384 eventManager->SetUserAction(userSteppingAction);
427 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
464 LogDebug(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce(): stream " << inpevt.
streamID() <<
" thread "
465 << getThreadIndex() <<
" initializing";
482 auto simEvent = std::make_unique<G4SimEvent>();
489 genVertex->y() / CLHEP::cm,
490 genVertex->z() / CLHEP::cm,
494 std::stringstream
ss;
495 ss <<
"RunManagerMTWorker::produce(): event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices \n";
500 std::stringstream
ss;
501 ss <<
" RunManagerMT::produce(): "
502 <<
" no G4WorkerRunManagerKernel yet for thread index" << getThreadIndex() <<
", id " << std::hex
503 << std::this_thread::get_id() <<
" \n";
508 <<
" RunManagerMTWorker::produce: start Event " << inpevt.
id().
event() <<
" stream id " << inpevt.
streamID()
509 <<
" thread index " << getThreadIndex() <<
" of weight " <<
m_simEvent->
weight() <<
" with "
515 edm::LogVerbatim(
"SimG4CoreApplication") <<
" RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
533 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
534 t->SetTrackStatus(fStopAndKill);
542 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
543 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
560 G4Event* evt =
new G4Event(
evtid);
594 <<
" RunManager WARNING : error opening file <" <<
file <<
"> for magnetic field";
597 double rmax = 9000 * mm;
598 double zmax = 24000 * mm;
614 double point[4] = {0.0, 0.0, 0.0, 0.0};
615 double bfield[3] = {0.0, 0.0, 0.0};
617 fout << std::setprecision(6);
618 for (
int i = 0;
i <=
nr; ++
i) {
620 for (
int j = 0;
j <= nz; ++
j) {
624 field->GetFieldValue(
point, bfield);
625 fout <<
"R(mm)= " <<
r / mm <<
" phi(deg)= " <<
phi / degree <<
" Z(mm)= " <<
z / mm
626 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
627 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / tesla << G4endl;