00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
00053
00054 LCDG4LcioHelper* LCDG4LcioHelper::_me = new LCDG4LcioHelper();
00055
00056
00057 LCDG4LcioHelper* LCDG4LcioHelper::getInstance() {
00058 return _me;
00059 }
00060
00061
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
00072 this->~LCDG4LcioHelper();
00073 }
00074 }
00075
00076
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
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
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
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
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
00128 SimTrackerHitImpl*
00129 LCDG4LcioHelper::getTrkHitLcio(const LCDG4TrackerHit& inhit) {
00130
00131
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
00145
00146
00147 outhit->setPosition( pos );
00148
00149
00150 int trkid = inhit.GetTrackID();
00151
00152 G4int mctag = LCDG4McPartManager::GetPointer()->trkidToMctag(trkid);
00153 assert(mctag>=0);
00154
00155 MCParticleImpl* ppart = _mcPartColl->find(mctag)->second;
00156 outhit->setMCParticle( ppart );
00157
00158 return outhit;
00159 }
00160
00161
00162 MCParticleImpl* LCDG4LcioHelper::getMCParticleLcio(LCDMcPart& inpart) {
00163
00164 MCParticleImpl* outpart = new MCParticleImpl();
00165
00166
00167 outpart->setPDG( inpart.GetParticleID() );
00168
00169
00170 int simstat = inpart.GetG4Status();
00171 switch(simstat) {
00172 case 0:
00173 cout<<"inpart: ALIVE, tag="<< inpart.GetParticleTag() << endl;
00174
00175 break;
00176 case 1: outpart->setDecayedInTracker(true); break;
00177 case 2: break;
00178 case 3: outpart->setHasLeftDetector(true); break;
00179 case 4: outpart->setStopped(true); break;
00180 case 5: assert(false); break;
00181 case 6: assert(false); break;
00182 case 7: assert(false); break;
00183 case 8: break;
00184 case 9: outpart->isDecayedInCalorimeter(); break;
00185 case 10: assert(false); break;
00186 default: cout<< "Problem: simstat="<< simstat << endl;
00187 }
00188
00189
00190 outpart->setGeneratorStatus( inpart.GetGenStatus() );
00191 if( outpart->getGeneratorStatus()==4 ) {
00192 outpart->setGeneratorStatus( 0 );
00193 outpart->setCreatedInSimulation(true);
00194 }
00195
00196
00197 Hep3Vector pos = inpart.GetPosition()/mm;
00198 double daux[3] = { pos.x(), pos.y(), pos.z() };
00199 outpart->setVertex( daux );
00200
00201
00202 pos = inpart.GetTermPosition()/mm;
00203 daux[0] = pos.x(); daux[1] = pos.y(); daux[2] = pos.z();
00204 outpart->setEndpoint( daux );
00205
00206
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
00214 return outpart;
00215 }
00216
00217
00218 void LCDG4LcioHelper::buildMCParticleColl(const vector<LCDMcPart*>& lcdMcpColl) {
00219
00220 assert( _mcPartColl->size()==0 );
00221
00222
00223 typedef std::map< MCParticleImpl*, int > PointerToIndexMap;
00224
00225 vector<LCDMcPart*>::const_iterator mciter = lcdMcpColl.begin();
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 int mctag = 1;
00240 for(mciter = lcdMcpColl.begin();
00241 mciter != lcdMcpColl.end();
00242 mciter++, mctag++) {
00243
00244 LCDMcPart* pMcPart = *mciter;
00245 if(!pMcPart) continue;
00246
00247
00248 MCParticleImpl* mcplcio = getMCParticleLcio(*pMcPart);
00249
00250 _mcPartColl->insert( std::pair<int,MCParticleImpl*>(mctag,mcplcio) );
00251 _mcp2tag[ mcplcio ] = mctag;
00252 }
00253
00254
00255 buildParentageLinks(lcdMcpColl);
00256 }
00257
00258
00259 void LCDG4LcioHelper::buildParentageLinks(const vector<LCDMcPart*>& lcdMcpColl) {
00260
00261 vector<LCDMcPart*>::const_iterator mciter = lcdMcpColl.begin();
00262 int mctag=1;
00263 for(mciter = lcdMcpColl.begin();
00264 mciter != lcdMcpColl.end();
00265 mciter++, mctag++) {
00266
00267 LCDMcPart* plcdPart = *mciter;
00268 if(!plcdPart) continue;
00269
00270
00271 MCParticleImpl* pLcioPart = NULL;
00272 TagToMCParticleMap::iterator ipair = _mcPartColl->find(mctag);
00273 if( ipair!=_mcPartColl->end() ) pLcioPart = ipair->second;
00274 assert( pLcioPart );
00275
00276
00277 int par1,par2;
00278 plcdPart->GetMotherTags(par1,par2);
00279
00280
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
00290 pLcioPart->addParent( pLcioParent );
00291 ++nparents;
00292 }
00293
00294
00295
00296 }
00297 }
00298 }
00299
00300
00301
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
00313
00314
00315
00316
00317 void LCDG4LcioHelper::insertAllFamily(LCCollectionVec* newColl,
00318 TagToMCParticleMap::iterator head) {
00319
00320 G4cout<< " pushing tag="<< head->second << G4endl;
00321 G4cout<< " tag="<< _mcp2tag[ head->second ] << G4endl;
00322 newColl->push_back( head->second );
00323
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
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
00346 LCEventImpl* lcevt = new LCEventImpl();
00347 lcevt->setEventNumber( g4evt->GetEventID() );
00348 lcevt->setRunNumber( _runHdr->getRunNumber() );
00349 lcevt->setDetectorName( _runHdr->getDetectorName() );
00350
00351
00352
00353
00354 LCCollectionVec* mcVec = new LCCollectionVec( LCIO::MCPARTICLE );
00355 TagToMCParticleMap::const_iterator ipart;
00356
00357
00358
00359 for( ipart = _mcPartColl->begin();
00360 ipart != _mcPartColl->end(); ++ipart ) {
00361 mcVec->push_back( ipart->second );
00362 }
00363
00364
00365 lcevt->addCollection(mcVec,"MCParticle");
00366
00367
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
00376 _writer->writeEvent( lcevt );
00377
00378
00379
00380
00381
00382
00383
00384
00385 delete lcevt;
00386 reset();
00387 }
00388
00389 void LCDG4LcioHelper::beginRun(const G4Run* aRun, const string& detname) {
00390
00391
00392 _runHdr = new LCRunHeaderImpl();
00393 _runHdr->setRunNumber( aRun->GetRunID() );
00394
00395
00396
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
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
00433 G4cout<< "MCParticle list sizes: "<< lcdMcpColl.size()
00434 <<' '<<_mcPartColl->size() << G4endl;
00435
00436 for(unsigned int itag=0; itag<lcdMcpColl.size(); ++itag) {
00437
00438 LCDMcPart* plcdmc = *(lcdMcpColl.begin() + itag);
00439 if(plcdmc) {
00440
00441 G4cout<< "---LCDMcPart: itag="<< itag << G4endl;
00442 plcdmc->printParents();
00443 plcdmc->printDaughters();
00444 }
00445
00446
00447 TagToMCParticleMap::const_iterator imcp = _mcPartColl->find(itag);
00448 if( imcp==_mcPartColl->end() ) continue;
00449 MCParticleImpl* pmcp = imcp->second;
00450
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
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 }