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;
123 std::vector<std::shared_ptr<SimWatcher> >
watchers;
165 std::vector<edm::ParameterSet> watchers = iConfig.
getParameter<std::vector<edm::ParameterSet> >(
"Watchers");
175 ++n_tls_shutdown_task;
183 while (n_tls_shutdown_task != 0) {
184 nanosleep(&s,
nullptr);
193 if (active_tlsdata != 0 and not tls_shutdown_timeout) {
194 ++n_tls_shutdown_task;
197 tbb::task::enqueue(*
task);
205 while (active_tlsdata.load() != 0 and ++count < 1000) {
206 nanosleep(&s,
nullptr);
209 tls_shutdown_timeout =
true;
212 --n_tls_shutdown_task;
228 int thisID = getThreadIndex();
233 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. " 234 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
246 int thisID = getThreadIndex();
248 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread " << thisID;
251 G4Threading::G4SetThreadId(thisID);
252 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
254 if (uitype ==
"MessageLogger") {
256 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
259 }
else if (uitype ==
"FilePerThread") {
264 <<
"Invalid value of CustomUIsession.Type '" << uitype
265 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
269 G4WorkerThread::BuildGeometryAndPhysicsVector();
272 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
274 m_tls->
kernel.reset(
new G4WorkerRunManagerKernel());
278 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler());
283 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
284 tM->SetWorldForTracking(worldPV);
298 tM->SetFieldManager(fieldManager);
299 fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
302 if (!fieldFile.empty()) {
305 edm::LogVerbatim(
"SimG4CoreApplication") <<
" RunManagerMTWorker: Dump magnetic field to file " << fieldFile;
320 <<
" RunManagerMTWorker: Sensitive Detector building finished; found " <<
m_tls->
sensTkDets.size()
321 <<
" Tk type Producers, and " <<
m_tls->
sensCaloDets.size() <<
" Calo type producers ";
326 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: start initialisation of PhysicsList for the thread";
330 G4cout <<
"RunManagerMTWorker: Requested UI commands: " << G4endl;
333 G4UImanager::GetUIpointer()->ApplyCommand(
command);
336 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
338 physicsList->InitializeWorker();
342 const bool kernelInit =
m_tls->
kernel->RunInitialization();
361 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeThread done for the thread " << thisID;
363 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
372 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
378 eventManager->SetUserAction(userEventAction);
382 eventManager->SetUserAction(userTrackingAction);
387 eventManager->SetUserAction(userSteppingAction);
430 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
467 LogDebug(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce(): stream " << inpevt.
streamID() <<
" thread " 468 << getThreadIndex() <<
" initializing";
485 auto simEvent = std::make_unique<G4SimEvent>();
492 genVertex->y() / CLHEP::cm,
493 genVertex->z() / CLHEP::cm,
497 std::stringstream
ss;
498 ss <<
"RunManagerMTWorker::produce(): event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices \n";
503 std::stringstream
ss;
504 ss <<
" RunManagerMT::produce(): " 505 <<
" no G4WorkerRunManagerKernel yet for thread index" << getThreadIndex() <<
", id " << std::hex
506 << std::this_thread::get_id() <<
" \n";
511 <<
" RunManagerMTWorker::produce: start Event " << inpevt.
id().
event() <<
" stream id " << inpevt.
streamID()
512 <<
" thread index " << getThreadIndex() <<
" of weight " << m_simEvent->weight() <<
" with " 513 << m_simEvent->nTracks() <<
" tracks and " << m_simEvent->nVertices() <<
" vertices, generated by " 514 << m_simEvent->nGenParts() <<
" particles ";
518 edm::LogVerbatim(
"SimG4CoreApplication") <<
" RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
528 m_simEvent =
nullptr;
536 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
537 t->SetTrackStatus(fStopAndKill);
545 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
546 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
563 G4Event* evt =
new G4Event(evtid);
597 <<
" RunManager WARNING : error opening file <" << file <<
"> for magnetic field";
600 double rmax = 9000 * mm;
601 double zmax = 24000 * mm;
606 int nr = (
int)(rmax / dr);
607 int nz = 2 * (
int)(zmax / dz);
614 double cosf =
cos(phi);
615 double sinf =
sin(phi);
617 double point[4] = {0.0, 0.0, 0.0, 0.0};
618 double bfield[3] = {0.0, 0.0, 0.0};
620 fout << std::setprecision(6);
621 for (
int i = 0;
i <=
nr; ++
i) {
623 for (
int j = 0;
j <= nz; ++
j) {
627 field->GetFieldValue(point, bfield);
628 fout <<
"R(mm)= " << r / mm <<
" phi(deg)= " << phi / degree <<
" Z(mm)= " << z / mm
629 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
630 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / tesla << G4endl;
edm::ParameterSet m_pSteppingAction
T getParameter(std::string const &) const
EventNumber_t event() const
std::vector< std::shared_ptr< SimWatcher > > watchers
const SensitiveDetectorCatalog & catalog() const
T getUntrackedParameter(std::string const &, T const &) const
virtual const math::XYZTLorentzVector * genVertex() const
std::unique_ptr< G4Event > currentEvent
virtual const double eventWeight() const
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
void initializeUserActions()
def create(alignables, pedeDump, additionalData, outputFile, config)
virtual const HepMC::GenEvent * genEvent() const
SimActivityRegistry::G4StepSignal m_g4StepSignal
SimTrackManager * GetSimTrackManager()
bool getByToken(EDGetToken token, Handle< PROD > &result) const
FunctorTask< F > * make_functor_task(ALLOC &&iAlloc, F f)
void HepMC2G4(const HepMC::GenEvent *g, G4Event *e)
std::unique_ptr< SimRunInterface > runInterface
Sin< T >::type sin(const T &t)
std::unique_ptr< CMSSteppingVerbose > m_sVerbose
SimActivityRegistry::EndOfRunSignal m_endOfRunSignal
bool exists(std::string const ¶meterName) const
checks if a parameter exists
edm::RunNumber_t currentRunNumber
std::vector< SensitiveTkDetector * > sensTkDets
SimActivityRegistry::EndOfEventSignal m_endOfEventSignal
static void createWatchers(const edm::ParameterSet &iP, SimActivityRegistry &iReg, std::vector< std::shared_ptr< SimWatcher > > &oWatchers, std::vector< std::shared_ptr< SimProducer > > &oProds)
edm::EDGetTokenT< edm::HepMCProduct > m_InToken
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
std::unique_ptr< G4RunManagerKernel > kernel
U second(std::pair< T, U > const &p)
std::unique_ptr< SimActivityRegistry > registry
edm::ParameterSet m_pEventAction
const DDDWorld & world() const
RunAction
list of unwanted particles (gluons and quarks)
std::pair< std::vector< SensitiveTkDetector * >, std::vector< SensitiveCaloDetector * > > create(const edm::EventSetup &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *, SimActivityRegistry ®) const
std::unique_ptr< SimTrackManager > trackManager
std::unique_ptr< CustomUIsession > UIsession
static thread_local bool dumpMF
static thread_local TLSData * m_tls
edm::ParameterSet m_pRunAction
std::vector< SensitiveCaloDetector * > sensCaloDets
Cos< T >::type cos(const T &t)
std::vector< SensitiveTkDetector * > & sensTkDetectors()
void resetGenParticleId(const edm::Event &inpevt)
std::unique_ptr< G4SimEvent > produce(const edm::Event &inpevt, const edm::EventSetup &es, RunManagerMT &runManagerMaster)
std::unique_ptr< RunAction > userRunAction
void initializeThread(RunManagerMT &runManagerMaster, const edm::EventSetup &es)
void hepEvent(const HepMC::GenEvent *r)
void setGenEvent(const HepMC::GenEvent *inpevt)
G4VPhysicalVolume * GetWorldVolume() const
SimActivityRegistry::EndOfTrackSignal m_endOfTrackSignal
std::vector< std::shared_ptr< SimProducer > > producers
void abortRun(bool softAbort=false)
RunManagerMTWorker(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&i)
void connect(Observer< const T * > *iObs)
does not take ownership of memory
static std::once_flag applyOnce
PhysicsList * physicsListForWorker() const
const HepMC::GenEvent * GetEvent() const
T const * product() const
std::vector< SensitiveCaloDetector * > & sensCaloDetectors()
edm::ParameterSet m_pTrackingAction
edm::ParameterSet m_pField
G4Event * generateEvent(const edm::Event &inpevt)
std::vector< std::shared_ptr< SimProducer > > & producers()
edm::EDGetTokenT< edm::LHCTransportLinkContainer > m_theLHCTlinkToken
void nonBeamEvent2G4(const HepMC::GenEvent *g, G4Event *e)
SimActivityRegistry::BeginOfRunSignal m_beginOfRunSignal
const std::vector< std::string > & G4Commands() const
edm::ParameterSet m_pCustomUIsession
StreamID streamID() const
std::vector< LHCTransportLink > LHCTransportLinkContainer
void PostUserTrackingAction(const G4Track *aTrack) override
T const * product() const
SimActivityRegistry::BeginOfEventSignal m_beginOfEventSignal
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
void DumpMagneticField(const G4Field *, const std::string &) const
edm::ParameterSet m_pStackingAction
void Connect(RunAction *)
SimActivityRegistry::BeginOfTrackSignal m_beginOfTrackSignal