51 #include <CLHEP/Units/SystemOfUnits.h> 52 #include "G4Threading.hh" 53 #include "G4UImanager.hh" 54 #include "G4WorkerThread.hh" 55 #include "G4WorkerRunManagerKernel.hh" 56 #include "G4StateManager.hh" 57 #include "G4TransportationManager.hh" 58 #include "G4LossTableManager.hh" 59 #include "G4PhysListUtil.hh" 61 #include "G4FieldManager.hh" 62 #include "G4ScoringManager.hh" 63 #include "G4UserSteppingAction.hh" 64 #include "G4GDMLParser.hh" 65 #include "G4Threading.hh" 79 std::atomic<int> thread_counter{0};
81 int get_new_thread_index() {
return thread_counter++; }
85 std::vector<std::shared_ptr<SimWatcher>>& oWatchers,
88 std::vector<edm::ParameterSet>
ws = iP.
getParameter<std::vector<edm::ParameterSet>>(
"Watchers");
93 for (
auto& watcher :
ws) {
94 std::unique_ptr<SimWatcherMakerBase> maker(
96 if (maker ==
nullptr) {
98 <<
"RunManagerMTWorker::createWatchers: " 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 if (
nullptr != watcherTemp) {
105 if (!watcherTemp->isMT() && 0 < threadID) {
107 <<
"RunManagerMTWorker::createWatchers: " 108 <<
"Unable to use Watcher " << watcher.getParameter<
std::string>(
"type") <<
" if number of threads > 1";
110 oWatchers.push_back(watcherTemp);
111 if (
nullptr != producerTemp) {
112 oProds.push_back(producerTemp);
118 return (!oWatchers.empty());
123 std::unique_ptr<G4RunManagerKernel>
kernel;
158 m_nonBeam(
p.getParameter<
bool>(
"NonBeamEvent")),
159 m_UseG4EventManager(
p.getParameter<
bool>(
"UseG4EventManager")),
160 m_pUseMagneticField(
p.getParameter<
bool>(
"UseMagneticField")),
161 m_LHCTransport(
p.getParameter<
bool>(
"LHCTransport")),
162 m_thread_index{(get_new_thread_index())},
169 m_G4Commands(
p.getParameter<std::vector<std::string>>(
"G4Commands")),
170 m_G4CommandsEndRun(
p.getParameter<std::vector<std::string>>(
"G4CommandsEndRun")),
172 int id = getThreadIndex();
173 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker for the thread " <<
id;
176 G4Threading::G4SetThreadId(
id);
177 G4UImanager::GetUIpointer()->SetUpForAThread(
id);
180 if (uitype ==
"MessageLogger") {
182 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
184 }
else if (uitype ==
"FilePerThread") {
188 <<
"RunManagerMTWorker::initializeG4: Invalid value of CustomUIsession.Type '" << uitype
189 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
191 G4UImanager::GetUIpointer()->SetCoutDestination(m_UIsession);
196 std::vector<std::string> onlySDs =
p.getParameter<std::vector<std::string>>(
"OnlySDs");
202 for (
auto& watcher : m_tls->watchers) {
203 watcher->registerConsumes(iC);
206 if (m_LHCTransport) {
209 if (m_pUseMagneticField) {
212 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker is constructed for the thread " <<
id;
214 for (std::unordered_map<
std::string, std::unique_ptr<SensitiveDetectorMakerBase>>::const_iterator itr =
216 itr != m_sdMakers.end();
229 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun for the thread " <<
id;
231 maker.second->beginRun(es);
238 watcher->beginRun(es);
241 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun done for the thread " <<
id;
246 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " <<
id;
251 if (
nullptr !=
m_tls) {
266 <<
"RunManagerMTWorker::initializeTLS : " 267 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. " 268 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
285 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeG4 in thread " << thisID <<
" is started";
288 G4WorkerThread::BuildGeometryAndPhysicsVector();
291 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
293 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
297 double th =
m_p.
getParameter<
double>(
"ThresholdForGeometryExceptions") * CLHEP::GeV;
299 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler(th, tr));
304 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
305 tM->SetWorldForTracking(worldPV);
318 tM->SetFieldManager(fieldManager);
319 fieldBuilder.
build(fieldManager, tM->GetPropagatorInField());
322 if (!fieldFile.empty()) {
326 <<
"RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
340 <<
"RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID <<
" found " 345 if (!writeFile.empty()) {
349 G4int thID = G4Threading::G4GetThreadId();
351 G4Threading::G4SetThreadId(-1);
353 gdml.SetRegionExport(
true);
354 gdml.SetEnergyCutsExport(
true);
355 gdml.SetSDExport(
true);
356 gdml.Write(writeFile, worldPV,
true);
357 G4Threading::G4SetThreadId(thID);
364 G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
365 scManager->SetVerboseLevel(1);
373 <<
"RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
376 if (!runManagerMaster->
G4Commands().empty()) {
377 G4cout <<
"RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
380 G4UImanager::GetUIpointer()->ApplyCommand(
command);
383 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
385 physicsList->InitializeWorker();
391 <<
"RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
405 m_sVerbose = std::make_unique<CMSSteppingVerbose>(
sv, elim, ve, vn, vt);
411 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
415 <<
"RunManagerMTWorker::initializeG4 done for the thread " << thisID <<
" " << timer;
426 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
427 eventManager->SetVerboseLevel(ver);
429 auto userEventAction =
433 eventManager->SetUserAction(userEventAction);
441 eventManager->SetUserAction(userTrackingAction);
447 G4UserSteppingAction* userSteppingAction;
452 userSteppingAction = (G4UserSteppingAction*)ptr;
456 userSteppingAction = (G4UserSteppingAction*)ptr;
459 eventManager->SetUserAction(userSteppingAction);
466 eventManager->SetUserAction(userStackingAction);
514 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
519 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun done for thread " <<
id;
524 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun for thread " <<
id;
533 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: Requested end of run UI commands: ";
536 G4UImanager::GetUIpointer()->ApplyCommand(
command);
549 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun done for thread " <<
id;
558 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event();
583 genVertex->y() / CLHEP::cm,
584 genVertex->z() / CLHEP::cm,
589 <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices" 594 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
612 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
620 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
621 t->SetTrackStatus(fStopAndKill);
629 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
630 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
646 G4Event* evt =
new G4Event(
evtid);
683 <<
"MTWorker::DumpMagneticField: error opening file <" <<
file <<
"> for magnetic field";
686 double rmax = 9000 * CLHEP::mm;
687 double zmax = 24000 * CLHEP::mm;
689 double dr = 1 * CLHEP::cm;
690 double dz = 5 * CLHEP::cm;
703 double point[4] = {0.0, 0.0, 0.0, 0.0};
704 double bfield[3] = {0.0, 0.0, 0.0};
706 fout << std::setprecision(6);
707 for (
int i = 0;
i <=
nr; ++
i) {
709 for (
int j = 0;
j <= nz; ++
j) {
713 field->GetFieldValue(
point, bfield);
714 fout <<
"R(mm)= " <<
r / CLHEP::mm <<
" phi(deg)= " <<
phi / CLHEP::degree <<
" Z(mm)= " <<
z / CLHEP::mm
715 <<
" Bz(tesla)= " << bfield[2] / CLHEP::tesla
716 <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / CLHEP::tesla
717 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / CLHEP::tesla << G4endl;
void connect(Observer< const T *> *iObs)
does not take ownership of memory
edm::ParameterSet m_pSteppingAction
Log< level::Info, true > LogVerbatim
void setHepEvent(const HepMC::GenEvent *r)
virtual const HepMC::GenEvent * genEvent() const
std::vector< std::shared_ptr< SimWatcher > > watchers
static std::once_flag applyOnceGDML
T getParameter(std::string const &) const
CustomUIsession * m_UIsession
void nonCentralEvent2G4(const HepMC::GenEvent *g, G4Event *e)
std::unique_ptr< G4Event > currentEvent
unsigned int nTracks() const
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
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)
SimActivityRegistry::G4StepSignal m_g4StepSignal
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
T const * product() const
SimActivityRegistry::EndOfRunSignal m_endOfRunSignal
edm::RunNumber_t currentRunNumber
std::vector< SensitiveTkDetector * > sensTkDets
bool getByToken(EDGetToken token, Handle< PROD > &result) const
SimActivityRegistry::EndOfEventSignal m_endOfEventSignal
G4VPhysicalVolume * GetWorldVolume() const
virtual const math::XYZTLorentzVector * genVertex() const
void beginRun(const edm::EventSetup &)
edm::EDGetTokenT< edm::HepMCProduct > m_InToken
SimActivityRegistry::G4StepSignal m_g4StepSignal
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::vector< std::string > m_G4CommandsEndRun
std::unique_ptr< G4RunManagerKernel > kernel
std::unique_ptr< CMSSimEventManager > m_evtManager
edm::EDGetTokenT< edm::HepMCProduct > m_LHCToken
T getUntrackedParameter(std::string const &, T const &) const
U second(std::pair< T, U > const &p)
static std::once_flag applyOnceEnd
std::unique_ptr< SimActivityRegistry > registry
edm::ParameterSet m_pEventAction
std::unique_ptr< SimTrackManager > trackManager
edm::ParameterSet m_pRunAction
std::vector< SensitiveCaloDetector * > sensCaloDets
std::unordered_map< std::string, std::unique_ptr< SensitiveDetectorMakerBase > > m_sdMakers
Cos< T >::type cos(const T &t)
std::vector< SensitiveTkDetector * > & sensTkDetectors()
void collisionPoint(const math::XYZTLorentzVectorD &v)
void resetGenParticleId(const edm::Event &inpevt)
RunManagerMTWorker(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iC)
const SensitiveDetectorCatalog & catalog() const
std::unique_ptr< RunAction > userRunAction
void setGenEvent(const HepMC::GenEvent *inpevt)
SimActivityRegistry::EndOfTrackSignal m_endOfTrackSignal
StreamID streamID() const
std::vector< std::shared_ptr< SimProducer > > producers
void abortRun(bool softAbort=false)
TmpSimEvent * produce(const edm::Event &inpevt, const edm::EventSetup &es, RunManagerMT &runManagerMaster)
const HepMC::GenEvent * GetEvent() const
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 ®)
const DDDWorld & world() const
static std::once_flag applyOnce
std::vector< SensitiveCaloDetector * > & sensCaloDetectors()
edm::ParameterSet m_pTrackingAction
SimTrackManager * getSimTrackManager()
edm::ParameterSet m_pField
G4Event * generateEvent(const edm::Event &inpevt)
std::vector< std::shared_ptr< SimProducer > > & producers()
edm::EDGetTokenT< edm::LHCTransportLinkContainer > m_theLHCTlinkToken
const std::vector< std::string > & G4Commands() const
SimActivityRegistry::BeginOfRunSignal m_beginOfRunSignal
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)
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)
virtual const double eventWeight() const
Log< level::Warning, false > LogWarning
void DumpMagneticField(const G4Field *, const std::string &) const
int getThreadIndex() const
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
EventNumber_t event() const
PhysicsList * physicsListForWorker() const
edm::ParameterSet m_pStackingAction
void Connect(RunAction *)
SimActivityRegistry::BeginOfTrackSignal m_beginOfTrackSignal