47 #include "G4SystemOfUnits.hh" 48 #include "G4Threading.hh" 49 #include "G4UImanager.hh" 50 #include "G4WorkerThread.hh" 51 #include "G4WorkerRunManagerKernel.hh" 52 #include "G4StateManager.hh" 53 #include "G4TransportationManager.hh" 55 #include "G4FieldManager.hh" 56 #include "G4ScoringManager.hh" 70 std::atomic<int> thread_counter{0};
72 int get_new_thread_index() {
return thread_counter++; }
76 std::vector<std::shared_ptr<SimWatcher>>& oWatchers,
79 std::vector<edm::ParameterSet>
ws = iP.
getParameter<std::vector<edm::ParameterSet>>(
"Watchers");
84 for (
auto& watcher :
ws) {
85 std::unique_ptr<SimWatcherMakerBase> maker(
87 if (maker ==
nullptr) {
89 <<
"RunManagerMTWorker::createWatchers: " 90 <<
"Unable to find the requested Watcher " << watcher.getParameter<
std::string>(
"type");
92 std::shared_ptr<SimWatcher> watcherTemp;
93 std::shared_ptr<SimProducer> producerTemp;
94 maker->make(watcher, *(iReg), watcherTemp, producerTemp);
95 if (
nullptr != watcherTemp) {
96 if (!watcherTemp->isMT() && 0 < threadID) {
98 <<
"RunManagerMTWorker::createWatchers: " 99 <<
"Unable to use Watcher " << watcher.getParameter<
std::string>(
"type") <<
" if number of threads > 1";
101 oWatchers.push_back(watcherTemp);
102 if (
nullptr != producerTemp) {
103 oProds.push_back(producerTemp);
109 return (!oWatchers.empty());
114 std::unique_ptr<G4RunManagerKernel>
kernel;
150 m_nonBeam(iConfig.getParameter<
bool>(
"NonBeamEvent")),
151 m_pUseMagneticField(iConfig.getParameter<
bool>(
"UseMagneticField")),
152 m_LHCTransport(iConfig.getParameter<
bool>(
"LHCTransport")),
153 m_thread_index{get_new_thread_index()},
160 m_pCustomUIsession(iConfig.getUntrackedParameter<
edm::ParameterSet>(
"CustomUIsession")),
161 m_G4CommandsEndRun(iConfig.getParameter<std::vector<std::string>>(
"G4CommandsEndRun")),
163 int thisID = getThreadIndex();
164 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker for the thread " << thisID;
167 std::vector<std::string> onlySDs = iConfig.getParameter<std::vector<std::string>>(
"OnlySDs");
173 for (
auto& watcher : m_tls->watchers) {
174 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();
199 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun for the thread " <<
id;
201 maker.second->beginRun(es);
208 watcher->beginRun(es);
211 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun done for the thread " <<
id;
216 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " <<
id;
221 if (
nullptr !=
m_tls) {
236 <<
"RunManagerMTWorker::initializeTLS : " 237 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. " 238 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
255 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeG4 in thread " << thisID <<
" is started";
258 G4Threading::G4SetThreadId(thisID);
259 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
261 if (uitype ==
"MessageLogger") {
263 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
266 }
else if (uitype ==
"FilePerThread") {
271 <<
"RunManagerMTWorker::initializeG4: Invalid value of CustomUIsession.Type '" << uitype
272 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
274 G4UImanager::GetUIpointer()->SetCoutDestination(
m_UIsession);
277 G4WorkerThread::BuildGeometryAndPhysicsVector();
280 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
282 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
286 double th =
m_p.
getParameter<
double>(
"ThresholdForGeometryExceptions") * CLHEP::GeV;
288 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler(th, tr));
293 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
294 tM->SetWorldForTracking(worldPV);
306 tM->SetFieldManager(fieldManager);
307 fieldBuilder.
build(fieldManager, tM->GetPropagatorInField());
310 if (!fieldFile.empty()) {
314 <<
"RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
328 <<
"RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID <<
" found " 334 G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
335 scManager->SetVerboseLevel(1);
342 <<
"RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
345 if (!runManagerMaster->
G4Commands().empty()) {
346 G4cout <<
"RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
349 G4UImanager::GetUIpointer()->ApplyCommand(
command);
352 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
354 physicsList->InitializeWorker();
360 <<
"RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
373 m_sVerbose = std::make_unique<CMSSteppingVerbose>(
sv, elim, ve, vn, vt);
377 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
381 <<
"RunManagerMTWorker::initializeG4 done for the thread " << thisID <<
" " << timer;
392 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
393 eventManager->SetVerboseLevel(ver);
398 eventManager->SetUserAction(userEventAction);
402 eventManager->SetUserAction(userTrackingAction);
407 eventManager->SetUserAction(userSteppingAction);
450 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
455 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun done for thread " <<
id;
460 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun for thread " <<
id;
469 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: Requested end of run UI commands: ";
472 G4UImanager::GetUIpointer()->ApplyCommand(
command);
485 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun done for thread " <<
id;
523 genVertex->y() / CLHEP::cm,
524 genVertex->z() / CLHEP::cm,
529 <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices" 534 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
536 <<
m_tls->
currentEvent->GetNumberOfPrimaryVertex() <<
" vertices for Geant4; generator produced " 548 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
556 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
557 t->SetTrackStatus(fStopAndKill);
565 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
566 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
582 G4Event* evt =
new G4Event(
evtid);
620 <<
"MTWorker::DumpMagneticField: error opening file <" <<
file <<
"> for magnetic field";
623 double rmax = 9000 * mm;
624 double zmax = 24000 * mm;
640 double point[4] = {0.0, 0.0, 0.0, 0.0};
641 double bfield[3] = {0.0, 0.0, 0.0};
643 fout << std::setprecision(6);
644 for (
int i = 0;
i <=
nr; ++
i) {
646 for (
int j = 0;
j <= nz; ++
j) {
650 field->GetFieldValue(
point, bfield);
651 fout <<
"R(mm)= " <<
r / mm <<
" phi(deg)= " <<
phi / degree <<
" Z(mm)= " <<
z / mm
652 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
653 <<
" Bphi(tesla)= " << (bfield[0] * sinf - bfield[1] * cosf) / tesla << G4endl;
void connect(Observer< const T *> *iObs)
does not take ownership of memory
edm::ParameterSet m_pSteppingAction
Log< level::Info, true > LogVerbatim
virtual const HepMC::GenEvent * genEvent() const
std::vector< std::shared_ptr< SimWatcher > > watchers
T getParameter(std::string const &) const
CustomUIsession * m_UIsession
void nonCentralEvent2G4(const HepMC::GenEvent *g, G4Event *e)
std::unique_ptr< G4Event > currentEvent
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.
unsigned int nGenParts() const
void initializeUserActions()
def create(alignables, pedeDump, additionalData, outputFile, config)
SimActivityRegistry::G4StepSignal m_g4StepSignal
SimTrackManager * GetSimTrackManager()
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
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
G4SimEvent * produce(const edm::Event &inpevt, const edm::EventSetup &es, RunManagerMT &runManagerMaster)
std::unique_ptr< G4RunManagerKernel > kernel
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 resetGenParticleId(const edm::Event &inpevt)
RunManagerMTWorker(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iC)
const SensitiveDetectorCatalog & catalog() const
std::unique_ptr< RunAction > userRunAction
void hepEvent(const HepMC::GenEvent *r)
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)
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
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
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)
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
void collisionPoint(const math::XYZTLorentzVectorD &v)
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