CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimG4Core/Application/src/SimTrackManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Application
00004 // Class  :     SimTrackManager
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  
00010 //         Created:  Fri Nov 25 17:44:19 EST 2005
00011 // $Id: SimTrackManager.cc,v 1.21 2012/04/02 12:24:43 davidlt Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 
00017 // user include files
00018 #include "SimG4Core/Application/interface/SimTrackManager.h"
00019 #include "SimG4Core/Application/interface/G4SimTrack.h"
00020 #include "SimG4Core/Application/interface/G4SimVertex.h"
00021 
00022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00023 
00024 //#define DebugLog
00025 
00026 //
00027 // constants, enums and typedefs
00028 //
00029 
00030 //
00031 // static data member definitions
00032 //
00033 
00034 //
00035 // constructors and destructor
00036 //
00037 SimTrackManager::SimTrackManager(bool iCollapsePrimaryVertices) :
00038   m_trksForThisEvent(0),m_nVertices(0),
00039   m_collapsePrimaryVertices(iCollapsePrimaryVertices),
00040   lastTrack(0),lastHist(0),theLHCTlink(0){}
00041 
00042 
00043 SimTrackManager::~SimTrackManager()
00044 {
00045   if ( m_trksForThisEvent != 0 ) deleteTracks() ;
00046 }
00047 
00048 //
00049 // assignment operators
00050 //
00051 // const SimTrackManager& SimTrackManager::operator=(const SimTrackManager& rhs)
00052 // {
00053 //   //An exception safe implementation is
00054 //   SimTrackManager temp(rhs);
00055 //   swap(rhs);
00056 //
00057 //   return *this;
00058 // }
00059 
00060 //
00061 // member functions
00062 //
00063 void SimTrackManager::reset()
00064 {
00065   if (m_trksForThisEvent==0) m_trksForThisEvent = new TrackContainer();
00066   else
00067     {
00068       for (unsigned int i = 0; i < m_trksForThisEvent->size(); i++) 
00069         delete (*m_trksForThisEvent)[i];
00070       delete m_trksForThisEvent;
00071       m_trksForThisEvent = new TrackContainer();
00072     }
00073   cleanVertexMap();
00074   cleanTkCaloStateInfoMap();
00075   std::vector<std::pair <int, int> >().swap(idsave);
00076   ancestorList.clear();
00077   lastTrack=0;
00078   lastHist=0;
00079 }
00080 
00081 void SimTrackManager::deleteTracks()
00082 {
00083   for (unsigned int i = 0; i < m_trksForThisEvent->size(); i++) delete (*m_trksForThisEvent)[i];
00084   delete m_trksForThisEvent;
00085   m_trksForThisEvent = 0;
00086 }
00087 
00089 void SimTrackManager::saveTrackAndItsBranch(TrackWithHistory * trkWHist)
00090 {
00091   using namespace std;
00092   TrackWithHistory * trkH = trkWHist;
00093   if (trkH == 0)
00094     {
00095       edm::LogError("SimTrackManager") << " SimTrackManager::saveTrackAndItsBranch got 0 pointer ";
00096       abort();
00097     }
00098   trkH->save();
00099   unsigned int parent = trkH->parentID();
00100   bool parentExists=false;
00101   
00102   TrackContainer::const_iterator tk_itr = std::lower_bound((*m_trksForThisEvent).begin(),(*m_trksForThisEvent).end(),
00103                                                            parent,SimTrackManager::StrictWeakOrdering());
00104 
00105   TrackWithHistory * tempTk = *tk_itr;
00106   //  TrackWithHistory * tempTk = new TrackWithHistory(**tk_itr);
00107   if (tk_itr!=m_trksForThisEvent->end() && (*tk_itr)->trackID()==parent) { 
00108     parentExists=true;  
00109   }
00110   
00111   if (parentExists) saveTrackAndItsBranch(tempTk);
00112   
00113   //  delete tempTk;
00114   
00115 }
00116 
00117 void SimTrackManager::storeTracks(G4SimEvent* simEvent)
00118 {
00119   cleanTracksWithHistory();
00120 
00121   // fill the map with the final mother-daughter relationship
00122   idsave.swap(ancestorList);
00123   stable_sort(idsave.begin(),idsave.end());
00124 
00125   std::vector<std::pair<int,int> >().swap(ancestorList);
00126 
00127   // to get a backward compatible order
00128   stable_sort(m_trksForThisEvent->begin(),m_trksForThisEvent->end(),trkIDLess());
00129 
00130   // to reset the GenParticle ID of a SimTrack to its pre-LHCTransport value
00131   resetGenID();
00132 
00133   reallyStoreTracks(simEvent);
00134 }
00135 
00136 void SimTrackManager::reallyStoreTracks(G4SimEvent * simEvent)
00137 {
00138   // loop over the (now ordered) vector and really save the tracks
00139 #ifdef DebugLog
00140   LogDebug("SimTrackManager")  << "Inside the reallyStoreTracks method object to be stored = " 
00141                                << m_trksForThisEvent->size();
00142 #endif 
00143  
00144   for (unsigned int it = 0; it < m_trksForThisEvent->size(); it++)
00145     {
00146       TrackWithHistory * trkH = (*m_trksForThisEvent)[it];
00147       // at this stage there is one vertex per track, so the vertex id of track N is also N
00148       int ivertex = -1;
00149       int ig;
00150       
00151       math::XYZVectorD pm(0.,0.,0.);
00152       unsigned int iParentID = trkH->parentID();
00153       for(unsigned int iit = 0; iit < m_trksForThisEvent->size(); iit++)
00154         {
00155           if((*m_trksForThisEvent)[iit]->trackID()==iParentID){
00156             pm = (*m_trksForThisEvent)[iit]->momentum();
00157             break;
00158           }
00159         }
00160       ig = trkH->genParticleID();
00161       ivertex = getOrCreateVertex(trkH,iParentID,simEvent);
00162       std::map<uint32_t,std::pair<math::XYZVectorD,math::XYZTLorentzVectorD> >::const_iterator cit = mapTkCaloStateInfo.find(trkH->trackID());
00163       std::pair<math::XYZVectorD,math::XYZTLorentzVectorD> tcinfo;
00164       if (cit !=  mapTkCaloStateInfo.end()){
00165         tcinfo = cit->second;
00166       }
00167       simEvent->add(new G4SimTrack(trkH->trackID(),trkH->particleID(),
00168                                    trkH->momentum(),trkH->totalEnergy(),ivertex,ig,pm,tcinfo.first,tcinfo.second));
00169     }
00170 }
00171 
00172 int SimTrackManager::getOrCreateVertex(TrackWithHistory * trkH, int iParentID,
00173                                        G4SimEvent * simEvent){
00174   
00175   int parent = iParentID;
00176   int check = -1;
00177   
00178   for( std::vector<TrackWithHistory*>::const_iterator it = (*m_trksForThisEvent).begin(); 
00179        it!= (*m_trksForThisEvent).end();it++){
00180     if ((*it)->trackID() == uint32_t(parent)){
00181       check = 0;
00182       break;
00183     }
00184   }
00185   
00186   if(check==-1) parent = -1;
00187   
00188   VertexMap::const_iterator iterator = m_vertexMap.find(parent);
00189   if (iterator != m_vertexMap.end()){
00190     // loop over saved vertices
00191     for (unsigned int k=0; k<m_vertexMap[parent].size(); k++){
00192       if (sqrt((trkH->vertexPosition()-(((m_vertexMap[parent])[k]).second)).Mag2())<0.001)
00193         return (((m_vertexMap[parent])[k]).first);
00194     }
00195   }
00196   
00197   simEvent->add(new G4SimVertex(trkH->vertexPosition(),trkH->globalTime(),parent));
00198   m_vertexMap[parent].push_back(MapVertexPosition(m_nVertices,trkH->vertexPosition()));
00199   m_nVertices++;
00200   return (m_nVertices-1);
00201   
00202 }
00203 
00204 void SimTrackManager::cleanVertexMap() { 
00205   m_vertexMap.clear();
00206   MotherParticleToVertexMap().swap(m_vertexMap);
00207   m_nVertices=0; 
00208 }
00209 
00210 void SimTrackManager::cleanTkCaloStateInfoMap() { 
00211   mapTkCaloStateInfo.clear();
00212   std::map<uint32_t,std::pair<math::XYZVectorD,math::XYZTLorentzVectorD > >().swap(mapTkCaloStateInfo);
00213 }
00214 
00215 int SimTrackManager::idSavedTrack (int i) const
00216 {
00217 
00218   int id = 0;  
00219   if (i > 0) {
00220     for (unsigned int itr=0; itr<idsave.size(); itr++) { if ((idsave[itr]).first == i) { id = (idsave[itr]).second; break; } }
00221       if (id != i) return idSavedTrack(id);
00222       id = i;
00223   }
00224   return id;
00225 }
00226 
00227 
00228 void SimTrackManager::fillMotherList() {
00229 
00230   if ( ancestorList.size() > 0 && lastHist > ancestorList.size() ) {
00231     lastHist = ancestorList.size();
00232     edm::LogError("SimTrackManager") << " SimTrackManager::fillMotherList track index corrupted";
00233   }
00234 
00235   for (unsigned int n = lastHist; n < ancestorList.size(); n++) { 
00236     
00237     int theMotherId = idSavedTrack((ancestorList[n]).first);
00238     ancestorList[n].second = theMotherId;
00239 #ifdef DebugLog
00240     LogDebug("SimTrackManager")  << "Track ID = " << (ancestorList[n]).first << " Mother ID = " << (ancestorList[n]).second;
00241 #endif    
00242   }
00243 
00244   lastHist = ancestorList.size();
00245 
00246   idsave.clear();
00247 
00248 }
00249 
00250 void SimTrackManager::cleanTracksWithHistory(){
00251 
00252   using namespace std;
00253 
00254   if ((*m_trksForThisEvent).size() == 0 && idsave.size() == 0) return;
00255 
00256 #ifdef DebugLog
00257   LogDebug("SimTrackManager") << "SimTrackManager::cleanTracksWithHistory has " << idsave.size() 
00258                               << " mother-daughter relationships stored with lastTrack = " << lastTrack;
00259 #endif
00260 
00261   if ( lastTrack > 0 && lastTrack >= (*m_trksForThisEvent).size() ) {
00262     lastTrack = 0;
00263     edm::LogError("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory track index corrupted";
00264   }
00265   
00266   stable_sort(m_trksForThisEvent->begin()+lastTrack,m_trksForThisEvent->end(),trkIDLess());
00267   
00268   stable_sort(idsave.begin(),idsave.end());
00269   
00270 #ifdef DebugLog
00271   LogDebug("SimTrackManager")  << " SimTrackManager::cleanTracksWithHistory knows " << m_trksForThisEvent->size()
00272                                << " tracks with history before branching";
00273   for (unsigned int it =0;  it <(*m_trksForThisEvent).size(); it++)
00274     LogDebug("SimTrackManager")   << " 1 - Track in position " << it << " G4 track number "
00275                                   << (*m_trksForThisEvent)[it]->trackID()
00276                                   << " mother " << (*m_trksForThisEvent)[it]->parentID()
00277                                   << " status " << (*m_trksForThisEvent)[it]->saved();
00278 #endif  
00279 
00280   for (unsigned int it = lastTrack; it < m_trksForThisEvent->size(); it++)
00281     {
00282       TrackWithHistory * t = (*m_trksForThisEvent)[it];
00283       if (t->saved()) saveTrackAndItsBranch(t);
00284     }
00285   unsigned int num = lastTrack;
00286   for (unsigned int it = lastTrack; it < m_trksForThisEvent->size(); it++)
00287     {
00288       TrackWithHistory * t = (*m_trksForThisEvent)[it];
00289       int g4ID = t->trackID();
00290       if (t->saved() == true)
00291         {
00292           if (it>num) (*m_trksForThisEvent)[num] = t;
00293           num++;
00294           for (unsigned int itr=0; itr<idsave.size(); itr++) { 
00295             if ((idsave[itr]).first == g4ID) { 
00296               (idsave[itr]).second = g4ID; break; } 
00297           }
00298         }
00299       else 
00300         {       
00301           delete t;
00302         }
00303     }
00304   
00305   (*m_trksForThisEvent).resize(num);
00306   
00307 #ifdef DebugLog
00308   LogDebug("SimTrackManager")  << " AFTER CLEANING, I GET " << (*m_trksForThisEvent).size()
00309                                << " tracks to be saved persistently";
00310   for (unsigned int it = 0;  it < (*m_trksForThisEvent).size(); it++)
00311     LogDebug("SimTrackManager")   << " Track in position " << it
00312                                   << " G4 track number " << (*m_trksForThisEvent)[it]->trackID()
00313                                   << " mother " << (*m_trksForThisEvent)[it]->parentID()
00314                                   << " Status " << (*m_trksForThisEvent)[it]->saved();
00315 #endif  
00316 
00317   fillMotherList();
00318 
00319   lastTrack = (*m_trksForThisEvent).size();
00320 
00321 }
00322 
00323 void SimTrackManager::resetGenID() {
00324 
00325   if ( theLHCTlink == 0 ) return;
00326 
00327   for  (unsigned int it = 0; it < m_trksForThisEvent->size(); it++)
00328     {
00329       TrackWithHistory * trkH = (*m_trksForThisEvent)[it];
00330       int genParticleID_ = trkH->genParticleID();
00331       if ( genParticleID_ == -1 ) { continue; }
00332       else {
00333         for ( unsigned int itrlink = 0; itrlink < (*theLHCTlink).size(); itrlink++ ) {
00334           if ( (*theLHCTlink)[itrlink].afterHector() == genParticleID_ ) {
00335             trkH->setGenParticleID( (*theLHCTlink)[itrlink].beforeHector() );
00336             continue;
00337           }
00338         }
00339       }
00340     }
00341 
00342   theLHCTlink = 0;
00343 
00344 }