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