48 #include "G4SystemOfUnits.hh"
49 #include "G4Threading.hh"
50 #include "G4UImanager.hh"
51 #include "G4WorkerThread.hh"
52 #include "G4WorkerRunManagerKernel.hh"
53 #include "G4StateManager.hh"
54 #include "G4TransportationManager.hh"
56 #include "G4FieldManager.hh"
69 std::atomic<int> thread_counter{0};
71 int get_new_thread_index() {
return thread_counter++; }
75 std::vector<std::shared_ptr<SimWatcher>>& oWatchers,
78 std::vector<edm::ParameterSet>
ws = iP.
getParameter<std::vector<edm::ParameterSet>>(
"Watchers");
83 for (
auto& watcher : ws) {
84 std::unique_ptr<SimWatcherMakerBase> maker(
86 if (maker ==
nullptr) {
88 <<
"RunManagerMTWorker::createWatchers: "
89 <<
"Unable to find the requested Watcher " << watcher.getParameter<
std::string>(
"type");
91 std::shared_ptr<SimWatcher> watcherTemp;
92 std::shared_ptr<SimProducer> producerTemp;
93 maker->make(watcher, *(iReg), watcherTemp, producerTemp);
94 if (
nullptr != watcherTemp) {
95 if (!watcherTemp->isMT() && 0 < threadID) {
97 <<
"RunManagerMTWorker::createWatchers: "
98 <<
"Unable to use Watcher " << watcher.getParameter<
std::string>(
"type") <<
" if number of threads > 1";
100 oWatchers.push_back(watcherTemp);
101 if (
nullptr != producerTemp) {
102 oProds.push_back(producerTemp);
108 return (!oWatchers.empty());
113 std::unique_ptr<G4RunManagerKernel>
kernel;
144 : m_generator(iConfig.getParameter<edm::
ParameterSet>(
"Generator")),
146 iConfig.getParameter<edm::
ParameterSet>(
"Generator").getParameter<edm::
InputTag>(
"HepMCProductLabel"))),
149 m_nonBeam(iConfig.getParameter<bool>(
"NonBeamEvent")),
150 m_pUseMagneticField(iConfig.getParameter<bool>(
"UseMagneticField")),
151 m_LHCTransport(iConfig.getParameter<bool>(
"LHCTransport")),
152 m_thread_index{get_new_thread_index()},
153 m_EvtMgrVerbosity(
iConfig.getUntrackedParameter<
int>(
"G4EventManagerVerbosity", 0)),
162 int thisID = getThreadIndex();
163 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker for the thread " << thisID;
166 std::vector<std::string> onlySDs =
iConfig.getParameter<std::vector<std::string>>(
"OnlySDs");
172 for (
auto& watcher : m_tls->watchers) {
173 watcher->registerConsumes(iC);
177 if (m_LHCTransport) {
180 if (m_pUseMagneticField) {
183 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker is constructed for the thread " << thisID;
185 for (std::unordered_map<
std::string, std::unique_ptr<SensitiveDetectorMakerBase>>::const_iterator itr =
187 itr != m_sdMakers.end();
189 edm::LogVerbatim(
"SimG4CoreApplication") <<
"SD[" << k <<
"] " << itr->first;
198 for (
auto& maker : m_sdMakers) {
199 maker.second->beginRun(es);
206 watcher->beginRun(es);
213 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " << thisID;
218 if (
nullptr !=
m_tls) {
233 <<
"RunManagerMTWorker::initializeTLS : "
234 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. "
235 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
252 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeG4 in thread " << thisID <<
" is started";
255 G4Threading::G4SetThreadId(thisID);
256 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
258 if (uitype ==
"MessageLogger") {
260 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
263 }
else if (uitype ==
"FilePerThread") {
268 <<
"RunManagerMTWorker::initializeG4: Invalid value of CustomUIsession.Type '" << uitype
269 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
271 G4UImanager::GetUIpointer()->SetCoutDestination(
m_UIsession);
274 G4WorkerThread::BuildGeometryAndPhysicsVector();
277 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
279 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
283 double th =
m_p.
getParameter<
double>(
"ThresholdForGeometryExceptions") * CLHEP::GeV;
285 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler(th, tr));
290 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
291 tM->SetWorldForTracking(worldPV);
303 tM->SetFieldManager(fieldManager);
304 fieldBuilder.
build(fieldManager, tM->GetPropagatorInField());
307 if (!fieldFile.empty()) {
311 <<
"RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
325 <<
"RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID <<
" found "
332 <<
"RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
335 if (!runManagerMaster->
G4Commands().empty()) {
336 G4cout <<
"RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
338 G4cout <<
" " <<
command << G4endl;
339 G4UImanager::GetUIpointer()->ApplyCommand(
command);
342 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
344 physicsList->InitializeWorker();
350 <<
"RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
363 m_sVerbose = std::make_unique<CMSSteppingVerbose>(sv, elim, ve, vn, vt);
367 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
371 <<
"RunManagerMTWorker::initializeG4 done for the thread " << thisID <<
" " << timer;
381 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
387 eventManager->SetUserAction(userEventAction);
391 eventManager->SetUserAction(userTrackingAction);
396 eventManager->SetUserAction(userSteppingAction);
439 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun " << thisID <<
" is started";
441 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
448 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun ";
453 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun " << thisID <<
" is started";
497 auto simEvent = std::make_unique<G4SimEvent>();
504 genVertex->y() / CLHEP::cm,
505 genVertex->z() / CLHEP::cm,
510 <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices"
515 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
516 <<
" threadIndex=" <<
getThreadIndex() <<
" weight=" << m_simEvent->weight() <<
"; "
517 <<
m_tls->
currentEvent->GetNumberOfPrimaryVertex() <<
" vertices for Geant4; generator produced "
518 << m_simEvent->nGenParts() <<
" particles.";
529 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
530 m_simEvent =
nullptr;
538 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
539 t->SetTrackStatus(fStopAndKill);
547 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
548 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
565 G4Event* evt =
new G4Event(evtid);
603 <<
"MTWorker::DumpMagneticField: error opening file <" << file <<
"> for magnetic field";
606 double rmax = 9000 * mm;
607 double zmax = 24000 * mm;
612 int nr = (int)(rmax / dr);
613 int nz = 2 * (int)(zmax / dz);
620 double cosf =
cos(phi);
621 double sinf =
sin(phi);
623 double point[4] = {0.0, 0.0, 0.0, 0.0};
624 double bfield[3] = {0.0, 0.0, 0.0};
626 fout << std::setprecision(6);
627 for (
int i = 0;
i <= nr; ++
i) {
629 for (
int j = 0;
j <= nz; ++
j) {
633 field->GetFieldValue(point, bfield);
634 fout <<
"R(mm)= " << r / mm <<
" phi(deg)= " << phi / degree <<
" Z(mm)= " << z / mm
635 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
636 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / tesla << G4endl;
edm::ParameterSet m_pSteppingAction
Log< level::Info, true > LogVerbatim
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
CustomUIsession * m_UIsession
void nonCentralEvent2G4(const HepMC::GenEvent *g, G4Event *e)
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()
virtual const HepMC::GenEvent * genEvent() const
SimActivityRegistry::G4StepSignal m_g4StepSignal
SimTrackManager * GetSimTrackManager()
bool getByToken(EDGetToken token, Handle< PROD > &result) const
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
edm::RunNumber_t currentRunNumber
std::vector< SensitiveTkDetector * > sensTkDets
SimActivityRegistry::EndOfEventSignal m_endOfEventSignal
void beginRun(const edm::EventSetup &)
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
edm::EDGetTokenT< edm::HepMCProduct > m_LHCToken
bool getData(T &iHolder) const
U second(std::pair< T, U > const &p)
std::unique_ptr< SimActivityRegistry > registry
edm::ParameterSet m_pEventAction
const DDDWorld & world() const
std::unique_ptr< SimTrackManager > trackManager
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)
RunManagerMTWorker(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iC)
std::unique_ptr< G4SimEvent > produce(const edm::Event &inpevt, const edm::EventSetup &es, RunManagerMT &runManagerMaster)
std::unique_ptr< RunAction > userRunAction
int getThreadIndex() const
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)
void connect(Observer< const T * > *iObs)
does not take ownership of memory
void build(CMSFieldManager *fM, G4PropagatorInField *fP)
std::pair< std::vector< SensitiveTkDetector * >, std::vector< SensitiveCaloDetector * > > attachSD(const std::unordered_map< std::string, std::unique_ptr< SensitiveDetectorMakerBase >> &, const edm::EventSetup &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *, SimActivityRegistry ®)
static std::once_flag applyOnce
PhysicsList * physicsListForWorker() const
T const * product() const
std::vector< SensitiveCaloDetector * > & sensCaloDetectors()
edm::ParameterSet m_pTrackingAction
edm::ParameterSet m_pField
T getParameter(std::string const &) const
G4Event * generateEvent(const edm::Event &inpevt)
std::vector< std::shared_ptr< SimProducer > > & producers()
edm::EDGetTokenT< edm::LHCTransportLinkContainer > m_theLHCTlinkToken
SimActivityRegistry::BeginOfRunSignal m_beginOfRunSignal
const std::vector< std::string > & G4Commands() const
edm::ParameterSet m_pCustomUIsession
const MagneticField * m_pMagField
std::unordered_map< std::string, std::unique_ptr< SensitiveDetectorMakerBase > > sensitiveDetectorMakers(edm::ParameterSet const &, edm::ConsumesCollector, std::vector< std::string > const &chosenMakers)
StreamID streamID() const
std::vector< LHCTransportLink > LHCTransportLinkContainer
static void createWatchers(const edm::ParameterSet &iP, SimActivityRegistry &iReg, std::vector< std::shared_ptr< SimWatcher >> &oWatchers, std::vector< std::shared_ptr< SimProducer >> &oProds)
void PostUserTrackingAction(const G4Track *aTrack) override
void initializeG4(RunManagerMT *runManagerMaster, const edm::EventSetup &es)
Log< level::Warning, false > LogWarning
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > m_MagField
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