50 #include "G4SystemOfUnits.hh" 51 #include "G4Threading.hh" 52 #include "G4UImanager.hh" 53 #include "G4WorkerThread.hh" 54 #include "G4WorkerRunManagerKernel.hh" 55 #include "G4StateManager.hh" 56 #include "G4TransportationManager.hh" 58 #include "G4FieldManager.hh" 59 #include "G4ScoringManager.hh" 60 #include "G4UserSteppingAction.hh" 74 std::atomic<int> thread_counter{0};
76 int get_new_thread_index() {
return thread_counter++; }
80 std::vector<std::shared_ptr<SimWatcher>>& oWatchers,
83 std::vector<edm::ParameterSet>
ws = iP.
getParameter<std::vector<edm::ParameterSet>>(
"Watchers");
88 for (
auto& watcher :
ws) {
89 std::unique_ptr<SimWatcherMakerBase> maker(
91 if (maker ==
nullptr) {
93 <<
"RunManagerMTWorker::createWatchers: " 94 <<
"Unable to find the requested Watcher " << watcher.getParameter<
std::string>(
"type");
96 std::shared_ptr<SimWatcher> watcherTemp;
97 std::shared_ptr<SimProducer> producerTemp;
98 maker->make(watcher, *(iReg), watcherTemp, producerTemp);
99 if (
nullptr != watcherTemp) {
100 if (!watcherTemp->isMT() && 0 < threadID) {
102 <<
"RunManagerMTWorker::createWatchers: " 103 <<
"Unable to use Watcher " << watcher.getParameter<
std::string>(
"type") <<
" if number of threads > 1";
105 oWatchers.push_back(watcherTemp);
106 if (
nullptr != producerTemp) {
107 oProds.push_back(producerTemp);
113 return (!oWatchers.empty());
118 std::unique_ptr<G4RunManagerKernel>
kernel;
154 m_nonBeam(iConfig.getParameter<
bool>(
"NonBeamEvent")),
155 m_UseG4EventManager(iConfig.getParameter<
bool>(
"UseG4EventManager")),
156 m_pUseMagneticField(iConfig.getParameter<
bool>(
"UseMagneticField")),
157 m_LHCTransport(iConfig.getParameter<
bool>(
"LHCTransport")),
158 m_thread_index{get_new_thread_index()},
165 m_pCustomUIsession(iConfig.getUntrackedParameter<
edm::ParameterSet>(
"CustomUIsession")),
166 m_G4CommandsEndRun(iConfig.getParameter<std::vector<std::string>>(
"G4CommandsEndRun")),
168 int thisID = getThreadIndex();
169 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker for the thread " << thisID;
172 std::vector<std::string> onlySDs = iConfig.getParameter<std::vector<std::string>>(
"OnlySDs");
178 for (
auto& watcher : m_tls->watchers) {
179 watcher->registerConsumes(iC);
182 if (m_LHCTransport) {
185 if (m_pUseMagneticField) {
188 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker is constructed for the thread " << thisID;
190 for (std::unordered_map<
std::string, std::unique_ptr<SensitiveDetectorMakerBase>>::const_iterator itr =
192 itr != m_sdMakers.end();
204 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun for the thread " <<
id;
206 maker.second->beginRun(es);
213 watcher->beginRun(es);
216 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::beginRun done for the thread " <<
id;
221 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::endRun for the thread " <<
id;
226 if (
nullptr !=
m_tls) {
241 <<
"RunManagerMTWorker::initializeTLS : " 242 <<
"SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. " 243 <<
" \n If this use case is needed, RunManagerMTWorker has to be updated.";
260 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeG4 in thread " << thisID <<
" is started";
263 G4Threading::G4SetThreadId(thisID);
264 G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
266 if (uitype ==
"MessageLogger") {
268 }
else if (uitype ==
"MessageLoggerThreadPrefix") {
271 }
else if (uitype ==
"FilePerThread") {
276 <<
"RunManagerMTWorker::initializeG4: Invalid value of CustomUIsession.Type '" << uitype
277 <<
"', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
279 G4UImanager::GetUIpointer()->SetCoutDestination(
m_UIsession);
282 G4WorkerThread::BuildGeometryAndPhysicsVector();
285 m_tls->
kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
287 m_tls->
kernel = std::make_unique<G4WorkerRunManagerKernel>();
291 double th =
m_p.
getParameter<
double>(
"ThresholdForGeometryExceptions") * CLHEP::GeV;
293 G4StateManager::GetStateManager()->SetExceptionHandler(
new ExceptionHandler(th, tr));
298 G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
299 tM->SetWorldForTracking(worldPV);
311 tM->SetFieldManager(fieldManager);
312 fieldBuilder.
build(fieldManager, tM->GetPropagatorInField());
315 if (!fieldFile.empty()) {
319 <<
"RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
333 <<
"RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID <<
" found " 339 G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
340 scManager->SetVerboseLevel(1);
348 <<
"RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
351 if (!runManagerMaster->
G4Commands().empty()) {
352 G4cout <<
"RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
355 G4UImanager::GetUIpointer()->ApplyCommand(
command);
358 G4StateManager::GetStateManager()->SetNewState(G4State_Init);
360 physicsList->InitializeWorker();
366 <<
"RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
380 m_sVerbose = std::make_unique<CMSSteppingVerbose>(
sv, elim, ve, vn, vt);
386 G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
390 <<
"RunManagerMTWorker::initializeG4 done for the thread " << thisID <<
" " << timer;
401 G4EventManager* eventManager =
m_tls->
kernel->GetEventManager();
402 eventManager->SetVerboseLevel(ver);
404 auto userEventAction =
408 eventManager->SetUserAction(userEventAction);
416 eventManager->SetUserAction(userTrackingAction);
422 G4UserSteppingAction* userSteppingAction;
426 userSteppingAction = (G4UserSteppingAction*)ptr;
430 userSteppingAction = (G4UserSteppingAction*)ptr;
433 eventManager->SetUserAction(userSteppingAction);
440 eventManager->SetUserAction(userStackingAction);
488 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
493 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::initializeRun done for thread " <<
id;
498 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun for thread " <<
id;
507 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker: Requested end of run UI commands: ";
510 G4UImanager::GetUIpointer()->ApplyCommand(
command);
523 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::terminateRun done for thread " <<
id;
560 genVertex->y() / CLHEP::cm,
561 genVertex->z() / CLHEP::cm,
566 <<
"RunManagerMTWorker::produce: event " << inpevt.
id().
event() <<
" with no G4PrimaryVertices" 571 <<
"RunManagerMTWorker::produce: start EventID=" << inpevt.
id().
event() <<
" StreamID=" << inpevt.
streamID()
573 <<
m_tls->
currentEvent->GetNumberOfPrimaryVertex() <<
" vertices for Geant4; generator produced " 589 edm::LogVerbatim(
"SimG4CoreApplication") <<
"RunManagerMTWorker::produce: ended Event " << inpevt.
id().
event();
597 G4Track*
t =
m_tls->
kernel->GetEventManager()->GetTrackingManager()->GetTrack();
598 t->SetTrackStatus(fStopAndKill);
606 m_tls->
kernel->GetEventManager()->GetStackManager()->clear();
607 m_tls->
kernel->GetEventManager()->GetTrackingManager()->EventAborted();
623 G4Event* evt =
new G4Event(
evtid);
660 <<
"MTWorker::DumpMagneticField: error opening file <" <<
file <<
"> for magnetic field";
663 double rmax = 9000 * mm;
664 double zmax = 24000 * mm;
680 double point[4] = {0.0, 0.0, 0.0, 0.0};
681 double bfield[3] = {0.0, 0.0, 0.0};
683 fout << std::setprecision(6);
684 for (
int i = 0;
i <=
nr; ++
i) {
686 for (
int j = 0;
j <= nz; ++
j) {
690 field->GetFieldValue(
point, bfield);
691 fout <<
"R(mm)= " <<
r / mm <<
" phi(deg)= " <<
phi / degree <<
" Z(mm)= " <<
z / mm
692 <<
" Bz(tesla)= " << bfield[2] / tesla <<
" Br(tesla)= " << (bfield[0] * cosf + bfield[1] * sinf) / tesla
693 <<
" 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.
void hepEvent(const HepMC::GenEvent *r)
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()
unsigned int nGenParts() const
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
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