CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/SimG4Core/Application/src/RunManager.cc

Go to the documentation of this file.
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 // RunManager * RunManager::me = 0;
00101 /*
00102 RunManager * RunManager::init(edm::ParameterSet const & p)
00103 {
00104     if (me != 0) abort();
00105     me = new RunManager(p);
00106     return me;
00107 }
00108 
00109 RunManager * RunManager::instance() 
00110 {
00111     if (me==0) abort();
00112     return me;
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       //m_geometryInitialized(true), m_physicsInitialized(true),
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     //Look for an outside SimActivityRegistry
00150     // this is used by the visualization code
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   // DDDWorld: get the DDCV from the ES and use it to build the World
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       // setup the magnetic field
00201       edm::ESHandle<MagneticField> pMF;
00202       es.get<IdealMagneticFieldRecord>().get(pMF);
00203       const GlobalPoint g(0.,0.,0.);
00204 
00205       // m_fieldBuilder = std::auto_ptr<sim::FieldBuilder>(new sim::FieldBuilder(&(*pMF), map_, m_pField));
00206       m_fieldBuilder = (new sim::FieldBuilder(&(*pMF), m_pField));
00207       G4TransportationManager * tM = G4TransportationManager::GetTransportationManager();
00208       m_fieldBuilder->build( tM->GetFieldManager(),tM->GetPropagatorInField() ) ;
00209       // m_fieldBuilder->configure("MagneticFieldType",tM->GetFieldManager(),tM->GetPropagatorInField());
00210     }
00211 
00212   // we need the track manager now
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   // m_InTag = m_pGenerator.getParameter<edm::InputTag>("HepMCProductLabel") ;
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   //tell all interesting parties that we are beginning the job
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   // If the Geant4 particle table is needed, decomment the lines below
00276   //
00277   //  G4cout << "Output of G4ParticleTable DumpTable:" << G4endl;
00278   //  G4ParticleTable::GetParticleTable()->DumpTable("ALL");
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   // std::vector< edm::Handle<edm::HepMCProduct> > AllHepMCEvt;
00327   edm::Handle<edm::HepMCProduct> HepMCEvt;
00328   
00329   // inpevt.getByType(HepMCEvt);       
00330   // inpevt.getManyByType(AllHepMCEvt);
00331   inpevt.getByLabel( m_InTag, HepMCEvt ) ;
00332   
00333   // actually, it's a double protection - it's not even necessary 
00334   // because getByLabel will throw if the correct product isn't there         
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       // required to reset the GenParticle Id for particles transported along the beam pipe
00344       // to their original value for SimTrack creation
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     // CMS-specific act
00369     //
00370     TrackingAction* uta =
00371     (TrackingAction*)m_kernel->GetEventManager()->GetUserTrackingAction() ;
00372     uta->PostUserTrackingAction(t) ;
00373 
00374     m_currentEvent->SetEventAborted();
00375     
00376     // do NOT call this method for now
00377     // because it'll set abortRequested=true (withing G4EventManager)
00378     // this will make Geant4, in the event *next* after the aborted one
00379     // NOT to get the primamry, thus there's NOTHING to trace, and it goes
00380     // to the end of G4Event::DoProcessing(G4Event*), where abortRequested
00381     // will be reset to true again
00382     //    
00383     //m_kernel->GetEventManager()->AbortCurrentEvent();
00384     //
00385     // instead, mimic what it does, except (re)setting abortRequested
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         //userEventAction->SetRunManager(this) ;
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     // m_currentRun->SetRunID(m_RunNumber);   // run on default runID=0; doesn't matter...
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 }