Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-07-31 22:37:37

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 
0024 #include <iostream>
0025 #include <memory>
0026 
0027 static void createWatchers(const edm::ParameterSet &iP,
0028                            SimActivityRegistry &iReg,
0029                            std::vector<std::shared_ptr<SimWatcher>> &oWatchers,
0030                            std::vector<std::shared_ptr<SimProducer>> &oProds) {
0031   using namespace std;
0032   using namespace edm;
0033   std::vector<ParameterSet> watchers;
0034   try {
0035     watchers = iP.getParameter<vector<ParameterSet>>("Watchers");
0036   } catch (edm::Exception const &) {
0037   }
0038 
0039   for (std::vector<ParameterSet>::iterator itWatcher = watchers.begin(); itWatcher != watchers.end(); ++itWatcher) {
0040     std::unique_ptr<SimWatcherMakerBase> maker(
0041         SimWatcherFactory::get()->create(itWatcher->getParameter<std::string>("type")));
0042     if (maker.get() == nullptr) {
0043       throw cms::Exception("SimG4CoreGeometryProducer", " createWatchers: Unable to find the requested Watcher");
0044     }
0045 
0046     std::shared_ptr<SimWatcher> watcherTemp;
0047     std::shared_ptr<SimProducer> producerTemp;
0048     maker->make(*itWatcher, iReg, watcherTemp, producerTemp);
0049     oWatchers.push_back(watcherTemp);
0050     if (producerTemp)
0051       oProds.push_back(producerTemp);
0052   }
0053 }
0054 
0055 GeometryProducer::GeometryProducer(edm::ParameterSet const &p)
0056     : m_kernel(nullptr),
0057       m_pField(p.getParameter<edm::ParameterSet>("MagneticField")),
0058       m_p(p),
0059       m_pDD(nullptr),
0060       m_pDD4hep(nullptr),
0061       m_firstRun(true),
0062       m_pUseMagneticField(p.getParameter<bool>("UseMagneticField")),
0063       m_pUseSensitiveDetectors(p.getParameter<bool>("UseSensitiveDetectors")),
0064       m_pGeoFromDD4hep(p.getParameter<bool>("GeoFromDD4hep")) {
0065   // Look for an outside SimActivityRegistry
0066   // this is used by the visualization code
0067 
0068   edm::Service<SimActivityRegistry> otherRegistry;
0069   if (otherRegistry)
0070     m_registry.connect(*otherRegistry);
0071   createWatchers(m_p, m_registry, m_watchers, m_producers);
0072 
0073   if (m_pUseSensitiveDetectors)
0074     m_sdMakers = sim::sensitiveDetectorMakers(m_p, consumesCollector(), std::vector<std::string>());
0075 
0076   tokMF_ = esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>();
0077   if (m_pGeoFromDD4hep) {
0078     tokDD4hep_ = esConsumes<cms::DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0079   } else {
0080     tokDDD_ = esConsumes<DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0081   }
0082   produces<int>();
0083 }
0084 
0085 GeometryProducer::~GeometryProducer() { delete m_kernel; }
0086 
0087 void GeometryProducer::updateMagneticField(edm::EventSetup const &es) {
0088   if (m_pUseMagneticField) {
0089     // setup the magnetic field
0090     auto const &pMF = &es.getData(tokMF_);
0091     const GlobalPoint g(0., 0., 0.);
0092     edm::LogInfo("GeometryProducer") << "B-field(T) at (0,0,0)(cm): " << pMF->inTesla(g);
0093 
0094     sim::FieldBuilder fieldBuilder(pMF, m_pField);
0095     CMSFieldManager *fieldManager = new CMSFieldManager();
0096     G4TransportationManager *tM = G4TransportationManager::GetTransportationManager();
0097     tM->SetFieldManager(fieldManager);
0098     fieldBuilder.build(fieldManager, tM->GetPropagatorInField());
0099     edm::LogInfo("GeometryProducer") << "Magentic field is built";
0100   }
0101 }
0102 
0103 void GeometryProducer::beginLuminosityBlock(edm::LuminosityBlock &, edm::EventSetup const &) {
0104   // mag field cannot be change in new lumi section - this is commented out
0105   //     updateMagneticField( es );
0106 }
0107 
0108 void GeometryProducer::beginRun(const edm::Run &run, const edm::EventSetup &es) {
0109   makeGeom(es);
0110   updateMagneticField(es);
0111   for (auto &maker : m_sdMakers) {
0112     maker.second->beginRun(es);
0113   }
0114 }
0115 
0116 void GeometryProducer::endRun(const edm::Run &, const edm::EventSetup &) {}
0117 
0118 void GeometryProducer::produce(edm::Event &e, const edm::EventSetup &es) {
0119   if (!m_firstRun)
0120     return;
0121   m_firstRun = false;
0122   for (Producers::iterator itProd = m_producers.begin(); itProd != m_producers.end(); ++itProd) {
0123     (*itProd)->produce(e, es);
0124   }
0125 }
0126 void GeometryProducer::makeGeom(const edm::EventSetup &es) {
0127   if (!m_firstRun)
0128     return;
0129 
0130   edm::LogVerbatim("GeometryProducer") << "Producing G4 Geom";
0131 
0132   m_kernel = G4RunManagerKernel::GetRunManagerKernel();
0133   if (m_kernel == nullptr)
0134     m_kernel = new G4RunManagerKernel();
0135   edm::LogVerbatim("GeometryProducer") << " GeometryProducer initializing ";
0136   // DDDWorld: get the DDCV from the ES and use it to build the World
0137   if (m_pGeoFromDD4hep) {
0138     m_pDD4hep = &es.getData(tokDD4hep_);
0139   } else {
0140     m_pDD = &es.getData(tokDDD_);
0141   }
0142 
0143   SensitiveDetectorCatalog catalog;
0144   const DDDWorld *dddworld = new DDDWorld(m_pDD, m_pDD4hep, catalog, 1, false, false);
0145   G4VPhysicalVolume *world = dddworld->GetWorldVolume();
0146   if (nullptr != world)
0147     edm::LogVerbatim("GeometryProducer") << " World Volume: " << world->GetName();
0148   m_kernel->DefineWorldVolume(world, true);
0149 
0150   m_registry.dddWorldSignal_(dddworld);
0151 
0152   edm::LogVerbatim("GeometryProducer") << " Magnetic field initialisation";
0153   updateMagneticField(es);
0154 
0155   if (m_pUseSensitiveDetectors) {
0156     edm::LogInfo("GeometryProducer") << " instantiating sensitive detectors ";
0157     // instantiate and attach the sensitive detectors
0158     m_trackManager = std::make_unique<SimTrackManager>();
0159     {
0160       std::pair<std::vector<SensitiveTkDetector *>, std::vector<SensitiveCaloDetector *>> sensDets =
0161           sim::attachSD(m_sdMakers, es, catalog, m_p, m_trackManager.get(), m_registry);
0162 
0163       m_sensTkDets.swap(sensDets.first);
0164       m_sensCaloDets.swap(sensDets.second);
0165     }
0166 
0167     edm::LogInfo("GeometryProducer") << " Sensitive Detector building finished; found " << m_sensTkDets.size()
0168                                      << " Tk type Producers, and " << m_sensCaloDets.size() << " Calo type producers ";
0169   }
0170 }
0171 
0172 DEFINE_FWK_MODULE(GeometryProducer);