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