00001 #include "SimG4Core/Application/interface/RunManager.h"
00002 #include "SimG4Core/Application/interface/PrimaryTransformer.h"
00003 #include "SimG4Core/Application/interface/RunAction.h"
00004 #include "SimG4Core/Application/interface/EventAction.h"
00005 #include "SimG4Core/Application/interface/StackingAction.h"
00006 #include "SimG4Core/Application/interface/TrackingAction.h"
00007 #include "SimG4Core/Application/interface/SteppingAction.h"
00008 #include "SimG4Core/Application/interface/G4SimEvent.h"
00009
00010 #include "SimG4Core/Geometry/interface/DDDWorld.h"
00011 #include "SimG4Core/Geometry/interface/G4LogicalVolumeToDDLogicalPartMap.h"
00012 #include "SimG4Core/Geometry/interface/SensitiveDetectorCatalog.h"
00013 #include "SimG4Core/SensitiveDetector/interface/AttachSD.h"
00014 #include "SimG4Core/Generators/interface/Generator.h"
00015 #include "SimG4Core/Physics/interface/PhysicsListFactory.h"
00016 #include "SimG4Core/Watcher/interface/SimWatcherFactory.h"
00017 #include "SimG4Core/MagneticField/interface/FieldBuilder.h"
00018 #include "SimG4Core/MagneticField/interface/Field.h"
00019
00020 #include "MagneticField/Engine/interface/MagneticField.h"
00021 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00022
00023 #include "SimG4Core/Notification/interface/SimG4Exception.h"
00024 #include "SimG4Core/Notification/interface/BeginOfJob.h"
00025
00026 #include "FWCore/Framework/interface/EventSetup.h"
00027 #include "FWCore/Framework/interface/ESHandle.h"
00028 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00029
00030 #include "DetectorDescription/Core/interface/DDCompactView.h"
00031
00032 #include "FWCore/ServiceRegistry/interface/Service.h"
00033
00034 #include "SimDataFormats/HepMCProduct/interface/HepMCProduct.h"
00035
00036 #include "G4StateManager.hh"
00037 #include "G4ApplicationState.hh"
00038 #include "G4RunManagerKernel.hh"
00039 #include "G4UImanager.hh"
00040
00041 #include "G4EventManager.hh"
00042 #include "G4Run.hh"
00043 #include "G4Event.hh"
00044 #include "G4TransportationManager.hh"
00045
00046 #include "SimG4Core/Notification/interface/CurrentG4Track.h"
00047
00048 #include <iostream>
00049 #include <memory>
00050 #include <strstream>
00051 #include <fstream>
00052
00053 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00054
00055 #include "SimG4Core/Application/interface/ExceptionHandler.h"
00056
00057 static
00058 void createWatchers(const edm::ParameterSet& iP,
00059 SimActivityRegistry& iReg,
00060 std::vector<boost::shared_ptr<SimWatcher> >& oWatchers,
00061 std::vector<boost::shared_ptr<SimProducer> >& oProds
00062 )
00063 {
00064 using namespace std;
00065 using namespace edm;
00066 vector<ParameterSet> watchers;
00067 try {
00068 watchers = iP.getParameter<vector<ParameterSet> >("Watchers");
00069 } catch( edm::Exception) {
00070 }
00071
00072 for(vector<ParameterSet>::iterator itWatcher = watchers.begin();
00073 itWatcher != watchers.end();
00074 ++itWatcher) {
00075 std::auto_ptr<SimWatcherMakerBase> maker(
00076 SimWatcherFactory::get()->create
00077 (itWatcher->getParameter<std::string> ("type")) );
00078 if(maker.get()==0) {
00079 throw SimG4Exception("Unable to find the requested Watcher");
00080 }
00081
00082 boost::shared_ptr<SimWatcher> watcherTemp;
00083 boost::shared_ptr<SimProducer> producerTemp;
00084 maker->make(*itWatcher,iReg,watcherTemp,producerTemp);
00085 oWatchers.push_back(watcherTemp);
00086 if(producerTemp) {
00087 oProds.push_back(producerTemp);
00088 }
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 RunManager::RunManager(edm::ParameterSet const & p)
00109 : m_generator(0), m_nonBeam(p.getParameter<bool>("NonBeamEvent")),
00110 m_primaryTransformer(0),
00111 m_managerInitialized(false),
00112 m_geometryInitialized(true), m_physicsInitialized(true),
00113 m_runInitialized(false), m_runTerminated(false), m_runAborted(false),
00114 m_pUseMagneticField(p.getParameter<bool>("UseMagneticField")),
00115 m_currentRun(0), m_currentEvent(0), m_simEvent(0),
00116 m_PhysicsTablesDir(p.getParameter<std::string>("PhysicsTablesDirectory")),
00117 m_StorePhysicsTables(p.getParameter<bool>("StorePhysicsTables")),
00118 m_RestorePhysicsTables(p.getParameter<bool>("RestorePhysicsTables")),
00119 m_EvtMgrVerbosity(p.getUntrackedParameter<int>("G4EventManagerVerbosity",0)),
00120 m_Override(p.getParameter<bool>("OverrideUserStackingAction")),
00121 m_pField(p.getParameter<edm::ParameterSet>("MagneticField")),
00122 m_pGenerator(p.getParameter<edm::ParameterSet>("Generator")),
00123 m_pPhysics(p.getParameter<edm::ParameterSet>("Physics")),
00124 m_pRunAction(p.getParameter<edm::ParameterSet>("RunAction")),
00125 m_pEventAction(p.getParameter<edm::ParameterSet>("EventAction")),
00126 m_pStackingAction(p.getParameter<edm::ParameterSet>("StackingAction")),
00127 m_pTrackingAction(p.getParameter<edm::ParameterSet>("TrackingAction")),
00128 m_pSteppingAction(p.getParameter<edm::ParameterSet>("SteppingAction")),
00129 m_G4Commands(p.getParameter<std::vector<std::string> >("G4Commands")),
00130 m_p(p)
00131
00132 {
00133 m_kernel = G4RunManagerKernel::GetRunManagerKernel();
00134 if (m_kernel==0) m_kernel = new G4RunManagerKernel();
00135
00136 m_CustomExceptionHandler = new ExceptionHandler(this) ;
00137
00138 m_check = p.getUntrackedParameter<bool>("CheckOverlap",false);
00139
00140
00141
00142 edm::Service<SimActivityRegistry> otherRegistry;
00143 if(otherRegistry){
00144 m_registry.connect(*otherRegistry);
00145 }
00146
00147 createWatchers(m_p, m_registry, m_watchers, m_producers);
00148 }
00149
00150 RunManager::~RunManager()
00151 {
00152 if (m_kernel!=0) delete m_kernel;
00153 }
00154
00155 void RunManager::initG4(const edm::EventSetup & es)
00156 {
00157 if (m_managerInitialized) return;
00158
00159
00160 edm::ESHandle<DDCompactView> pDD;
00161 es.get<IdealGeometryRecord>().get(pDD);
00162
00163 G4LogicalVolumeToDDLogicalPartMap map_;
00164 SensitiveDetectorCatalog catalog_;
00165 const DDDWorld * world = new DDDWorld(&(*pDD), map_, catalog_, m_check);
00166 m_registry.dddWorldSignal_(world);
00167
00168 if (m_pUseMagneticField)
00169 {
00170
00171 edm::ESHandle<MagneticField> pMF;
00172 es.get<IdealMagneticFieldRecord>().get(pMF);
00173 const GlobalPoint g(0.,0.,0.);
00174
00175
00176 m_fieldBuilder = std::auto_ptr<sim::FieldBuilder>(new sim::FieldBuilder(&(*pMF), m_pField));
00177 G4TransportationManager * tM = G4TransportationManager::GetTransportationManager();
00178 m_fieldBuilder->build( tM->GetFieldManager(),tM->GetPropagatorInField() ) ;
00179
00180 }
00181
00182
00183 m_trackManager = std::auto_ptr<SimTrackManager>(new SimTrackManager);
00184
00185 m_attach = new AttachSD;
00186 {
00187 std::pair< std::vector<SensitiveTkDetector*>,
00188 std::vector<SensitiveCaloDetector*> > sensDets = m_attach->create(*world,(*pDD),catalog_,m_p,m_trackManager.get(),m_registry);
00189
00190 m_sensTkDets.swap(sensDets.first);
00191 m_sensCaloDets.swap(sensDets.second);
00192 }
00193
00194
00195 edm::LogInfo("SimG4CoreApplication") <<
00196 " RunManager: Sensitive Detector building finished; found " << m_sensTkDets.size()
00197 << " Tk type Producers, and " << m_sensCaloDets.size() << " Calo type producers ";
00198
00199
00200 m_generator = new Generator(m_pGenerator);
00201
00202 m_InTag = m_pGenerator.getParameter<std::string>("HepMCProductLabel") ;
00203 m_primaryTransformer = new PrimaryTransformer();
00204
00205 std::auto_ptr<PhysicsListMakerBase> physicsMaker(
00206 PhysicsListFactory::get()->create
00207 (m_pPhysics.getParameter<std::string> ("type")));
00208 if (physicsMaker.get()==0) throw SimG4Exception("Unable to find the Physics list requested");
00209 m_physicsList = physicsMaker->make(map_,m_pPhysics,m_registry);
00210 if (m_physicsList.get()==0) throw SimG4Exception("Physics list construction failed!");
00211 m_kernel->SetPhysics(m_physicsList.get());
00212 m_kernel->InitializePhysics();
00213
00214 m_physicsList->ResetStoredInAscii();
00215 std::string tableDir = m_PhysicsTablesDir;
00216 if (m_RestorePhysicsTables) m_physicsList->SetPhysicsTableRetrieved(tableDir);
00217
00218 if (m_kernel->RunInitialization()) m_managerInitialized = true;
00219 else throw SimG4Exception("G4RunManagerKernel initialization failed!");
00220
00221 if (m_StorePhysicsTables)
00222 {
00223 std::ostrstream dir;
00224 dir << tableDir << '\0';
00225 std::string cmd = std::string("/control/shell mkdir -p ")+tableDir;
00226 if (!std::ifstream(dir.str(), std::ios::in))
00227 G4UImanager::GetUIpointer()->ApplyCommand(cmd);
00228 m_physicsList->StorePhysicsTable(tableDir);
00229 }
00230
00231
00232 BeginOfJob aBeginOfJob(&es);
00233 m_registry.beginOfJobSignal_(&aBeginOfJob);
00234
00235 initializeUserActions();
00236
00237 for (unsigned it=0; it<m_G4Commands.size(); it++) {
00238 edm::LogInfo("SimG4CoreApplication") << "RunManager:: Requests UI: "
00239 << m_G4Commands[it];
00240 G4UImanager::GetUIpointer()->ApplyCommand(m_G4Commands[it]);
00241 }
00242
00243 initializeRun();
00244
00245 }
00246
00247 void RunManager::produce(edm::Event& inpevt, const edm::EventSetup & es)
00248 {
00249 m_currentEvent = generateEvent(inpevt);
00250 m_simEvent = new G4SimEvent;
00251 m_simEvent->hepEvent(m_generator->genEvent());
00252 m_simEvent->weight(m_generator->eventWeight());
00253 if (m_generator->genVertex()!=0)
00254 m_simEvent->collisionPoint(math::XYZTLorentzVectorD(m_generator->genVertex()->x()/centimeter,
00255 m_generator->genVertex()->y()/centimeter,
00256 m_generator->genVertex()->z()/centimeter,
00257 m_generator->genVertex()->t()/second));
00258
00259 if (m_currentEvent->GetNumberOfPrimaryVertex()==0)
00260 {
00261
00262 edm::LogError("SimG4CoreApplication")
00263 << " RunManager::produce event " << inpevt.id().event()
00264 << " with no G4PrimaryVertices \n Aborting Run" ;
00265
00266 abortRun(false);
00267 }
00268 else
00269 m_kernel->GetEventManager()->ProcessOneEvent(m_currentEvent);
00270
00271
00272 edm::LogInfo("SimG4CoreApplication")
00273 << " RunManager: saved : Event " << inpevt.id().event() << " of weight " << m_simEvent->weight()
00274 << " with " << m_simEvent->nTracks() << " tracks and " << m_simEvent->nVertices()
00275 << " vertices, generated by " << m_simEvent->nGenParts() << " particles " ;
00276
00277 }
00278
00279 G4Event * RunManager::generateEvent(edm::Event & inpevt)
00280 {
00281
00282 if (m_currentEvent!=0) delete m_currentEvent;
00283 m_currentEvent = 0;
00284 if (m_simEvent!=0) delete m_simEvent;
00285 m_simEvent = 0;
00286 G4Event * e = new G4Event(inpevt.id().event());
00287
00288
00289 edm::Handle<edm::HepMCProduct> HepMCEvt;
00290
00291
00292
00293 inpevt.getByLabel( m_InTag, HepMCEvt ) ;
00294
00295
00296
00297 if (!HepMCEvt.isValid())
00298 {
00299 throw SimG4Exception("Unable to find HepMCProduct(HepMC::GenEvent) in edm::Event ");
00300 }
00301 else
00302 {
00303 m_generator->setGenEvent(HepMCEvt->GetEvent());
00304 if (!m_nonBeam)
00305 {
00306 m_generator->HepMC2G4(HepMCEvt->GetEvent(),e);
00307 }
00308 else
00309 {
00310 m_generator->nonBeamEvent2G4(HepMCEvt->GetEvent(),e);
00311 }
00312 }
00313
00314 return e;
00315
00316 }
00317
00318 void RunManager::abortEvent()
00319 {
00320
00321 G4Track* t =
00322 m_kernel->GetEventManager()->GetTrackingManager()->GetTrack();
00323 t->SetTrackStatus(fStopAndKill) ;
00324
00325
00326
00327 TrackingAction* uta =
00328 (TrackingAction*)m_kernel->GetEventManager()->GetUserTrackingAction() ;
00329 uta->PostUserTrackingAction(t) ;
00330
00331 m_currentEvent->SetEventAborted();
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 m_kernel->GetEventManager()->GetStackManager()->clear() ;
00345 m_kernel->GetEventManager()->GetTrackingManager()->EventAborted() ;
00346
00347 G4StateManager* stateManager = G4StateManager::GetStateManager();
00348 stateManager->SetNewState(G4State_GeomClosed);
00349
00350 return ;
00351
00352 }
00353
00354 void RunManager::initializeUserActions()
00355 {
00356
00357 RunAction* userRunAction = new RunAction(m_pRunAction,this);
00358 m_userRunAction = userRunAction;
00359 userRunAction->m_beginOfRunSignal.connect(m_registry.beginOfRunSignal_);
00360 userRunAction->m_endOfRunSignal.connect(m_registry.endOfRunSignal_);
00361
00362 G4EventManager * eventManager = m_kernel->GetEventManager();
00363 eventManager->SetVerboseLevel(m_EvtMgrVerbosity);
00364 if (m_generator!=0)
00365 {
00366 EventAction * userEventAction = new EventAction(m_pEventAction,this,m_trackManager.get());
00367
00368 userEventAction->m_beginOfEventSignal.connect(m_registry.beginOfEventSignal_);
00369 userEventAction->m_endOfEventSignal.connect(m_registry.endOfEventSignal_);
00370 eventManager->SetUserAction(userEventAction);
00371 TrackingAction* userTrackingAction = new TrackingAction(userEventAction,m_pTrackingAction);
00372 userTrackingAction->m_beginOfTrackSignal.connect(m_registry.beginOfTrackSignal_);
00373 userTrackingAction->m_endOfTrackSignal.connect(m_registry.endOfTrackSignal_);
00374 eventManager->SetUserAction(userTrackingAction);
00375
00376 SteppingAction* userSteppingAction = new SteppingAction(userEventAction,m_pSteppingAction);
00377 userSteppingAction->m_g4StepSignal.connect(m_registry.g4StepSignal_);
00378 eventManager->SetUserAction(userSteppingAction);
00379 if (m_Override)
00380 {
00381 edm::LogInfo("SimG4CoreApplication") << " RunManager: user StackingAction overridden " ;
00382 eventManager->SetUserAction(new StackingAction(m_pStackingAction));
00383 }
00384 }
00385 else
00386 {
00387 edm::LogWarning("SimG4CoreApplication") << " RunManager: WARNING : No generator; initialized only RunAction!";
00388 }
00389
00390 return;
00391
00392 }
00393
00394 void RunManager::initializeRun()
00395 {
00396
00397 m_runInitialized = false;
00398 if (m_currentRun==0) m_currentRun = new G4Run();
00399
00400 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
00401 if (m_userRunAction!=0) m_userRunAction->BeginOfRunAction(m_currentRun);
00402 m_runAborted = false;
00403 m_runInitialized = true;
00404
00405 return ;
00406
00407 }
00408
00409 void RunManager::terminateRun()
00410 {
00411
00412 m_runTerminated = false;
00413 if (m_userRunAction!=0)
00414 {
00415 m_userRunAction->EndOfRunAction(m_currentRun);
00416 delete m_userRunAction; m_userRunAction = 0;
00417 }
00418 if (m_currentRun!=0) { delete m_currentRun; m_currentRun = 0; }
00419 if (m_kernel!=0) m_kernel->RunTermination();
00420 m_runInitialized = false;
00421 m_runTerminated = true;
00422
00423 return;
00424
00425 }
00426
00427 void RunManager::abortRun(bool softAbort)
00428 {
00429
00430 m_runAborted = false;
00431 if (!softAbort) abortEvent();
00432 if (m_currentRun!=0) { delete m_currentRun; m_currentRun = 0; }
00433 m_runInitialized = false;
00434 m_runAborted = true;
00435
00436 return;
00437
00438 }
00439