Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

LCDG4LcioHelper.cc

Go to the documentation of this file.
00001 //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
00002 //
00003 // File: LCDG4LcioHelper.cc
00004 // Module: lcdg4
00005 //
00006 // Purpose:  Prepare LCIO data objects for persistency, and
00007 //      save them into an LCIO output file
00008 //
00009 // 20040805 - G.Lima - Created
00010 //
00011 //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
00012 #include "LCDG4LcioHelper.hh"
00013 #include "LCDG4McPartManager.hh"
00014 #include "G4ThreeVector.hh"
00015 #include "G4Event.hh"
00016 #include "G4Run.hh"
00017 
00018 #include "IO/LCWriter.h"
00019 #include "IMPL/LCRunHeaderImpl.h" 
00020 #include "IMPL/LCEventImpl.h"
00021 #include "IMPL/LCCollectionVec.h"
00022 #include "UTIL/LCTOOLS.h"
00023 using IMPL::LCEventImpl;
00024 using IMPL::LCCollectionVec;
00025 using UTIL::LCTOOLS;
00026 
00027 #include "EVENT/LCIO.h"
00028 #include "IMPL/SimCalorimeterHitImpl.h"
00029 #include "IMPL/SimTrackerHitImpl.h"
00030 using IMPL::SimCalorimeterHitImpl;
00031 using IMPL::SimTrackerHitImpl;
00032 
00033 #include "IOIMPL/LCFactory.h"
00034 using IMPL::SimCalorimeterHitImpl;
00035 using IMPL::SimTrackerHitImpl;
00036 using IMPL::MCParticleImpl;
00037 using EVENT::LCIO;
00038 // using IO::LCWriter;
00039 using IMPL::LCRunHeaderImpl;
00040 
00041 #include <sstream>
00042 #include <string>
00043 #include <map>
00044 #include <vector>
00045 using std::stringstream;
00046 using std::string;
00047 using std::cout;
00048 using std::endl;
00049 using std::map;
00050 using std::vector;
00051 
00052 // initialize static pointer to first instance
00053 // (only one instance should be created, but this is not inforced)
00054 LCDG4LcioHelper* LCDG4LcioHelper::_me = new LCDG4LcioHelper();
00055 
00056 // singleton access point
00057 LCDG4LcioHelper* LCDG4LcioHelper::getInstance() {
00058   return _me;
00059 }
00060 
00061 // constructor
00062 LCDG4LcioHelper::LCDG4LcioHelper()
00063   : _writer(0), _mcPartColl(0)
00064 {
00065   if( _me==0 ) {
00066     cout << "*** LcioHelper constructor: _me="<< _me << endl;
00067     _writer = IOIMPL::LCFactory::getInstance()->createLCWriter();
00068     _mcPartColl = new map<int, MCParticleImpl*>();
00069   }
00070   else {
00071     // Inforce single instance
00072     this->~LCDG4LcioHelper();
00073   }
00074 }
00075 
00076 // destructor
00077 LCDG4LcioHelper::~LCDG4LcioHelper() {
00078   if(_writer) {
00079     _writer->close();
00080     delete _writer;
00081     _writer = NULL;
00082   }
00083   if(_mcPartColl) {
00084     delete _mcPartColl;
00085     _mcPartColl = NULL;
00086   }
00087 }
00088 
00089 // File open
00090 void LCDG4LcioHelper::openLcioFile(const string& filename) {
00091   G4cout << "attempting to open <" << filename << ">" << G4endl;
00092   if(_writer) _writer->open( filename, LCIO::WRITE_NEW );
00093 }
00094 
00095 //.. Create calorimeter-like hits for lcio output
00096 SimCalorimeterHitImpl*
00097 LCDG4LcioHelper::getCalHitLcio(const LCDG4CalHit& inhit) {
00098   SimCalorimeterHitImpl* outhit = new SimCalorimeterHitImpl();
00099   outhit->setCellID0( inhit.GetCellID() );
00100   outhit->setCellID1( 0 );
00101 
00102   const Hep3Vector inpos = inhit.GetPos()/mm;  
00103   float pos[3] = { inpos.x(), inpos.y(), inpos.z() };
00104   outhit->setPosition( pos );
00105 
00106   // loop over energy contributions
00107   LCDG4McPartManager* mcmgr = LCDG4McPartManager::GetPointer();
00108   unsigned int nmc = inhit.GetNMC();
00109   for(unsigned int imc=0; imc<nmc; ++imc) {
00110     float energy = inhit.GetEMC(imc)/GeV;
00111     float time = inhit.GetTimeMC(imc)/ns;
00112     // link to contributing MCParticle
00113     int trkid = inhit.GetTrkID(imc);
00114     G4int mctag = mcmgr->trkidToMctag(trkid);
00115     if(mctag != -1) {
00116       MCParticleImpl* ppart = _mcPartColl->find(mctag)->second;
00117       outhit->addMCParticleContribution( ppart, energy, time,
00118                                          ppart->getPDG() );
00119     }
00120     else {
00121       cout << "LcioHelper: mctag==-1?" << endl;
00122     }
00123   }
00124   return outhit;
00125 }
00126 
00127 // Create tracker-like hits
00128 SimTrackerHitImpl*
00129 LCDG4LcioHelper::getTrkHitLcio(const LCDG4TrackerHit& inhit) {
00130 
00131   // pack hit info into tag
00132   unsigned int tag = inhit.GetLayer();
00133   tag |= (inhit.GetSystem() << 28);
00134   tag |= (inhit.GetNorthSouth() << 30);
00135   tag |= (inhit.GetBarEnd() << 31);
00136 
00137   SimTrackerHitImpl* outhit = new SimTrackerHitImpl();
00138   outhit->setCellID( tag );
00139   outhit->setdEdx( inhit.GetEdep()/GeV );
00140   outhit->setTime( inhit.GetTdep()/ns );
00141 
00142   const Hep3Vector inpos = inhit.GetPos()/mm;
00143   double pos[3] = { inpos.x(), inpos.y(), inpos.z() };
00144 //   pos[0] = inhit.GetPos().x()/mm;
00145 //   pos[1] = inhit.GetPos().y()/mm;
00146 //   pos[2] = inhit.GetPos().z()/mm;
00147   outhit->setPosition( pos );
00148 
00149   // link to particle which produced hit
00150   int trkid = inhit.GetTrackID();
00151 
00152   G4int mctag = LCDG4McPartManager::GetPointer()->trkidToMctag(trkid);
00153   assert(mctag>=0);
00154 //   if(mctag != -1) {
00155     MCParticleImpl* ppart = _mcPartColl->find(mctag)->second;
00156     outhit->setMCParticle( ppart );
00157 //   }
00158   return outhit;
00159 }
00160 
00161 // Create MCParticleImpl objects for LCIO output
00162 MCParticleImpl* LCDG4LcioHelper::getMCParticleLcio(LCDMcPart& inpart) {
00163   // create an MCParticleImpl
00164   MCParticleImpl* outpart = new MCParticleImpl();
00165 
00166   // set PDGID
00167   outpart->setPDG( inpart.GetParticleID() );
00168 
00169   // set simulation status
00170   int simstat = inpart.GetG4Status();
00171   switch(simstat) {
00172   case 0:
00173     cout<<"inpart: ALIVE, tag="<< inpart.GetParticleTag() << endl;
00174 //     assert(false);
00175     break; // alive
00176   case 1: outpart->setDecayedInTracker(true); break; // decayed
00177   case 2: break;  // interacted
00178   case 3: outpart->setHasLeftDetector(true); break; // left
00179   case 4: outpart->setStopped(true); break; // stopped
00180   case 5: assert(false); break; // looped
00181   case 6: assert(false); break; // lost
00182   case 7: assert(false); break; // stuck
00183   case 8: break;  // documentation
00184   case 9: outpart->isDecayedInCalorimeter(); break;  // showered
00185   case 10: assert(false); break; // maxsteps
00186   default: cout<< "Problem: simstat="<< simstat << endl;
00187   }
00188 
00189   // set generator status
00190   outpart->setGeneratorStatus( inpart.GetGenStatus() );
00191   if( outpart->getGeneratorStatus()==4 ) {  // generated in simulation
00192     outpart->setGeneratorStatus( 0 );
00193     outpart->setCreatedInSimulation(true);
00194   }
00195 
00196   // set production vertex
00197   Hep3Vector pos = inpart.GetPosition()/mm;
00198   double daux[3] = { pos.x(), pos.y(), pos.z() };
00199   outpart->setVertex( daux );
00200 
00201   // set end point
00202   pos = inpart.GetTermPosition()/mm;
00203   daux[0] = pos.x();  daux[1] = pos.y();  daux[2] = pos.z();
00204   outpart->setEndpoint( daux );
00205 
00206   // set mass and momentum
00207   HepLorentzVector pmom = inpart.Get4Momentum()/GeV;
00208   float faux[3] = { pmom.px(), pmom.py(), pmom.pz() };
00209   outpart->setMomentum( faux );
00210   outpart->setMass( pmom.mag() );
00211   outpart->setCharge( inpart.GetCharge() );
00212 
00213   // Note: parentage info still not setup at this point
00214   return outpart;
00215 }
00216 
00217 // Build a MCParticle collection
00218 void LCDG4LcioHelper::buildMCParticleColl(const vector<LCDMcPart*>& lcdMcpColl) {
00219   // make sure collection is cleared
00220   assert( _mcPartColl->size()==0 );
00221 
00222   // MCParticle* to tag is a handy map
00223   typedef std::map< MCParticleImpl*, int > PointerToIndexMap;
00224 
00225   vector<LCDMcPart*>::const_iterator mciter = lcdMcpColl.begin();
00226 //   int mapindex = 0;  // tags start at one, no zero
00227 
00228 //   // sio format requires that first element is parent of all other elements.
00229 //   // Its ParticleID is set to 99999999 (HePEVT id).
00230 //   // Sometimes the input stdhep file already has this HepEVT element, then
00231 //   // keep it.  Otherwise, create a new one for the .sio output
00232 //   //  if( (*mciter)->GetParticleID()!=99999999 ) { // no, it did not work...
00233 //   MCParticleSIO* mcparthead = new MCParticleSIO(99999999,0,0);
00234 //   mcparthead->setfsflag(300);
00235 //   mcpartmap[mapindex] = mcparthead;
00236 //   mapindex++;
00237 //   //  }
00238 
00239   int mctag = 1;  // tags start at one, not zero
00240   for(mciter = lcdMcpColl.begin();
00241       mciter != lcdMcpColl.end();
00242       mciter++, mctag++) {
00243     // make sure LCDMcPart is valid
00244     LCDMcPart* pMcPart = *mciter;
00245     if(!pMcPart) continue;  // some McParts have been erased!
00246 
00247     // Create a new MCParticleImpl..
00248     MCParticleImpl* mcplcio = getMCParticleLcio(*pMcPart);
00249     //.. and save it into a map keyed by tag
00250     _mcPartColl->insert( std::pair<int,MCParticleImpl*>(mctag,mcplcio) );
00251     _mcp2tag[ mcplcio ] = mctag;
00252   }
00253 
00254   // Loop to set up parentage links
00255   buildParentageLinks(lcdMcpColl);
00256 }
00257 
00258 // Set parentage relationships.  Assumes MCParticle collection is complete
00259 void LCDG4LcioHelper::buildParentageLinks(const vector<LCDMcPart*>& lcdMcpColl) {
00260   // Loop over LCDMcParts and tags
00261   vector<LCDMcPart*>::const_iterator mciter = lcdMcpColl.begin();
00262   int mctag=1; // tags start at 1
00263   for(mciter = lcdMcpColl.begin();
00264       mciter != lcdMcpColl.end();
00265       mciter++, mctag++) {
00266     // make sure LCDMcPart is valid, as some of them have been erased
00267     LCDMcPart* plcdPart = *mciter;
00268     if(!plcdPart) continue;
00269 
00270     // Make sure there is a corresponding MCParticleImpl
00271     MCParticleImpl* pLcioPart = NULL;
00272     TagToMCParticleMap::iterator ipair = _mcPartColl->find(mctag);
00273     if( ipair!=_mcPartColl->end() ) pLcioPart = ipair->second;
00274     assert( pLcioPart );
00275 
00276     // Fetch parent info from LCDMcPart
00277     int par1,par2;
00278     plcdPart->GetMotherTags(par1,par2);
00279 
00280     // loop over parents
00281     int nparents = 0;
00282     int parmax=par1;
00283     if(par2>par1) parmax=par2;
00284     for(int ii=par1; ii<=parmax; ++ii) {
00285       MCParticleImpl* pLcioParent = NULL;
00286       TagToMCParticleMap::iterator ipair = _mcPartColl->find(ii);
00287       if( ipair!=_mcPartColl->end() ) pLcioParent = ipair->second;
00288       if(pLcioParent) {
00289         // associate particles
00290         pLcioPart->addParent( pLcioParent );
00291         ++nparents;
00292       }
00293 //       if(ii==parmax && nparents==0) {
00294 //      cout<< "***** No parent to be added, iParTag="<< ii << endl;
00295 //       }
00296     }
00297   }
00298 }
00299 
00300 // Make sure that no daughter can come before its parent
00301 // in the output LCIO particle table
00302 void LCDG4LcioHelper::prepareMCParticleCollection(LCCollectionVec* newColl) {
00303   TagToMCParticleMap::iterator head = NULL;
00304   while( _mcPartColl->size()>0 ) {
00305     head = _mcPartColl->begin();
00306     G4cout<< "*** prepare: size="<< _mcPartColl->size()
00307           <<", head tag="<< _mcp2tag[head->second] << G4endl;
00308     insertAllFamily(newColl, head);
00309   }
00310 }
00311 
00312 // Recursive method used for reordering a la SIO
00313 // It inserts the head into the new collection, calls itself for each
00314 // daughter and deletes the head from the original map.
00315 // It needs the head iterator in order to erase it from the original
00316 // collection, otherwise just MCParticleImpl* would be necessary.
00317 void LCDG4LcioHelper::insertAllFamily(LCCollectionVec* newColl,
00318                                       TagToMCParticleMap::iterator head) {
00319   // First of all, insert head
00320   G4cout<< " pushing tag="<< head->second << G4endl;
00321   G4cout<< " tag="<< _mcp2tag[ head->second ] << G4endl;
00322   newColl->push_back( head->second );
00323   // then loop over all daughters, inserting them recursively
00324   int ndau = head->second->getNumberOfDaughters();
00325   for(int i=0; i<ndau; ++i) {
00326     G4cout<< " ndau="<< ndau <<", i="<< i << G4endl;
00327     MCParticleImpl* dau
00328       = dynamic_cast<MCParticleImpl*>(head->second->getDaughter(i));
00329     int key = _mcp2tag[ dau ];
00330     insertAllFamily( newColl, _mcPartColl->find(key) );
00331   }
00332   // remove head from the original collection
00333   G4cout<< " erasing tag="<< _mcp2tag[head->second] << G4endl;
00334   _mcPartColl->erase(head);
00335 }
00336 
00337 void LCDG4LcioHelper::saveCollection(const string& collName,
00338                                      LCCollectionVec* coll) {
00339   std::pair<string,LCCollectionVec*> tmpPair(collName,coll);
00340   _savedColls.insert( tmpPair );
00341 }
00342 
00343 void LCDG4LcioHelper::writeEvent(const G4Event* g4evt) {
00344 
00345   // we need to use the implementation classes here 
00346   LCEventImpl*  lcevt = new LCEventImpl();
00347   lcevt->setEventNumber( g4evt->GetEventID() );
00348   lcevt->setRunNumber( _runHdr->getRunNumber() );
00349   lcevt->setDetectorName( _runHdr->getDetectorName() );
00350 
00351   //***** MCParticle collection
00352 
00353   // Create collection for writing into LCIO file
00354   LCCollectionVec* mcVec = new LCCollectionVec( LCIO::MCPARTICLE );
00355   TagToMCParticleMap::const_iterator ipart;
00356 
00357   // Setup LCCollectionVec for MCParticle table
00358 //   prepareMCParticleCollection(mcVec);
00359   for( ipart = _mcPartColl->begin();
00360        ipart != _mcPartColl->end(); ++ipart ) {
00361     mcVec->push_back( ipart->second );
00362   }
00363 
00364   // Save particles into LCIO event
00365   lcevt->addCollection(mcVec,"MCParticle");
00366 
00367   // other collections to be saved
00368   map<string,LCCollectionVec*>::const_iterator icoll;
00369   for( icoll=_savedColls.begin();
00370        icoll!=_savedColls.end();
00371        ++icoll ) {
00372     lcevt->addCollection( icoll->second, icoll->first);
00373   }
00374 
00375   // write the event to the file
00376   _writer->writeEvent( lcevt );
00377 
00378 //   // dump the event to the screen
00379 //   G4cout<< "Dumping LCIO event:"<< G4endl;
00380 //   LCTOOLS::dumpEvent( lcevt );
00381 
00382   // ------------ IMPORTANT ------------- !
00383   // we created the event so we need to delete it ...
00384   // the LCEvent destructor takes care of deleting all the hits and particles
00385   delete lcevt;
00386   reset();
00387 }
00388 
00389 void LCDG4LcioHelper::beginRun(const G4Run* aRun, const string& detname) {
00390 
00391   // Create the LCIO run header
00392   _runHdr = new LCRunHeaderImpl();
00393   _runHdr->setRunNumber( aRun->GetRunID() );
00394 
00395   // Need a way to pass the detector name, description and
00396   // subdetectors from construction class. ????
00397   std::string detName(detname);
00398   _runHdr->setDetectorName( detName );
00399 
00400   stringstream description;
00401   description << " Run: " << aRun->GetRunID()
00402               << ", just for testing lcio with G4";
00403   _runHdr->setDescription( description.str() );
00404 
00405   _runHdr->addActiveSubdetector( string("EMcal") );
00406   _runHdr->addActiveSubdetector( string("HADcal") );
00407   _runHdr->addActiveSubdetector( string("LUMcal") );
00408   _runHdr->addActiveSubdetector( string("MUONcal") );
00409   _runHdr->addActiveSubdetector( string("CENt") );
00410   _runHdr->addActiveSubdetector( string("VXDt") );
00411 
00412 //
00413 // Write the run header
00414 //
00415   _writer->writeRunHeader( _runHdr );
00416 }
00417 
00418 void  LCDG4LcioHelper::endRun() {
00419   if(_runHdr) {
00420     delete _runHdr;
00421     _runHdr=0;
00422   }
00423 }
00424 
00425 void  LCDG4LcioHelper::reset() {
00426   _mcPartColl->clear();
00427   _savedColls.clear();
00428   _mcp2tag.clear();
00429 }
00430 
00431 void LCDG4LcioHelper::dumpParticleLists(const vector<LCDMcPart*>& lcdMcpColl) const {
00432   //*** Collection dumps for debugging
00433   G4cout<< "MCParticle list sizes: "<< lcdMcpColl.size()
00434         <<' '<<_mcPartColl->size() << G4endl;
00435 
00436   for(unsigned int itag=0; itag<lcdMcpColl.size(); ++itag) {
00437     //== dump LCDMcPart from tag
00438     LCDMcPart* plcdmc = *(lcdMcpColl.begin() + itag);
00439     if(plcdmc) {
00440       // parents
00441       G4cout<< "---LCDMcPart: itag="<< itag << G4endl;
00442       plcdmc->printParents();
00443       plcdmc->printDaughters();
00444     }
00445 
00446     //== dump MCParticle from tag
00447     TagToMCParticleMap::const_iterator imcp = _mcPartColl->find(itag);
00448     if( imcp==_mcPartColl->end() ) continue;
00449     MCParticleImpl* pmcp = imcp->second;
00450     // parents
00451     G4int npars=pmcp->getNumberOfParents();
00452     G4cout<< "MCParticle: "<< npars <<" parents=";
00453     for(int ii=0; ii<npars; ++ii) {
00454       MCParticleImpl* pp= dynamic_cast<MCParticleImpl*>(pmcp->getParent(ii));
00455       if(pp) G4cout<<" "<< _mcp2tag.find(pp)->second;
00456     }
00457     G4cout << endl;
00458     // daughters
00459     G4int ndaus=pmcp->getNumberOfDaughters();
00460     G4cout<< "MCParticle: "<< ndaus <<" daughters=";
00461     for(int ii=0; ii<ndaus; ++ii) {
00462       MCParticleImpl* pp= dynamic_cast<MCParticleImpl*>(pmcp->getDaughter(ii));
00463       if(pp) G4cout<<" "<< _mcp2tag.find(pp)->second;
00464     }
00465     G4cout << endl;
00466   }
00467 }

Generated on Thu Oct 7 18:44:46 2004 for LCDG4 by doxygen 1.3.4