CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_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 #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 // RunManager * RunManager::me = 0;
00102 /*
00103 RunManager * RunManager::init(edm::ParameterSet const & p)
00104 {
00105     if (me != 0) abort();
00106     me = new RunManager(p);
00107     return me;
00108 }
00109 
00110 RunManager * RunManager::instance() 
00111 {
00112     if (me==0) abort();
00113     return me;
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       //m_geometryInitialized(true), m_physicsInitialized(true),
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     //Look for an outside SimActivityRegistry
00151     // this is used by the visualization code
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   // DDDWorld: get the DDCV from the ES and use it to build the World
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       // setup the magnetic field
00202       edm::ESHandle<MagneticField> pMF;
00203       es.get<IdealMagneticFieldRecord>().get(pMF);
00204       const GlobalPoint g(0.,0.,0.);
00205 
00206       // m_fieldBuilder = std::auto_ptr<sim::FieldBuilder>(new sim::FieldBuilder(&(*pMF), map_, m_pField));
00207       m_fieldBuilder = (new sim::FieldBuilder(&(*pMF), m_pField));
00208       G4TransportationManager * tM = G4TransportationManager::GetTransportationManager();
00209       m_fieldBuilder->build( tM->GetFieldManager(),tM->GetPropagatorInField() ) ;
00210       // m_fieldBuilder->configure("MagneticFieldType",tM->GetFieldManager(),tM->GetPropagatorInField());
00211     }
00212 
00213   // we need the track manager now
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   // m_InTag = m_pGenerator.getParameter<edm::InputTag>("HepMCProductLabel") ;
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   // adding GFlash and Russian Roulette for eletrons and gamma
00249   // on top of any Physics Lists
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   //tell all interesting parties that we are beginning the job
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   // If the Geant4 particle table is needed, decomment the lines below
00285   //
00286   //  G4cout << "Output of G4ParticleTable DumpTable:" << G4endl;
00287   //  G4ParticleTable::GetParticleTable()->DumpTable("ALL");
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   // std::vector< edm::Handle<edm::HepMCProduct> > AllHepMCEvt;
00336   edm::Handle<edm::HepMCProduct> HepMCEvt;
00337   
00338   // inpevt.getByType(HepMCEvt);       
00339   // inpevt.getManyByType(AllHepMCEvt);
00340   inpevt.getByLabel( m_InTag, HepMCEvt ) ;
00341   
00342   // actually, it's a double protection - it's not even necessary 
00343   // because getByLabel will throw if the correct product isn't there         
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       // required to reset the GenParticle Id for particles transported along the beam pipe
00353       // to their original value for SimTrack creation
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     // CMS-specific act
00378     //
00379     TrackingAction* uta =
00380     (TrackingAction*)m_kernel->GetEventManager()->GetUserTrackingAction() ;
00381     uta->PostUserTrackingAction(t) ;
00382 
00383     m_currentEvent->SetEventAborted();
00384     
00385     // do NOT call this method for now
00386     // because it'll set abortRequested=true (withing G4EventManager)
00387     // this will make Geant4, in the event *next* after the aborted one
00388     // NOT to get the primamry, thus there's NOTHING to trace, and it goes
00389     // to the end of G4Event::DoProcessing(G4Event*), where abortRequested
00390     // will be reset to true again
00391     //    
00392     //m_kernel->GetEventManager()->AbortCurrentEvent();
00393     //
00394     // instead, mimic what it does, except (re)setting abortRequested
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         //userEventAction->SetRunManager(this) ;
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     // m_currentRun->SetRunID(m_RunNumber);   // run on default runID=0; doesn't matter...
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 }