File indexing completed on 2025-03-23 16:00:31
0001 #include "FWCore/PluginManager/interface/PluginManager.h"
0002
0003 #include "SimG4Core/GeometryProducer/interface/GeometryProducer.h"
0004
0005 #include "FWCore/Framework/interface/ConsumesCollector.h"
0006 #include "FWCore/ServiceRegistry/interface/Service.h"
0007 #include "FWCore/Utilities/interface/Exception.h"
0008
0009 #include "SimG4Core/Geometry/interface/DDDWorld.h"
0010 #include "SimG4Core/Geometry/interface/G4LogicalVolumeToDDLogicalPartMap.h"
0011 #include "SimG4Core/Geometry/interface/SensitiveDetectorCatalog.h"
0012 #include "SimG4Core/MagneticField/interface/CMSFieldManager.h"
0013 #include "SimG4Core/MagneticField/interface/Field.h"
0014 #include "SimG4Core/MagneticField/interface/FieldBuilder.h"
0015 #include "SimG4Core/Notification/interface/SimTrackManager.h"
0016 #include "SimG4Core/Watcher/interface/SimProducer.h"
0017 #include "SimG4Core/Watcher/interface/SimWatcherFactory.h"
0018 #include "SimG4Core/SensitiveDetector/interface/sensitiveDetectorMakers.h"
0019 #include "SimG4Core/SensitiveDetector/interface/AttachSD.h"
0020
0021 #include "G4RunManagerKernel.hh"
0022 #include "G4TransportationManager.hh"
0023 #include "G4EmParameters.hh"
0024 #include "G4HadronicParameters.hh"
0025 #include "G4GeometryManager.hh"
0026
0027 #include <iostream>
0028 #include <memory>
0029
0030 static void createWatchers(const edm::ParameterSet &iP,
0031 SimActivityRegistry &iReg,
0032 std::vector<std::shared_ptr<SimWatcher>> &oWatchers,
0033 std::vector<std::shared_ptr<SimProducer>> &oProds) {
0034 using namespace std;
0035 using namespace edm;
0036 std::vector<ParameterSet> watchers;
0037 try {
0038 watchers = iP.getParameter<vector<ParameterSet>>("Watchers");
0039 } catch (edm::Exception const &) {
0040 }
0041
0042 for (std::vector<ParameterSet>::iterator itWatcher = watchers.begin(); itWatcher != watchers.end(); ++itWatcher) {
0043 std::unique_ptr<SimWatcherMakerBase> maker(
0044 SimWatcherFactory::get()->create(itWatcher->getParameter<std::string>("type")));
0045 if (maker.get() == nullptr) {
0046 throw cms::Exception("SimG4CoreGeometryProducer", " createWatchers: Unable to find the requested Watcher");
0047 }
0048
0049 std::shared_ptr<SimWatcher> watcherTemp;
0050 std::shared_ptr<SimProducer> producerTemp;
0051 maker->make(*itWatcher, iReg, watcherTemp, producerTemp);
0052 oWatchers.push_back(watcherTemp);
0053 if (producerTemp)
0054 oProds.push_back(producerTemp);
0055 }
0056 }
0057
0058 GeometryProducer::GeometryProducer(edm::ParameterSet const &p)
0059 : m_kernel(nullptr),
0060 m_pField(p.getParameter<edm::ParameterSet>("MagneticField")),
0061 m_p(p),
0062 m_pDD(nullptr),
0063 m_pDD4hep(nullptr),
0064 m_verbose(0),
0065 m_firstRun(true),
0066 m_pUseMagneticField(p.getParameter<bool>("UseMagneticField")),
0067 m_pUseSensitiveDetectors(p.getParameter<bool>("UseSensitiveDetectors")),
0068 m_pGeoFromDD4hep(p.getParameter<bool>("GeoFromDD4hep")) {
0069
0070
0071
0072 edm::Service<SimActivityRegistry> otherRegistry;
0073 if (otherRegistry)
0074 m_registry.connect(*otherRegistry);
0075 createWatchers(m_p, m_registry, m_watchers, m_producers);
0076
0077 G4EmParameters::Instance()->SetVerbose(m_verbose);
0078 G4HadronicParameters::Instance()->SetVerboseLevel(m_verbose);
0079
0080 m_kernel = G4RunManagerKernel::GetRunManagerKernel();
0081 if (m_kernel == nullptr)
0082 m_kernel = new G4RunManagerKernel();
0083
0084 m_kernel->SetVerboseLevel(m_verbose);
0085
0086 #if G4VERSION_NUMBER >= 1130
0087 G4GeometryManager::GetInstance()->RequestParallelOptimisation(false, false);
0088 #endif
0089
0090 tokMF_ = esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>();
0091 if (m_pGeoFromDD4hep) {
0092 tokDD4hep_ = esConsumes<cms::DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0093 } else {
0094 tokDDD_ = esConsumes<DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0095 }
0096 produces<int>();
0097 }
0098
0099 GeometryProducer::~GeometryProducer() { delete m_kernel; }
0100
0101 void GeometryProducer::updateMagneticField(edm::EventSetup const &es) {
0102 if (m_pUseMagneticField) {
0103
0104 auto const &pMF = &es.getData(tokMF_);
0105 const GlobalPoint g(0., 0., 0.);
0106 edm::LogVerbatim("GeometryProducer") << "B-field(T) at (0,0,0)(cm): " << pMF->inTesla(g);
0107
0108 sim::FieldBuilder fieldBuilder(pMF, m_pField);
0109 CMSFieldManager *fieldManager = new CMSFieldManager();
0110 G4TransportationManager *tM = G4TransportationManager::GetTransportationManager();
0111 tM->SetFieldManager(fieldManager);
0112 fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
0113 edm::LogVerbatim("GeometryProducer") << "Magentic field is built";
0114 }
0115 }
0116
0117 void GeometryProducer::beginLuminosityBlock(edm::LuminosityBlock &, edm::EventSetup const &) {
0118
0119
0120 }
0121
0122 void GeometryProducer::beginRun(const edm::Run &run, const edm::EventSetup &es) {
0123 makeGeom(es);
0124 updateMagneticField(es);
0125 for (auto &maker : m_sdMakers) {
0126 maker.second->beginRun(es);
0127 }
0128 }
0129
0130 void GeometryProducer::endRun(const edm::Run &, const edm::EventSetup &) {}
0131
0132 void GeometryProducer::produce(edm::Event &e, const edm::EventSetup &es) {
0133 if (!m_firstRun)
0134 return;
0135 m_firstRun = false;
0136 for (Producers::iterator itProd = m_producers.begin(); itProd != m_producers.end(); ++itProd) {
0137 (*itProd)->produce(e, es);
0138 }
0139 }
0140
0141 void GeometryProducer::makeGeom(const edm::EventSetup &es) {
0142 if (!m_firstRun)
0143 return;
0144
0145 edm::LogVerbatim("GeometryProducer") << " GeometryProducer initializing ";
0146
0147 if (m_pGeoFromDD4hep) {
0148 m_pDD4hep = &es.getData(tokDD4hep_);
0149 } else {
0150 m_pDD = &es.getData(tokDDD_);
0151 }
0152
0153 SensitiveDetectorCatalog catalog;
0154 const DDDWorld *dddworld = new DDDWorld(m_pDD, m_pDD4hep, catalog, m_verbose, false, false);
0155 G4VPhysicalVolume *world = dddworld->GetWorldVolume();
0156 if (nullptr != world)
0157 edm::LogVerbatim("GeometryProducer") << " World Volume: " << world->GetName();
0158 m_kernel->DefineWorldVolume(world, true);
0159
0160 m_registry.dddWorldSignal_(dddworld);
0161
0162 edm::LogVerbatim("GeometryProducer") << " Magnetic field initialisation";
0163 updateMagneticField(es);
0164
0165 if (m_pUseSensitiveDetectors) {
0166 edm::LogVerbatim("GeometryProducer") << " instantiating sensitive detectors ";
0167
0168 TmpSimEvent *ptr = nullptr;
0169 m_trackManager = std::make_unique<SimTrackManager>(ptr, m_verbose);
0170 {
0171 std::pair<std::vector<SensitiveTkDetector *>, std::vector<SensitiveCaloDetector *>> sensDets =
0172 sim::attachSD(m_sdMakers, es, catalog, m_p, m_trackManager.get(), m_registry);
0173
0174 m_sensTkDets.swap(sensDets.first);
0175 m_sensCaloDets.swap(sensDets.second);
0176 }
0177
0178 edm::LogVerbatim("GeometryProducer") << " Sensitive Detector building finished; found " << m_sensTkDets.size()
0179 << " Tk type Producers, and " << m_sensCaloDets.size()
0180 << " Calo type producers ";
0181 }
0182 }
0183
0184 DEFINE_FWK_MODULE(GeometryProducer);