CMS 3D CMS Logo

RunManagerMTWorker.cc
Go to the documentation of this file.
14 
16 
25 
31 
35 
38 
40 
46 
47 #include "G4Timer.hh"
48 #include "G4Event.hh"
49 #include "G4Run.hh"
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"
57 #include "G4Field.hh"
58 #include "G4FieldManager.hh"
59 #include "G4ScoringManager.hh"
60 #include "G4UserSteppingAction.hh"
61 
62 #include <atomic>
63 #include <memory>
64 
65 #include <thread>
66 #include <sstream>
67 #include <vector>
68 
69 static std::once_flag applyOnce;
70 static std::once_flag applyOnceEnd;
71 
72 // from https://hypernews.cern.ch/HyperNews/CMS/get/edmFramework/3302/2.html
73 namespace {
74  std::atomic<int> thread_counter{0};
75 
76  int get_new_thread_index() { return thread_counter++; }
77 
78  bool createWatchers(const edm::ParameterSet& iP,
79  SimActivityRegistry* iReg,
80  std::vector<std::shared_ptr<SimWatcher>>& oWatchers,
81  std::vector<std::shared_ptr<SimProducer>>& oProds,
82  int threadID) {
83  std::vector<edm::ParameterSet> ws = iP.getParameter<std::vector<edm::ParameterSet>>("Watchers");
84  if (ws.empty()) {
85  return false;
86  }
87 
88  for (auto& watcher : ws) {
89  std::unique_ptr<SimWatcherMakerBase> maker(
90  SimWatcherFactory::get()->create(watcher.getParameter<std::string>("type")));
91  if (maker == nullptr) {
92  throw cms::Exception("Configuration")
93  << "RunManagerMTWorker::createWatchers: "
94  << "Unable to find the requested Watcher " << watcher.getParameter<std::string>("type");
95  } else {
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) {
101  throw cms::Exception("Configuration")
102  << "RunManagerMTWorker::createWatchers: "
103  << "Unable to use Watcher " << watcher.getParameter<std::string>("type") << " if number of threads > 1";
104  } else {
105  oWatchers.push_back(watcherTemp);
106  if (nullptr != producerTemp) {
107  oProds.push_back(producerTemp);
108  }
109  }
110  }
111  }
112  }
113  return (!oWatchers.empty());
114  }
115 } // namespace
116 
118  std::unique_ptr<G4RunManagerKernel> kernel; //must be deleted last
119  std::unique_ptr<RunAction> userRunAction;
120  std::unique_ptr<SimRunInterface> runInterface;
121  std::unique_ptr<SimActivityRegistry> registry;
122  std::unique_ptr<SimTrackManager> trackManager;
123  std::vector<SensitiveTkDetector*> sensTkDets;
124  std::vector<SensitiveCaloDetector*> sensCaloDets;
125  std::vector<std::shared_ptr<SimWatcher>> watchers;
126  std::vector<std::shared_ptr<SimProducer>> producers;
127  // G4Run can only be deleted if there is a G4RunManager
128  // on the thread where the G4Run is being deleted,
129  // else it causes a segmentation fault
130  G4Run* currentRun = nullptr;
131  std::unique_ptr<G4Event> currentEvent;
133  bool threadInitialized = false;
134  bool runTerminated = false;
135 
136  TLSData() {}
137 
138  ~TLSData() = default;
139 };
140 
141 // This can not be a smart pointer since we must delete some of the members
142 // before leaving main() else we get a segmentation fault caused by accessing
143 // other 'singletons' after those singletons have been deleted. Instead we
144 // atempt to delete all TLS at RunManagerMTWorker destructor. If that fails for
145 // some reason, it is better to leak than cause a crash.
146 // thread_local RunManagerMTWorker::TLSData* RunManagerMTWorker::m_tls{nullptr};
147 
149  : m_generator(iConfig.getParameter<edm::ParameterSet>("Generator")),
150  m_InToken(iC.consumes<edm::HepMCProduct>(
151  iConfig.getParameter<edm::ParameterSet>("Generator").getParameter<edm::InputTag>("HepMCProductLabel"))),
152  m_theLHCTlinkToken(
153  iC.consumes<edm::LHCTransportLinkContainer>(iConfig.getParameter<edm::InputTag>("theLHCTlinkTag"))),
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()},
159  m_pField(iConfig.getParameter<edm::ParameterSet>("MagneticField")),
160  m_pRunAction(iConfig.getParameter<edm::ParameterSet>("RunAction")),
161  m_pEventAction(iConfig.getParameter<edm::ParameterSet>("EventAction")),
162  m_pStackingAction(iConfig.getParameter<edm::ParameterSet>("StackingAction")),
163  m_pTrackingAction(iConfig.getParameter<edm::ParameterSet>("TrackingAction")),
164  m_pSteppingAction(iConfig.getParameter<edm::ParameterSet>("SteppingAction")),
165  m_pCustomUIsession(iConfig.getUntrackedParameter<edm::ParameterSet>("CustomUIsession")),
166  m_G4CommandsEndRun(iConfig.getParameter<std::vector<std::string>>("G4CommandsEndRun")),
167  m_p(iConfig) {
168  int thisID = getThreadIndex();
169  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker for the thread " << thisID;
170 
171  // sensitive detectors
172  std::vector<std::string> onlySDs = iConfig.getParameter<std::vector<std::string>>("OnlySDs");
173  m_sdMakers = sim::sensitiveDetectorMakers(m_p, iC, onlySDs);
174 
175  // TLS and watchers
176  initializeTLS();
177  if (m_hasWatchers) {
178  for (auto& watcher : m_tls->watchers) {
179  watcher->registerConsumes(iC);
180  }
181  }
182  if (m_LHCTransport) {
183  m_LHCToken = iC.consumes<edm::HepMCProduct>(edm::InputTag("LHCTransport"));
184  }
185  if (m_pUseMagneticField) {
186  m_MagField = iC.esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>();
187  }
188  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker is constructed for the thread " << thisID;
189  unsigned int k = 0;
190  for (std::unordered_map<std::string, std::unique_ptr<SensitiveDetectorMakerBase>>::const_iterator itr =
191  m_sdMakers.begin();
192  itr != m_sdMakers.end();
193  ++itr, ++k)
194  edm::LogVerbatim("SimG4CoreApplication") << "SD[" << k << "] " << itr->first;
195 }
196 
198  m_tls = nullptr;
199  delete m_UIsession;
200 }
201 
203  int id = getThreadIndex();
204  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::beginRun for the thread " << id;
205  for (auto& maker : m_sdMakers) {
206  maker.second->beginRun(es);
207  }
208  if (m_pUseMagneticField) {
210  }
211  if (m_hasWatchers) {
212  for (auto& watcher : m_tls->watchers) {
213  watcher->beginRun(es);
214  }
215  }
216  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::beginRun done for the thread " << id;
217 }
218 
220  int id = getThreadIndex();
221  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::endRun for the thread " << id;
222  terminateRun();
223 }
224 
226  if (nullptr != m_tls) {
227  return;
228  }
229 
230  m_tls = new TLSData();
231  m_tls->registry = std::make_unique<SimActivityRegistry>();
232 
233  edm::Service<SimActivityRegistry> otherRegistry;
234  //Look for an outside SimActivityRegistry
235  // this is used by the visualization code
236  int thisID = getThreadIndex();
237  if (otherRegistry) {
238  m_tls->registry->connect(*otherRegistry);
239  if (thisID > 0) {
240  throw cms::Exception("Configuration")
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.";
244  }
245  }
247 }
248 
251  return;
252 
253  G4Timer timer;
254  timer.Start();
255 
256  // I guess everything initialized here should be in thread_local storage
257  initializeTLS();
258 
259  int thisID = getThreadIndex();
260  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::initializeG4 in thread " << thisID << " is started";
261 
262  // Initialize per-thread output
263  G4Threading::G4SetThreadId(thisID);
264  G4UImanager::GetUIpointer()->SetUpForAThread(thisID);
265  const std::string& uitype = m_pCustomUIsession.getUntrackedParameter<std::string>("Type", "MessageLogger");
266  if (uitype == "MessageLogger") {
268  } else if (uitype == "MessageLoggerThreadPrefix") {
270  m_pCustomUIsession.getUntrackedParameter<std::string>("ThreadPrefix", ""), thisID);
271  } else if (uitype == "FilePerThread") {
272  m_UIsession =
274  } else {
275  throw cms::Exception("Configuration")
276  << "RunManagerMTWorker::initializeG4: Invalid value of CustomUIsession.Type '" << uitype
277  << "', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
278  }
279  G4UImanager::GetUIpointer()->SetCoutDestination(m_UIsession);
280 
281  // Initialize worker part of shared resources (geometry, physics)
282  G4WorkerThread::BuildGeometryAndPhysicsVector();
283 
284  // Create worker run manager
285  m_tls->kernel.reset(G4WorkerRunManagerKernel::GetRunManagerKernel());
286  if (nullptr == m_tls->kernel) {
287  m_tls->kernel = std::make_unique<G4WorkerRunManagerKernel>();
288  }
289 
290  // Define G4 exception handler
291  double th = m_p.getParameter<double>("ThresholdForGeometryExceptions") * CLHEP::GeV;
292  bool tr = m_p.getParameter<bool>("TraceExceptions");
293  G4StateManager::GetStateManager()->SetExceptionHandler(new ExceptionHandler(th, tr));
294 
295  // Set the geometry for the worker, share from master
296  auto worldPV = runManagerMaster->world().GetWorldVolume();
297  m_tls->kernel->WorkerDefineWorldVolume(worldPV);
298  G4TransportationManager* tM = G4TransportationManager::GetTransportationManager();
299  tM->SetWorldForTracking(worldPV);
300 
301  // we need the track manager now
302  m_tls->trackManager = std::make_unique<SimTrackManager>(&m_simEvent);
303 
304  // setup the magnetic field
305  if (m_pUseMagneticField) {
306  const GlobalPoint g(0.f, 0.f, 0.f);
307 
308  sim::FieldBuilder fieldBuilder(m_pMagField, m_pField);
309 
310  CMSFieldManager* fieldManager = new CMSFieldManager();
311  tM->SetFieldManager(fieldManager);
312  fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
313 
314  std::string fieldFile = m_p.getUntrackedParameter<std::string>("FileNameField", "");
315  if (!fieldFile.empty()) {
316  std::call_once(applyOnce, [this]() { m_dumpMF = true; });
317  if (m_dumpMF) {
318  edm::LogVerbatim("SimG4CoreApplication")
319  << "RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
320  DumpMagneticField(tM->GetFieldManager()->GetDetectorField(), fieldFile);
321  }
322  }
323  }
324 
325  // attach sensitive detector
326  auto sensDets = sim::attachSD(
327  m_sdMakers, es, runManagerMaster->catalog(), m_p, m_tls->trackManager.get(), *(m_tls->registry.get()));
328 
329  m_tls->sensTkDets.swap(sensDets.first);
330  m_tls->sensCaloDets.swap(sensDets.second);
331 
332  edm::LogVerbatim("SimG4CoreApplication")
333  << "RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID << " found "
334  << m_tls->sensTkDets.size() << " Tk type SD, and " << m_tls->sensCaloDets.size() << " Calo type SD";
335 
336  // Enable couple transportation
337  bool scorer = m_p.getParameter<bool>("UseCommandBaseScorer");
338  if (scorer) {
339  G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
340  scManager->SetVerboseLevel(1);
341  }
342 
343  // Set the physics list for the worker, share from master
344  PhysicsList* physicsList = runManagerMaster->physicsListForWorker();
345  m_isPhase2 = runManagerMaster->isPhase2();
346 
347  edm::LogVerbatim("SimG4CoreApplication")
348  << "RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
349 
350  // Geant4 UI commands in PreInit state
351  if (!runManagerMaster->G4Commands().empty()) {
352  G4cout << "RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
353  for (const std::string& command : runManagerMaster->G4Commands()) {
354  G4cout << " " << command << G4endl;
355  G4UImanager::GetUIpointer()->ApplyCommand(command);
356  }
357  }
358  G4StateManager::GetStateManager()->SetNewState(G4State_Init);
359 
360  physicsList->InitializeWorker();
361  m_tls->kernel->SetPhysics(physicsList);
362  m_tls->kernel->InitializePhysics();
363 
364  if (!m_tls->kernel->RunInitialization()) {
365  throw cms::Exception("Configuration")
366  << "RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
367  }
368 
369  //tell all interesting parties that we are beginning the job
370  BeginOfJob aBeginOfJob(&es);
371  m_tls->registry->beginOfJobSignal_(&aBeginOfJob);
372 
373  G4int sv = m_p.getUntrackedParameter<int>("SteppingVerbosity", 0);
374  G4double elim = m_p.getUntrackedParameter<double>("StepVerboseThreshold", 0.1) * CLHEP::GeV;
375  std::vector<int> ve = m_p.getUntrackedParameter<std::vector<int>>("VerboseEvents");
376  std::vector<int> vn = m_p.getUntrackedParameter<std::vector<int>>("VertexNumber");
377  std::vector<int> vt = m_p.getUntrackedParameter<std::vector<int>>("VerboseTracks");
378 
379  if (sv > 0) {
380  m_sVerbose = std::make_unique<CMSSteppingVerbose>(sv, elim, ve, vn, vt);
381  }
382  if (!m_UseG4EventManager)
383  m_evtManager = std::make_unique<CMSSimEventManager>(m_p);
385 
386  G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
387 
388  timer.Stop();
389  edm::LogVerbatim("SimG4CoreApplication")
390  << "RunManagerMTWorker::initializeG4 done for the thread " << thisID << " " << timer;
391  m_tls->threadInitialized = true;
392 }
393 
395  m_tls->runInterface = std::make_unique<SimRunInterface>(this, false);
396  m_tls->userRunAction = std::make_unique<RunAction>(m_pRunAction, m_tls->runInterface.get(), false);
397  m_tls->userRunAction->SetMaster(false);
398  Connect(m_tls->userRunAction.get());
399 
400  G4int ver = m_p.getParameter<int>("EventVerbose");
401  G4EventManager* eventManager = m_tls->kernel->GetEventManager();
402  eventManager->SetVerboseLevel(ver);
403 
404  auto userEventAction =
406  Connect(userEventAction);
407  if (m_UseG4EventManager) {
408  eventManager->SetUserAction(userEventAction);
409  } else {
410  m_evtManager->SetUserAction(userEventAction);
411  }
412 
413  auto userTrackingAction = new TrackingAction(m_tls->trackManager.get(), m_sVerbose.get(), m_pTrackingAction);
414  Connect(userTrackingAction);
415  if (m_UseG4EventManager) {
416  eventManager->SetUserAction(userTrackingAction);
417  } else {
418  m_evtManager->SetUserAction(userTrackingAction);
419  }
420 
421  // different stepping actions for Run2,3 and Phase2
422  G4UserSteppingAction* userSteppingAction;
423  if (m_isPhase2) {
425  Connect(ptr);
426  userSteppingAction = (G4UserSteppingAction*)ptr;
427  } else {
429  Connect(ptr);
430  userSteppingAction = (G4UserSteppingAction*)ptr;
431  }
432  if (m_UseG4EventManager) {
433  eventManager->SetUserAction(userSteppingAction);
434  } else {
435  m_evtManager->SetUserAction(userSteppingAction);
436  }
437 
438  auto userStackingAction = new StackingAction(userTrackingAction, m_pStackingAction, m_sVerbose.get());
439  if (m_UseG4EventManager) {
440  eventManager->SetUserAction(userStackingAction);
441  } else {
442  m_evtManager->SetUserAction(userStackingAction);
443  }
444 }
445 
447  runAction->m_beginOfRunSignal.connect(m_tls->registry->beginOfRunSignal_);
448  runAction->m_endOfRunSignal.connect(m_tls->registry->endOfRunSignal_);
449 }
450 
452  eventAction->m_beginOfEventSignal.connect(m_tls->registry->beginOfEventSignal_);
453  eventAction->m_endOfEventSignal.connect(m_tls->registry->endOfEventSignal_);
454 }
455 
457  trackingAction->m_beginOfTrackSignal.connect(m_tls->registry->beginOfTrackSignal_);
458  trackingAction->m_endOfTrackSignal.connect(m_tls->registry->endOfTrackSignal_);
459 }
460 
462  steppingAction->m_g4StepSignal.connect(m_tls->registry->g4StepSignal_);
463 }
464 
466  steppingAction->m_g4StepSignal.connect(m_tls->registry->g4StepSignal_);
467 }
468 
470  initializeTLS();
471  return m_tls->trackManager.get();
472 }
473 std::vector<SensitiveTkDetector*>& RunManagerMTWorker::sensTkDetectors() {
474  initializeTLS();
475  return m_tls->sensTkDets;
476 }
477 std::vector<SensitiveCaloDetector*>& RunManagerMTWorker::sensCaloDetectors() {
478  initializeTLS();
479  return m_tls->sensCaloDets;
480 }
481 std::vector<std::shared_ptr<SimProducer>>& RunManagerMTWorker::producers() {
482  initializeTLS();
483  return m_tls->producers;
484 }
485 
487  m_tls->currentRun = new G4Run();
488  G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
489  if (nullptr != m_tls->userRunAction) {
490  m_tls->userRunAction->BeginOfRunAction(m_tls->currentRun);
491  }
492  int id = getThreadIndex();
493  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::initializeRun done for thread " << id;
494 }
495 
497  int id = getThreadIndex();
498  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::terminateRun for thread " << id;
499  if (nullptr == m_tls || m_tls->runTerminated) {
500  return;
501  }
502 
503  // Geant4 UI commands after the run
504  if (!m_G4CommandsEndRun.empty()) {
505  std::call_once(applyOnceEnd, [this]() { m_endOfRun = true; });
506  if (m_endOfRun) {
507  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker: Requested end of run UI commands: ";
508  for (const std::string& command : m_G4CommandsEndRun) {
509  edm::LogVerbatim("SimG4CoreApplication") << " " << command;
510  G4UImanager::GetUIpointer()->ApplyCommand(command);
511  }
512  }
513  }
514  if (m_tls->userRunAction) {
515  m_tls->userRunAction->EndOfRunAction(m_tls->currentRun);
516  m_tls->userRunAction.reset();
517  }
518  m_tls->currentEvent.reset();
519  if (m_tls->kernel) {
520  m_tls->kernel->RunTermination();
521  }
522  m_tls->runTerminated = true;
523  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::terminateRun done for thread " << id;
524 }
525 
527  const edm::EventSetup& es,
528  RunManagerMT& runManagerMaster) {
529  // The initialization and begin/end run is a bit convoluted due to
530  // - Geant4 deals per-thread
531  // - OscarMTProducer deals per-stream
532  // and framework/TBB is free to schedule work in streams to the
533  // threads as it likes.
534  //
535  // We have to do the per-thread initialization, and per-thread
536  // per-run initialization here by ourselves.
537 
538  assert(m_tls != nullptr and m_tls->threadInitialized);
539  // Initialize run
540  if (inpevt.id().run() != m_tls->currentRunNumber) {
541  edm::LogVerbatim("SimG4CoreApplication")
542  << "RunManagerMTWorker::produce: RunID= " << inpevt.id().run() << " TLS RunID= " << m_tls->currentRunNumber;
543  if (m_tls->currentRunNumber != 0 && !m_tls->runTerminated) {
544  // If previous run in this thread was not terminated via endRun() call,
545  // terminate it now
546  terminateRun();
547  }
548  initializeRun();
549  m_tls->currentRunNumber = inpevt.id().run();
550  }
551 
552  m_tls->currentEvent.reset(generateEvent(inpevt));
553 
554  m_simEvent.clear();
557  if (m_generator.genVertex() != nullptr) {
558  auto genVertex = m_generator.genVertex();
559  m_simEvent.collisionPoint(math::XYZTLorentzVectorD(genVertex->x() / CLHEP::cm,
560  genVertex->y() / CLHEP::cm,
561  genVertex->z() / CLHEP::cm,
562  genVertex->t() / CLHEP::second));
563  }
564  if (m_tls->currentEvent->GetNumberOfPrimaryVertex() == 0) {
565  throw cms::Exception("EventCorruption")
566  << "RunManagerMTWorker::produce: event " << inpevt.id().event() << " with no G4PrimaryVertices"
567  << " StreamID=" << inpevt.streamID() << " threadIndex=" << getThreadIndex();
568 
569  } else {
570  edm::LogVerbatim("SimG4CoreApplication")
571  << "RunManagerMTWorker::produce: start EventID=" << inpevt.id().event() << " StreamID=" << inpevt.streamID()
572  << " threadIndex=" << getThreadIndex() << " weight=" << m_simEvent.weight() << "; "
573  << m_tls->currentEvent->GetNumberOfPrimaryVertex() << " vertices for Geant4; generator produced "
574  << m_simEvent.nGenParts() << " particles.";
575 
576  if (m_UseG4EventManager) {
577  m_tls->kernel->GetEventManager()->ProcessOneEvent(m_tls->currentEvent.get());
578  } else {
579  m_evtManager->ProcessOneEvent(m_tls->currentEvent.get());
580  }
581  }
582 
583  //remove memory only needed during event processing
584  m_tls->currentEvent.reset();
585 
586  for (auto& sd : m_tls->sensCaloDets) {
587  sd->reset();
588  }
589  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::produce: ended Event " << inpevt.id().event();
590  return &m_simEvent;
591 }
592 
594  if (m_tls->runTerminated) {
595  return;
596  }
597  G4Track* t = m_tls->kernel->GetEventManager()->GetTrackingManager()->GetTrack();
598  t->SetTrackStatus(fStopAndKill);
599 
600  // CMS-specific act
601  //
602  TrackingAction* uta = static_cast<TrackingAction*>(m_tls->kernel->GetEventManager()->GetUserTrackingAction());
604 
605  m_tls->currentEvent->SetEventAborted();
606  m_tls->kernel->GetEventManager()->GetStackManager()->clear();
607  m_tls->kernel->GetEventManager()->GetTrackingManager()->EventAborted();
608 }
609 
610 void RunManagerMTWorker::abortRun(bool softAbort) {
611  if (!softAbort) {
612  abortEvent();
613  }
614  m_tls->currentRun = nullptr;
615  terminateRun();
616 }
617 
619  m_tls->currentEvent.reset();
620 
621  // 64 bits event ID in CMSSW converted into Geant4 event ID
622  G4int evtid = (G4int)inpevt.id().event();
623  G4Event* evt = new G4Event(evtid);
624 
626  inpevt.getByToken(m_InToken, HepMCEvt);
627 
628  m_generator.setGenEvent(HepMCEvt->GetEvent());
629 
630  // required to reset the GenParticle Id for particles transported
631  // along the beam pipe to their original value for SimTrack creation
632  resetGenParticleId(inpevt);
633 
634  if (!m_nonBeam) {
635  m_generator.HepMC2G4(HepMCEvt->GetEvent(), evt);
636  if (m_LHCTransport) {
638  inpevt.getByToken(m_LHCToken, LHCMCEvt);
639  m_generator.nonCentralEvent2G4(LHCMCEvt->GetEvent(), evt);
640  }
641  } else {
642  m_generator.nonCentralEvent2G4(HepMCEvt->GetEvent(), evt);
643  }
644 
645  return evt;
646 }
647 
650  inpevt.getByToken(m_theLHCTlinkToken, theLHCTlink);
651  if (theLHCTlink.isValid()) {
652  m_tls->trackManager->setLHCTransportLink(theLHCTlink.product());
653  }
654 }
655 
656 void RunManagerMTWorker::DumpMagneticField(const G4Field* field, const std::string& file) const {
657  std::ofstream fout(file.c_str(), std::ios::out);
658  if (fout.fail()) {
659  edm::LogWarning("SimG4CoreApplication")
660  << "MTWorker::DumpMagneticField: error opening file <" << file << "> for magnetic field";
661  } else {
662  // CMS magnetic field volume
663  double rmax = 9000 * mm;
664  double zmax = 24000 * mm;
665 
666  double dr = 1 * cm;
667  double dz = 5 * cm;
668 
669  int nr = (int)(rmax / dr);
670  int nz = 2 * (int)(zmax / dz);
671 
672  double r = 0.0;
673  double z0 = -zmax;
674  double z;
675 
676  double phi = 0.0;
677  double cosf = cos(phi);
678  double sinf = sin(phi);
679 
680  double point[4] = {0.0, 0.0, 0.0, 0.0};
681  double bfield[3] = {0.0, 0.0, 0.0};
682 
683  fout << std::setprecision(6);
684  for (int i = 0; i <= nr; ++i) {
685  z = z0;
686  for (int j = 0; j <= nz; ++j) {
687  point[0] = r * cosf;
688  point[1] = r * sinf;
689  point[2] = z;
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;
694  z += dz;
695  }
696  r += dr;
697  }
698 
699  fout.close();
700  }
701 }
void connect(Observer< const T *> *iObs)
does not take ownership of memory
Definition: Signaler.h:55
edm::ParameterSet m_pSteppingAction
Log< level::Info, true > LogVerbatim
virtual const HepMC::GenEvent * genEvent() const
Definition: Generator.h:30
std::vector< std::shared_ptr< SimWatcher > > watchers
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
CustomUIsession * m_UIsession
void nonCentralEvent2G4(const HepMC::GenEvent *g, G4Event *e)
Definition: Generator.cc:552
std::unique_ptr< G4Event > currentEvent
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
void hepEvent(const HepMC::GenEvent *r)
Definition: TmpSimEvent.h:23
def create(alignables, pedeDump, additionalData, outputFile, config)
SimActivityRegistry::G4StepSignal m_g4StepSignal
void clear()
Definition: TmpSimEvent.cc:18
void weight(float w)
Definition: TmpSimEvent.h:25
void HepMC2G4(const HepMC::GenEvent *g, G4Event *e)
Definition: Generator.cc:112
std::unique_ptr< SimRunInterface > runInterface
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::unique_ptr< CMSSteppingVerbose > m_sVerbose
T const * product() const
Definition: Handle.h:70
SimActivityRegistry::EndOfRunSignal m_endOfRunSignal
Definition: RunAction.h:24
std::vector< SensitiveTkDetector * > sensTkDets
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:536
SimActivityRegistry::EndOfEventSignal m_endOfEventSignal
Definition: EventAction.h:37
G4VPhysicalVolume * GetWorldVolume() const
Definition: DDDWorld.h:24
virtual const math::XYZTLorentzVector * genVertex() const
Definition: Generator.h:31
assert(be >=bs)
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
Definition: Activities.doc:4
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
auto &__restrict__ ws
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)
Definition: Cos.h:22
std::vector< SensitiveTkDetector * > & sensTkDetectors()
void collisionPoint(const math::XYZTLorentzVectorD &v)
Definition: TmpSimEvent.h:27
void resetGenParticleId(const edm::Event &inpevt)
double f[11][100]
RunManagerMTWorker(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iC)
const SensitiveDetectorCatalog & catalog() const
Definition: RunManagerMT.h:72
std::unique_ptr< RunAction > userRunAction
edm::EventID id() const
Definition: EventBase.h:63
void setGenEvent(const HepMC::GenEvent *inpevt)
Definition: Generator.h:24
SimActivityRegistry::EndOfTrackSignal m_endOfTrackSignal
StreamID streamID() const
Definition: Event.h:98
std::vector< std::shared_ptr< SimProducer > > producers
bool isPhase2() const
Definition: RunManagerMT.h:80
void abortRun(bool softAbort=false)
TmpSimEvent * produce(const edm::Event &inpevt, const edm::EventSetup &es, RunManagerMT &runManagerMaster)
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:37
void build(CMSFieldManager *fM, G4PropagatorInField *fP)
Definition: FieldBuilder.cc:32
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 &reg)
const DDDWorld & world() const
Definition: RunManagerMT.h:70
static std::once_flag applyOnce
RunNumber_t run() const
Definition: EventID.h:38
std::vector< SensitiveCaloDetector * > & sensCaloDetectors()
edm::ParameterSet m_pTrackingAction
SimTrackManager * getSimTrackManager()
unsigned int nGenParts() const
Definition: TmpSimEvent.h:22
edm::ParameterSet m_pField
G4Event * generateEvent(const edm::Event &inpevt)
std::vector< std::shared_ptr< SimProducer > > & producers()
edm::EDGetTokenT< edm::LHCTransportLinkContainer > m_theLHCTlinkToken
bool isValid() const
Definition: HandleBase.h:70
list command
Definition: mps_check.py:25
const std::vector< std::string > & G4Commands() const
Definition: RunManagerMT.h:74
SimActivityRegistry::BeginOfRunSignal m_beginOfRunSignal
Definition: RunAction.h:23
HLT enums.
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
unsigned int RunNumber_t
void initializeG4(RunManagerMT *runManagerMaster, const edm::EventSetup &es)
virtual const double eventWeight() const
Definition: Generator.h:32
#define get
Log< level::Warning, false > LogWarning
edm::ParameterSet m_p
void DumpMagneticField(const G4Field *, const std::string &) const
int getThreadIndex() const
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > m_MagField
SimActivityRegistry::BeginOfEventSignal m_beginOfEventSignal
Definition: EventAction.h:36
*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
Definition: invegas.h:5
EventNumber_t event() const
Definition: EventID.h:40
PhysicsList * physicsListForWorker() const
Definition: RunManagerMT.h:78
edm::ParameterSet m_pStackingAction
void Connect(RunAction *)
SimActivityRegistry::BeginOfTrackSignal m_beginOfTrackSignal