9 #include "Helpers/MCParticleHelper.h" 11 #include "Objects/CaloHit.h" 12 #include "Objects/Cluster.h" 13 #include "Objects/MCParticle.h" 15 #include "Pandora/PdgTable.h" 16 #include "Pandora/StatusCodes.h" 32 m_minPrimaryGoodHits(15),
33 m_minHitsForGoodView(5),
34 m_minPrimaryGoodViews(2),
35 m_selectInputHits(true),
36 m_maxPhotonPropagation(2.5
f),
37 m_minHitSharingFraction(0.9
f),
38 m_foldBackHierarchy(true)
50 return fCriteria(pPrimaryMCParticle);
52 catch (
const StatusCodeException &)
66 return fCriteria(pLeadingMCParticle);
68 catch (
const StatusCodeException &)
121 const LArMCParticle *
const pLArMCParticle(dynamic_cast<const LArMCParticle *>(pMCParticle));
125 std::cout <<
"LArMCParticleHelper::GetNuanceCode - Error: Can't cast to LArMCParticle" << std::endl;
126 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
134 if ((nuance == 0) || (nuance == 2000) || (nuance == 2001) || (nuance == 3000))
137 const int absoluteParticleId(
std::abs(pMCParticle->GetParticleId()));
138 return ((NU_E == absoluteParticleId) || (NU_MU == absoluteParticleId) || (NU_TAU == absoluteParticleId));
149 catch (
const StatusCodeException &)
164 catch (
const StatusCodeException &)
175 const MCParticle *pParentMCParticle = pMCParticle;
178 while (pParentMCParticle->GetParentList().empty() ==
false)
180 if (1 != pParentMCParticle->GetParentList().size())
181 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
183 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
194 const int absoluteParticleId(
std::abs(pMCParticle->GetParticleId()));
196 if ((E_MINUS == absoluteParticleId) || (MU_MINUS == absoluteParticleId) || (PI_PLUS == absoluteParticleId) || (K_PLUS == absoluteParticleId) ||
197 (SIGMA_MINUS == absoluteParticleId) || (SIGMA_PLUS == absoluteParticleId) || (HYPERON_MINUS == absoluteParticleId) ||
198 (PROTON == absoluteParticleId) || (PHOTON == absoluteParticleId) || (NEUTRON == absoluteParticleId))
208 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
211 trueNeutrinos.push_back(pMCParticle);
221 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
224 trueTestBeamParticles.push_back(pMCParticle);
236 if (!primaries.empty())
238 const MCParticle *primary{primaries.front()};
239 const MCParticleList &parents{primary->GetParentList()};
240 if (parents.size() == 1)
242 const MCParticle *trueNeutrino{parents.front()};
245 trueVertex = primaries.front()->GetVertex();
258 const MCParticle *pParentMCParticle = pMCParticle;
260 while (pParentMCParticle->GetParentList().empty() ==
false)
262 if (1 != pParentMCParticle->GetParentList().size())
263 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
265 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
268 return pParentMCParticle;
275 for (
const MCParticle *pDaughterMCParticle : pMCParticle->GetDaughterList())
277 if (std::find(descendentMCParticleList.begin(), descendentMCParticleList.end(), pDaughterMCParticle) == descendentMCParticleList.end())
279 descendentMCParticleList.emplace_back(pDaughterMCParticle);
288 MCParticleList &leadingShowerParticles, MCParticleList &leadingNeutrons)
290 for (
const MCParticle *pDaughterMCParticle : pMCParticle->GetDaughterList())
292 if (std::find(descendentTrackParticles.begin(), descendentTrackParticles.end(), pDaughterMCParticle) == descendentTrackParticles.end())
294 const int pdg{
std::abs(pDaughterMCParticle->GetParticleId())};
295 if (pdg == E_MINUS || pdg == PHOTON)
297 leadingShowerParticles.emplace_back(pDaughterMCParticle);
299 else if (pdg == NEUTRON)
301 leadingNeutrons.emplace_back(pDaughterMCParticle);
305 descendentTrackParticles.emplace_back(pDaughterMCParticle);
316 const MCParticleList &parentMCParticleList = pMCParticle->GetParentList();
317 if (parentMCParticleList.empty())
319 if (parentMCParticleList.size() != 1)
320 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
322 const MCParticle *pParentMCParticle = *parentMCParticleList.begin();
323 if (std::find(ancestorMCParticleList.begin(), ancestorMCParticleList.end(), pParentMCParticle) == ancestorMCParticleList.end())
325 ancestorMCParticleList.push_back(pParentMCParticle);
334 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
337 mcPrimaryVector.push_back(pMCParticle);
347 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
353 mcLeadingVector.push_back(pMCParticle);
366 visibleParticleList.emplace_back(pRoot);
370 for (
const MCParticle *
const pMCParticle : pRoot->GetDaughterList())
382 const MCParticle *pParentMCParticle = pMCParticle;
383 mcVector.push_back(pParentMCParticle);
385 while (!pParentMCParticle->GetParentList().empty())
387 if (1 != pParentMCParticle->GetParentList().size())
388 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
390 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
391 mcVector.push_back(pParentMCParticle);
395 for (MCParticleVector::const_reverse_iterator iter = mcVector.rbegin(), iterEnd = mcVector.rend(); iter != iterEnd; ++iter)
397 const MCParticle *
const pNextParticle = *iter;
400 return pNextParticle;
403 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
419 const MCParticle *pParentMCParticle = pMCParticle;
420 mcVector.push_back(pParentMCParticle);
422 while (!pParentMCParticle->GetParentList().empty())
424 if (1 != pParentMCParticle->GetParentList().size())
425 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
427 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
428 mcVector.push_back(pParentMCParticle);
431 int hierarchyTier(0);
432 const MCParticle *pLeadingMCParticle(
nullptr);
435 for (MCParticleVector::const_reverse_iterator iter = mcVector.rbegin(), iterEnd = mcVector.rend(); iter != iterEnd; ++iter)
437 const MCParticle *
const pNextParticle = *iter;
443 if (hierarchyTier <= hierarchyTierLimit)
444 pLeadingMCParticle = pNextParticle;
449 if (!pLeadingMCParticle)
450 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
452 return pLeadingMCParticle;
459 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
464 mcPrimaryMap[pMCParticle] = pPrimaryMCParticle;
466 catch (
const StatusCodeException &)
476 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
481 mcLeadingMap[pMCParticle] = pLeadingMCParticle;
483 catch (
const StatusCodeException &)
493 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
495 mcToSelfMap[pMCParticle] = pMCParticle;
516 for (
const auto &[mc,
hits] : mcToHitsMap)
518 mcHierarchy.emplace_back(mc);
522 catch (
const StatusCodeException &
e)
530 if (pivot != mcHierarchy.end())
531 std::rotate(mcHierarchy.begin(), pivot, std::next(pivot));
533 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
540 ClusterList clusterList;
542 return MCParticleHelper::GetMainMCParticle(&clusterList);
550 const float momentumLhs(pLhs->GetMomentum().GetMagnitudeSquared());
551 const float momentumRhs(pRhs->GetMomentum().GetMagnitudeSquared());
553 if (std::fabs(momentumLhs - momentumRhs) > std::numeric_limits<float>::epsilon())
554 return (momentumLhs > momentumRhs);
557 if (std::fabs(pLhs->GetEnergy() - pRhs->GetEnergy()) > std::numeric_limits<float>::epsilon())
558 return (pLhs->GetEnergy() < pRhs->GetEnergy());
561 if (pLhs->GetParticleId() != pRhs->GetParticleId())
562 return (pLhs->GetParticleId() < pRhs->GetParticleId());
565 const float positionLhs(pLhs->GetVertex().GetMagnitudeSquared());
566 const float positionRhs(pRhs->GetVertex().GetMagnitudeSquared());
568 return (positionLhs < positionRhs);
576 for (
const CaloHit *
const pCaloHit : *pCaloHitList)
580 const MCParticle *
const pHitParticle(MCParticleHelper::GetMainMCParticle(pCaloHit));
581 const MCParticle *pTargetParticle(pHitParticle);
584 if (!mcToTargetMCMap.empty())
588 if (mcToTargetMCMap.end() == mcIter)
591 pTargetParticle = mcIter->second;
594 mcToTrueHitListMap[pTargetParticle].push_back(pCaloHit);
595 hitToMCMap[pCaloHit] = pTargetParticle;
597 catch (StatusCodeException &statusCodeException)
599 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
600 throw statusCodeException;
617 CaloHitList selectedCaloHitList;
633 std::copy(pMCParticleList->begin(), pMCParticleList->end(), std::back_inserter(targetMCVector));
656 CaloHitList selectedCaloHitList;
672 std::copy(pMCParticleList->begin(), pMCParticleList->end(), std::back_inserter(targetMCVector));
683 for (
const MCParticle *
const pMCParticle : candidateTargets)
689 if (selectedMCParticlesToHitsMap.find(pParentMCParticle) == selectedMCParticlesToHitsMap.end())
691 CaloHitList caloHitList;
692 selectedMCParticlesToHitsMap.insert(MCContributionMap::value_type(pParentMCParticle, caloHitList));
703 pfoList,
MCContributionMapVector({selectedMCParticleToHitsMap}), pfoToReconstructable2DHitsMap, foldBackHierarchy);
712 pfoList,
MCContributionMapVector({selectedMCParticleToHitsMap}), pfoToReconstructable2DHitsMap, foldBackHierarchy);
720 for (
const ParticleFlowObject *
const pPfo : pfoList)
722 CaloHitList pfoHitList;
725 if (!pfoToReconstructable2DHitsMap.insert(PfoContributionMap::value_type(pPfo, pfoHitList)).second)
726 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
735 for (
const ParticleFlowObject *
const pPfo : pfoList)
737 CaloHitList pfoHitList;
740 if (!pfoToReconstructable2DHitsMap.insert(PfoContributionMap::value_type(pPfo, pfoHitList)).second)
741 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
751 PfoVector sortedPfos;
752 for (
const auto &mapEntry : pfoToReconstructable2DHitsMap)
753 sortedPfos.push_back(mapEntry.first);
756 for (
const ParticleFlowObject *
const pPfo : sortedPfos)
758 for (
const MCContributionMap &mcParticleToHitsMap : selectedMCParticleToHitsMaps)
761 for (
const auto &mapEntry : mcParticleToHitsMap)
762 sortedMCParticles.push_back(mapEntry.first);
763 std::sort(sortedMCParticles.begin(), sortedMCParticles.end(), PointerLessThan<MCParticle>());
765 for (
const MCParticle *
const pMCParticle : sortedMCParticles)
768 if (pfoToMCParticleHitSharingMap.find(pPfo) == pfoToMCParticleHitSharingMap.end())
770 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
772 if (mcParticleToPfoHitSharingMap.find(pMCParticle) == mcParticleToPfoHitSharingMap.end())
773 if (!mcParticleToPfoHitSharingMap.insert(MCParticleToPfoHitSharingMap::value_type(pMCParticle,
PfoToSharedHitsVector())).second)
774 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
780 if (std::any_of(mcHitPairs.begin(), mcHitPairs.end(),
782 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
784 if (std::any_of(pfoHitPairs.begin(), pfoHitPairs.end(), [&](
const PfoCaloHitListPair &pair) {
return (pair.first == pPfo); }))
785 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
788 const CaloHitList sharedHits(
791 if (!sharedHits.empty())
796 std::sort(mcHitPairs.begin(), mcHitPairs.end(),
799 return ((a.second.size() != b.second.size()) ? a.second.size() > b.second.size()
803 std::sort(pfoHitPairs.begin(), pfoHitPairs.end(),
805 return ((a.second.size() != b.second.size()) ? a.second.size() > b.second.size()
827 for (
const Cluster *
const pCluster : clusterList)
829 CaloHitList caloHitList;
832 if (!clusterToReconstructable2DHitsMap.insert(ClusterContributionMap::value_type(pCluster, caloHitList)).second)
833 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
845 switch (pLArMCParticle->GetProcess())
866 switch (pLArMCParticle->GetProcess())
889 switch (pLArMCParticle->GetProcess())
908 switch (pLArMCParticle->GetProcess())
930 switch (pLArMCParticle->GetProcess())
967 switch (pLArMCParticle->GetProcess())
989 switch (pLArMCParticle->GetProcess())
1007 if (!pLArMCParticle)
1010 switch (pLArMCParticle->GetProcess())
1026 CaloHitList sharedHits;
1028 for (
const CaloHit *
const pCaloHit : hitListA)
1030 if (std::find(hitListB.begin(), hitListB.end(), pCaloHit) != hitListB.end())
1031 sharedHits.push_back(pCaloHit);
1041 CartesianVector childDirection{pMCChild->GetEndpoint() - pMCChild->GetVertex()};
1042 if (childDirection.GetMagnitude() < std::numeric_limits<float>::epsilon())
1044 childDirection = childDirection.GetUnitVector();
1046 const MCParticle *pMCUpstream{pMCParent};
1049 CartesianVector parentDirection{pMCUpstream->GetEndpoint() - pMCUpstream->GetVertex()};
1050 if (parentDirection.GetMagnitude() > std::numeric_limits<float>::epsilon())
1052 parentDirection = parentDirection.GetUnitVector();
1053 return parentDirection.GetDotProduct(childDirection) >= cosAngleTolerance;
1057 const MCParticleList &parentList{pMCUpstream->GetParentList()};
1058 const size_t size{parentList.size()};
1060 pMCUpstream = parentList.front();
1075 const MCContributionMapVector &selectedMCParticleToHitsMaps, CaloHitList &reconstructableCaloHitList2D,
const bool foldBackHierarchy)
1082 if (foldBackHierarchy)
1088 pfoList.push_back(pPfo);
1097 const MCContributionMapVector &selectedMCParticleToHitsMaps, CaloHitList &reconstructableCaloHitList2D,
const bool foldBackHierarchy)
1103 if (foldBackHierarchy)
1108 pfoList.push_back(pPfo);
1117 pfoList.push_back(pPfo);
1126 const PfoList &pfoList,
const MCContributionMapVector &selectedMCParticleToHitsMaps, CaloHitList &reconstructableCaloHitList2D)
1128 CaloHitList caloHitList2D;
1137 for (
const CaloHit *
const pCaloHit : caloHitList2D)
1139 bool isTargetHit(
false);
1140 for (
const MCContributionMap &mcParticleToHitsMap : selectedMCParticleToHitsMaps)
1143 for (
const MCContributionMap::value_type &mapEntry : mcParticleToHitsMap)
1145 if (std::find(mapEntry.second.begin(), mapEntry.second.end(), pCaloHit) != mapEntry.second.end())
1156 reconstructableCaloHitList2D.push_back(pCaloHit);
1165 const CaloHitList &isolatedCaloHitList{pCluster->GetIsolatedCaloHitList()};
1166 CaloHitList caloHitList;
1167 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
1168 for (
const CaloHit *pCaloHit : isolatedCaloHitList)
1169 caloHitList.push_back(pCaloHit);
1172 for (
const CaloHit *
const pCaloHit : caloHitList)
1174 bool isTargetHit{
false};
1177 for (
const MCContributionMap::value_type &mapEntry : mcParticleToHitsMap)
1179 if (std::find(mapEntry.second.begin(), mapEntry.second.end(), pCaloHit) != mapEntry.second.end())
1190 reconstructableCaloHitList2D.push_back(pCaloHit);
1197 CaloHitList &selectedCaloHitList,
const bool selectInputHits,
const float maxPhotonPropagation)
1199 if (!selectInputHits)
1201 selectedCaloHitList.insert(selectedCaloHitList.end(), pCaloHitList->begin(), pCaloHitList->end());
1205 for (
const CaloHit *
const pCaloHit : *pCaloHitList)
1209 const MCParticle *
const pHitParticle(MCParticleHelper::GetMainMCParticle(pCaloHit));
1213 if (mcToTargetMCMap.end() == mcIter)
1219 if (
PassMCParticleChecks(pPrimaryParticle, pPrimaryParticle, pHitParticle, maxPhotonPropagation))
1220 selectedCaloHitList.push_back(pCaloHit);
1222 catch (
const StatusCodeException &)
1232 const MCParticle *pCurrentParticle = pMCParticle;
1233 while (!pCurrentParticle->GetParentList().empty())
1235 if (pCurrentParticle->GetParentList().size() > 1)
1236 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
1238 const MCParticle *pParent = *(pCurrentParticle->GetParentList().begin());
1239 const bool found{isChargeSensitive ? pParent->GetParticleId() == pdg :
std::abs(pParent->GetParticleId()) ==
std::abs(pdg)};
1242 pCurrentParticle = pParent;
1253 MCParticleList queue;
1254 mcParticleList.emplace_back(pRoot);
1255 queue.emplace_back(pRoot);
1257 while (!queue.empty())
1259 const MCParticleList &daughters{queue.front()->GetDaughterList()};
1261 for (
const MCParticle *pDaughter : daughters)
1263 mcParticleList.emplace_back(pDaughter);
1264 queue.emplace_back(pDaughter);
1275 for (
const MCParticle *
const pMCTarget : candidateTargets)
1278 if (mcToTrueHitListMap.end() == trueHitsIter)
1281 const CaloHitList &caloHitList(trueHitsIter->second);
1284 CaloHitList goodCaloHitList;
1291 unsigned int nGoodViews(0);
1304 if (!selectedMCParticlesToHitsMap.insert(MCContributionMap::value_type(pMCTarget, caloHitList)).second)
1305 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
1312 CaloHitList &selectedGoodCaloHitList,
const bool selectInputHits,
const float minHitSharingFraction)
1314 if (!selectInputHits)
1316 selectedGoodCaloHitList.insert(selectedGoodCaloHitList.end(), pSelectedCaloHitList->begin(), pSelectedCaloHitList->end());
1320 for (
const CaloHit *
const pCaloHit : *pSelectedCaloHitList)
1323 for (
const auto &mapEntry : pCaloHit->GetMCParticleWeightMap())
1324 mcParticleVector.push_back(mapEntry.first);
1325 std::sort(mcParticleVector.begin(), mcParticleVector.end(), PointerLessThan<MCParticle>());
1327 MCParticleWeightMap targetWeightMap;
1329 for (
const MCParticle *
const pMCParticle : mcParticleVector)
1331 const float weight(pCaloHit->GetMCParticleWeightMap().at(pMCParticle));
1334 if (mcToTargetMCMap.end() != mcIter)
1335 targetWeightMap[mcIter->second] +=
weight;
1339 for (
const auto &mapEntry : targetWeightMap)
1340 mcTargetVector.push_back(mapEntry.first);
1341 std::sort(mcTargetVector.begin(), mcTargetVector.end(), PointerLessThan<MCParticle>());
1343 const MCParticle *pBestTargetParticle(
nullptr);
1344 float bestTargetWeight(0.
f), targetWeightSum(0.
f);
1346 for (
const MCParticle *
const pTargetMCParticle : mcTargetVector)
1348 const float targetWeight(targetWeightMap.at(pTargetMCParticle));
1349 targetWeightSum += targetWeight;
1351 if (targetWeight > bestTargetWeight)
1353 bestTargetWeight = targetWeight;
1354 pBestTargetParticle = pTargetMCParticle;
1358 if (!pBestTargetParticle || (targetWeightSum < std::numeric_limits<float>::epsilon()) || ((bestTargetWeight / targetWeightSum) < minHitSharingFraction))
1361 selectedGoodCaloHitList.push_back(pCaloHit);
1370 for (
const MCParticle *
const pMCParticle : inputMCParticles)
1374 if (!fCriteria(pMCParticle))
1390 selectedParticles.push_back(pMCParticle);
1397 const MCParticle *
const pHitMCParticle,
const float maxPhotonPropagation)
1399 if (NEUTRON ==
std::abs(pThisMCParticle->GetParticleId()))
1402 if ((PHOTON == pThisMCParticle->GetParticleId()) && (PHOTON != pOriginalPrimary->GetParticleId()) &&
1403 (E_MINUS !=
std::abs(pOriginalPrimary->GetParticleId())))
1405 if ((pThisMCParticle->GetEndpoint() - pThisMCParticle->GetVertex()).GetMagnitude() > maxPhotonPropagation)
1409 if (pThisMCParticle == pHitMCParticle)
1412 for (
const MCParticle *
const pDaughterMCParticle : pThisMCParticle->GetDaughterList())
1414 if (
PassMCParticleChecks(pOriginalPrimary, pDaughterMCParticle, pHitMCParticle, maxPhotonPropagation))
static bool IsVisible(const pandora::MCParticle *const pMCParticle)
Whether a mc particle is visible (i.e. long-lived charged particle)
static void GetFirstVisibleMCParticles(const pandora::MCParticle *const pRoot, pandora::MCParticleList &visibleParticleList)
Get the first visible MC particles given a root particle. For example, given a neutrino this would re...
static bool PassMCParticleChecks(const pandora::MCParticle *const pOriginalPrimary, const pandora::MCParticle *const pThisMCParticle, const pandora::MCParticle *const pHitMCParticle, const float maxPhotonPropagation)
Whether it is possible to navigate from a primary mc particle to a downstream mc particle without "pa...
unsigned int m_minPrimaryGoodViews
the minimum number of primary good views
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
static bool IsNuclear(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from a nuclear interaction process.
Header file for the pfo helper class.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
bool m_selectInputHits
whether to select input hits
std::pair< const pandora::MCParticle *, pandora::CaloHitList > MCParticleCaloHitListPair
static void GetTestBeamHierarchyPfoToReconstructable2DHitsMap(const pandora::PfoList &pfoList, const MCContributionMap &selectedMCParticleToHitsMap, PfoContributionMap &pfoToReconstructable2DHitsMap, const bool foldBackHierarchy)
Get mapping from Pfo in reconstructed test beam hierarchy to reconstructable 2D hits (=good hits belo...
static bool IsPrimary(const pandora::MCParticle *const pMCParticle)
Whether a provided mc particle matches the implemented definition of being primary.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
static void GetLeadingMCParticleList(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &mcLeadingVector)
Get vector of leading MC particles from an input list of MC particles.
static bool IsLeadingBeamParticle(const pandora::MCParticle *const pMCParticle)
Returns true if passed a leading beam MCParticle.
unsigned int m_minPrimaryGoodHits
the minimum number of primary good Hits
int GetNuanceCode() const
Get the nuance code.
static void GetPfoToReconstructable2DHitsMap(const pandora::PfoList &pfoList, const MCContributionMap &selectedMCParticleToHitsMap, PfoContributionMap &pfoToReconstructable2DHitsMap, const bool foldBackHierarchy)
Get mapping from Pfo to reconstructable 2D hits (=good hits belonging to a selected reconstructable M...
std::unordered_map< const pandora::CaloHit *, const pandora::MCParticle * > CaloHitToMCMap
constexpr auto abs(T v)
Returns the absolute value of the argument.
static int GetHierarchyTier(const pandora::MCParticle *const pMCParticle)
Determine the position in the hierarchy for the MCParticle.
static void GetPfoMCParticleHitSharingMaps(const PfoContributionMap &pfoToReconstructable2DHitsMap, const MCContributionMapVector &selectedMCParticleToHitsMaps, PfoToMCParticleHitSharingMap &pfoToMCParticleHitSharingMap, MCParticleToPfoHitSharingMap &mcParticleToPfoHitSharingMap)
Get the mappings from Pfo -> pair (reconstructable MCparticles, number of reconstructable 2D hits sha...
static const pandora::MCParticle * GetPrimaryMCParticle(const pandora::MCParticle *const pMCParticle)
Get the primary parent mc particle.
std::map< const pandora::MCParticle *, PfoToSharedHitsVector > MCParticleToPfoHitSharingMap
std::vector< PfoCaloHitListPair > PfoToSharedHitsVector
static void SelectGoodCaloHits(const pandora::CaloHitList *const pSelectedCaloHitList, const MCRelationMap &mcToTargetMCMap, pandora::CaloHitList &selectedGoodCaloHitList, const bool selectInputHits, const float minHitSharingFraction)
Apply further selection criteria to end up with a collection of "good" calo hits that can be use to d...
bool m_foldBackHierarchy
whether to fold the hierarchy back to the primary (neutrino) or leading particles (test beam) ...
static void SelectReconstructableTestBeamHierarchyMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters ¶meters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles in the relevant hierarchy that match given criteria...
static void GetMCPrimaryMap(const pandora::MCParticleList *const pMCParticleList, MCRelationMap &mcPrimaryMap)
Get mapping from individual mc particles (in a provided list) and their primary parent mc particles...
static bool IsPairProduction(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from a pair production process.
Header file for the lar monitoring helper helper class.
static const pandora::MCParticle * GetMainMCParticle(const pandora::ParticleFlowObject *const pPfo)
Find the mc particle making the largest contribution to 2D clusters in a specified pfo...
static unsigned int GetNuanceCode(const pandora::MCParticle *const pMCParticle)
Get the nuance code of an MCParticle.
unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
static const pandora::MCParticle * GetLeadingMCParticle(const pandora::MCParticle *const pMCParticle, const int hierarchyTierLimit=1)
Get the leading particle in the hierarchy, for use at ProtoDUNE.
float m_maxPhotonPropagation
the maximum photon propagation length
static void SelectParticlesByHitCount(const pandora::MCParticleVector &candidateTargets, const MCContributionMap &mcToTrueHitListMap, const MCRelationMap &mcToTargetMCMap, const PrimaryParameters ¶meters, MCContributionMap &selectedMCParticlesToHitsMap)
Filter an input vector of MCParticles to ensure they have sufficient good hits to be reconstructable...
static void CollectReconstructableTestBeamHierarchy2DHits(const pandora::ParticleFlowObject *const pPfo, const MCContributionMapVector &selectedMCParticleToHitsMaps, pandora::CaloHitList &reconstructableCaloHitList2D, const bool foldBackHierarchy)
For a given Pfo, collect the hits which are reconstructable (=good hits belonging to a selected recon...
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
static bool IsCosmicRay(const pandora::MCParticle *const pMCParticle)
Return true if passed a primary cosmic ray MCParticle.
static bool IsInelasticScatter(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle came from an inelastic scattering process.
static bool IsLeading(const pandora::MCParticle *const pMCParticle)
Whether a provided mc particle matches the implemented definition of being leading.
static void SelectReconstructableMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters ¶meters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles that match given criteria.
static bool IsTestBeam(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a test beam particle.
static void GetMCToSelfMap(const pandora::MCParticleList *const pMCParticleList, MCRelationMap &mcToSelfMap)
Get mapping from individual mc particles (in a provided list) to themselves (to be used when not fold...
Header file for the lar monte carlo particle helper helper class.
Header file for the cluster helper class.
static void GetMCParticleToCaloHitMatches(const pandora::CaloHitList *const pCaloHitList, const MCRelationMap &mcToTargetMCMap, CaloHitToMCMap &hitToMCMap, MCContributionMap &mcToTrueHitListMap)
Match calo hits to their parent particles.
static bool IsBeamParticle(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary beam MCParticle.
std::unordered_map< const pandora::Cluster *, pandora::CaloHitList > ClusterContributionMap
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
static const pandora::MCParticle * GetParentMCParticle(const pandora::MCParticle *const pMCParticle)
Get the parent mc particle.
static bool IsTriggeredBeamParticle(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary triggered beam MCParticle.
static void GetMCToHitsMap(const pandora::CaloHitList *const pCaloHitList2S, const pandora::MCParticleList *const pMCParticleList, LArMCParticleHelper::MCContributionMap &mcToHitsMap)
float m_minHitSharingFraction
the minimum Hit sharing fraction
static void GetMCLeadingMap(const pandora::MCParticleList *const pMCParticleList, MCRelationMap &mcLeadingMap)
Get mapping from individual mc particles (in a provided list) and their leading parent mc particles...
static bool IsDecay(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from a decay process.
static void CompleteMCHierarchy(const LArMCParticleHelper::MCContributionMap &mcToHitsMap, pandora::MCParticleList &mcHierarchy)
std::vector< MCContributionMap > MCContributionMapVector
static bool AreTopologicallyContinuous(const pandora::MCParticle *const pMCParent, const pandora::MCParticle *const pMCChild, const float cosAngleTolerance)
Determine if two MC particles are topologically continuous within a given tolerance. If the parent does not travel any distance, a travelling parent is sought and the comparison made between this and the child. If no travelling parent can be found, the particles are treated as continuous.
static bool IsBremsstrahlung(const pandora::MCParticle *const pMCParticle)
static void GetPrimaryMCParticleList(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &mcPrimaryVector)
Get vector of primary MC particles from an input list of MC particles.
static bool DoesPrimaryMeetCriteria(const pandora::MCParticle *const pMCParticle, std::function< bool(const pandora::MCParticle *const)> fCriteria)
Returns true if passed particle whose primary meets the passed criteria.
static void GetAllAncestorMCParticles(const pandora::MCParticle *const pMCParticle, pandora::MCParticleList &ancestorMCParticleList)
Get all ancestor mc particles.
static void CollectReconstructable2DHits(const pandora::ParticleFlowObject *const pPfo, const MCContributionMapVector &selectedMCParticleToHitsMaps, pandora::CaloHitList &reconstructableCaloHitList2D, const bool foldBackHierarchy)
For a given Pfo, collect the hits which are reconstructable (=good hits belonging to a selected recon...
static void GetTrueNeutrinos(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &trueNeutrinos)
Get neutrino MC particles from an input MC particle list.
std::pair< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoCaloHitListPair
static bool IsCapture(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from a capture process.
static void GetIsolatedCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of isolated calo hits of a particular hit type from a list of pfos.
PrimaryParameters()
Constructor.
static void GetClusterToReconstructable2DHitsMap(const pandora::ClusterList &clusterList, const MCContributionMap &selectedMCToHitsMap, ClusterContributionMap &clusterToReconstructable2DHitsMap)
Get mapping from cluster to reconstructable 2D hits (=good hits belonging to a selected reconstructab...
static void GetAllDownstreamPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively, of all daughters associated with those pfos in an input lis...
static bool IsIonisation(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from an ionisation process.
static bool DoesLeadingMeetCriteria(const pandora::MCParticle *const pMCParticle, std::function< bool(const pandora::MCParticle *const)> fCriteria)
Returns true if passed particle whose leading meets the passed criteria.
static bool GetTrueVertex(const pandora::MCParticleList *const pMCParticleList, pandora::CartesianVector &trueVertex)
Retrieve the true neutrino vertex.
std::vector< MCParticleCaloHitListPair > MCParticleToSharedHitsVector
static void SelectParticlesMatchingCriteria(const pandora::MCParticleVector &inputMCParticles, std::function< bool(const pandora::MCParticle *const)> fCriteria, pandora::MCParticleVector &selectedParticles, const PrimaryParameters ¶meters, const bool isTestBeam)
Select mc particles matching given criteria from an input list.
static void GetTrueTestBeamParticles(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &trueTestBeamParticles)
Get triggered test beam MC particles from an input MC particle list.
static bool IsDescendentOf(const pandora::MCParticle *const pMCParticle, const int pdg, const bool isChargeSensitive=false)
Determine if the MC particle is a descendent of a particle with the given PDG code.
std::unordered_map< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoContributionMap
static void GetAllDescendentMCParticles(const pandora::MCParticle *const pMCParticle, pandora::MCParticleList &descendentMCParticleList)
Get all descendent mc particles.
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
static pandora::CaloHitList GetSharedHits(const pandora::CaloHitList &hitListA, const pandora::CaloHitList &hitListB)
Get the hits in the intersection of two hit lists.
static bool IsBeamNeutrinoFinalState(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary neutrino final state MCParticle.
static unsigned int CountHitsByType(const pandora::HitType hitType, const pandora::CaloHitList &caloHitList)
Count the number of calo hits, in a provided list, of a specified type.
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
static void GetBreadthFirstHierarchyRepresentation(const pandora::MCParticle *const pMCParticle, pandora::MCParticleList &mcParticleList)
Retrieve a linearised representation of the MC particle hierarchy in breadth first order...
static bool IsElasticScatter(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle came from an elastic scattering process.
std::map< const pandora::ParticleFlowObject *, MCParticleToSharedHitsVector > PfoToMCParticleHitSharingMap
static bool IsNeutrino(const pandora::MCParticle *const pMCParticle)
Whether a mc particle is a neutrino or antineutrino.
static void SelectCaloHits(const pandora::CaloHitList *const pCaloHitList, const MCRelationMap &mcToTargetMCMap, pandora::CaloHitList &selectedCaloHitList, const bool selectInputHits, const float maxPhotonPropagation)
Select a subset of calo hits representing those that represent "reconstructable" regions of the event...