Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
CheatingSliceSelectionTool.cc
Go to the documentation of this file.
1
10
12
14
15using namespace pandora;
16
17namespace lar_content
18{
19
20CheatingSliceSelectionTool::CheatingSliceSelectionTool() : m_maxSlices{1}, m_threshold{-1.f}, m_cutVariable{"completeness"}
21{
22}
23
24//-----------------------------------------------------------------------------------------------------------------------------------------
25
26void CheatingSliceSelectionTool::SelectSlices(const pandora::Algorithm *const /*pAlgorithm*/, const SliceVector &inputSliceVector, SliceVector &outputSliceVector)
27{
28 // ATTN Ensure this only runs if slicing enabled
29 unsigned int sliceCounter{0};
30 MetricSliceIndexMap reducedSliceVarIndexMap;
31
32 FloatVector targetWeights(inputSliceVector.size());
33 FloatVector otherWeights(inputSliceVector.size());
34
35 // Calculate target and total weight for each slice
36 for (const CaloHitList &sliceHits : inputSliceVector)
37 {
38 CaloHitList localHitList{};
39 // ATTN Must ensure we copy the hit actually owned by master instance; access differs with/without slicing enabled
40 for (const CaloHit *const pSliceCaloHit : sliceHits)
41 localHitList.push_back(static_cast<const CaloHit *>(pSliceCaloHit->GetParentAddress()));
42
43 for (const CaloHit *const pCaloHit : localHitList)
44 {
45 float thisTargetParticleWeight{0.f}, thisTotalWeight{0.f};
46 const MCParticleWeightMap &hitMCParticleWeightMap(pCaloHit->GetMCParticleWeightMap());
47
48 if (hitMCParticleWeightMap.empty())
49 continue;
50
51 MCParticleList mcParticleList;
52 for (const auto &mapEntry : hitMCParticleWeightMap)
53 mcParticleList.push_back(mapEntry.first);
54 mcParticleList.sort(LArMCParticleHelper::SortByMomentum);
55
56 for (const MCParticle *const pMCParticle : mcParticleList)
57 {
58 const float weight{hitMCParticleWeightMap.at(pMCParticle)};
59 const MCParticle *const pParentMCParticle{LArMCParticleHelper::GetParentMCParticle(pMCParticle)};
60
61 if (this->IsTarget(pParentMCParticle))
62 thisTargetParticleWeight += weight;
63
64 thisTotalWeight += weight;
65 }
66
67 // ATTN normalise arbitrary input weights at this point
68 if (thisTotalWeight > std::numeric_limits<float>::epsilon())
69 {
70 thisTargetParticleWeight *= 1.f / thisTotalWeight;
71 thisTotalWeight = 1.f;
72 }
73 else
74 {
75 thisTargetParticleWeight = 0.f;
76 thisTotalWeight = 0.f;
77 }
78 targetWeights[sliceCounter] += thisTargetParticleWeight;
79 otherWeights[sliceCounter] += (1. - thisTargetParticleWeight);
80 }
81
82 ++sliceCounter;
83 }
84
85 float totalTargetWeight{0.f};
86 for (const float weight : targetWeights)
87 totalTargetWeight += weight;
88
89 // Add slices passing cut threshold to map
90 for (unsigned int i = 0; i < targetWeights.size(); ++i)
91 {
92 const float sliceWeight = targetWeights[i] + otherWeights[i];
93 const float completeness{totalTargetWeight > std::numeric_limits<float>::epsilon() ? targetWeights[i] / totalTargetWeight : 0.f};
94 const float purity{sliceWeight > std::numeric_limits<float>::epsilon() ? targetWeights[i] / sliceWeight : 0.f};
95 // Already checked correctness of variable in ReadSettings
96 if (m_cutVariable == "completeness")
97 {
98 if (completeness >= m_threshold)
99 reducedSliceVarIndexMap.emplace(completeness, i);
100 }
101 else if (m_cutVariable == "purity")
102 {
103 if (purity >= m_threshold)
104 reducedSliceVarIndexMap.emplace(purity, i);
105 }
106 }
107 // Select the best m_maxSlices slices - prefix increment ensures all slices retained if m_maxSlices == 0
108 std::vector<int> reducedSliceIndices{};
109 int i = 0;
110 for (const auto [cutVariable, index] : reducedSliceVarIndexMap)
111 { // ATTN: Map is sorted on cut variable from max to min
112 (void)cutVariable; // GCC 7 support, versions 8+ do not need this
113 reducedSliceIndices.push_back(index);
114 outputSliceVector.push_back(inputSliceVector[index]);
115 if (++i == m_maxSlices)
116 break;
117 }
118}
119
120//------------------------------------------------------------------------------------------------------------------------------------------
121
123{
124 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxSlices", m_maxSlices));
125 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Threshold", m_threshold));
126
127 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CutVariable", m_cutVariable));
128 std::transform(m_cutVariable.begin(), m_cutVariable.end(), m_cutVariable.begin(), [](unsigned char c) { return std::tolower(c); });
129 if (m_cutVariable != "completeness" && m_cutVariable != "purity")
130 {
131 std::cout << "CheatingSliceSelectionTool::ReadSettings: Unknown cut variable \'" << m_cutVariable << "\'" << std::endl;
132 return STATUS_CODE_INVALID_PARAMETER;
133 }
134
135 return STATUS_CODE_SUCCESS;
136}
137
138} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the cheating slice selection tool class.
Header file for the lar monte carlo particle helper helper class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
void SelectSlices(const pandora::Algorithm *const pAlgorithm, const SliceVector &inputSliceVector, SliceVector &outputSliceVector)
Select which slice(s) to use.
virtual bool IsTarget(const pandora::MCParticle *const mcParticle) const =0
Template method to determine if an MC particle matches the target criteria for slice selection....
float m_threshold
The minimum cut threshold to retain a slice (< 0 for no threshold) - default -1.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
std::map< float, int, std::greater< float > > MetricSliceIndexMap
std::string m_cutVariable
The variable to cut on ("purity" or "completeness") - default "completeness".
int m_maxSlices
The maximum number of slices to retain (0 to retain all) - default 0.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
static const pandora::MCParticle * GetParentMCParticle(const pandora::MCParticle *const pMCParticle)
Get the parent mc particle.
Algorithm class. Algorithm addresses are held only by the algorithm manager. They have a fully define...
Definition Algorithm.h:21
CaloHit class.
Definition CaloHit.h:26
MCParticle class.
Definition MCParticle.h:26
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::vector< pandora::CaloHitList > SliceVector
MANAGED_CONTAINER< const MCParticle * > MCParticleList
std::unordered_map< const MCParticle *, float > MCParticleWeightMap
MANAGED_CONTAINER< const CaloHit * > CaloHitList
std::vector< float > FloatVector
StatusCode
The StatusCode enum.