CMS 3D CMS Logo

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