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"
76 std::atomic<int> thread_counter{0};
78 int get_new_thread_index() {
return thread_counter++; }
80 thread_local
int s_thread_index = get_new_thread_index();
82 int getThreadIndex() {
return s_thread_index; }
86 std::vector<std::shared_ptr<SimWatcher> >& oWatchers,
87 std::vector<std::shared_ptr<SimProducer> >& oProds) {
88 if (!iP.
exists(
"Watchers")) {
92 std::vector<edm::ParameterSet> watchers = iP.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
94 for (
auto& watcher : watchers) {
95 std::unique_ptr<SimWatcherMakerBase> maker(
97 if (maker ==
nullptr) {
99 <<
"Unable to find the requested Watcher <" << watcher.getParameter<
std::string>(
"type");
101 std::shared_ptr<SimWatcher> watcherTemp;
102 std::shared_ptr<SimProducer> producerTemp;
103 maker->make(watcher, *(iReg), watcherTemp, producerTemp);
104 oWatchers.push_back(watcherTemp);
106 oProds.push_back(producerTemp);
111 std::atomic<int> active_tlsdata{0};
112 std::atomic<bool> tls_shutdown_timeout{
false};
113 std::atomic<int> n_tls_shutdown_task{0};
117 std::unique_ptr<G4RunManagerKernel>
kernel;
124 std::vector<std::shared_ptr<SimWatcher> >
watchers;
153 m_nonBeam(iConfig.getParameter<
bool>(
"NonBeamEvent")),
154 m_pUseMagneticField(iConfig.getParameter<
bool>(
"UseMagneticField")),
155 m_LHCTransport(iConfig.getParameter<
bool>(
"LHCTransport")),
156 m_EvtMgrVerbosity(iConfig.getUntrackedParameter<
int>(
"G4EventManagerVerbosity", 0)),
159 m_pEventAction(iConfig.getParameter<
edm::
ParameterSet>(
"EventAction")),
160 m_pStackingAction(iConfig.getParameter<
edm::
ParameterSet>(
"StackingAction")),
161 m_pTrackingAction(iConfig.getParameter<
edm::
ParameterSet>(
"TrackingAction")),
162 m_pSteppingAction(iConfig.getParameter<
edm::
ParameterSet>(
"SteppingAction")),
163 m_pCustomUIsession(iConfig.getUntrackedParameter<
edm::
ParameterSet>(
"CustomUIsession")),
166 m_sVerbose(nullptr) {
167 std::vector<edm::ParameterSet> watchers = iConfig.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
170 int thisID = getThreadIndex();
174 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker is constructed for the thread " << thisID;
178 ++n_tls_shutdown_task;
186 while (n_tls_shutdown_task != 0) {
187 nanosleep(&
s,
nullptr);
195 if (active_tlsdata != 0 and not tls_shutdown_timeout) {
196 ++n_tls_shutdown_task;
199 tbb::task::enqueue(*
task);
207 while (active_tlsdata.load() != 0 and ++
count < 1000) {
208 nanosleep(&
s,
nullptr);
211 tls_shutdown_timeout =
true;
214 --n_tls_shutdown_task;
218 int thisID = getThreadIndex();
219 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " << thisID;
234 int thisID = getThreadIndex();
239 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. "
240 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
254 int thisID = getThreadIndex();
255 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread " << thisID <<
" is started";
258 G4Threading::G4SetThreadId(thisID);
259 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
261 if (uitype ==
"MessageLogger") {
263 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
265 }
else if (uitype ==
"FilePerThread") {
269 <<
"Invalid value of CustomUIsession.Type '" << uitype
270 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
274 G4WorkerThread::BuildGeometryAndPhysicsVector();
277 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
279 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
283 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler());
288 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
289 tM->SetWorldForTracking(worldPV);
303 tM->SetFieldManager(fieldManager);
304 fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
307 if (!fieldFile.empty()) {
310 edm::LogVerbatim(
"SimG4CoreApplication") <<
" RunManagerMTWorker: Dump magnetic field to file " << fieldFile;
325 <<
" RunManagerMTWorker: Sensitive Detector building finished; found " <<
m_tls->
sensTkDets.size()
326 <<
" Tk type Producers, and " <<
m_tls->
sensCaloDets.size() <<
" Calo type producers ";
331 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: start initialisation of PhysicsList for the thread";
334 if (!runManagerMaster->
G4Commands().empty()) {
335 G4cout <<
"RunManagerMTWorker: Requested UI commands: " << G4endl;
338 G4UImanager::GetUIpointer()->ApplyCommand(
command);
341 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
343 physicsList->InitializeWorker();
347 const bool kernelInit =
m_tls->
kernel->RunInitialization();
362 m_sVerbose = std::make_unique<CMSSteppingVerbose>(
sv, elim, ve, vn, vt);
366 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread done for the thread " << thisID;
368 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
378 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
384 eventManager->SetUserAction(userEventAction);
388 eventManager->SetUserAction(userTrackingAction);
393 eventManager->SetUserAction(userSteppingAction);
435 int thisID = getThreadIndex();
436 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun " << thisID <<
" is started";
438 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
445 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun ";
449 int thisID = getThreadIndex();
450 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun " << thisID <<
" is started";
479 <<
"RunManagerMTWorker::produce(): stream " << inpevt.
streamID() <<
" thread " << getThreadIndex()
480 <<
" Geant4 initialisation for this thread";
497 auto simEvent = std::make_unique<G4SimEvent>();
504 genVertex->y() / CLHEP::cm,
505 genVertex->z() / CLHEP::cm,
509 std::stringstream
ss;
510 ss <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices \n";
515 std::stringstream
ss;
516 ss <<
"RunManagerMTWorker::produce: "
517 <<
" no G4WorkerRunManagerKernel yet for thread index" << getThreadIndex() <<
", id " << std::hex
518 << std::this_thread::get_id() <<
" \n";
523 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
524 <<
" threadIndex=" << getThreadIndex() <<
" weight=" <<
m_simEvent->
weight() <<
"; "
525 <<
m_tls->
currentEvent->GetNumberOfPrimaryVertex() <<
" vertices for Geant4; generator produced "
537 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
547 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
548 t->SetTrackStatus(fStopAndKill);
556 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
557 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
574 G4Event* evt =
new G4Event(
evtid);
612 <<
" RunManager WARNING : error opening file <" <<
file <<
"> for magnetic field";
615 double rmax = 9000 * mm;
616 double zmax = 24000 * mm;
632 double point[4] = {0.0, 0.0, 0.0, 0.0};
633 double bfield[3] = {0.0, 0.0, 0.0};
635 fout << std::setprecision(6);
636 for (
int i = 0;
i <=
nr; ++
i) {
638 for (
int j = 0;
j <= nz; ++
j) {
642 field->GetFieldValue(
point, bfield);
643 fout <<
"R(mm)= " <<
r / mm <<
" phi(deg)= " <<
phi / degree <<
" Z(mm)= " <<
z / mm
644 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
645 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / tesla << G4endl;