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 <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"
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  int verbose = m_p.getParameter<int>("EventVerbose");
305  m_tls->trackManager = std::make_unique<SimTrackManager>(&m_simEvent, verbose);
306 
307  // setup the magnetic field
308  if (m_pUseMagneticField) {
309  const GlobalPoint g(0.f, 0.f, 0.f);
310 
311  sim::FieldBuilder fieldBuilder(m_pMagField, m_pField);
312 
313  CMSFieldManager* fieldManager = new CMSFieldManager();
314  tM->SetFieldManager(fieldManager);
315  fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
316 
317  std::string fieldFile = m_p.getUntrackedParameter<std::string>("FileNameField", "");
318  if (!fieldFile.empty()) {
319  std::call_once(applyOnce, [this]() { m_dumpMF = true; });
320  if (m_dumpMF) {
321  edm::LogVerbatim("SimG4CoreApplication")
322  << "RunManagerMTWorker::InitializeG4: Dump magnetic field to file " << fieldFile;
323  DumpMagneticField(tM->GetFieldManager()->GetDetectorField(), fieldFile);
324  }
325  }
326  }
327 
328  // attach sensitive detector
329  auto sensDets = sim::attachSD(
330  m_sdMakers, es, runManagerMaster->catalog(), m_p, m_tls->trackManager.get(), *(m_tls->registry.get()));
331 
332  m_tls->sensTkDets = sensDets.first;
333  m_tls->sensCaloDets = sensDets.second;
334 
335  edm::LogVerbatim("SimG4CoreApplication")
336  << "RunManagerMTWorker::InitializeG4: Sensitive Detectors are built in thread " << thisID << " found "
337  << m_tls->sensTkDets.size() << " Tk type SD, and " << m_tls->sensCaloDets.size() << " Calo type SD";
338 
339  // geometry dump
340  G4String writeFile = (G4String)m_p.getUntrackedParameter<std::string>("FileNameGDML");
341  if (!writeFile.empty()) {
342  std::call_once(applyOnceGDML, [this]() { m_dumpGDML = true; });
343  edm::LogVerbatim("SimG4CoreApplication") << "DumpGDML:" << m_dumpGDML;
344  if (m_dumpGDML) {
345  G4int thID = G4Threading::G4GetThreadId();
346  edm::LogVerbatim("SimG4CoreApplication") << "ThreadID=" << thID;
347  G4Threading::G4SetThreadId(-1);
348  G4GDMLParser gdml;
349  gdml.SetRegionExport(true);
350  gdml.SetEnergyCutsExport(true);
351  gdml.SetSDExport(true);
352  gdml.Write(writeFile, worldPV, true);
353  G4Threading::G4SetThreadId(thID);
354  }
355  }
356 
357  // Enable couple transportation
358  bool scorer = m_p.getParameter<bool>("UseCommandBaseScorer");
359  if (scorer) {
360  G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
361  scManager->SetVerboseLevel(1);
362  }
363 
364  // Set the physics list for the worker, share from master
365  PhysicsList* physicsList = runManagerMaster->physicsListForWorker();
366  m_isPhase2 = runManagerMaster->isPhase2();
367 
368  edm::LogVerbatim("SimG4CoreApplication")
369  << "RunManagerMTWorker::InitializeG4: start initialisation of PhysicsList for the thread " << thisID;
370 
371  // Geant4 UI commands in PreInit state
372  if (!runManagerMaster->G4Commands().empty()) {
373  G4cout << "RunManagerMTWorker::InitializeG4: Requested UI commands: " << G4endl;
374  for (const std::string& command : runManagerMaster->G4Commands()) {
375  G4cout << " " << command << G4endl;
376  G4UImanager::GetUIpointer()->ApplyCommand(command);
377  }
378  }
379  G4StateManager::GetStateManager()->SetNewState(G4State_Init);
380 
381  physicsList->InitializeWorker();
382  m_tls->kernel->SetPhysics(physicsList);
383  m_tls->kernel->InitializePhysics();
384 
385  if (!m_tls->kernel->RunInitialization()) {
386  throw cms::Exception("Configuration")
387  << "RunManagerMTWorker::InitializeG4: Geant4 kernel initialization failed in thread " << thisID;
388  }
389 
390  //tell all interesting parties that we are beginning the job
391  BeginOfJob aBeginOfJob(&es);
392  m_tls->registry->beginOfJobSignal_(&aBeginOfJob);
393 
394  G4int sv = m_p.getUntrackedParameter<int>("SteppingVerbosity");
395 
396  if (sv > 0) {
397  G4double elim = m_p.getUntrackedParameter<double>("StepVerboseThreshold", 0.1) * CLHEP::GeV;
398  std::vector<int> ve = m_p.getUntrackedParameter<std::vector<int>>("VerboseEvents");
399  std::vector<int> vn = m_p.getUntrackedParameter<std::vector<int>>("VertexNumber");
400  std::vector<int> vt = m_p.getUntrackedParameter<std::vector<int>>("VerboseTracks");
401  m_sVerbose = std::make_unique<CMSSteppingVerbose>(sv, elim, ve, vn, vt);
402  }
403  if (!m_UseG4EventManager)
404  m_evtManager = std::make_unique<CMSSimEventManager>(m_p);
406 
407  G4StateManager::GetStateManager()->SetNewState(G4State_Idle);
408 
409  timer.Stop();
410  edm::LogVerbatim("SimG4CoreApplication")
411  << "RunManagerMTWorker::initializeG4 done for the thread " << thisID << " " << timer;
412  m_tls->threadInitialized = true;
413 }
414 
416  m_tls->runInterface = std::make_unique<SimRunInterface>(this, false);
417  m_tls->userRunAction = std::make_unique<RunAction>(m_pRunAction, m_tls->runInterface.get(), false);
418  m_tls->userRunAction->SetMaster(false);
419  Connect(m_tls->userRunAction.get());
420 
421  G4int ver = m_p.getParameter<int>("EventVerbose");
422  G4EventManager* eventManager = m_tls->kernel->GetEventManager();
423  eventManager->SetVerboseLevel(ver);
424 
425  auto userEventAction =
427  Connect(userEventAction);
428  if (m_UseG4EventManager) {
429  eventManager->SetUserAction(userEventAction);
430  } else {
431  m_evtManager->SetUserAction(userEventAction);
432  }
433 
434  auto userTrackingAction = new TrackingAction(m_tls->trackManager.get(), m_sVerbose.get(), m_pTrackingAction);
435  Connect(userTrackingAction);
436  if (m_UseG4EventManager) {
437  eventManager->SetUserAction(userTrackingAction);
438  } else {
439  m_evtManager->SetUserAction(userTrackingAction);
440  }
441 
442  // different stepping actions for Run2,3 and Phase2
443  G4UserSteppingAction* userSteppingAction;
444  bool dd4hep = m_p.getParameter<bool>("g4GeometryDD4hepSource");
445  if (m_isPhase2) {
447  Connect(ptr);
448  userSteppingAction = (G4UserSteppingAction*)ptr;
449  } else {
451  Connect(ptr);
452  userSteppingAction = (G4UserSteppingAction*)ptr;
453  }
454  if (m_UseG4EventManager) {
455  eventManager->SetUserAction(userSteppingAction);
456  } else {
457  m_evtManager->SetUserAction(userSteppingAction);
458  }
459 
460  auto userStackingAction = new StackingAction(userTrackingAction, m_pStackingAction, m_sVerbose.get());
461  if (m_UseG4EventManager) {
462  eventManager->SetUserAction(userStackingAction);
463  } else {
464  m_evtManager->SetUserAction(userStackingAction);
465  }
466 }
467 
469  runAction->m_beginOfRunSignal.connect(m_tls->registry->beginOfRunSignal_);
470  runAction->m_endOfRunSignal.connect(m_tls->registry->endOfRunSignal_);
471 }
472 
474  eventAction->m_beginOfEventSignal.connect(m_tls->registry->beginOfEventSignal_);
475  eventAction->m_endOfEventSignal.connect(m_tls->registry->endOfEventSignal_);
476 }
477 
479  trackingAction->m_beginOfTrackSignal.connect(m_tls->registry->beginOfTrackSignal_);
480  trackingAction->m_endOfTrackSignal.connect(m_tls->registry->endOfTrackSignal_);
481 }
482 
484  steppingAction->m_g4StepSignal.connect(m_tls->registry->g4StepSignal_);
485 }
486 
488  steppingAction->m_g4StepSignal.connect(m_tls->registry->g4StepSignal_);
489 }
490 
492  initializeTLS();
493  return m_tls->trackManager.get();
494 }
495 std::vector<SensitiveTkDetector*>& RunManagerMTWorker::sensTkDetectors() {
496  initializeTLS();
497  return m_tls->sensTkDets;
498 }
499 std::vector<SensitiveCaloDetector*>& RunManagerMTWorker::sensCaloDetectors() {
500  initializeTLS();
501  return m_tls->sensCaloDets;
502 }
503 std::vector<std::shared_ptr<SimProducer>>& RunManagerMTWorker::producers() {
504  initializeTLS();
505  return m_tls->producers;
506 }
507 
509  m_tls->currentRun = new G4Run();
510  G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
511  if (nullptr != m_tls->userRunAction) {
512  m_tls->userRunAction->BeginOfRunAction(m_tls->currentRun);
513  }
514  int id = getThreadIndex();
515  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::initializeRun done for thread " << id;
516 }
517 
519  int id = getThreadIndex();
520  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::terminateRun for thread " << id;
521  if (nullptr == m_tls || m_tls->runTerminated) {
522  return;
523  }
524 
525  // Geant4 UI commands after the run
526  if (!m_G4CommandsEndRun.empty()) {
527  std::call_once(applyOnceEnd, [this]() { m_endOfRun = true; });
528  if (m_endOfRun) {
529  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker: Requested end of run UI commands: ";
530  for (const std::string& command : m_G4CommandsEndRun) {
531  edm::LogVerbatim("SimG4CoreApplication") << " " << command;
532  G4UImanager::GetUIpointer()->ApplyCommand(command);
533  }
534  }
535  }
536  if (m_tls->userRunAction) {
537  m_tls->userRunAction->EndOfRunAction(m_tls->currentRun);
538  m_tls->userRunAction.reset();
539  }
540  m_tls->currentEvent.reset();
541  if (m_tls->kernel) {
542  m_tls->kernel->RunTermination();
543  }
544  m_tls->runTerminated = true;
545  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::terminateRun done for thread " << id;
546 }
547 
549  const edm::EventSetup& es,
550  RunManagerMT& runManagerMaster) {
551  // We have to do the per-thread initialization, and per-thread
552  // per-run initialization here by ourselves.
553 
554  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::produce: start EventID=" << inpevt.id().event();
555 
556  assert(m_tls != nullptr and m_tls->threadInitialized);
557  // Initialize run
558  if (inpevt.id().run() != m_tls->currentRunNumber) {
559  edm::LogVerbatim("SimG4CoreApplication")
560  << "RunManagerMTWorker::produce: RunID= " << inpevt.id().run() << " TLS RunID= " << m_tls->currentRunNumber;
561  if (m_tls->currentRunNumber != 0 && !m_tls->runTerminated) {
562  // If previous run in this thread was not terminated via endRun() call,
563  // then terminate it now
564  terminateRun();
565  }
566  initializeRun();
567  m_tls->currentRunNumber = inpevt.id().run();
568  }
569 
570  // event and primary
571  m_tls->currentEvent.reset(generateEvent(inpevt));
572  m_simEvent.clear();
575 
576  if (m_generator.genVertex() != nullptr) {
577  auto genVertex = m_generator.genVertex();
578  m_simEvent.collisionPoint(math::XYZTLorentzVectorD(genVertex->x() / CLHEP::cm,
579  genVertex->y() / CLHEP::cm,
580  genVertex->z() / CLHEP::cm,
581  genVertex->t() / CLHEP::second));
582  }
583  if (m_tls->currentEvent->GetNumberOfPrimaryVertex() == 0) {
584  throw cms::Exception("EventCorruption")
585  << "RunManagerMTWorker::produce: event " << inpevt.id().event() << " with no G4PrimaryVertices"
586  << " StreamID=" << inpevt.streamID() << " threadIndex=" << getThreadIndex();
587 
588  } else {
589  edm::LogVerbatim("SimG4CoreApplication")
590  << "RunManagerMTWorker::produce: start EventID=" << inpevt.id().event() << " StreamID=" << inpevt.streamID()
591  << " threadIndex=" << getThreadIndex() << " weight=" << m_simEvent.weight()
592  << " Nprimary: " << m_tls->currentEvent->GetNumberOfPrimaryVertex() << " vertices and " << m_simEvent.nTracks()
593  << " particles";
594  // process event
595  if (m_UseG4EventManager) {
596  m_tls->kernel->GetEventManager()->ProcessOneEvent(m_tls->currentEvent.get());
597  } else {
598  m_evtManager->ProcessOneEvent(m_tls->currentEvent.get());
599  }
600  }
601 
602  // remove memory only needed during event processing
603  m_tls->currentEvent.reset();
604  for (auto& sd : m_tls->sensCaloDets) {
605  sd->reset();
606  }
607 
608  edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker::produce: ended Event " << inpevt.id().event();
609  return &m_simEvent;
610 }
611 
613  if (m_tls->runTerminated) {
614  return;
615  }
616  G4Track* t = m_tls->kernel->GetEventManager()->GetTrackingManager()->GetTrack();
617  t->SetTrackStatus(fStopAndKill);
618 
619  // CMS-specific act
620  //
621  TrackingAction* uta = static_cast<TrackingAction*>(m_tls->kernel->GetEventManager()->GetUserTrackingAction());
623 
624  m_tls->currentEvent->SetEventAborted();
625  m_tls->kernel->GetEventManager()->GetStackManager()->clear();
626  m_tls->kernel->GetEventManager()->GetTrackingManager()->EventAborted();
627 }
628 
629 void RunManagerMTWorker::abortRun(bool softAbort) {
630  if (!softAbort) {
631  abortEvent();
632  }
633  m_tls->currentRun = nullptr;
634  terminateRun();
635 }
636 
638  m_tls->currentEvent.reset();
639 
640  // 64 bits event ID in CMSSW converted into Geant4 event ID
641  G4int evtid = (G4int)inpevt.id().event();
642  G4Event* evt = new G4Event(evtid);
643 
645  inpevt.getByToken(m_InToken, HepMCEvt);
646 
647  m_generator.setGenEvent(HepMCEvt->GetEvent());
648 
649  // required to reset the GenParticle Id for particles transported
650  // along the beam pipe to their original value for SimTrack creation
651  resetGenParticleId(inpevt);
652 
653  if (!m_nonBeam) {
654  m_generator.HepMC2G4(HepMCEvt->GetEvent(), evt);
655  if (m_LHCTransport) {
657  inpevt.getByToken(m_LHCToken, LHCMCEvt);
658  m_generator.nonCentralEvent2G4(LHCMCEvt->GetEvent(), evt);
659  }
660  } else {
661  m_generator.nonCentralEvent2G4(HepMCEvt->GetEvent(), evt);
662  }
663 
664  return evt;
665 }
666 
669  inpevt.getByToken(m_theLHCTlinkToken, theLHCTlink);
670  if (theLHCTlink.isValid()) {
671  m_tls->trackManager->setLHCTransportLink(theLHCTlink.product());
672  }
673 }
674 
675 void RunManagerMTWorker::DumpMagneticField(const G4Field* field, const std::string& file) const {
676  std::ofstream fout(file.c_str(), std::ios::out);
677  if (fout.fail()) {
678  edm::LogWarning("SimG4CoreApplication")
679  << "MTWorker::DumpMagneticField: error opening file <" << file << "> for magnetic field";
680  } else {
681  // CMS magnetic field volume
682  double rmax = 9000 * CLHEP::mm;
683  double zmax = 24000 * CLHEP::mm;
684 
685  double dr = 1 * CLHEP::cm;
686  double dz = 5 * CLHEP::cm;
687 
688  int nr = (int)(rmax / dr);
689  int nz = 2 * (int)(zmax / dz);
690 
691  double r = 0.0;
692  double z0 = -zmax;
693  double z;
694 
695  double phi = 0.0;
696  double cosf = cos(phi);
697  double sinf = sin(phi);
698 
699  double point[4] = {0.0, 0.0, 0.0, 0.0};
700  double bfield[3] = {0.0, 0.0, 0.0};
701 
702  fout << std::setprecision(6);
703  for (int i = 0; i <= nr; ++i) {
704  z = z0;
705  for (int j = 0; j <= nz; ++j) {
706  point[0] = r * cosf;
707  point[1] = r * sinf;
708  point[2] = z;
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;
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
void setHepEvent(const HepMC::GenEvent *r)
Definition: TmpSimEvent.h:23
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:553
std::unique_ptr< G4Event > currentEvent
unsigned int nTracks() const
Definition: TmpSimEvent.h:20
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
def create(alignables, pedeDump, additionalData, outputFile, config)
void setWeight(float w)
Definition: TmpSimEvent.h:25
SimActivityRegistry::G4StepSignal m_g4StepSignal
void clear()
Definition: TmpSimEvent.cc:18
bool verbose
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
float weight() const
Definition: TmpSimEvent.h:26
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)
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()
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