CMS 3D CMS Logo

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