Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-11 22:29:58

0001 #include "SimG4Core/Application/interface/RunManagerMT.h"
0002 #include "SimG4Core/Application/interface/PrimaryTransformer.h"
0003 #include "SimG4Core/Application/interface/SimRunInterface.h"
0004 #include "SimG4Core/Application/interface/RunAction.h"
0005 #include "SimG4Core/Application/interface/ParametrisedEMPhysics.h"
0006 #include "SimG4Core/Application/interface/ExceptionHandler.h"
0007 
0008 #include "SimG4Core/Geometry/interface/DDDWorld.h"
0009 #include "SimG4Core/Geometry/interface/CustomUIsession.h"
0010 
0011 #include "SimG4Core/Physics/interface/PhysicsListFactory.h"
0012 #include "SimG4Core/PhysicsLists/interface/CMSMonopolePhysics.h"
0013 #include "SimG4Core/CustomPhysics/interface/CMSExoticaPhysics.h"
0014 
0015 #include "SimG4Core/Watcher/interface/SimWatcherFactory.h"
0016 
0017 #include "SimG4Core/Notification/interface/G4SimEvent.h"
0018 #include "SimG4Core/Notification/interface/SimTrackManager.h"
0019 #include "SimG4Core/Notification/interface/BeginOfJob.h"
0020 #include "SimG4Core/Notification/interface/CurrentG4Track.h"
0021 #include "SimG4Core/Application/interface/CMSGDMLWriteStructure.h"
0022 #include "SimG4Core/Geometry/interface/CMSG4CheckOverlap.h"
0023 
0024 #include "DetectorDescription/Core/interface/DDCompactView.h"
0025 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0026 
0027 #include "SimDataFormats/Forward/interface/LHCTransportLinkContainer.h"
0028 
0029 #include "HepPDT/ParticleDataTable.hh"
0030 
0031 #include "G4Timer.hh"
0032 #include "G4GeometryManager.hh"
0033 #include "G4ScoringManager.hh"
0034 #include "G4StateManager.hh"
0035 #include "G4ApplicationState.hh"
0036 #include "G4MTRunManagerKernel.hh"
0037 #include "G4UImanager.hh"
0038 
0039 #include "G4EventManager.hh"
0040 #include "G4Run.hh"
0041 #include "G4Event.hh"
0042 #include "G4TransportationManager.hh"
0043 #include "G4ParticleTable.hh"
0044 #include "G4CascadeInterface.hh"
0045 #include "G4EmParameters.hh"
0046 #include "G4HadronicParameters.hh"
0047 #include "G4NuclearLevelData.hh"
0048 
0049 #include "G4GDMLParser.hh"
0050 #include "G4SystemOfUnits.hh"
0051 
0052 #include "G4LogicalVolume.hh"
0053 #include "G4LogicalVolumeStore.hh"
0054 #include "G4PhysicalVolumeStore.hh"
0055 #include "G4Region.hh"
0056 #include "G4RegionStore.hh"
0057 
0058 #include <iostream>
0059 #include <memory>
0060 
0061 #include <sstream>
0062 #include <fstream>
0063 #include <memory>
0064 
0065 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0066 #include "FWCore/Utilities/interface/Exception.h"
0067 
0068 RunManagerMT::RunManagerMT(edm::ParameterSet const& p)
0069     : m_managerInitialized(false),
0070       m_runTerminated(false),
0071       m_PhysicsTablesDir(p.getUntrackedParameter<std::string>("PhysicsTablesDirectory", "")),
0072       m_StorePhysicsTables(p.getUntrackedParameter<bool>("StorePhysicsTables", false)),
0073       m_RestorePhysicsTables(p.getUntrackedParameter<bool>("RestorePhysicsTables", false)),
0074       m_pPhysics(p.getParameter<edm::ParameterSet>("Physics")),
0075       m_pRunAction(p.getParameter<edm::ParameterSet>("RunAction")),
0076       m_g4overlap(p.getUntrackedParameter<edm::ParameterSet>("G4CheckOverlap")),
0077       m_G4Commands(p.getParameter<std::vector<std::string> >("G4Commands")),
0078       m_p(p) {
0079   m_currentRun = nullptr;
0080   m_UIsession = new CustomUIsession();
0081   m_physicsList.reset(nullptr);
0082   m_world.reset(nullptr);
0083 
0084   m_runInterface.reset(nullptr);
0085   m_userRunAction = nullptr;
0086   m_currentRun = nullptr;
0087 
0088   m_kernel = new G4MTRunManagerKernel();
0089   m_stateManager = G4StateManager::GetStateManager();
0090   double th = p.getParameter<double>("ThresholdForGeometryExceptions") * CLHEP::GeV;
0091   bool tr = p.getParameter<bool>("TraceExceptions");
0092   m_stateManager->SetExceptionHandler(new ExceptionHandler(th, tr));
0093   m_check = p.getUntrackedParameter<bool>("CheckGeometry", false);
0094 }
0095 
0096 RunManagerMT::~RunManagerMT() { delete m_UIsession; }
0097 
0098 void RunManagerMT::initG4(const DDCompactView* pDD,
0099                           const cms::DDCompactView* pDD4hep,
0100                           const HepPDT::ParticleDataTable* fPDGTable) {
0101   if (m_managerInitialized) {
0102     edm::LogWarning("SimG4CoreApplication") << "RunManagerMT::initG4 was already done - exit";
0103     return;
0104   }
0105   bool geoFromDD4hep = m_p.getParameter<bool>("g4GeometryDD4hepSource");
0106   bool cuts = m_pPhysics.getParameter<bool>("CutsPerRegion");
0107   bool protonCut = m_pPhysics.getParameter<bool>("CutsOnProton");
0108   int verb = m_pPhysics.getUntrackedParameter<int>("Verbosity", 0);
0109   int stepverb = m_p.getUntrackedParameter<int>("SteppingVerbosity", 0);
0110   edm::LogVerbatim("SimG4CoreApplication")
0111       << "RunManagerMT: start initialising of geometry DD4hep: " << geoFromDD4hep << "\n"
0112       << "              cutsPerRegion: " << cuts << " cutForProton: " << protonCut << "\n"
0113       << "              G4 verbosity: " << verb;
0114 
0115   G4Timer timer;
0116   timer.Start();
0117 
0118   G4UImanager::GetUIpointer()->SetCoutDestination(m_UIsession);
0119   G4UImanager::GetUIpointer()->SetMasterUIManager(true);
0120 
0121   m_world = std::make_unique<DDDWorld>(pDD, pDD4hep, m_catalog, verb, cuts, protonCut);
0122   G4VPhysicalVolume* world = m_world.get()->GetWorldVolume();
0123 
0124   m_kernel->SetVerboseLevel(verb);
0125   edm::LogVerbatim("SimG4CoreApplication")
0126       << "RunManagerMT: Define cuts: " << cuts << " Geant4 run manager verbosity: " << verb;
0127 
0128   const G4RegionStore* regStore = G4RegionStore::GetInstance();
0129   const G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
0130   const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
0131   unsigned int numPV = pvs->size();
0132   unsigned int numLV = lvs->size();
0133   unsigned int nn = regStore->size();
0134   edm::LogVerbatim("SimG4CoreApplication")
0135       << "RunManagerMT: " << numPV << " physical volumes; " << numLV << " logical volumes; " << nn << " regions.";
0136 
0137   if (m_check) {
0138     m_kernel->SetVerboseLevel(2);
0139   }
0140   m_kernel->DefineWorldVolume(world, true);
0141   m_registry.dddWorldSignal_(m_world.get());
0142   m_stateManager->SetNewState(G4State_PreInit);
0143 
0144   // Create physics list
0145   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT: create PhysicsList";
0146 
0147   std::unique_ptr<PhysicsListMakerBase> physicsMaker(
0148       PhysicsListFactory::get()->create(m_pPhysics.getParameter<std::string>("type")));
0149   if (physicsMaker.get() == nullptr) {
0150     throw cms::Exception("Configuration") << "Unable to find the Physics list requested";
0151   }
0152   m_physicsList = physicsMaker->make(m_pPhysics, m_registry);
0153 
0154   PhysicsList* phys = m_physicsList.get();
0155   if (phys == nullptr) {
0156     throw cms::Exception("Configuration") << "Physics list construction failed!";
0157   }
0158   if (stepverb > 0) {
0159     verb = std::max(verb, 1);
0160   }
0161   G4HadronicParameters::Instance()->SetVerboseLevel(verb);
0162   G4EmParameters::Instance()->SetVerbose(verb);
0163   G4EmParameters::Instance()->SetWorkerVerbose(std::max(verb - 1, 0));
0164 
0165   // exotic particle physics
0166   double monopoleMass = m_pPhysics.getUntrackedParameter<double>("MonopoleMass", 0);
0167   if (monopoleMass > 0.0) {
0168     phys->RegisterPhysics(new CMSMonopolePhysics(fPDGTable, m_pPhysics));
0169   }
0170   bool exotica = m_pPhysics.getUntrackedParameter<bool>("ExoticaTransport", false);
0171   if (exotica) {
0172     CMSExoticaPhysics exo(phys, m_pPhysics);
0173   }
0174 
0175   // adding GFlash, Russian Roulette for eletrons and gamma,
0176   // step limiters on top of any Physics Lists
0177   phys->RegisterPhysics(new ParametrisedEMPhysics("EMoptions", m_pPhysics));
0178 
0179   if (m_RestorePhysicsTables) {
0180     m_physicsList->SetPhysicsTableRetrieved(m_PhysicsTablesDir);
0181   }
0182   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT: start initialisation of PhysicsList for master";
0183 
0184   m_physicsList->SetDefaultCutValue(m_pPhysics.getParameter<double>("DefaultCutValue") * CLHEP::cm);
0185   m_physicsList->SetCutsWithDefault();
0186   m_kernel->SetPhysics(phys);
0187 
0188   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT: PhysicsList and cuts are defined";
0189 
0190   // Enable couple transportation
0191   bool scorer = m_p.getParameter<bool>("UseCommandBaseScorer");
0192   if (scorer) {
0193     G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
0194     scManager->SetVerboseLevel(1);
0195   }
0196   // Geant4 UI commands before initialisation of physics
0197   if (!m_G4Commands.empty()) {
0198     edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT: Requested UI commands: ";
0199     for (const std::string& command : m_G4Commands) {
0200       edm::LogVerbatim("SimG4CoreApplication") << "    " << command;
0201       G4UImanager::GetUIpointer()->ApplyCommand(command);
0202     }
0203   }
0204 
0205   m_stateManager->SetNewState(G4State_Init);
0206   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT: G4State is Init";
0207   m_kernel->InitializePhysics();
0208   if (verb > 0) {
0209     G4EmParameters::Instance()->Dump();
0210   }
0211   m_kernel->SetUpDecayChannels();
0212 
0213   if (m_kernel->RunInitialization()) {
0214     m_managerInitialized = true;
0215   } else {
0216     throw cms::Exception("LogicError") << "G4RunManagerKernel initialization failed!";
0217   }
0218 
0219   if (m_StorePhysicsTables) {
0220     std::ostringstream dir;
0221     dir << m_PhysicsTablesDir << '\0';
0222     std::string cmd = std::string("/control/shell mkdir -p ") + m_PhysicsTablesDir;
0223     if (!std::ifstream(dir.str().c_str(), std::ios::in))
0224       G4UImanager::GetUIpointer()->ApplyCommand(cmd);
0225     m_physicsList->StorePhysicsTable(m_PhysicsTablesDir);
0226   }
0227   // Appload nuclear level data up to Z=84
0228   G4NuclearLevelData::GetInstance()->UploadNuclearLevelData(84);
0229 
0230   if (verb > 1) {
0231     m_physicsList->DumpCutValuesTable();
0232   }
0233   edm::LogVerbatim("SimG4CoreApplication")
0234       << "RunManagerMT: Physics is initilized, now initialise user actions, verb=" << verb;
0235 
0236   initializeUserActions();
0237 
0238   // geometry dump
0239   auto writeFile = m_p.getUntrackedParameter<std::string>("FileNameGDML", "");
0240   if (!writeFile.empty()) {
0241     G4GDMLParser gdml;
0242     gdml.SetRegionExport(true);
0243     gdml.SetEnergyCutsExport(true);
0244     gdml.Write(writeFile, m_world->GetWorldVolume(), true);
0245   }
0246 
0247   // G4Region dump file name
0248   auto regionFile = m_p.getUntrackedParameter<std::string>("FileNameRegions", "");
0249 
0250   // Geometry checks
0251   if (m_check || !regionFile.empty()) {
0252     CMSG4CheckOverlap check(m_g4overlap, regionFile, m_UIsession, world);
0253   }
0254 
0255   m_stateManager->SetNewState(G4State_PreInit);
0256   G4HadronicParameters::Instance()->SetVerboseLevel(std::max(verb - 1, 0));
0257 
0258   // If the Geant4 particle table is needed, decomment the lines below
0259   //
0260   //G4ParticleTable::GetParticleTable()->DumpTable("ALL");
0261   //
0262   m_stateManager->SetNewState(G4State_GeomClosed);
0263   m_currentRun = new G4Run();
0264   m_userRunAction->BeginOfRunAction(m_currentRun);
0265   timer.Stop();
0266   G4cout.precision(4);
0267   G4cout << "RunManagerMT: initG4 done " << timer << G4endl;
0268 }
0269 
0270 void RunManagerMT::initializeUserActions() {
0271   m_runInterface = std::make_unique<SimRunInterface>(this, true);
0272   m_userRunAction = new RunAction(m_pRunAction, m_runInterface.get(), true);
0273   Connect(m_userRunAction);
0274 }
0275 
0276 void RunManagerMT::Connect(RunAction* runAction) {
0277   runAction->m_beginOfRunSignal.connect(m_registry.beginOfRunSignal_);
0278   runAction->m_endOfRunSignal.connect(m_registry.endOfRunSignal_);
0279 }
0280 
0281 void RunManagerMT::stopG4() {
0282   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT::stopG4";
0283   G4GeometryManager::GetInstance()->OpenGeometry();
0284   m_stateManager->SetNewState(G4State_Quit);
0285   if (!m_runTerminated) {
0286     terminateRun();
0287   }
0288   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT::stopG4 done";
0289 }
0290 
0291 void RunManagerMT::terminateRun() {
0292   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT::terminateRun";
0293   if (nullptr != m_userRunAction) {
0294     m_userRunAction->EndOfRunAction(m_currentRun);
0295     delete m_userRunAction;
0296     m_userRunAction = nullptr;
0297   }
0298   if (!m_runTerminated) {
0299     m_kernel->RunTermination();
0300   }
0301   m_runTerminated = true;
0302   edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMT::terminateRun done";
0303 }