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