00001 #include "FWCore/PluginManager/interface/PluginManager.h" 00002 00003 #include "FWCore/Framework/interface/MakerMacros.h" 00004 #include "FWCore/ParameterSet/interface/ParameterSet.h" 00005 00006 #include "SimG4Core/Application/interface/OscarProducer.h" 00007 #include "SimG4Core/Application/interface/G4SimEvent.h" 00008 00009 #include "SimDataFormats/Track/interface/SimTrackContainer.h" 00010 #include "SimDataFormats/Vertex/interface/SimVertexContainer.h" 00011 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" 00012 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h" 00013 00014 #include "SimG4Core/Watcher/interface/SimProducer.h" 00015 00016 #include "FWCore/Utilities/interface/Exception.h" 00017 #include "SimG4Core/Notification/interface/SimG4Exception.h" 00018 00019 #include "FWCore/ServiceRegistry/interface/Service.h" 00020 #include "FWCore/Utilities/interface/RandomNumberGenerator.h" 00021 #include "CLHEP/Random/Random.h" 00022 00023 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00024 00025 #include <iostream> 00026 00027 namespace { 00028 // 00029 // this machinery allows to set CLHEP static engine 00030 // to the one defined by RandomNumberGenerator service 00031 // at the beginning of an event, and reset it back to 00032 // "default-default" at the end of the event; 00033 // Dave D. has decided to implement it this way because 00034 // we don't know if there're other modules using CLHEP 00035 // static engine, thus we want to ensure that the one 00036 // we use for OscarProducer is unique to OscarProducer 00037 // 00038 class StaticRandomEngineSetUnset { 00039 public: 00040 StaticRandomEngineSetUnset(); 00041 explicit StaticRandomEngineSetUnset(CLHEP::HepRandomEngine * engine); 00042 ~StaticRandomEngineSetUnset(); 00043 CLHEP::HepRandomEngine* getEngine() const; 00044 private: 00045 CLHEP::HepRandomEngine* m_currentEngine; 00046 CLHEP::HepRandomEngine* m_previousEngine; 00047 }; 00048 } 00049 00050 OscarProducer::OscarProducer(edm::ParameterSet const & p) 00051 { 00052 StaticRandomEngineSetUnset random; 00053 m_engine = random.getEngine(); 00054 00055 produces<edm::SimTrackContainer>().setBranchAlias("SimTracks"); 00056 produces<edm::SimVertexContainer>().setBranchAlias("SimVertices"); 00057 produces<edm::PSimHitContainer>("TrackerHitsPixelBarrelLowTof"); 00058 produces<edm::PSimHitContainer>("TrackerHitsPixelBarrelHighTof"); 00059 produces<edm::PSimHitContainer>("TrackerHitsTIBLowTof"); 00060 produces<edm::PSimHitContainer>("TrackerHitsTIBHighTof"); 00061 produces<edm::PSimHitContainer>("TrackerHitsTIDLowTof"); 00062 produces<edm::PSimHitContainer>("TrackerHitsTIDHighTof"); 00063 produces<edm::PSimHitContainer>("TrackerHitsPixelEndcapLowTof"); 00064 produces<edm::PSimHitContainer>("TrackerHitsPixelEndcapHighTof"); 00065 produces<edm::PSimHitContainer>("TrackerHitsTOBLowTof"); 00066 produces<edm::PSimHitContainer>("TrackerHitsTOBHighTof"); 00067 produces<edm::PSimHitContainer>("TrackerHitsTECLowTof"); 00068 produces<edm::PSimHitContainer>("TrackerHitsTECHighTof"); 00069 00070 produces<edm::PSimHitContainer>("TotemHitsT1"); 00071 produces<edm::PSimHitContainer>("TotemHitsT2Gem"); 00072 produces<edm::PSimHitContainer>("TotemHitsRP"); 00073 produces<edm::PSimHitContainer>("FP420SI"); 00074 produces<edm::PSimHitContainer>("BSCHits"); 00075 00076 produces<edm::PCaloHitContainer>("EcalHitsEB"); 00077 produces<edm::PCaloHitContainer>("EcalHitsEE"); 00078 produces<edm::PCaloHitContainer>("EcalHitsES"); 00079 produces<edm::PCaloHitContainer>("HcalHits"); 00080 produces<edm::PCaloHitContainer>("CaloHitsTk"); 00081 produces<edm::PSimHitContainer>("MuonDTHits"); 00082 produces<edm::PSimHitContainer>("MuonCSCHits"); 00083 produces<edm::PSimHitContainer>("MuonRPCHits"); 00084 produces<edm::PCaloHitContainer>("CastorPL"); 00085 produces<edm::PCaloHitContainer>("CastorFI"); 00086 produces<edm::PCaloHitContainer>("CastorBU"); 00087 produces<edm::PCaloHitContainer>("CastorTU"); 00088 produces<edm::PCaloHitContainer>("EcalTBH4BeamHits"); 00089 produces<edm::PCaloHitContainer>("HcalTB06BeamHits"); 00090 produces<edm::PCaloHitContainer>("ZDCHITS"); 00091 00092 //m_runManager = RunManager::init(p); 00093 m_runManager = new RunManager(p); 00094 00095 //register any products 00096 m_producers= m_runManager->producers(); 00097 00098 for(Producers::iterator itProd = m_producers.begin(); 00099 itProd != m_producers.end(); 00100 ++itProd) { 00101 (*itProd)->registerProducts(*this); 00102 } 00103 00104 //UIsession manager for message handling 00105 m_UIsession = new CustomUIsession(); 00106 00107 } 00108 00109 OscarProducer::~OscarProducer() 00110 { 00111 //this is causing a seg fault when an exception occurs while constructing 00112 // an HcalSD. Need to check for memory problems. 00113 if (m_runManager!=0) delete m_runManager; 00114 if (m_UIsession!=0) delete m_UIsession; 00115 00116 } 00117 00118 void OscarProducer::beginJob(const edm::EventSetup & es) 00119 { 00120 StaticRandomEngineSetUnset random(m_engine); 00121 00122 m_runManager->initG4(es); 00123 } 00124 00125 void OscarProducer::endJob() { } 00126 00127 void OscarProducer::produce(edm::Event & e, const edm::EventSetup & es) 00128 { 00129 StaticRandomEngineSetUnset random(m_engine); 00130 00131 std::vector<SensitiveTkDetector*>& sTk = m_runManager->sensTkDetectors(); 00132 std::vector<SensitiveCaloDetector*>& sCalo = m_runManager->sensCaloDetectors(); 00133 00134 try 00135 { 00136 m_runManager->produce(e,es); 00137 00138 std::auto_ptr<edm::SimTrackContainer> p1(new edm::SimTrackContainer); 00139 std::auto_ptr<edm::SimVertexContainer> p2(new edm::SimVertexContainer); 00140 G4SimEvent * evt = m_runManager->simEvent(); 00141 evt->load(*p1); 00142 evt->load(*p2); 00143 00144 e.put(p1); 00145 e.put(p2); 00146 00147 for (std::vector<SensitiveTkDetector*>::iterator it = sTk.begin(); it != sTk.end(); it++) 00148 { 00149 std::vector<std::string> v = (*it)->getNames(); 00150 for (std::vector<std::string>::iterator in = v.begin(); in!= v.end(); in++) 00151 { 00152 std::auto_ptr<edm::PSimHitContainer> product(new edm::PSimHitContainer); 00153 (*it)->fillHits(*product,*in); 00154 e.put(product,*in); 00155 } 00156 } 00157 for (std::vector<SensitiveCaloDetector*>::iterator it = sCalo.begin(); it != sCalo.end(); it++) 00158 { 00159 std::vector<std::string> v = (*it)->getNames(); 00160 for (std::vector<std::string>::iterator in = v.begin(); in!= v.end(); in++) 00161 { 00162 std::auto_ptr<edm::PCaloHitContainer> product(new edm::PCaloHitContainer); 00163 (*it)->fillHits(*product,*in); 00164 e.put(product,*in); 00165 } 00166 } 00167 00168 for(Producers::iterator itProd = m_producers.begin(); 00169 itProd != m_producers.end(); 00170 ++itProd) { 00171 (*itProd)->produce(e,es); 00172 } 00173 } 00174 catch ( const SimG4Exception& simg4ex ) 00175 { 00176 00177 edm::LogInfo("SimG4CoreApplication") << " SimG4Exception caght !" << simg4ex.what() << std::endl ; 00178 00179 m_runManager->abortEvent() ; 00180 throw edm::Exception( edm::errors::EventCorruption ) ; 00181 } 00182 } 00183 00184 00185 StaticRandomEngineSetUnset::StaticRandomEngineSetUnset() { 00186 00187 using namespace edm; 00188 Service<RandomNumberGenerator> rng; 00189 00190 if ( ! rng.isAvailable()) { 00191 throw cms::Exception("Configuration") 00192 << "The OscarProducer module requires the RandomNumberGeneratorService\n" 00193 "which is not present in the configuration file. You must add the service\n" 00194 "in the configuration file if you want to run OscarProducer"; 00195 } 00196 m_currentEngine = &(rng->getEngine()); 00197 00198 m_previousEngine = HepRandom::getTheEngine(); 00199 HepRandom::setTheEngine(m_currentEngine); 00200 } 00201 00202 StaticRandomEngineSetUnset::StaticRandomEngineSetUnset(CLHEP::HepRandomEngine * engine) { 00203 00204 m_currentEngine = engine; 00205 00206 m_previousEngine = HepRandom::getTheEngine(); 00207 HepRandom::setTheEngine(m_currentEngine); 00208 } 00209 00210 StaticRandomEngineSetUnset::~StaticRandomEngineSetUnset() { 00211 HepRandom::setTheEngine(m_previousEngine); 00212 } 00213 00214 CLHEP::HepRandomEngine* 00215 StaticRandomEngineSetUnset::getEngine() const { return m_currentEngine; } 00216 00217 DEFINE_FWK_MODULE(OscarProducer); 00218