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);
234 const MCParticle *pParentMCParticle = pMCParticle;
236 while (pParentMCParticle->GetParentList().empty() ==
false)
238 if (1 != pParentMCParticle->GetParentList().size())
239 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
241 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
244 return pParentMCParticle;
251 for (
const MCParticle *pDaughterMCParticle : pMCParticle->GetDaughterList())
253 if (std::find(descendentMCParticleList.begin(), descendentMCParticleList.end(), pDaughterMCParticle) == descendentMCParticleList.end())
255 descendentMCParticleList.emplace_back(pDaughterMCParticle);
264 MCParticleList &leadingShowerParticles, MCParticleList &leadingNeutrons)
266 for (
const MCParticle *pDaughterMCParticle : pMCParticle->GetDaughterList())
268 if (std::find(descendentTrackParticles.begin(), descendentTrackParticles.end(), pDaughterMCParticle) == descendentTrackParticles.end())
270 const int pdg{
std::abs(pDaughterMCParticle->GetParticleId())};
271 if (pdg == E_MINUS || pdg == PHOTON)
273 leadingShowerParticles.emplace_back(pDaughterMCParticle);
275 else if (pdg == NEUTRON)
277 leadingNeutrons.emplace_back(pDaughterMCParticle);
281 descendentTrackParticles.emplace_back(pDaughterMCParticle);
292 const MCParticleList &parentMCParticleList = pMCParticle->GetParentList();
293 if (parentMCParticleList.empty())
295 if (parentMCParticleList.size() != 1)
296 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
298 const MCParticle *pParentMCParticle = *parentMCParticleList.begin();
299 if (std::find(ancestorMCParticleList.begin(), ancestorMCParticleList.end(), pParentMCParticle) == ancestorMCParticleList.end())
301 ancestorMCParticleList.push_back(pParentMCParticle);
310 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
313 mcPrimaryVector.push_back(pMCParticle);
323 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
329 mcLeadingVector.push_back(pMCParticle);
342 visibleParticleList.emplace_back(pRoot);
346 for (
const MCParticle *
const pMCParticle : pRoot->GetDaughterList())
358 const MCParticle *pParentMCParticle = pMCParticle;
359 mcVector.push_back(pParentMCParticle);
361 while (!pParentMCParticle->GetParentList().empty())
363 if (1 != pParentMCParticle->GetParentList().size())
364 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
366 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
367 mcVector.push_back(pParentMCParticle);
371 for (MCParticleVector::const_reverse_iterator iter = mcVector.rbegin(), iterEnd = mcVector.rend(); iter != iterEnd; ++iter)
373 const MCParticle *
const pNextParticle = *iter;
376 return pNextParticle;
379 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
395 const MCParticle *pParentMCParticle = pMCParticle;
396 mcVector.push_back(pParentMCParticle);
398 while (!pParentMCParticle->GetParentList().empty())
400 if (1 != pParentMCParticle->GetParentList().size())
401 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
403 pParentMCParticle = *(pParentMCParticle->GetParentList().begin());
404 mcVector.push_back(pParentMCParticle);
407 int hierarchyTier(0);
408 const MCParticle *pLeadingMCParticle(
nullptr);
411 for (MCParticleVector::const_reverse_iterator iter = mcVector.rbegin(), iterEnd = mcVector.rend(); iter != iterEnd; ++iter)
413 const MCParticle *
const pNextParticle = *iter;
419 if (hierarchyTier <= hierarchyTierLimit)
420 pLeadingMCParticle = pNextParticle;
425 if (!pLeadingMCParticle)
426 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
428 return pLeadingMCParticle;
435 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
440 mcPrimaryMap[pMCParticle] = pPrimaryMCParticle;
442 catch (
const StatusCodeException &)
452 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
457 mcLeadingMap[pMCParticle] = pLeadingMCParticle;
459 catch (
const StatusCodeException &)
469 for (
const MCParticle *
const pMCParticle : *pMCParticleList)
471 mcToSelfMap[pMCParticle] = pMCParticle;
479 ClusterList clusterList;
481 return MCParticleHelper::GetMainMCParticle(&clusterList);
489 const float momentumLhs(pLhs->GetMomentum().GetMagnitudeSquared());
490 const float momentumRhs(pRhs->GetMomentum().GetMagnitudeSquared());
492 if (std::fabs(momentumLhs - momentumRhs) > std::numeric_limits<float>::epsilon())
493 return (momentumLhs > momentumRhs);
496 if (std::fabs(pLhs->GetEnergy() - pRhs->GetEnergy()) > std::numeric_limits<float>::epsilon())
497 return (pLhs->GetEnergy() < pRhs->GetEnergy());
500 if (pLhs->GetParticleId() != pRhs->GetParticleId())
501 return (pLhs->GetParticleId() < pRhs->GetParticleId());
504 const float positionLhs(pLhs->GetVertex().GetMagnitudeSquared());
505 const float positionRhs(pRhs->GetVertex().GetMagnitudeSquared());
507 return (positionLhs < positionRhs);
515 for (
const CaloHit *
const pCaloHit : *pCaloHitList)
519 const MCParticle *
const pHitParticle(MCParticleHelper::GetMainMCParticle(pCaloHit));
520 const MCParticle *pTargetParticle(pHitParticle);
523 if (!mcToTargetMCMap.empty())
527 if (mcToTargetMCMap.end() == mcIter)
530 pTargetParticle = mcIter->second;
533 mcToTrueHitListMap[pTargetParticle].push_back(pCaloHit);
534 hitToMCMap[pCaloHit] = pTargetParticle;
536 catch (StatusCodeException &statusCodeException)
538 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
539 throw statusCodeException;
556 CaloHitList selectedCaloHitList;
572 std::copy(pMCParticleList->begin(), pMCParticleList->end(), std::back_inserter(targetMCVector));
595 CaloHitList selectedCaloHitList;
611 std::copy(pMCParticleList->begin(), pMCParticleList->end(), std::back_inserter(targetMCVector));
622 for (
const MCParticle *
const pMCParticle : candidateTargets)
628 if (selectedMCParticlesToHitsMap.find(pParentMCParticle) == selectedMCParticlesToHitsMap.end())
630 CaloHitList caloHitList;
631 selectedMCParticlesToHitsMap.insert(MCContributionMap::value_type(pParentMCParticle, caloHitList));
642 pfoList,
MCContributionMapVector({selectedMCParticleToHitsMap}), pfoToReconstructable2DHitsMap, foldBackHierarchy);
651 pfoList,
MCContributionMapVector({selectedMCParticleToHitsMap}), pfoToReconstructable2DHitsMap, foldBackHierarchy);
659 for (
const ParticleFlowObject *
const pPfo : pfoList)
661 CaloHitList pfoHitList;
664 if (!pfoToReconstructable2DHitsMap.insert(PfoContributionMap::value_type(pPfo, pfoHitList)).second)
665 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
674 for (
const ParticleFlowObject *
const pPfo : pfoList)
676 CaloHitList pfoHitList;
679 if (!pfoToReconstructable2DHitsMap.insert(PfoContributionMap::value_type(pPfo, pfoHitList)).second)
680 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
690 PfoVector sortedPfos;
691 for (
const auto &mapEntry : pfoToReconstructable2DHitsMap)
692 sortedPfos.push_back(mapEntry.first);
695 for (
const ParticleFlowObject *
const pPfo : sortedPfos)
697 for (
const MCContributionMap &mcParticleToHitsMap : selectedMCParticleToHitsMaps)
700 for (
const auto &mapEntry : mcParticleToHitsMap)
701 sortedMCParticles.push_back(mapEntry.first);
702 std::sort(sortedMCParticles.begin(), sortedMCParticles.end(), PointerLessThan<MCParticle>());
704 for (
const MCParticle *
const pMCParticle : sortedMCParticles)
707 if (pfoToMCParticleHitSharingMap.find(pPfo) == pfoToMCParticleHitSharingMap.end())
709 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
711 if (mcParticleToPfoHitSharingMap.find(pMCParticle) == mcParticleToPfoHitSharingMap.end())
712 if (!mcParticleToPfoHitSharingMap.insert(MCParticleToPfoHitSharingMap::value_type(pMCParticle,
PfoToSharedHitsVector())).second)
713 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
719 if (std::any_of(mcHitPairs.begin(), mcHitPairs.end(),
721 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
723 if (std::any_of(pfoHitPairs.begin(), pfoHitPairs.end(), [&](
const PfoCaloHitListPair &pair) {
return (pair.first == pPfo); }))
724 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
727 const CaloHitList sharedHits(
730 if (!sharedHits.empty())
735 std::sort(mcHitPairs.begin(), mcHitPairs.end(),
738 return ((a.second.size() != b.second.size()) ? a.second.size() > b.second.size()
742 std::sort(pfoHitPairs.begin(), pfoHitPairs.end(),
744 return ((a.second.size() != b.second.size()) ? a.second.size() > b.second.size()
766 for (
const Cluster *
const pCluster : clusterList)
768 CaloHitList caloHitList;
771 if (!clusterToReconstructable2DHitsMap.insert(ClusterContributionMap::value_type(pCluster, caloHitList)).second)
772 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
784 switch (pLArMCParticle->GetProcess())
805 switch (pLArMCParticle->GetProcess())
828 switch (pLArMCParticle->GetProcess())
847 switch (pLArMCParticle->GetProcess())
869 switch (pLArMCParticle->GetProcess())
906 switch (pLArMCParticle->GetProcess())
928 switch (pLArMCParticle->GetProcess())
949 switch (pLArMCParticle->GetProcess())
965 CaloHitList sharedHits;
967 for (
const CaloHit *
const pCaloHit : hitListA)
969 if (std::find(hitListB.begin(), hitListB.end(), pCaloHit) != hitListB.end())
970 sharedHits.push_back(pCaloHit);
980 CartesianVector childDirection{pMCChild->GetEndpoint() - pMCChild->GetVertex()};
981 if (childDirection.GetMagnitude() < std::numeric_limits<float>::epsilon())
983 childDirection = childDirection.GetUnitVector();
985 const MCParticle *pMCUpstream{pMCParent};
988 CartesianVector parentDirection{pMCUpstream->GetEndpoint() - pMCUpstream->GetVertex()};
989 if (parentDirection.GetMagnitude() > std::numeric_limits<float>::epsilon())
991 parentDirection = parentDirection.GetUnitVector();
992 return parentDirection.GetDotProduct(childDirection) >= cosAngleTolerance;
996 const MCParticleList &parentList{pMCUpstream->GetParentList()};
997 const size_t size{parentList.size()};
999 pMCUpstream = parentList.front();
1014 const MCContributionMapVector &selectedMCParticleToHitsMaps, CaloHitList &reconstructableCaloHitList2D,
const bool foldBackHierarchy)
1021 if (foldBackHierarchy)
1027 pfoList.push_back(pPfo);
1036 const MCContributionMapVector &selectedMCParticleToHitsMaps, CaloHitList &reconstructableCaloHitList2D,
const bool foldBackHierarchy)
1042 if (foldBackHierarchy)
1047 pfoList.push_back(pPfo);
1056 pfoList.push_back(pPfo);
1065 const PfoList &pfoList,
const MCContributionMapVector &selectedMCParticleToHitsMaps, CaloHitList &reconstructableCaloHitList2D)
1067 CaloHitList caloHitList2D;
1076 for (
const CaloHit *
const pCaloHit : caloHitList2D)
1078 bool isTargetHit(
false);
1079 for (
const MCContributionMap &mcParticleToHitsMap : selectedMCParticleToHitsMaps)
1082 for (
const MCContributionMap::value_type &mapEntry : mcParticleToHitsMap)
1084 if (std::find(mapEntry.second.begin(), mapEntry.second.end(), pCaloHit) != mapEntry.second.end())
1095 reconstructableCaloHitList2D.push_back(pCaloHit);
1104 const CaloHitList &isolatedCaloHitList{pCluster->GetIsolatedCaloHitList()};
1105 CaloHitList caloHitList;
1106 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
1107 for (
const CaloHit *pCaloHit : isolatedCaloHitList)
1108 caloHitList.push_back(pCaloHit);
1111 for (
const CaloHit *
const pCaloHit : caloHitList)
1113 bool isTargetHit{
false};
1116 for (
const MCContributionMap::value_type &mapEntry : mcParticleToHitsMap)
1118 if (std::find(mapEntry.second.begin(), mapEntry.second.end(), pCaloHit) != mapEntry.second.end())
1129 reconstructableCaloHitList2D.push_back(pCaloHit);
1136 CaloHitList &selectedCaloHitList,
const bool selectInputHits,
const float maxPhotonPropagation)
1138 if (!selectInputHits)
1140 selectedCaloHitList.insert(selectedCaloHitList.end(), pCaloHitList->begin(), pCaloHitList->end());
1144 for (
const CaloHit *
const pCaloHit : *pCaloHitList)
1148 const MCParticle *
const pHitParticle(MCParticleHelper::GetMainMCParticle(pCaloHit));
1152 if (mcToTargetMCMap.end() == mcIter)
1158 if (
PassMCParticleChecks(pPrimaryParticle, pPrimaryParticle, pHitParticle, maxPhotonPropagation))
1159 selectedCaloHitList.push_back(pCaloHit);
1161 catch (
const StatusCodeException &)
1171 const MCParticle *pCurrentParticle = pMCParticle;
1172 while (!pCurrentParticle->GetParentList().empty())
1174 if (pCurrentParticle->GetParentList().size() > 1)
1175 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
1177 const MCParticle *pParent = *(pCurrentParticle->GetParentList().begin());
1178 const bool found{isChargeSensitive ? pParent->GetParticleId() == pdg :
std::abs(pParent->GetParticleId()) ==
std::abs(pdg)};
1181 pCurrentParticle = pParent;
1192 MCParticleList queue;
1193 mcParticleList.emplace_back(pRoot);
1194 queue.emplace_back(pRoot);
1196 while (!queue.empty())
1198 const MCParticleList &daughters{queue.front()->GetDaughterList()};
1200 for (
const MCParticle *pDaughter : daughters)
1202 mcParticleList.emplace_back(pDaughter);
1203 queue.emplace_back(pDaughter);
1214 for (
const MCParticle *
const pMCTarget : candidateTargets)
1217 if (mcToTrueHitListMap.end() == trueHitsIter)
1220 const CaloHitList &caloHitList(trueHitsIter->second);
1223 CaloHitList goodCaloHitList;
1230 unsigned int nGoodViews(0);
1243 if (!selectedMCParticlesToHitsMap.insert(MCContributionMap::value_type(pMCTarget, caloHitList)).second)
1244 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
1251 CaloHitList &selectedGoodCaloHitList,
const bool selectInputHits,
const float minHitSharingFraction)
1253 if (!selectInputHits)
1255 selectedGoodCaloHitList.insert(selectedGoodCaloHitList.end(), pSelectedCaloHitList->begin(), pSelectedCaloHitList->end());
1259 for (
const CaloHit *
const pCaloHit : *pSelectedCaloHitList)
1262 for (
const auto &mapEntry : pCaloHit->GetMCParticleWeightMap())
1263 mcParticleVector.push_back(mapEntry.first);
1264 std::sort(mcParticleVector.begin(), mcParticleVector.end(), PointerLessThan<MCParticle>());
1266 MCParticleWeightMap targetWeightMap;
1268 for (
const MCParticle *
const pMCParticle : mcParticleVector)
1270 const float weight(pCaloHit->GetMCParticleWeightMap().at(pMCParticle));
1273 if (mcToTargetMCMap.end() != mcIter)
1274 targetWeightMap[mcIter->second] +=
weight;
1278 for (
const auto &mapEntry : targetWeightMap)
1279 mcTargetVector.push_back(mapEntry.first);
1280 std::sort(mcTargetVector.begin(), mcTargetVector.end(), PointerLessThan<MCParticle>());
1282 const MCParticle *pBestTargetParticle(
nullptr);
1283 float bestTargetWeight(0.
f), targetWeightSum(0.
f);
1285 for (
const MCParticle *
const pTargetMCParticle : mcTargetVector)
1287 const float targetWeight(targetWeightMap.at(pTargetMCParticle));
1288 targetWeightSum += targetWeight;
1290 if (targetWeight > bestTargetWeight)
1292 bestTargetWeight = targetWeight;
1293 pBestTargetParticle = pTargetMCParticle;
1297 if (!pBestTargetParticle || (targetWeightSum < std::numeric_limits<float>::epsilon()) || ((bestTargetWeight / targetWeightSum) < minHitSharingFraction))
1300 selectedGoodCaloHitList.push_back(pCaloHit);
1309 for (
const MCParticle *
const pMCParticle : inputMCParticles)
1313 if (!fCriteria(pMCParticle))
1329 selectedParticles.push_back(pMCParticle);
1336 const MCParticle *
const pHitMCParticle,
const float maxPhotonPropagation)
1338 if (NEUTRON ==
std::abs(pThisMCParticle->GetParticleId()))
1341 if ((PHOTON == pThisMCParticle->GetParticleId()) && (PHOTON != pOriginalPrimary->GetParticleId()) &&
1342 (E_MINUS !=
std::abs(pOriginalPrimary->GetParticleId())))
1344 if ((pThisMCParticle->GetEndpoint() - pThisMCParticle->GetVertex()).GetMagnitude() > maxPhotonPropagation)
1348 if (pThisMCParticle == pHitMCParticle)
1351 for (
const MCParticle *
const pDaughterMCParticle : pThisMCParticle->GetDaughterList())
1353 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.
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.
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.
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...