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" 59 #include "G4FieldManager.hh" 60 #include "G4ScoringManager.hh" 61 #include "G4UserSteppingAction.hh" 62 #include "G4GDMLParser.hh" 63 #include "G4Threading.hh" 77 std::atomic<int> thread_counter{0};
79 int get_new_thread_index() {
return thread_counter++; }
83 std::vector<std::shared_ptr<SimWatcher>>& oWatchers,
86 std::vector<edm::ParameterSet>
ws = iP.
getParameter<std::vector<edm::ParameterSet>>(
"Watchers");
91 for (
auto& watcher :
ws) {
92 std::unique_ptr<SimWatcherMakerBase> maker(
94 if (maker ==
nullptr) {
96 <<
"RunManagerMTWorker::createWatchers: " 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 if (
nullptr != watcherTemp) {
103 if (!watcherTemp->isMT() && 0 < threadID) {
105 <<
"RunManagerMTWorker::createWatchers: " 106 <<
"Unable to use Watcher " << watcher.getParameter<
std::string>(
"type") <<
" if number of threads > 1";
108 oWatchers.push_back(watcherTemp);
109 if (
nullptr != producerTemp) {
110 oProds.push_back(producerTemp);
116 return (!oWatchers.empty());
121 std::unique_ptr<G4RunManagerKernel>
kernel;
156 m_nonBeam(
p.getParameter<
bool>(
"NonBeamEvent")),
157 m_UseG4EventManager(
p.getParameter<
bool>(
"UseG4EventManager")),
158 m_pUseMagneticField(
p.getParameter<
bool>(
"UseMagneticField")),
159 m_LHCTransport(
p.getParameter<
bool>(
"LHCTransport")),
160 m_thread_index{(get_new_thread_index())},
167 m_G4Commands(
p.getParameter<std::vector<std::string>>(
"G4Commands")),
168 m_G4CommandsEndRun(
p.getParameter<std::vector<std::string>>(
"G4CommandsEndRun")),
170 int id = getThreadIndex();
171 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker for the thread " <<
id;
174 G4Threading::G4SetThreadId(
id);
175 G4UImanager::GetUIpointer()->SetUpForAThread(
id);
178 if (uitype ==
"MessageLogger") {
180 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
182 }
else if (uitype ==
"FilePerThread") {
186 <<
"RunManagerMTWorker::initializeG4: Invalid value of CustomUIsession.Type '" << uitype
187 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
189 G4UImanager::GetUIpointer()->SetCoutDestination(m_UIsession);
192 std::vector<std::string> onlySDs =
p.getParameter<std::vector<std::string>>(
"OnlySDs");
198 for (
auto& watcher : m_tls->watchers) {
199 watcher->registerConsumes(iC);
202 if (m_LHCTransport) {
205 if (m_pUseMagneticField) {
208 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker is constructed for the thread " <<
id;
210 for (std::unordered_map<
std::string, std::unique_ptr<SensitiveDetectorMakerBase>>::const_iterator itr =
212 itr != m_sdMakers.end();
225 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun for the thread " <<
id;
227 maker.second->beginRun(es);
234 watcher->beginRun(es);
237 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun done for the thread " <<
id;
242 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " <<
id;
247 if (
nullptr !=
m_tls) {
262 <<
"RunManagerMTWorker::initializeTLS : " 263 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. " 264 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
281 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeG4 in thread " << thisID <<
" is started";
284 G4WorkerThread::BuildGeometryAndPhysicsVector();
287 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
289 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
293 double th =
m_p.
getParameter<
double>(
"ThresholdForGeometryExceptions") * CLHEP::GeV;
295 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler(th, tr));
300 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
301 tM->SetWorldForTracking(worldPV);
314 tM->SetFieldManager(fieldManager);
315 fieldBuilder.
build(fieldManager, tM->GetPropagatorInField());
318 if (!fieldFile.empty()) {
322 <<
"RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
336 <<
"RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID <<
" found " 341 if (!writeFile.empty()) {
345 G4int thID = G4Threading::G4GetThreadId();
347 G4Threading::G4SetThreadId(-1);
349 gdml.SetRegionExport(
true);
350 gdml.SetEnergyCutsExport(
true);
351 gdml.SetSDExport(
true);
352 gdml.Write(writeFile, worldPV,
true);
353 G4Threading::G4SetThreadId(thID);
360 G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
361 scManager->SetVerboseLevel(1);
369 <<
"RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
372 if (!runManagerMaster->
G4Commands().empty()) {
373 G4cout <<
"RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
376 G4UImanager::GetUIpointer()->ApplyCommand(
command);
379 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
381 physicsList->InitializeWorker();
387 <<
"RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
401 m_sVerbose = std::make_unique<CMSSteppingVerbose>(
sv, elim, ve, vn, vt);
407 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
411 <<
"RunManagerMTWorker::initializeG4 done for the thread " << thisID <<
" " << timer;
422 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
423 eventManager->SetVerboseLevel(ver);
425 auto userEventAction =
429 eventManager->SetUserAction(userEventAction);
437 eventManager->SetUserAction(userTrackingAction);
443 G4UserSteppingAction* userSteppingAction;
448 userSteppingAction = (G4UserSteppingAction*)ptr;
452 userSteppingAction = (G4UserSteppingAction*)ptr;
455 eventManager->SetUserAction(userSteppingAction);
462 eventManager->SetUserAction(userStackingAction);
510 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
515 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun done for thread " <<
id;
520 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun for thread " <<
id;
529 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: Requested end of run UI commands: ";
532 G4UImanager::GetUIpointer()->ApplyCommand(
command);
545 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun done for thread " <<
id;
554 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event();
579 genVertex->y() / CLHEP::cm,
580 genVertex->z() / CLHEP::cm,
585 <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices" 590 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
608 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
616 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
617 t->SetTrackStatus(fStopAndKill);
625 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
626 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
642 G4Event* evt =
new G4Event(
evtid);
679 <<
"MTWorker::DumpMagneticField: error opening file <" <<
file <<
"> for magnetic field";
682 double rmax = 9000 * CLHEP::mm;
683 double zmax = 24000 * CLHEP::mm;
685 double dr = 1 * CLHEP::cm;
686 double dz = 5 * CLHEP::cm;
699 double point[4] = {0.0, 0.0, 0.0, 0.0};
700 double bfield[3] = {0.0, 0.0, 0.0};
702 fout << std::setprecision(6);
703 for (
int i = 0;
i <=
nr; ++
i) {
705 for (
int j = 0;
j <= nz; ++
j) {
709 field->GetFieldValue(
point, bfield);
710 fout <<
"R(mm)= " <<
r / CLHEP::mm <<
" phi(deg)= " <<
phi / CLHEP::degree <<
" Z(mm)= " <<
z / CLHEP::mm
711 <<
" Bz(tesla)= " << bfield[2] / CLHEP::tesla
712 <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / CLHEP::tesla
713 <<
" 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