Print

Print


Commit in slic on MAIN
include/LcioMcpFactory.hh+88added 1.1
src/LcioMcpFactory.cc+472added 1.1
+560
2 added files
Refactored MCParticle creation functions from LcioMcpManager into separate class.

slic/include
LcioMcpFactory.hh added at 1.1
diff -N LcioMcpFactory.hh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ LcioMcpFactory.hh	14 Sep 2005 23:09:48 -0000	1.1
@@ -0,0 +1,88 @@
+// $Header: /cvs/lcd/slic/include/LcioMcpFactory.hh,v 1.1 2005/09/14 23:09:48 jeremy Exp $
+#ifndef LcioMcpFactory_hh
+#define LcioMcpFactory_hh 1
+
+// LCIO
+#include "EVENT/LCCollection.h"
+#include "EVENT/LCEvent.h"
+#include "EVENT/MCParticle.h"
+#include "IMPL/MCParticleImpl.h"
+
+// slic
+#include "Verbose.hh"
+
+class G4PrimaryParticle;
+class G4TrajectoryContainer;
+
+namespace slic
+{
+  class LcioMcpManager;
+  class Trajectory;
+
+  /**
+   * @class LcioMcpFactory
+   * @brief Creates LCIO MCParticles from saved Geant4/SLIC runtime information.
+   */
+  class LcioMcpFactory : public Verbose
+  {
+
+  public:
+    LcioMcpFactory(LcioMcpManager*);
+    virtual ~LcioMcpFactory();
+
+  public:
+
+    // create new, blank Mcp coll
+    EVENT::LCCollection* createEmptyMcpCollection(const std::string& collName, bool errorOnExist = true);
+
+    // chooses to create from initial or traj cont
+    void createFinalMcpCollection();
+
+    // use StdHep-generated mcpVec to create final mcpVec for an event
+    void createFinalMcpCollectionFromInitial(EVENT::LCCollection* mcpVecInitial);
+
+    // These two functions create the Mcp coll from trajectories only in case of G4 GPS or gun
+    void createFinalMcpCollectionFromTrajectoryContainer(G4TrajectoryContainer* trjCont);
+
+    /* Create Mcp daughters of a trajectory with the given track ID. */
+    void addMcpDaughtersFromTrajectoryContainer(IMPL::MCParticleImpl* parMcp, int parTrkID);
+
+    // create an Mcp from a trajectory only
+    IMPL::MCParticleImpl* createMcpFromTrajectory( Trajectory* );
+
+    // create Mcps recursively given an initial Mcp
+    IMPL::MCParticleImpl* createMcpFromInitialRecurse(EVENT::MCParticle* mcp);
+
+    // create an Mcp from another, associated initial Mcp only
+    IMPL::MCParticleImpl* createMcpFromInitialOnly(EVENT::MCParticle* mcpInit);
+
+    // create an Mcp from a G4PrimaryParticle
+    IMPL::MCParticleImpl* createMcpFromPrimary(G4PrimaryParticle*, EVENT::MCParticle* );
+
+    // create an Mcp from primary and input Mcp
+    IMPL::MCParticleImpl* createMcpFromInitialAndPrimary(G4PrimaryParticle* primary, EVENT::MCParticle* mcpInit);
+
+    // create an Mcp from a trajectory and an input Mcp
+    IMPL::MCParticleImpl* createMcpFromInitialAndTrajectory( Trajectory*, EVENT::MCParticle* mcpInit );
+
+    // create an Mcp from a G4PrimaryParticle, shallow copy only
+    IMPL::MCParticleImpl* createMcpFromPrimaryShallowCopy(G4PrimaryParticle*);
+
+    // create new Mcp and shallow copy from input Mcp
+    IMPL::MCParticleImpl* createMcpShallowCopy(EVENT::MCParticle* mcp);
+
+    // create and add MCP daughters based on G4PrimaryParticle and associated MCP from StdHep
+    void createDaughtersFromPrimary(G4PrimaryParticle* primary,
+				    EVENT::MCParticle* mcpInit,
+				    IMPL::MCParticleImpl* mcpPar);
+
+    // add daughters to a MCP based on associated intial MCP from StdHep
+    void addMcpDaughtersFromInitial( IMPL::MCParticleImpl* mcpNew, EVENT::MCParticle* mcpInit );
+
+  private:
+    LcioMcpManager* m_manager;
+    EVENT::LCCollection* m_finalColl;
+  };
+}
+
+#endif

