diff --git a/SimG4Core/Application/interface/OscarMTMasterThread.h b/SimG4Core/Application/interface/OscarMTMasterThread.h index 09cd989f21eac..bb066beab35fd 100644 --- a/SimG4Core/Application/interface/OscarMTMasterThread.h +++ b/SimG4Core/Application/interface/OscarMTMasterThread.h @@ -4,9 +4,13 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/ESWatcher.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "DetectorDescription/Core/interface/DDCompactView.h" +#include "DetectorDescription/DDCMS/interface/DDCompactView.h" #include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "HepPDT/ParticleDataTable.hh" +#include "SimGeneral/HepPDTRecord/interface/PDTRecord.h" + #include #include #include @@ -14,7 +18,8 @@ namespace edm { class EventSetup; -} + class ConsumesCollector; +} // namespace edm class RunManagerMT; @@ -38,12 +43,12 @@ class OscarMTMasterThread { void endRun() const; void stopThread(); + void callConsumes(edm::ConsumesCollector&& iC) const; + inline RunManagerMT& runManagerMaster() const { return *m_runManagerMaster; } inline RunManagerMT* runManagerMasterPtr() const { return m_runManagerMaster.get(); } private: - void readES(const edm::EventSetup& iSetup) const; - enum class ThreadState { NotExist = 0, BeginRun = 1, EndRun = 2, Destruct = 3 }; const bool m_pGeoFromDD4hep; @@ -52,12 +57,14 @@ class OscarMTMasterThread { std::thread m_masterThread; // ES products needed for Geant4 initialization - mutable edm::ESWatcher idealGeomRcdWatcher_; - mutable edm::ESWatcher idealMagRcdWatcher_; - mutable const DDCompactView* m_pDD; - mutable const cms::DDCompactView* m_pDD4hep; - mutable const HepPDT::ParticleDataTable* m_pTable; - + mutable const DDCompactView* m_pDDD = nullptr; + mutable const cms::DDCompactView* m_pDD4Hep = nullptr; + mutable const HepPDT::ParticleDataTable* m_pTable = nullptr; + mutable edm::ESGetToken m_DDD; + mutable edm::ESGetToken m_DD4Hep; + mutable edm::ESGetToken m_PDT; + + // status flags mutable std::mutex m_protectMutex; mutable std::mutex m_threadMutex; mutable std::condition_variable m_notifyMasterCv; @@ -65,10 +72,11 @@ class OscarMTMasterThread { mutable ThreadState m_masterThreadState; - mutable bool m_masterCanProceed; - mutable bool m_mainCanProceed; - mutable bool m_firstRun; - mutable bool m_stopped; + mutable bool m_hasToken = false; + mutable bool m_masterCanProceed = false; + mutable bool m_mainCanProceed = false; + mutable bool m_firstRun = true; + mutable bool m_stopped = false; }; #endif diff --git a/SimG4Core/Application/interface/RunManagerMT.h b/SimG4Core/Application/interface/RunManagerMT.h index 093f0c48911b1..a290b6c93ae49 100644 --- a/SimG4Core/Application/interface/RunManagerMT.h +++ b/SimG4Core/Application/interface/RunManagerMT.h @@ -2,10 +2,7 @@ #define SimG4Core_RunManagerMT_H #include "FWCore/Framework/interface/Event.h" -#include "DataFormats/Common/interface/Handle.h" -#include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/InputTag.h" #include "SimG4Core/Geometry/interface/SensitiveDetectorCatalog.h" @@ -59,7 +56,6 @@ class RunManagerMT { explicit RunManagerMT(edm::ParameterSet const&); ~RunManagerMT(); - // void initG4(const DDCompactView*, const cms::DDCompactView*, const MagneticField*, const HepPDT::ParticleDataTable*); void initG4(const DDCompactView*, const cms::DDCompactView*, const HepPDT::ParticleDataTable*); void initializeUserActions(); diff --git a/SimG4Core/Application/interface/RunManagerMTWorker.h b/SimG4Core/Application/interface/RunManagerMTWorker.h index e1c0e65586cb6..f42895f449894 100644 --- a/SimG4Core/Application/interface/RunManagerMTWorker.h +++ b/SimG4Core/Application/interface/RunManagerMTWorker.h @@ -7,6 +7,9 @@ #include "SimG4Core/Generators/interface/Generator.h" #include "SimDataFormats/Forward/interface/LHCTransportLinkContainer.h" +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" + #include #include #include @@ -19,6 +22,7 @@ namespace edm { class ConsumesCollector; class HepMCProduct; } // namespace edm + class Generator; class RunManagerMT; @@ -43,7 +47,7 @@ class SimProducer; class RunManagerMTWorker { public: - explicit RunManagerMTWorker(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& i); + explicit RunManagerMTWorker(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC); ~RunManagerMTWorker(); void beginRun(const edm::EventSetup&); @@ -88,6 +92,8 @@ class RunManagerMTWorker { edm::EDGetTokenT m_InToken; edm::EDGetTokenT m_LHCToken; edm::EDGetTokenT m_theLHCTlinkToken; + edm::ESGetToken m_MagField; + const MagneticField* m_pMagField = nullptr; bool m_nonBeam; bool m_pUseMagneticField; diff --git a/SimG4Core/Application/plugins/OscarMTProducer.cc b/SimG4Core/Application/plugins/OscarMTProducer.cc index 8b450dcf9264a..cfce6e9fed2d6 100644 --- a/SimG4Core/Application/plugins/OscarMTProducer.cc +++ b/SimG4Core/Application/plugins/OscarMTProducer.cc @@ -1,33 +1,30 @@ -#include "FWCore/PluginManager/interface/PluginManager.h" +#include "OscarMTProducer.h" +#include "FWCore/PluginManager/interface/PluginManager.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "OscarMTProducer.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Utilities/interface/RandomNumberGenerator.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "SimG4Core/Notification/interface/SimG4Exception.h" #include "SimG4Core/Application/interface/RunManagerMT.h" #include "SimG4Core/Application/interface/RunManagerMTWorker.h" #include "SimG4Core/Notification/interface/G4SimEvent.h" #include "SimG4Core/SensitiveDetector/interface/SensitiveTkDetector.h" #include "SimG4Core/SensitiveDetector/interface/SensitiveCaloDetector.h" +#include "SimG4Core/Watcher/interface/SimProducer.h" #include "SimDataFormats/Track/interface/SimTrackContainer.h" #include "SimDataFormats/Vertex/interface/SimVertexContainer.h" #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h" -#include "SimG4Core/Watcher/interface/SimProducer.h" - -#include "FWCore/Utilities/interface/Exception.h" -#include "SimG4Core/Notification/interface/SimG4Exception.h" - -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/Utilities/interface/RandomNumberGenerator.h" #include "Randomize.hh" -#include "FWCore/MessageLogger/interface/MessageLogger.h" - #include #include @@ -70,7 +67,9 @@ OscarMTProducer::OscarMTProducer(edm::ParameterSet const& p, const OscarMTMaster m_runManagerWorker = std::make_unique(p, consumesCollector()); m_masterThread = ms; + m_masterThread->callConsumes(consumesCollector()); + // List of produced containers produces().setBranchAlias("SimTracks"); produces().setBranchAlias("SimVertices"); produces("TrackerHitsPixelBarrelLowTof"); @@ -128,9 +127,8 @@ OscarMTProducer::OscarMTProducer(edm::ParameterSet const& p, const OscarMTMaster //register any products auto& producers = m_runManagerWorker->producers(); - - for (Producers::iterator itProd = producers.begin(); itProd != producers.end(); ++itProd) { - (*itProd)->registerProducts(producesCollector()); + for (auto& ptr : producers) { + ptr->registerProducts(producesCollector()); } edm::LogVerbatim("SimG4CoreApplication") << "OscarMTProducer is constructed"; } @@ -145,19 +143,18 @@ std::unique_ptr OscarMTProducer::initializeGlobalCache(cons return std::make_unique(iConfig); } -std::shared_ptr OscarMTProducer::globalBeginRun(const edm::Run& iRun, +std::shared_ptr OscarMTProducer::globalBeginRun(const edm::Run&, const edm::EventSetup& iSetup, const OscarMTMasterThread* masterThread) { // Random number generation not allowed here StaticRandomEngineSetUnset random(nullptr); - edm::LogVerbatim("SimG4CoreApplication") << "OscarMTProducer::globalBeginRun"; masterThread->beginRun(iSetup); edm::LogVerbatim("SimG4CoreApplication") << "OscarMTProducer::globalBeginRun done"; return std::shared_ptr(); } -void OscarMTProducer::globalEndRun(const edm::Run& iRun, const edm::EventSetup& iSetup, const RunContext* iContext) { +void OscarMTProducer::globalEndRun(const edm::Run&, const edm::EventSetup&, const RunContext* iContext) { edm::LogVerbatim("SimG4CoreApplication") << "OscarMTProducer::globalEndRun"; iContext->global()->endRun(); } @@ -185,7 +182,7 @@ void OscarMTProducer::endRun(const edm::Run&, const edm::EventSetup&) { void OscarMTProducer::produce(edm::Event& e, const edm::EventSetup& es) { StaticRandomEngineSetUnset random(e.streamID()); edm::LogVerbatim("SimG4CoreApplication") << "Produce event " << e.id() << " stream " << e.streamID(); - LogDebug("SimG4CoreApplication") << "Before event rand= " << G4UniformRand(); + //edm::LogVerbatim("SimG4CoreApplication") << " rand= " << G4UniformRand(); auto& sTk = m_runManagerWorker->sensTkDetectors(); auto& sCalo = m_runManagerWorker->sensCaloDetectors(); @@ -215,7 +212,7 @@ void OscarMTProducer::produce(edm::Event& e, const edm::EventSetup& es) { std::unique_ptr product(new edm::PSimHitContainer); tracker->fillHits(*product, name); if (product != nullptr && !product->empty()) - edm::LogVerbatim("SimG4CoreApplication") << "Produced " << product->size() << " traker hits <" << name << ">"; + edm::LogVerbatim("SimG4CoreApplication") << "Produced " << product->size() << " tracker hits <" << name << ">"; e.put(std::move(product), name); } } @@ -236,7 +233,7 @@ void OscarMTProducer::produce(edm::Event& e, const edm::EventSetup& es) { prod.get()->produce(e, es); } edm::LogVerbatim("SimG4CoreApplication") << "Event is produced " << e.id() << " stream " << e.streamID(); - LogDebug("SimG4CoreApplication") << "End of event rand= " << G4UniformRand(); + //edm::LogVerbatim("SimG4CoreApplication") << " rand= " << G4UniformRand(); } StaticRandomEngineSetUnset::StaticRandomEngineSetUnset(edm::StreamID const& streamID) { diff --git a/SimG4Core/Application/plugins/OscarMTProducer.h b/SimG4Core/Application/plugins/OscarMTProducer.h index bd6765444310b..5d9bc43ce25d7 100644 --- a/SimG4Core/Application/plugins/OscarMTProducer.h +++ b/SimG4Core/Application/plugins/OscarMTProducer.h @@ -3,7 +3,6 @@ #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" -#include "DataFormats/Common/interface/Handle.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/Run.h" diff --git a/SimG4Core/Application/src/OscarMTMasterThread.cc b/SimG4Core/Application/src/OscarMTMasterThread.cc index 575665607901d..468e2196c0810 100644 --- a/SimG4Core/Application/src/OscarMTMasterThread.cc +++ b/SimG4Core/Application/src/OscarMTMasterThread.cc @@ -1,40 +1,24 @@ #include #include "SimG4Core/Application/interface/OscarMTMasterThread.h" +#include "FWCore/Utilities/interface/EDMException.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" #include "SimG4Core/Application/interface/RunManagerMT.h" #include "SimG4Core/Geometry/interface/CustomUIsession.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/Framework/interface/ESTransientHandle.h" -#include "FWCore/Utilities/interface/EDMException.h" - -#include "Geometry/Records/interface/IdealGeometryRecord.h" -#include "DetectorDescription/Core/interface/DDCompactView.h" -#include "DetectorDescription/DDCMS/interface/DDCompactView.h" - -#include "HepPDT/ParticleDataTable.hh" -#include "SimGeneral/HepPDTRecord/interface/PDTRecord.h" - #include "G4PhysicalVolumeStore.hh" OscarMTMasterThread::OscarMTMasterThread(const edm::ParameterSet& iConfig) : m_pGeoFromDD4hep(iConfig.getParameter("g4GeometryDD4hepSource")), - m_pDD(nullptr), - m_pDD4hep(nullptr), - m_pTable(nullptr), - m_masterThreadState(ThreadState::NotExist), - m_masterCanProceed(false), - m_mainCanProceed(false), - m_firstRun(true), - m_stopped(false) { + m_masterThreadState(ThreadState::NotExist) { // Lock the mutex std::unique_lock lk(m_threadMutex); - edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: creating master thread"; + edm::LogVerbatim("SimG4CoreApplication") + << "OscarMTMasterThread: creating master thread DD4Hep: " << m_pGeoFromDD4hep; - // Create Genat4 master thread + // Create Geant4 master thread m_masterThread = std::thread([&]() { ///////////////// // Initialization @@ -64,6 +48,7 @@ OscarMTMasterThread::OscarMTMasterThread(const edm::ParameterSet& iConfig) m_masterCanProceed = false; edm::LogVerbatim("OscarMTMasterThread") << "Master thread: State loop, starting wait"; m_notifyMasterCv.wait(lk2, [&] { return m_masterCanProceed; }); + //m_notifyMasterCv.wait(lk2, [&] { return false; }); // Act according to the state edm::LogVerbatim("OscarMTMasterThread") @@ -71,7 +56,7 @@ OscarMTMasterThread::OscarMTMasterThread(const edm::ParameterSet& iConfig) if (m_masterThreadState == ThreadState::BeginRun) { // Initialize Geant4 edm::LogVerbatim("OscarMTMasterThread") << "Master thread: Initializing Geant4"; - m_runManagerMaster->initG4(m_pDD, m_pDD4hep, m_pTable); + m_runManagerMaster->initG4(m_pDDD, m_pDD4Hep, m_pTable); isG4Alive = true; } else if (m_masterThreadState == ThreadState::EndRun) { // Stop Geant4 @@ -119,14 +104,33 @@ OscarMTMasterThread::~OscarMTMasterThread() { } } +void OscarMTMasterThread::callConsumes(edm::ConsumesCollector&& iC) const { + if (m_hasToken) { + return; + } + if (m_pGeoFromDD4hep) { + m_DD4Hep = iC.esConsumes(); + } else { + m_DDD = iC.esConsumes(); + } + m_PDT = iC.esConsumes(); + m_hasToken = true; +} + void OscarMTMasterThread::beginRun(const edm::EventSetup& iSetup) const { std::lock_guard lk(m_protectMutex); - std::unique_lock lk2(m_threadMutex); + edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::beginRun"; - // Reading from ES must be done in the main (CMSSW) thread - readES(iSetup); - + if (m_firstRun) { + if (m_pGeoFromDD4hep) { + m_pDD4Hep = &(*iSetup.getTransientHandle(m_DD4Hep)); + } else { + m_pDDD = &(*iSetup.getTransientHandle(m_DDD)); + } + m_pTable = &iSetup.getData(m_PDT); + m_firstRun = false; + } m_masterThreadState = ThreadState::BeginRun; m_masterCanProceed = true; m_mainCanProceed = false; @@ -140,8 +144,8 @@ void OscarMTMasterThread::beginRun(const edm::EventSetup& iSetup) const { void OscarMTMasterThread::endRun() const { std::lock_guard lk(m_protectMutex); - std::unique_lock lk2(m_threadMutex); + m_masterThreadState = ThreadState::EndRun; m_mainCanProceed = false; m_masterCanProceed = true; @@ -176,33 +180,3 @@ void OscarMTMasterThread::stopThread() { edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: main thread finished"; m_stopped = true; } - -void OscarMTMasterThread::readES(const edm::EventSetup& iSetup) const { - bool geomChanged = idealGeomRcdWatcher_.check(iSetup); - if (geomChanged && (!m_firstRun)) { - throw edm::Exception(edm::errors::Configuration) - << "[SimG4Core OscarMTMasterThread]\n" - << "The Geometry configuration is changed during the job execution\n" - << "this is not allowed, the geometry must stay unchanged"; - } - // Don't read from ES if not the first run, just as in - if (!m_firstRun) - return; - - // DDDWorld: get the DDCV from the ES and use it to build the World - if (m_pGeoFromDD4hep) { - edm::ESTransientHandle pDD; - iSetup.get().get(pDD); - m_pDD4hep = pDD.product(); - } else { - edm::ESTransientHandle pDD; - iSetup.get().get(pDD); - m_pDD = pDD.product(); - } - - edm::ESHandle fTable; - iSetup.get().get(fTable); - m_pTable = fTable.product(); - - m_firstRun = false; -} diff --git a/SimG4Core/Application/src/RunManagerMT.cc b/SimG4Core/Application/src/RunManagerMT.cc index bc79172131078..22b69f68bf938 100644 --- a/SimG4Core/Application/src/RunManagerMT.cc +++ b/SimG4Core/Application/src/RunManagerMT.cc @@ -203,11 +203,6 @@ void RunManagerMT::initG4(const DDCompactView* pDD, throw edm::Exception(edm::errors::LogicError, "G4RunManagerKernel initialization failed!"); } - timer.Stop(); - G4cout.precision(4); - G4cout << "RunManagerMT: physics is initialized: " << timer << G4endl; - timer.Start(); - if (m_StorePhysicsTables) { std::ostringstream dir; dir << m_PhysicsTablesDir << '\0'; diff --git a/SimG4Core/Application/src/RunManagerMTWorker.cc b/SimG4Core/Application/src/RunManagerMTWorker.cc index 6d47628f2ddf7..7771f3f4a7e7e 100644 --- a/SimG4Core/Application/src/RunManagerMTWorker.cc +++ b/SimG4Core/Application/src/RunManagerMTWorker.cc @@ -16,7 +16,6 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" -#include "DataFormats/Common/interface/Handle.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ServiceRegistry/interface/Service.h" #include "FWCore/Utilities/interface/thread_safety_macros.h" @@ -28,19 +27,12 @@ #include "SimG4Core/Notification/interface/CMSSteppingVerbose.h" #include "SimG4Core/Watcher/interface/SimWatcherFactory.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/Framework/interface/ESTransientHandle.h" -#include "Geometry/Records/interface/IdealGeometryRecord.h" - #include "SimG4Core/Geometry/interface/DDDWorld.h" #include "SimG4Core/MagneticField/interface/FieldBuilder.h" #include "SimG4Core/MagneticField/interface/CMSFieldManager.h" -#include "MagneticField/Engine/interface/MagneticField.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" - #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h" +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include "SimG4Core/Physics/interface/PhysicsList.h" @@ -176,6 +168,9 @@ RunManagerMTWorker::RunManagerMTWorker(const edm::ParameterSet& iConfig, edm::Co if (m_LHCTransport) { m_LHCToken = iC.consumes(edm::InputTag("LHCTransport")); } + if (m_pUseMagneticField) { + m_MagField = iC.esConsumes(); + } edm::LogVerbatim("SimG4CoreApplication") << "RunManagerMTWorker is constructed for the thread " << thisID; unsigned int k = 0; for (std::unordered_map>::const_iterator itr = @@ -315,12 +310,11 @@ void RunManagerMTWorker::initializeG4(RunManagerMT* runManagerMaster, const edm: // setup the magnetic field if (m_pUseMagneticField) { - const GlobalPoint g(0., 0., 0.); + const GlobalPoint g(0.f, 0.f, 0.f); - edm::ESHandle pMF; - es.get().get(pMF); + m_pMagField = &es.getData(m_MagField); + sim::FieldBuilder fieldBuilder(m_pMagField, m_pField); - sim::FieldBuilder fieldBuilder(pMF.product(), m_pField); CMSFieldManager* fieldManager = new CMSFieldManager(); tM->SetFieldManager(fieldManager); fieldBuilder.build(fieldManager, tM->GetPropagatorInField()); diff --git a/SimG4Core/Watcher/interface/SimProducer.h b/SimG4Core/Watcher/interface/SimProducer.h index 8292ecd1199e6..8e8b95ef44660 100644 --- a/SimG4Core/Watcher/interface/SimProducer.h +++ b/SimG4Core/Watcher/interface/SimProducer.h @@ -64,13 +64,7 @@ namespace simproducer { class SimProducer : public SimWatcher { public: SimProducer() {} - // virtual ~SimProducer(); - // ---------- const member functions --------------------- - - // ---------- static member functions -------------------- - - // ---------- member functions --------------------------- virtual void produce(edm::Event &, const edm::EventSetup &) = 0; void registerProducts(edm::ProducesCollector producesCollector) { @@ -81,6 +75,9 @@ class SimProducer : public SimWatcher { }); } + SimProducer(const SimProducer &) = delete; + const SimProducer &operator=(const SimProducer &) = delete; + protected: template void produces() { @@ -93,11 +90,6 @@ class SimProducer : public SimWatcher { } private: - SimProducer(const SimProducer &) = delete; // stop default - - const SimProducer &operator=(const SimProducer &) = delete; // stop default - - // ---------- member data -------------------------------- std::vector> m_info; };