9 #include "Helpers/MCParticleHelper.h" 10 #include "Objects/CaloHit.h" 11 #include "Pandora/PdgTable.h" 23 LArEventTopology::LArEventTopology(
const CaloHitList &caloHitList2D) :
27 for (
const CaloHit *
const pCaloHit : caloHitList2D)
31 const MCParticle *pMCParticle{MCParticleHelper::GetMainMCParticle(pCaloHit)};
32 m_mcHitMap[pMCParticle].emplace_back(pCaloHit);
35 const MCParticle *pRoot{pMCParticle};
36 while (!pRoot->GetParentList().empty())
37 pRoot = pRoot->GetParentList().front();
41 catch (
const StatusCodeException &)
68 CartesianPointVector forRemoval;
69 for (
auto iter1 = vertices.begin(); iter1 != vertices.end(); ++iter1)
71 const CartesianVector &vertex1{*iter1};
72 if (std::find(forRemoval.begin(), forRemoval.end(), vertex1) != forRemoval.end())
74 for (
auto iter2 = std::next(iter1); iter2 != vertices.end(); ++iter2)
76 const CartesianVector &vertex2{*iter2};
77 if (std::find(forRemoval.begin(), forRemoval.end(), vertex2) != forRemoval.end())
79 if (vertex1.GetDistanceSquared(vertex2) < 1)
80 forRemoval.emplace_back(vertex2);
84 for (
auto iter = vertices.begin(); iter != vertices.end();)
86 if (std::find(forRemoval.begin(), forRemoval.end(), *iter) != forRemoval.end())
87 iter = vertices.erase(iter);
99 std::cout << str << std::endl;
106 for (
const MCParticle *
const pMC : pRootMC->GetDaughterList())
135 m_particles.emplace_back(pRoot);
141 m_caloHits{caloHitList},
144 m_particles.emplace_back(pRoot);
151 for (
Particle *pParticle : m_children)
159 m_children.emplace_back(pChild);
166 const MCParticle *
const pMC{m_particles.front()};
169 if (std::find(vertices.begin(), vertices.end(), pMC->GetVertex()) == vertices.end())
170 vertices.emplace_back(pMC->GetVertex());
175 const MCParticle *
const pParentMC{pMC->GetParentList().front()};
178 if (std::find(vertices.begin(), vertices.end(), pMC->GetVertex()) == vertices.end())
179 vertices.emplace_back(pMC->GetVertex());
183 const CartesianVector &momParent{pParentMC->GetMomentum().GetUnitVector()};
184 const CartesianVector &mom{pMC->GetMomentum().GetUnitVector()};
185 if ((pMC->GetParticleId() != pParentMC->GetParticleId()) || (mom.GetDotProduct(momParent) < 0.996f))
188 if (pMC->GetParticleId() != PHOTON && std::find(vertices.begin(), vertices.end(), pMC->GetVertex()) == vertices.end())
189 vertices.emplace_back(pMC->GetVertex());
193 int nTrackLikeChildren{0};
194 for (
const Particle *
const pChild : m_children)
196 const MCParticle *
const pChildMC{pChild->m_particles.front()};
197 const int pdg{
std::abs(pChildMC->GetParticleId())};
198 if (!(pdg == PHOTON || pdg == E_MINUS))
199 ++nTrackLikeChildren;
204 if (nTrackLikeChildren != 1)
206 if (std::find(vertices.begin(), vertices.end(), pMC->GetEndpoint()) == vertices.end())
207 vertices.emplace_back(pMC->GetEndpoint());
211 for (
const Particle *
const pChild : m_children)
212 pChild->GetVertices(vertices);
219 const MCParticle *
const pMC{m_particles.front()};
220 const CaloHitList &caloHitList{mcHitMap.find(pMC) != mcHitMap.end() ? mcHitMap.at(pMC) : CaloHitList()};
221 int uHits{0}, vHits{0}, wHits{0};
222 for (
const CaloHit *
const pCaloHit : caloHitList)
224 switch (pCaloHit->GetHitType())
240 const int pdg{
std::abs(pMC->GetParticleId())};
241 const int target{pdg == PHOTON || pdg == E_MINUS ? 8 : 5};
242 const int totalHits{uHits + vHits + wHits};
243 int goodViews{uHits >=
target ? 1 : 0};
244 goodViews += vHits >=
target ? 1 : 0;
245 goodViews += wHits >=
target ? 1 : 0;
247 if (totalHits < (3 *
target) || goodViews < 2)
250 for (
Particle *
const pChild : m_children)
251 pChild->Parse(mcHitMap);
258 for (
Particle *
const pChild : m_children)
261 std::list<Particle> toPrune;
262 for (
auto iter = m_children.begin(); iter != m_children.end();)
264 if ((*iter)->m_fold && (*iter)->m_children.empty())
265 iter = m_children.erase(iter);
275 const MCParticle *
const pMC{m_particles.front()};
276 const CaloHitList &caloHitList{mcHitMap.find(pMC) != mcHitMap.end() ? mcHitMap.at(pMC) : CaloHitList()};
277 int uHits{0}, vHits{0}, wHits{0};
278 for (
const CaloHit *
const pCaloHit : caloHitList)
280 switch (pCaloHit->GetHitType())
296 std::ostringstream os;
297 os << indent << pMC->GetParticleId() <<
": E: " << pMC->GetEnergy() <<
" GeV";
298 os <<
" (" << uHits <<
"," << vHits <<
"," << wHits <<
") " << (m_fold ?
"[fold]" :
"") <<
"\n";
299 for (
const Particle *
const pChild : m_children)
300 os << pChild->Print(mcHitMap, indent +
" ");
void Parse(const MCHitMap &mcHitMap)
Assess this child particle and its descendents to see if it is topologically significant either indep...
void AddChild(Particle *pChild)
Add a child particle to this particle.
void GetVertices(pandora::CartesianPointVector &vertices) const
Extract the clear topological vertices from the event.
constexpr auto abs(T v)
Returns the absolute value of the argument.
void ConstructVisibleHierarchy()
Construct a particle hierarchy based on the key topological features in an event. ...
Header file for lar event topology.
Header file for the lar monte carlo particle helper helper class.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
const pandora::MCParticle * m_pRoot
virtual ~LArEventTopology()
Destructor.
std::string indent(std::size_t const i)
Particle(const pandora::MCParticle *const pRoot)
Default constructor.
void Prune()
Prune particles from the hierarchy if they are not deemed topologically significant.
const std::string Print(const MCHitMap &mcHitMap, const std::string &indent) const
Print the visible hierarchy.
std::map< const pandora::MCParticle *, pandora::CaloHitList > MCHitMap
cout<< "-> Edep in the target
void PruneHierarchy()
Fold or remove particles that aren't substantive parts of the hierarchy.
virtual ~Particle()
Destructor.
static bool IsNeutrino(const pandora::MCParticle *const pMCParticle)
Whether a mc particle is a neutrino or antineutrino.
void Print() const
Print the visible hierarchy.
void GetVertices(pandora::CartesianPointVector &vertices) const
Extract the clear topological vertices from the event.