slic/src
LcioMcpFactory.cc added at 1.1
diff -N LcioMcpFactory.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ LcioMcpFactory.cc	14 Sep 2005 23:09:49 -0000	1.1
@@ -0,0 +1,472 @@
+// $Header: /cvs/lcd/slic/src/LcioMcpFactory.cc,v 1.1 2005/09/14 23:09:49 jeremy Exp $
+#include "LcioMcpFactory.hh"
+
+// slic
+#include "LcioMcpManager.hh"
+#include "LcioMcpUtil.hh"
+#include "Trajectory.hh"
+#include "EventSourceManager.hh"
+#include "TrajectoryManager.hh"
+#include "LcioMcpStatusSetter.hh"
+
+// geant4
+#include "globals.hh"
+#include "G4TrajectoryContainer.hh"
+#include "G4EventManager.hh"
+
+// lcio
+#include "IMPL/LCCollectionVec.h"
+
+using EVENT::LCIO;
+using EVENT::MCParticle;
+using IMPL::MCParticleImpl;
+using IMPL::LCCollectionVec;
+
+namespace slic
+{
+
+  LcioMcpFactory::LcioMcpFactory(LcioMcpManager* manager)
+  {
+    m_manager = manager;
+  }
+
+  LcioMcpFactory::~LcioMcpFactory()
+  {}
+
+  void LcioMcpFactory::createFinalMcpCollection()
+  {
+    // new coll for final Mcps
+    m_finalColl = m_manager->getFinalMcpCollection();
+
+    // using StdHep or LCIO e.g. a file-based source?
+    if ( EventSourceManager::instance()->isFileSource() ) {
+
+      // create from the initial coll of Mcp
+      createFinalMcpCollectionFromInitial( m_manager->getInitialMcpCollection() );
+    }
+    // G4 source using traj only
+    else {
+
+      /* Create from trj cont of current G4Event, only. */
+      createFinalMcpCollectionFromTrajectoryContainer(G4EventManager::GetEventManager()
+						      ->GetNonconstCurrentEvent()
+						      ->GetTrajectoryContainer() );
+    }
+  }
+
+  void LcioMcpFactory::createFinalMcpCollectionFromInitial(EVENT::LCCollection* mcpVecInitial)
+  {
+    // coll must exist
+    if ( mcpVecInitial ) {
+
+      // get num Mcp in coll
+      int numInitMcp = mcpVecInitial->getNumberOfElements();
+
+      // coll must have members
+      if ( numInitMcp > 0 ) {
+
+	// loop over input Mcp coll
+	for ( int i=0; i < numInitMcp; i++ ) {
+
+	  // get Mcp
+	  MCParticleImpl* mcp = static_cast<MCParticleImpl*> ( mcpVecInitial->getElementAt( i ) );
+
+	  // create only from Mcp primaries, e.g. no parents
+	  if ( LcioMcpUtil::isPrimary( mcp ) ) {
+	    createMcpFromInitialRecurse( mcp );
+	  }
+	}
+      }
+      else {
+	G4Exception("Initial McpVec has no members.");
+      }
+    }
+    else {
+      G4Exception("Initial McpVec ptr is null.");
+    }
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromInitialRecurse(EVENT::MCParticle* mcpInit)
+  {
+    MCParticleImpl* mcp = 0;
+
+    // find associated primary
+    G4PrimaryParticle* g4primary = m_manager->findPrimaryFromMcp( mcpInit );
+
+    // no associated primary with this initial mcp?
+    if( !g4primary ) {
+
+      // create from initial Mcp only
+      mcp = createMcpFromInitialOnly( mcpInit );
+    }
+    // create from primary
+    else {
+
+      // create it from primary
+      mcp = createMcpFromPrimary( g4primary, mcpInit );
+    }
+
+    // return the output MCP
+    return mcp;
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromInitialOnly(EVENT::MCParticle* mcpInit)
+  {
+    // copy shallow the initial
+    MCParticleImpl* mcp = createMcpShallowCopy( mcpInit );
+
+    // should add to Mcp map here?
+    m_manager->addInitialMcpToFinalMcpLink( mcpInit, mcp);
+
+    // given initial, create and add daughters
+    addMcpDaughtersFromInitial( mcp, mcpInit );
+
+    // add to final coll
+    m_finalColl->addElement( mcp );
+
+    return mcp;
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromPrimary(G4PrimaryParticle* primary,
+							     EVENT::MCParticle* mcpInit)
+  {
+    int trkID = primary->GetTrackID();
+    MCParticleImpl* mcp = 0;
+    Trajectory* trj = TrajectoryManager::instance()->findTrajectory( trkID );
+
+    /*
+     * No trajectory?
+     *
+     * This is a trap for G4Primaries with unrecognized PDGid,
+     * aka the dreaded "unknown particle".  In this case, no
+     * trajectory was created, so the final Mcp must be composed
+     * from trajectory and initial Mcp information.
+     *
+     */
+    if ( !trj ) {
+
+      /* Recursively create Mcps from primary and initial Mcp. */
+      mcp = createMcpFromInitialAndPrimary( primary, mcpInit );
+
+    }
+    /* Found a trajectory. */
+    else {
+
+      /* Recursively create Mcps from trajectory and initial Mcp. */
+      mcp = createMcpFromInitialAndTrajectory( trj, mcpInit );
+
+    }
+
+    /*
+     * In either case, the generator status is set from the initial particle.
+     */
+    mcp->setGeneratorStatus( mcpInit->getGeneratorStatus() );
+
+    /*
+     * The particle did not originate in the simulator, because it
+     * has a matching primary, which means that it had a corresponding
+     * record from the event generator.
+     */
+    mcp->setCreatedInSimulation( false );
+
+    /*
+     * Link the input MCP to an output MCP in order to check later if it was
+     * already created.
+     */
+    m_manager->addInitialMcpToFinalMcpLink( mcpInit, mcp);
+
+    return mcp;
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromInitialAndPrimary(G4PrimaryParticle* primary,
+								       EVENT::MCParticle* mcpInit)
+  {
+    /*
+     * Create new Mcp from primary particle,
+     * shallow copy only (no recursion).
+     */
+    MCParticleImpl* mcp = createMcpFromPrimaryShallowCopy( primary );
+
+    /* Get vertex from initial particle, because primary does not have it -- was immediately decayed */
+    double vtx[3] = { mcpInit->getVertex()[0], mcpInit->getVertex()[1], mcpInit->getVertex()[2] };
+    mcp->setVertex( vtx );
+
+    /* setup primary's daughters */
+    createDaughtersFromPrimary( primary, /* this primary */
+				mcpInit, /* associated initial Mcp particle */
+				mcp      /* parent Mcp particle */
+				);
+
+#ifdef SLIC_VERBOSE
+    if ( mcp->getDaughters().size() == 0 ) {
+      if ( verbose() ) {
+	std::cout << "No Mcp daughters added." << std::endl;
+      }
+    }
+#endif
+
+    // done with particle; add to coll
+    m_finalColl->addElement( mcp );
+
+    return mcp;
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromInitialAndTrajectory(Trajectory* trj,
+									  EVENT::MCParticle* mcpInit)
+  {
+    // shallow copy create with basic info and no daughters
+    IMPL::MCParticleImpl* mcp = createMcpFromTrajectory( trj );
+
+    // set generator status and created in sim flag
+    LcioMcpStatusSetter::setGeneratorStatus( mcpInit, mcp );
+
+    // loop over all trajectories to find trajectory daughter
+    G4TrajectoryContainer* trjCont = G4EventManager::GetEventManager()->GetNonconstCurrentEvent()->GetTrajectoryContainer();
+    int numTrj = trjCont->entries();
+    for( int j=0; j < numTrj; j++ ) {
+
+      Trajectory* thisTrj = static_cast<Trajectory*> ((*trjCont)[j]);
+
+      // found daughter
+      if ( thisTrj->GetParentID() == trj->GetTrackID() ) {
+
+	// find matching primary Mcp input particle
+	MCParticle* mcpPrim = m_manager->findPrimaryInitialMcpFromTrajectory( thisTrj );
+
+	// create MCP output particle from this input daughter
+	MCParticleImpl* mcpDauNew = createMcpFromInitialAndTrajectory( thisTrj, mcpPrim );
+
+	// set parent link of new daughter
+	mcpDauNew->addParent( mcp );
+      }
+    }
+
+    // add to collection
+    m_finalColl->addElement( mcp );
+
+    return mcp;
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpShallowCopy(EVENT::MCParticle* mcp)
+  {
+
+    IMPL::MCParticleImpl* mcpNew = new IMPL::MCParticleImpl();
+
+    mcpNew->setPDG( mcp->getPDG() );
+
+    float p[3] = { mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2] };
+    mcpNew->setMomentum( p );
+
+    mcpNew->setMass( mcp->getMass() );
+
+    double vtx[3] = { mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2] };
+    mcpNew->setVertex( vtx );
+
+    mcpNew->setGeneratorStatus( mcp->getGeneratorStatus() );
+
+    mcpNew->setSimulatorStatus( 0 );
+
+    mcpNew->setCharge( mcp->getCharge() );
+
+    return mcpNew;
+  }
+
+  IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromPrimaryShallowCopy(G4PrimaryParticle* primary)
+  {
+    // new MCP
+    MCParticleImpl* mcp = new MCParticleImpl();
+
+    // PDG
+    mcp->setPDG( primary->GetPDGcode() );
+
+    // momentum
+    G4ThreeVector pVec = primary->GetMomentum() / GeV;
+    float p[3] = { pVec.x(), pVec.y(), pVec.z() };
+    mcp->setMomentum( p );
+
+    // mass
+    mcp->setMass( primary->GetMass() / GeV );
+
+    // charge
+    mcp->setCharge( primary->GetCharge() );
+
+    return mcp;
+  }
+
+ IMPL::MCParticleImpl* LcioMcpFactory::createMcpFromTrajectory( Trajectory* trj)
+  {
+    // new Mcp
+    MCParticleImpl* mcp = new MCParticleImpl();
+
+    // PDG
+    mcp->setPDG( trj->GetPDGEncoding() );
+
+    // mom
+    G4ThreeVector mom = trj->GetInitialMomentum() / GeV;
+    float fmom[3] = { mom.x(), mom.y(), mom.z() };
+    mcp->setMomentum( fmom );
+
+    // mass
+    mcp->setMass( trj->GetParticleDefinition()->GetPDGMass() / GeV );
+
+    // charge
+    mcp->setCharge( trj->GetCharge() );
+
+    // begin and end points
+    G4int npts = trj->GetPointEntries();
+
+    // begin pnt
+    G4VTrajectoryPoint* beginTrjPnt = trj->GetPoint( 0 );
+    G4ThreeVector beginPos = beginTrjPnt->GetPosition() / mm;
+    double fBeginPos[3] = { beginPos.x(), beginPos.y(), beginPos.z() };
+    mcp->setVertex( fBeginPos );
+
+    // end pnt
+    G4VTrajectoryPoint* endTrjPnt = trj->GetPoint( npts - 1 );
+    G4ThreeVector endPos = endTrjPnt->GetPosition() / mm;
+    double fEndPos[3] = { endPos.x(), endPos.y(), endPos.z() };
+    mcp->setEndpoint( fEndPos );
+
+    // add to map of trkID -> mcp
+    m_manager->addTrackIDToMcpLink( trj->GetTrackID(), mcp );
+
+    // set status codes from trajectory info (with no dep on any associated Mcps)
+    LcioMcpStatusSetter::setMcpStatusCodesFromTrajectory( trj, mcp );
+
+    return mcp;
+  }
+
+  // create LCIO MCParticles from daughters, setting proper linkage
+  void LcioMcpFactory::createDaughtersFromPrimary(G4PrimaryParticle* primary,
+						  EVENT::MCParticle* mcpInit,
+						  IMPL::MCParticleImpl* mcpPar)
+  {
+
+#ifdef SLIC_VERBOSE
+    if ( verbose() > 1 ) {
+      std::cout << "LcioMcpFactory::createDaughtersFromPrimary()" << std::endl;
+      std::cout << "primary <" << primary << ">" << std::endl;
+      std::cout << "trkID <" << primary->GetTrackID() << ">" << std::endl;
+      std::cout << "mcpInit <" << mcpInit << ">" << std::endl;
+      std::cout << "mcpPar <" << mcpPar << ">" << std::endl;
+    }
+#endif
+
+    // loop over primary daughters
+    G4PrimaryParticle* primDau = primary->GetDaughter();
+    while ( primDau ) {
+
+      // find input Mcp for the primary dau
+      MCParticle* mcpDau = m_manager->findDaughterMcpFromPrimary( mcpInit,
+								  primDau );
+
+      // must find it or die
+      if ( 0 == mcpDau ) {
+	G4Exception( "Mcp daughter was not found." );
+      }
+
+      // create dau Mcp
+      MCParticleImpl* mcpDauNew = createMcpFromPrimary( primDau, mcpDau );
+
+      // make mcpPar the parent
+      mcpDauNew->addParent( mcpPar );
+
+      // get next primary dau
+      primDau = primDau->GetNext();
+    }
+  }
+
+  void LcioMcpFactory::createFinalMcpCollectionFromTrajectoryContainer(G4TrajectoryContainer* trjCont)
+  {
+    if ( trjCont ) {
+
+      // loop over trj cont
+      int n_trj = trjCont->entries();
+      for ( int i = 0;
+	    i < n_trj;
+	    i++ ) {
+
+	Trajectory* trj = static_cast<Trajectory*> ((*trjCont)[i]);
+
+	// only add primary trajectories; daughters are picked up within
+	if ( trj->GetParentID() == 0 ) {
+
+	  // create mcp output particle from trj
+	  MCParticleImpl* mcp = createMcpFromTrajectory( trj );
+
+	  // add this to coll
+	  m_finalColl->addElement( mcp );
+
+	  // add daughters
+	  addMcpDaughtersFromTrajectoryContainer( mcp, trj->GetTrackID() );
+	}
+      }
+    }
+    else {
+      G4Exception("G4TrajectoryContainer is null!");
+    }
+  }
+
+  void LcioMcpFactory::addMcpDaughtersFromTrajectoryContainer( MCParticleImpl* parMcp,
+							       int parTrkID)
+  {
+    // loop over trj cont
+    G4TrajectoryContainer* trjCont = G4EventManager::GetEventManager()->GetNonconstCurrentEvent()->GetTrajectoryContainer();
+    int n_trj = trjCont->entries();
+    for ( int i = 0;
+	  i < n_trj;
+	  i++ ) {
+
+      Trajectory* trj = static_cast<Trajectory*> ((*trjCont)[i]);
+
+      if ( trj->GetParentID() == parTrkID ) {
+
+	// lkp dau Mcp by track ID
+	MCParticleImpl* dauMcp = m_manager->findMcpFromTrackID( trj->GetTrackID() );
+
+	if ( dauMcp == 0 ) {
+
+	  // create from trj if null
+	  dauMcp = createMcpFromTrajectory( trj );
+	}
+
+	// must be created by now
+	assert( dauMcp );
+
+	// add this to final coll
+	m_finalColl->addElement( dauMcp );
+
+	// add daughters
+	addMcpDaughtersFromTrajectoryContainer( dauMcp, trj->GetTrackID() );
+
+	// set parent in daughter
+	dauMcp->addParent( parMcp );
+      }
+    }
+  }
+
+  void LcioMcpFactory::addMcpDaughtersFromInitial(IMPL::MCParticleImpl* mcpNew,
+						  EVENT::MCParticle* mcpInit)
+  {
+    int numDau = mcpInit->getDaughters().size();
+
+    for ( int i=0; i < numDau; i++ ) {
+
+      // child of input particle
+      MCParticle* mcpChildInit = mcpInit->getDaughters()[i];
+
+      // use a search function to avoid insert when null!
+      MCParticleImpl* mcpChildFinal = m_manager->findFinalParticleFromInitial( mcpChildInit );
+
+      // if not added already
+      if ( mcpChildFinal == 0 ) {
+
+	// create daughter
+	mcpChildFinal = createMcpFromInitialRecurse( mcpChildInit );
+      }
+
+      // add parent regardless of above; maybe new MCP or already created
+      mcpChildFinal->addParent( mcpNew );
+    }
+  }
+}
CVSspam 0.2.8