00001
00002 #include "StdHepToLcioConvertor.hh"
00003
00004
00005 #include "LcioMcpManager.hh"
00006
00007
00008 #include "IMPL/LCEventImpl.h"
00009 #include "UTIL/LCTOOLS.h"
00010
00011
00012 #include "G4ParticleDefinition.hh"
00013 #include "G4ParticleTable.hh"
00014
00015
00016 #include <cassert>
00017 #include <cmath>
00018
00019 using EVENT::LCIO;
00020 using EVENT::LCCollection;
00021 using IMPL::LCEventImpl;
00022 using IMPL::MCParticleImpl;
00023 using UTIL::LCTOOLS;
00024
00025 namespace slic
00026 {
00027 StdHepToLcioConvertor::StdHepToLcioConvertor(lStdHep* rdr)
00028 : Module("StdHepToLcioConverter"),
00029 m_reader(rdr)
00030 {
00031 assert( rdr );
00032 }
00033
00034 StdHepToLcioConvertor::StdHepToLcioConvertor()
00035 : Module("StdHepToLcioConverter"),
00036 m_reader(0)
00037 {}
00038
00039 StdHepToLcioConvertor::~StdHepToLcioConvertor()
00040 {}
00041
00042 void StdHepToLcioConvertor::setCurrentMcpCollection(EVENT::LCCollection* mcpColl)
00043 {
00044 m_currentMcpColl = mcpColl;
00045 }
00046
00047 EVENT::LCCollection* StdHepToLcioConvertor::getCurrentMcpCollection()
00048 {
00049 return m_currentMcpColl;
00050 }
00051
00052 void StdHepToLcioConvertor::fillCurrentMcpCollectionFromStdHep()
00053 {
00054 #ifdef SLIC_LOG
00055 log() << LOG::debug << "********** Creating LCIO MCParticle Collection from StdHep **********" << LOG::done;
00056 #endif
00057
00058 assert( m_reader );
00059 assert( m_currentMcpColl );
00060
00061 #ifdef SLIC_LOG
00062 log() << LOG::debug << "******** loop 1: create MCParticles ********" << LOG::done;
00063 #endif
00064
00065
00066 int ntracks = m_reader->nTracks();
00067 for ( int ihep = 0;
00068 ihep < ntracks;
00069 ihep++ ) {
00070
00071 #ifdef SLIC_DEBUG
00072 printTrack( ihep );
00073 #endif
00074
00075 #ifdef SLIC_DEBUG
00076 checkParentage( ihep );
00077 #endif
00078
00079
00080 createMcpFromStdHep( ihep );
00081
00082 #ifdef SLIC_LOG
00083 log() << LOG::debug << LOG::endl << "--" << LOG::endl << LOG::done;
00084 #endif
00085 }
00086
00087 #ifdef SLIC_LOG
00088 log() << LOG::debug << "******** loop 2: parent setup ********" << LOG::done << LOG::done;
00089 #endif
00090
00091
00092 for ( int ihep = 0;
00093 ihep < ntracks;
00094 ihep++ ) {
00095
00096 #ifdef SLIC_LOG
00097 printIndex( ihep );
00098 printMothers( ihep );
00099 #endif
00100
00101 MCParticleImpl* mcp =
00102 dynamic_cast<MCParticleImpl*> ( m_currentMcpColl->getElementAt(ihep) );
00103
00104 if ( mcp ) {
00105 setupParents( ihep, mcp );
00106 }
00107
00108 #ifdef SLIC_LOG
00109 log() << LOG::debug << LOG::done << "--" << LOG::done << LOG::done;
00110 #endif
00111
00112 }
00113
00114 #ifdef SLIC_LOG
00115 log() << LOG::debug << "******** loop 3: daughter setup ********" << LOG::done << LOG::done;
00116 #endif
00117
00118
00119 for ( int ihep = 0;
00120 ihep < ntracks;
00121 ihep++ ) {
00122
00123 #ifdef SLIC_LOG
00124 printIndex( ihep );
00125 printDaughters( ihep );
00126 #endif
00127
00128 MCParticleImpl* mcp =
00129 dynamic_cast<MCParticleImpl*> ( m_currentMcpColl->getElementAt(ihep) );
00130
00131 if ( mcp ) {
00132 setupDaughters( ihep, mcp );
00133 }
00134 else {
00135 log() << LOG::error << "mcp is null; ihep <" << ihep << "> does not appear to be a valid idx!" << LOG::done;
00136 }
00137
00138 #ifdef SLIC_LOG
00139 log() << LOG::debug << LOG::done << "--" << LOG::done << LOG::done;
00140 #endif
00141
00142 }
00143
00144 #ifdef SLIC_LOG
00145 log() << LOG::debug << LOG::done;
00146 #endif
00147 }
00148
00149 IMPL::MCParticleImpl* StdHepToLcioConvertor::createMcpFromStdHep( int ihep )
00150 {
00151
00152 MCParticleImpl* mcp = new MCParticleImpl();
00153
00154
00155 int pdgid = m_reader->pid( ihep );
00156 mcp->setPDG(pdgid);
00157
00158 G4ParticleDefinition* pdef = G4ParticleTable::GetParticleTable()->FindParticle(pdgid);
00159
00160 #ifdef SLIC_LOG
00161 if ( pdef != 0 ) {
00162 log() << LOG::debug << "found pdef for particle <" << pdef->GetParticleName() << "> with pdgid <" << pdgid << ">" << LOG::done;
00163 }
00164 else {
00165 log() << LOG::debug << "no pdef for pdgid <" << pdgid << ">" << LOG::done;
00166 }
00167 #endif
00168
00169
00170
00171
00172
00173 if ( pdef != 0 ) {
00174 mcp->setCharge( pdef->GetPDGCharge() );
00175 }
00176
00177
00178
00179 else {
00180 mcp->setCharge( LcioMcpManager::m_NAN );
00181 }
00182
00183
00184 float p[3] = { m_reader->Px( ihep ),
00185 m_reader->Py( ihep ),
00186 m_reader->Pz( ihep ) };
00187 mcp->setMomentum( p );
00188
00189
00190 mcp->setMass( m_reader->M( ihep ) );
00191
00192
00193 double vtx[3] = { m_reader->X( ihep ),
00194 m_reader->Y( ihep ),
00195 m_reader->Z( ihep ) };
00196 mcp->setVertex( vtx );
00197
00198
00199 mcp->setGeneratorStatus( m_reader->status( ihep ) );
00200
00201
00202 mcp->setSimulatorStatus( 0 );
00203
00204
00205 mcp->setTime( m_reader->T( ihep ) / c_light );
00206
00207
00208 m_currentMcpColl->addElement( mcp );
00209
00210 return mcp;
00211 }
00212
00213
00214 void StdHepToLcioConvertor::setupParents( int ihep, IMPL::MCParticleImpl* mcp )
00215 {
00216 #ifdef SLIC_LOG
00217 log() << LOG::debug << "setupParents" << LOG::done;
00218 #endif
00219
00220
00221 int mom1_idx = m_reader->mother1( ihep ) - 1;
00222 int mom2_idx = m_reader->mother2( ihep ) - 1;
00223
00224 std::vector<int> parVec;
00225 makeIndexVec( mom1_idx, mom2_idx, parVec );
00226
00227 if ( parVec.size() > 0 ) {
00228 for ( std::vector<int>::iterator it = parVec.begin();
00229 it != parVec.end();
00230 it++ ) {
00231 if ( *it != ihep ) {
00232 addMcpParent( *it, mcp );
00233 }
00234 #ifdef SLIC_LOG
00235 else {
00236 log() << LOG::warning << "Ignoring parent pointing to self!" << LOG::done;
00237 }
00238 #endif
00239 }
00240 }
00241 #ifdef SLIC_LOG
00242 log() << LOG::debug << "particle has no parents" << LOG::done;
00243 #endif
00244 }
00245
00246 void StdHepToLcioConvertor::setupDaughters( int ihep, IMPL::MCParticleImpl* mcp )
00247 {
00248 #ifdef SLIC_LOG
00249 log() << LOG::debug << "setupDaughters" << LOG::done;
00250 #endif
00251
00252
00253 int dau1_idx = m_reader->daughter1( ihep ) % 10000 - 1;
00254 int dau2_idx = m_reader->daughter2( ihep ) % 10000 - 1;
00255
00256 std::vector<int> dauVec;
00257 dauVec = makeIndexVec( dau1_idx, dau2_idx, dauVec );
00258
00259 if ( dauVec.size() > 0 ) {
00260 for ( std::vector<int>::iterator it = dauVec.begin();
00261 it != dauVec.end();
00262 it++ ) {
00263 if ( *it != ihep ) {
00264 addMcpDaughter( *it, mcp );
00265 }
00266 else {
00267 log() << LOG::error << "Ignoring daughter pointing to self!" << LOG::done;
00268 }
00269 }
00270 }
00271 #ifdef SLIC_LOG
00272 else {
00273 log() << LOG::debug << "particle has no daughters" << LOG::done;
00274 }
00275 #endif
00276 }
00277
00278 bool StdHepToLcioConvertor::hasParent( IMPL::MCParticleImpl* dauMcp, IMPL::MCParticleImpl* parMcp)
00279 {
00280 bool isPar = false;
00281 if ( dauMcp && parMcp ) {
00282 int numParents = dauMcp->getParents().size();
00283
00284 MCParticleImpl* pMomMcp;
00285
00286
00287 for ( int i = 0;
00288 i < numParents;
00289 i++ ) {
00290
00291 pMomMcp = static_cast<MCParticleImpl*>
00292 ( dauMcp->getParents()[i] );
00293
00294 if ( pMomMcp == parMcp ) {
00295 isPar = true;
00296 break;
00297 }
00298 }
00299 }
00300
00301 return isPar;
00302 }
00303
00304 void StdHepToLcioConvertor::addMcpDaughter( int dauIdx, IMPL::MCParticleImpl* parMcp )
00305 {
00306 if ( dauIdx >= 0 ) {
00307
00308 MCParticleImpl* dauMcp = static_cast<MCParticleImpl*>
00309 ( m_currentMcpColl->getElementAt( dauIdx ) );
00310 assert( dauMcp );
00311
00312 if ( dauMcp ) {
00313 if ( !hasParent( dauMcp, parMcp ) ) {
00314 dauMcp->addParent( parMcp );
00315
00316 #ifdef SLIC_LOG
00317 log() << LOG::debug << "added daughter <" << dauIdx << ">" << LOG::done;
00318 #endif
00319 }
00320 #ifdef SLIC_LOG
00321 else {
00322 log() << LOG::debug << "daughter <" << dauIdx << "> already has this parent" << LOG::done;
00323 }
00324 #endif
00325 }
00326 #ifdef SLIC_LOG
00327 else {
00328 log() << LOG::error << "WARNING: dauMcp or parMcp is null!" << LOG::done;
00329 }
00330 #endif
00331
00332 }
00333 }
00334
00335 void StdHepToLcioConvertor::addMcpParent( int parIdx, IMPL::MCParticleImpl* mcp )
00336 {
00337 #ifdef SLIC_LOG
00338 log() << LOG::debug << "addMcpParent" << LOG::done;
00339 #endif
00340
00341 if ( parIdx >= 0 ) {
00342
00343
00344 if ( parIdx > m_currentMcpColl->getNumberOfElements() ) {
00345 #ifdef SLIC_LOG
00346 log() << LOG::fatal << "StdHepToLcioConverter::addMcpParent - Parent index is out of range <" << parIdx << ">" << LOG::done;
00347 #endif
00348 G4Exception("ERROR: StdHep index (ihep) is out of range.");
00349 }
00350
00351 MCParticleImpl* parMcp = static_cast<MCParticleImpl*>
00352 ( m_currentMcpColl->getElementAt( parIdx ) );
00353
00354 if ( parMcp ) {
00355 if ( !hasParent(mcp, parMcp) ) {
00356 mcp->addParent( parMcp );
00357
00358 #ifdef SLIC_LOG
00359 log() << LOG::debug << "added parent <" << parIdx << ">" << LOG::done;
00360 #endif
00361 }
00362 #ifdef SLIC_LOG
00363 else {
00364 log() << LOG::debug << "daughter already has parent <" << parIdx << ">" << LOG::done;
00365 }
00366 #endif
00367 }
00368 else {
00369 G4Exception("Failed to get parent particle from MCParticle collection.");
00370 }
00371 }
00372 #ifdef SLIC_LOG
00373 else {
00374 log() << LOG::debug << "ignoring parIdx = -1 " << LOG::done;
00375 }
00376 #endif
00377 }
00378
00379 std::vector<int> StdHepToLcioConvertor::makeIndexVec( int idx1, int idx2, std::vector<int>& vec )
00380 {
00381 #ifdef SLIC_LOG
00382 log() << LOG::debug << "idx1 <" << idx1 << ">" << LOG::done;
00383 log() << LOG::debug << "idx2 <" << idx2 << ">" << LOG::done;
00384 #endif
00385
00386 if ( idx1 >= 0 && idx2 >= 0 ) {
00387
00388 if ( idx1 < idx2 ) {
00389
00390 #ifdef SLIC_LOG
00391 log() << LOG::debug << "range: idx1 to idx2" << LOG::done;
00392 #endif
00393
00394 for ( int i = idx1;
00395 i < (idx2 + 1);
00396 i++ ) {
00397 vec.push_back(i);
00398 }
00399 }
00400 else if ( idx1 > idx2 ) {
00401
00402 #ifdef SLIC_LOG
00403 log() << LOG::debug << "discrete: idx1 and idx2" << LOG::done;
00404 #endif
00405
00406 vec.push_back(idx1);
00407 vec.push_back(idx2);
00408 }
00409
00410 else {
00411
00412 #ifdef SLIC_LOG
00413 log() << LOG::debug << "single: idx1 == idx2" << LOG::done;
00414 #endif
00415
00416 vec.push_back(idx1);
00417 }
00418 }
00419 else if ( idx1 >= 0 ) {
00420
00421 #ifdef SLIC_LOG
00422 log() << LOG::debug << "single: idx1 only" << LOG::done;
00423 #endif
00424
00425 vec.push_back(idx1);
00426 }
00427 else if ( idx2 >= 0 ) {
00428
00429 #ifdef SLIC_LOG
00430 log() << LOG::debug << "single: idx2 only" << LOG::done;
00431 #endif
00432
00433 vec.push_back(idx2);
00434 }
00435
00436 return vec;
00437 }
00438
00439 void StdHepToLcioConvertor::printIndex( int ihep )
00440 {
00441 log() << LOG::debug << "ihep <" << ihep << ">" << LOG::done;
00442 }
00443
00444 void StdHepToLcioConvertor::printMothers( int ihep )
00445 {
00446 log() << LOG::debug << "mom1 <" << m_reader->mother1(ihep) - 1 << ">" << LOG::done;
00447 log() << LOG::debug << "mom2 <" << m_reader->mother2(ihep) - 1 << ">" << LOG::done;
00448 }
00449
00450 void StdHepToLcioConvertor::printDaughters( int ihep )
00451 {
00452 log() << LOG::debug << "dau1 <" << m_reader->daughter1(ihep) - 1 << ">" << LOG::done;
00453 log() << LOG::debug << "dau2 <" << m_reader->daughter2(ihep) - 1 << ">" << LOG::done;
00454 }
00455
00456 void StdHepToLcioConvertor::printTrack( int ihep )
00457 {
00458 printIndex( ihep );
00459
00460 log() << LOG::debug << "pid <" << m_reader->pid( ihep ) << ">" << LOG::done;
00461 log() << LOG::debug << "M = " << m_reader->M( ihep ) << LOG::done;
00462 log() << LOG::debug << "T = " << m_reader->T( ihep ) << LOG::done;
00463 log() << LOG::debug << "status <" << m_reader->status( ihep ) << ">" << LOG::done;
00464
00465 printMothers(ihep);
00466 printDaughters(ihep);
00467
00468 log() << LOG::debug << "P = ("
00469 << m_reader->Px( ihep ) << ", "
00470 << m_reader->Py( ihep ) << ", "
00471 << m_reader->Pz( ihep) << ")"
00472 << LOG::done;
00473
00474 log() << LOG::debug << "Vtx = ("
00475 << m_reader->X( ihep ) << ", "
00476 << m_reader->Y( ihep ) << ", "
00477 << m_reader->Z( ihep ) << ")"
00478 << LOG::done;
00479
00480 log() << LOG::debug << LOG::done;
00481 }
00482
00483 void StdHepToLcioConvertor::checkParentage(int ihep )
00484 {
00485 int mom1 = m_reader->mother1(ihep) - 1;
00486 int mom2 = m_reader->mother2(ihep) - 1;
00487 int dau1 = m_reader->daughter1(ihep) - 1;
00488 int dau2 = m_reader->daughter2(ihep) -1;
00489
00490
00491 if ( dau1 >= 0 && dau1 < ihep ) {
00492 log() << LOG::debug << "WARNING: dau1 < ihep" << LOG::done;
00493 }
00494
00495
00496 if ( dau2 >= 0 && dau2 < ihep ) {
00497 log() << LOG::debug << "WARNING: dau2 < ihep" << LOG::done;
00498 }
00499
00500
00501 if ( mom1 >= 0 && mom1 > ihep ) {
00502 log() << LOG::debug << "WARNING: mom1 > ihep" << LOG::done;
00503 }
00504
00505
00506 if ( mom2 >= 0 && mom2 > ihep ) {
00507 log() << LOG::debug << "WARNING: mom2 > ihep" << LOG::done;
00508 }
00509
00510
00511 if ( ihep == 0 && ( mom1 >= 0 || mom2 >= 0 ) ) {
00512 log() << LOG::debug << "WARNING: ihep == 0 has parents" << LOG::done;
00513 }
00514
00515
00516 if ( ihep > 1 && ( mom1 < 0 && mom2 < 0 ) ) {
00517 log() << LOG::debug << "WARNING: ihep > 1 with no mother" << LOG::done;
00518 }
00519
00520
00521 if ( ihep == mom1 || ihep == mom2 ) {
00522 log() << LOG::debug << "WARNING: mom1 or mom2 == ihep" << LOG::done;
00523 }
00524
00525
00526 if ( ihep == dau1 || ihep == dau2 ) {
00527 log() << LOG::debug << "WARNING: dau1 or dau2 == ihep" << LOG::done;
00528 }
00529 }
00530
00531 }