| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

DetSimProc.cc

Go to the documentation of this file.
00001 
00002 #include "DetSimProc.h"
00003 
00005 #include "G4DataHelpers/G4DhHit.h"
00006 
00007 #include "Event/GenHeader.h"
00008 
00009 #include "GiGa/IGiGaSvc.h"
00010 #include "G4DataHelpers/IHistoryKeeper.h"
00011 
00012 #include "G4Event.hh"
00013 #include "G4PrimaryVertex.hh"
00014 
00016 #include "G4DataHelpers/IHepMCtoG4.h"
00017 
00018 #include "Event/GenHeader.h"
00019 
00021 #include "MuonProphet/MpMuonFate.h"
00022 
00023 DetSimProc::DetSimProc(const std::string& name, ISvcLocator* pSvcLocator)
00024     : StageProcessor<DayaBay::SimHeader>(name,pSvcLocator)
00025     , m_giga(0)
00026     , m_converter(0)
00027     , m_historyKeeper(0)
00028     , m_genPrune(0)
00029 {
00030   DS_constructor();
00031 
00032   // Auxiliary
00033   declareProperty("GenPruneName",m_genPruneName = "GenPruneTool", "Name of GenHeader pruner");
00034 
00035 }
00036 
00037 DetSimProc::~DetSimProc()
00038 {
00039   DS_destructor();
00040 }
00041 
00042 StatusCode DetSimProc::initialize()
00043 {
00044   StatusCode sc = this->StageProcessor<DayaBay::SimHeader>::initialize();
00045   if (sc.isFailure()) return sc;
00046 
00047   debug()<<"DetSimProc"<<endreq;
00048 
00049   sc = DS_initialize();
00050   if (sc.isFailure()) return sc;
00051 
00052   // Although initialized to 0, however, no special meaning
00053   m_CurrentTime=0;
00054   m_SimDataList.clear();
00055 
00056   m_Start=true;
00057 
00058   // Auxiliary
00059   m_genPrune = tool<IGenPruneTool>(m_genPruneName);
00060   if( !m_genPrune ) {
00061     error() << "Failed to retrive GenPruneTool" << endreq;
00062     return StatusCode::FAILURE;
00063   }
00064 
00065   return StatusCode::SUCCESS;
00066 }
00067 
00068 StatusCode DetSimProc::execute()
00069 {
00070   debug()<<"DetSimProc"<<endreq;
00071 
00072   SimData::DataList::iterator psimdatalist;
00073 
00074   FFTimeStamp tm(0,0);
00075   FFTimeStamp dt(0,0); 
00076   FFTimeStamp localtime(0,0);
00077 
00079   if(lowerStage()) {
00082     debug() << "Consumer&Producer" << endreq;
00083     if(m_Start||m_CurrentTime<=thisStage()->currentTime()) {
00084 
00087       if(m_Start) {
00088         // nothing to do here
00089       } else {
00090         psimdatalist=m_SimDataList.begin();
00091         localtime=psimdatalist->first;
00092       }
00093 
00095       //debug()<<"A: local time= "<<localtime<<endreq;
00096       //debug()<<"A: lower stage time= "<<m_LowerStage->currentTime()<<endreq;
00097       while(m_Start||localtime>=lowerStage()->currentTime()) {
00098         m_Start=false;
00100         //debug() << "In while loop, pulling data from lower Stage ......" << endreq;
00101 
00102         IStageData* pIStageData=0;
00103         StatusCode sc = lowerStage()->nextElement(pIStageData);  // pulling out
00104         if (sc.isFailure()) {
00105           error() << "Failed to pull kinematics" << endreq;
00106           return sc;
00107         }
00108         
00109         GnrtrData* pGnrtrData=0;
00110         try{
00111           pGnrtrData = dynamic_cast<GnrtrData*>(pIStageData);
00112         }
00113         catch(...) {
00114           error() << "Failed to get GnrtrData pointer" <<endreq;
00115         }
00116 
00117         //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00124         // delete the used one
00125         tm=pGnrtrData->time();
00126         //debug() << "data pulled out from lower stage has time: "<<tm<<endreq;
00127 
00129         preExecute();
00130         SimData*   pSimData=0;   
00131         DS_execute(pGnrtrData,pSimData);
00132         this->AppendInputHeader(&pGnrtrData->header());
00134         //m_genPrune->prune( &pGnrtrData->header() );
00135         //
00136         postExecute();
00137         delete pGnrtrData; pGnrtrData=0;
00138 
00139         //debug() << "new data generated at time: "<< pSimData->time()<< endreq;
00141         //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
00142 
00143         // push back into a local store
00144         m_SimDataList.insert(SimData::DataList::value_type(pSimData->time(),pSimData));
00145 
00147         psimdatalist=m_SimDataList.begin();
00148         localtime=psimdatalist->first;
00149         //debug()<<"B: local time= "<<localtime<<endreq;
00150         //debug()<<"B: lower stage time= "<<m_LowerStage->currentTime()<<endreq;        
00151       }
00152 
00153       m_CurrentTime=localtime;
00154       //debug() << "m_CurrentTime= "<< m_CurrentTime << endreq;
00155 
00158       psimdatalist=m_SimDataList.begin();
00159       debug() << "to grep: new data pushed out at time " << psimdatalist->first << endreq;
00160       thisStage()->pushElement(psimdatalist->second);
00161       this->registerData(*(psimdatalist->second));
00162       m_SimDataList.erase(psimdatalist);
00163 
00165     }
00166   }
00167   return StatusCode::SUCCESS;  
00168 }
00169 
00170 StatusCode DetSimProc::finalize()
00171 {
00172   DS_finalize();
00173 
00174   return StatusCode::SUCCESS;
00175 }
00176 
00178 void DetSimProc::DS_constructor()
00179 {
00181   declareProperty("Converter",m_converterName="HepMCtoG4",
00182                   "Name of tool to convert HepMCEvents to G4PrimaryVertex");
00183 
00185   declareProperty("GenLocation",m_genLocation=DayaBay::GenHeaderLocation::Default,
00186                   "Location in the TES where the input GenHeader is to be found.");
00187 }
00188 
00189 void DetSimProc::DS_destructor()
00190 {}
00191 
00192 StatusCode DetSimProc::DS_initialize()
00193 {
00195 
00196   m_giga = svc<IGiGaSvc>("GiGa",true);
00197   try {
00198     m_converter = tool<IHepMCtoG4>(m_converterName);
00199   }
00200   catch (const GaudiException& gex) {
00201     fatal() << "Failed to get converter tool \""
00202             << m_converterName << "\"" << endreq;
00203     return StatusCode::FAILURE;
00204   }
00205 
00207   m_historyKeeper = svc<IHistoryKeeper>("HistoryKeeper",true);
00208 
00209   return StatusCode::SUCCESS;
00210 }
00211 
00212 StatusCode DetSimProc::DS_execute(GnrtrData* p_input, SimData*& p_output)
00213 {
00216 
00218 //DayaBay::GenHeader* gen_header = get<DayaBay::GenHeader>(m_location);
00219   DayaBay::GenHeader* gen_header = &p_input->header();
00220 
00221   //debug()<<"genheader, timeStamp: "<<gen_header->timeStamp()<<endreq;
00222   //debug()<<"genheader, earliest: "<<gen_header->earliest()<<endreq;
00223 
00224   HepMC::GenEvent* genevt = gen_header->event();
00225   std::vector<G4PrimaryVertex*> g4verts;
00226   m_converter->convert(*genevt,g4verts);
00227 
00228   debug() << "Got " << g4verts.size() << " primary vertices" << endreq;
00229 
00230   for (size_t ind=0; ind < g4verts.size(); ++ind) {
00231 
00232     *m_giga << g4verts[ind];
00233 
00234   }
00235 
00236   debug() << "Pushed " << gen_header->generatorName()
00237          << " to giga" << endreq;
00238 
00240   DayaBay::SimHeader* header = MakeHeaderObject();
00241 
00242   // Just pass through GenHeader's timestamp.  This also causes
00243   // GenHeader to be registered as input, something that would
00244   // normally just happen if DsPushKine and DsPullEvent were the
00245   // same algorithm.
00246   //  DayaBay::GenHeader* gen_header = getTES<DayaBay::GenHeader>(m_genLocation);
00247   header->setTimeStamp(gen_header->timeStamp());
00248 
00250   // Primary event vertices.
00251   const G4Event* g4event = 0;
00252   m_giga->retrieveEvent(g4event);
00253   if (!g4event) {
00254     error() << "No G4Event!" << endreq;
00255     return StatusCode::FAILURE;
00256   }
00257 
00258   int nverts = g4event->GetNumberOfPrimaryVertex();
00259   if( nverts == 0 ) {
00260     warning() << "The g4event has zero primary vertices!" << endreq;
00261   }
00262   debug() << "Pulled event with " << nverts
00263          << " primary vertices, event id:" << g4event->GetEventID() << endreq;
00264 
00265   G4PrimaryVertex* g4vtx = g4event->GetPrimaryVertex(0);
00266   while (g4vtx) {
00267     debug() << "\n\tat (" << g4vtx->GetX0() << "," << g4vtx->GetY0() << "," << g4vtx->GetZ0() << ")";
00268     g4vtx = g4vtx->GetNext();
00269     break;
00270   }
00271   debug() << endreq;
00272 
00274   // particle histories.
00275   // Do this first so we can use it below.
00276   DayaBay::SimParticleHistory* history =0;
00277   m_historyKeeper->ClaimCurrentHistory(history); // This takes ownership from the Keeper.
00278   header->setParticleHistory(history);
00279 
00281   // Unobservable Statistics
00282   DayaBay::SimUnobservableStatisticsHeader* unobs =0;
00283   m_historyKeeper->ClaimCurrentUnobservable(unobs); // This takes ownership from the Keeper.
00284   header->setUnobservableStatistics(unobs);
00285 
00286   // introduce the headers to each other
00287   DayaBay::SimHitHeader* hit_header = 0;
00288 
00289   double earliestTime = 0;
00290   double latestTime = 0;
00291   Context context;
00292   context.SetSimFlag(SimFlag::kMC);
00293   bool firstDetector = true;
00294   int hitcount=0;  // deal with no hits situation
00295 
00297   // Hit collections.
00298   G4HCofThisEvent* hcs = g4event->GetHCofThisEvent();
00299   if (!hcs) {
00300     debug() << "No HitCollections in this event" << endreq;
00301   }  else  {
00302     int nhc = hcs->GetNumberOfCollections();
00303     if (!nhc) {
00304       debug() << "Number of HitCollections is zero" << endreq;
00305     }  else  {
00306       debug () << "# HitCollections = " << nhc << endreq;
00307 
00309       hit_header = new DayaBay::SimHitHeader(header);
00310       for (int ihc=0; ihc<nhc; ++ihc) {
00311         G4DhHitCollection* g4hc = dynamic_cast<G4DhHitCollection*>(hcs->GetHC(ihc));
00312         if (!g4hc) {
00313           error() << "Failed to get hit collection #" << ihc << endreq;
00314           return StatusCode::FAILURE;
00315         }
00316         
00317         // DetSim produces hit collections even for unsimulated detectors
00318         size_t nhits = g4hc->GetSize();
00319         hitcount+=nhits;
00320         if (!nhits) continue;
00321         
00322         bool firstHit = true;
00323         DayaBay::SimHitCollection::hit_container hits;
00324         DayaBay::Detector detector;
00325         DayaBay::SimHitCollection* shc =
00326           new DayaBay::SimHitCollection(hit_header,detector,hits);
00327         for (size_t ihit=0; ihit<nhits; ++ihit) {
00328           DayaBay::SimHit* simhit = (*g4hc)[ihit]->get();
00329 
00330           // A protection on time overflow or underflow.
00331           // Kill the hit over two years.
00332           // It is impossible to simulate them with full Geant4 simulation.
00333           // See Trac#489.
00334           if( abs(simhit->hitTime()) > 6.3e16 ) {
00335             warning() << "Eccentric long hit time "<<simhit->hitTime()<<"ns. Skipped."<<endreq;
00336             hitcount--;
00337             continue;
00338           }
00339 
00340           if(history) {
00341             int trackid = (*g4hc)[ihit]->trackId();
00342             simhit->setAncestor(history->track(trackid));
00343           }
00344           // Set detector and site using first hit
00345           if(firstHit){
00346             detector = DayaBay::Detector(simhit->sensDetId()).siteDetPackedData();
00347             if(firstDetector){
00348               // Keep track of sites/detectors in this simulation for context
00349               context.SetSite(detector.site());
00350               context.SetDetId(detector.detectorId());
00351             }
00352             if(context.GetSite() != detector.site()){
00353               // Simulation contains multiple sites, unset
00354               context.SetSite(Site::kUnknown);
00355             }
00356             if(context.GetDetId() != detector.detectorId()){
00357               // Simulation contains multiple detectors, unset
00358               context.SetDetId(DetectorId::kUnknown);
00359             }
00360           }
00361           // Record earliest/latest simhit
00362           debug() << "Hit Time: " << simhit->hitTime() << endreq;
00363           if((firstHit && firstDetector) || simhit->hitTime() < earliestTime)
00364             earliestTime = simhit->hitTime();
00365           if((firstHit && firstDetector) || simhit->hitTime() > latestTime)
00366             latestTime = simhit->hitTime();
00367           firstHit = false;
00368 
00369           simhit->setHc(shc);
00370           hits.push_back(simhit);
00371         }
00372         firstDetector = false;
00373         
00374         shc->setDetector(detector);
00375         shc->setCollection(hits);
00376         debug() << "Adding " << detector.detName() << " hits ("
00377                 << shc->collection().size() << ") to header." << endreq;
00378         hit_header->addHitCollection(shc);
00379       }
00380     }
00381   }
00382 
00383   header->setHits(hit_header);
00386   context.SetTimeStamp(gen_header->timeStamp());
00387   header->setContext(context);
00388 
00389   // Set header time range based on hit times
00390   debug() << "Header Time sec, nanosec: " << header->timeStamp().GetSec()
00391           << "  " << header->timeStamp().GetNanoSec() << endreq;
00392   debug() << "Earliest Hit: " << earliestTime << endreq;
00393   debug() << "Latest Hit: " << latestTime << endreq;
00394   TimeStamp earliestTS(header->timeStamp());
00395   TimeStamp latestTS(header->timeStamp());
00396   earliestTS.Add(earliestTime * 1e-9);
00397   latestTS.Add(latestTime * 1e-9);
00398   debug() << "Earliest Time sec, nanosec: " << earliestTS.GetSec()
00399           << "  " << earliestTS.GetNanoSec() << endreq;
00400   debug() << "Latest Time sec, nanosec: " << latestTS.GetSec()
00401           << "  " << latestTS.GetNanoSec() << endreq;
00402   header->setEarliest(earliestTS);
00403   header->setLatest(latestTS);
00404   debug() << "Earliest Time sec, nanosec: " << header->earliest().GetSec()
00405           << "  " << header->earliest().GetNanoSec() << endreq;
00406   debug() << "Latest Time sec, nanosec: " << header->latest().GetSec()
00407           << "  " << header->latest().GetNanoSec() << endreq;
00408 
00411   HepMC::GenEvent::particle_const_iterator pci, pci_end = genevt->particles_end();
00412 
00413   for( pci = genevt->particles_begin(); pci != pci_end; ++pci ) {
00414     if( (*pci)->pdg_id() == 13 || (*pci)->pdg_id() == -13 ) {   // muon                                            
00415       if( (*pci)->status() != MpMuonFate::kNeedSim ) {   //  geant4-noble particle
00416         header->setEarliest(gen_header->timeStamp());
00417       }
00418     }
00419   }
00420 
00421   if(hitcount==0) {  // when there is no hit, set time stamp to genheader's earliest() to save causality
00422     header->setTimeStamp(gen_header->earliest());
00423     header->setEarliest(gen_header->earliest());
00424     header->setLatest(gen_header->earliest());
00425   }
00426 
00428   p_output=new SimData(*header);
00429 
00430   return StatusCode::SUCCESS;
00431 
00432 }
00433 
00434 StatusCode DetSimProc::DS_finalize()
00435 {
00436   return StatusCode::SUCCESS;
00437 }
00438 
00439 
00440 // Local Variables:
00441 // c-basic-offset: 2
00442 // End:
00443 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 21:03:43 2011 for DetSimProc by doxygen 1.4.7