Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
PreProcessingAlgorithm.cc
Go to the documentation of this file.
1
10
12
14
16
17using namespace pandora;
18
19namespace lar_content
20{
21
23 m_mipEquivalentCut(std::numeric_limits<float>::epsilon()),
24 m_minCellLengthScale(std::numeric_limits<float>::epsilon()),
25 m_maxCellLengthScale(3.f),
26 m_searchRegion1D(0.1f),
27 m_maxEventHits(std::numeric_limits<unsigned int>::max()),
28 m_onlyAvailableCaloHits(true),
29 m_inputCaloHitListName("Input")
30{
31}
32
33//------------------------------------------------------------------------------------------------------------------------------------------
34
36{
37 m_processedHits.clear();
38 return STATUS_CODE_SUCCESS;
39}
40
41//------------------------------------------------------------------------------------------------------------------------------------------
42
44{
45 if (!this->GetPandora().GetSettings()->SingleHitTypeClusteringMode())
46 {
47 std::cout << "PreProcessingAlgorithm: expect Pandora to be configured in SingleHitTypeClusteringMode." << std::endl;
48 return STATUS_CODE_FAILURE;
49 }
50
51 try
52 {
53 this->ProcessCaloHits();
54 }
55 catch (const StatusCodeException &statusCodeException)
56 {
57 if (STATUS_CODE_OUT_OF_RANGE == statusCodeException.GetStatusCode())
58 {
59 std::cout << "PreProcessingAlgorithm: Excessive number of hits in event, skipping the reconstruction" << std::endl;
61 }
62 }
63
65 {
67 {
69 std::cout << "PreProcessingAlgorithm: could not replace current calo hit list with list named: " << m_currentCaloHitListReplacement
70 << std::endl;
71 }
72 }
73
74 return STATUS_CODE_SUCCESS;
75}
76
77//------------------------------------------------------------------------------------------------------------------------------------------
78
80{
81 const CaloHitList *pCaloHitList(nullptr);
82 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_inputCaloHitListName, pCaloHitList));
83
84 if (pCaloHitList->empty())
85 return;
86
87 if (pCaloHitList->size() > m_maxEventHits)
88 throw StatusCodeException(STATUS_CODE_OUT_OF_RANGE);
89
90 CaloHitList selectedCaloHitListU, selectedCaloHitListV, selectedCaloHitListW;
91
92 for (const CaloHit *const pCaloHit : *pCaloHitList)
93 {
94 if (m_processedHits.count(pCaloHit))
95 continue;
96
97 (void)m_processedHits.insert(pCaloHit);
98
100 continue;
101
102 if (pCaloHit->GetMipEquivalentEnergy() < m_mipEquivalentCut)
103 continue;
104
105 if (pCaloHit->GetInputEnergy() < std::numeric_limits<float>::epsilon())
106 {
108 std::cout << "PreProcessingAlgorithm: found a hit with zero energy, will remove it" << std::endl;
109
110 continue;
111 }
112
113 if ((pCaloHit->GetCellLengthScale() < m_minCellLengthScale) || (pCaloHit->GetCellLengthScale() > m_maxCellLengthScale))
114 {
116 {
117 std::cout << "PreProcessingAlgorithm: found a hit with extent " << pCaloHit->GetCellLengthScale() << ", require ("
118 << m_minCellLengthScale << " - " << m_maxCellLengthScale << "), will remove it" << std::endl;
119 }
120
121 continue;
122 }
123
124 if (TPC_VIEW_U == pCaloHit->GetHitType())
125 {
126 selectedCaloHitListU.push_back(pCaloHit);
127 }
128 else if (TPC_VIEW_V == pCaloHit->GetHitType())
129 {
130 selectedCaloHitListV.push_back(pCaloHit);
131 }
132 else if (TPC_VIEW_W == pCaloHit->GetHitType())
133 {
134 selectedCaloHitListW.push_back(pCaloHit);
135 }
136 }
137
138 CaloHitList filteredCaloHitListU, filteredCaloHitListV, filteredCaloHitListW;
139 this->GetFilteredCaloHitList(selectedCaloHitListU, filteredCaloHitListU);
140 this->GetFilteredCaloHitList(selectedCaloHitListV, filteredCaloHitListV);
141 this->GetFilteredCaloHitList(selectedCaloHitListW, filteredCaloHitListW);
142
143 CaloHitList filteredInputList;
144 filteredInputList.insert(filteredInputList.end(), filteredCaloHitListU.begin(), filteredCaloHitListU.end());
145 filteredInputList.insert(filteredInputList.end(), filteredCaloHitListV.begin(), filteredCaloHitListV.end());
146 filteredInputList.insert(filteredInputList.end(), filteredCaloHitListW.begin(), filteredCaloHitListW.end());
147
148 if (!filteredInputList.empty() && !m_filteredCaloHitListName.empty())
149 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, filteredInputList, m_filteredCaloHitListName));
150
151 if (!filteredCaloHitListU.empty() && !m_outputCaloHitListNameU.empty())
152 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, filteredCaloHitListU, m_outputCaloHitListNameU));
153
154 if (!filteredCaloHitListV.empty() && !m_outputCaloHitListNameV.empty())
155 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, filteredCaloHitListV, m_outputCaloHitListNameV));
156
157 if (!filteredCaloHitListW.empty() && !m_outputCaloHitListNameW.empty())
158 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, filteredCaloHitListW, m_outputCaloHitListNameW));
159}
160
161//------------------------------------------------------------------------------------------------------------------------------------------
162
164{
165 CaloHitList emptyList;
166
167 try
168 {
169 if (!m_filteredCaloHitListName.empty())
170 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, emptyList, m_filteredCaloHitListName));
171
172 if (!m_outputCaloHitListNameU.empty())
173 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, emptyList, m_outputCaloHitListNameU));
174
175 if (!m_outputCaloHitListNameV.empty())
176 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, emptyList, m_outputCaloHitListNameV));
177
178 if (!m_outputCaloHitListNameW.empty())
179 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, emptyList, m_outputCaloHitListNameW));
180 }
181 catch (...)
182 {
183 std::cout << "PreProcessingAlgorithm: Unable to create void calo hit lists" << std::endl;
184 }
185}
186
187//------------------------------------------------------------------------------------------------------------------------------------------
188
190{
191 HitKDTree2D kdTree;
192 HitKDNode2DList hitKDNode2DList;
193
194 KDTreeBox hitsBoundingRegion2D = fill_and_bound_2d_kd_tree(inputList, hitKDNode2DList);
195 kdTree.build(hitKDNode2DList, hitsBoundingRegion2D);
196
197 // Remove hits that are in the same physical location!
198 for (const CaloHit *const pCaloHit1 : inputList)
199 {
200 bool isUnique(true);
202
203 HitKDNode2DList found;
204 kdTree.search(searchRegionHits, found);
205
206 for (const auto &hit : found)
207 {
208 const CaloHit *const pCaloHit2(hit.data);
209
210 if (pCaloHit1 == pCaloHit2)
211 continue;
212
213 const float displacementSquared((pCaloHit2->GetPositionVector() - pCaloHit1->GetPositionVector()).GetMagnitudeSquared());
214
215 if (displacementSquared < std::numeric_limits<float>::epsilon())
216 {
217 const float deltaMip(pCaloHit2->GetMipEquivalentEnergy() > pCaloHit1->GetMipEquivalentEnergy());
218
219 if ((deltaMip > std::numeric_limits<float>::epsilon()) ||
220 ((std::fabs(deltaMip) < std::numeric_limits<float>::epsilon()) &&
221 (outputList.end() != std::find(outputList.begin(), outputList.end(), pCaloHit2))))
222 {
223 isUnique = false;
224 break;
225 }
226 }
227 }
228
229 if (isUnique)
230 {
231 outputList.push_back(pCaloHit1);
232 }
233 else
234 {
236 std::cout << "PreProcessingAlgorithm: found two hits in same location, will remove lowest pulse height" << std::endl;
237 }
238 }
239}
240
241//------------------------------------------------------------------------------------------------------------------------------------------
242
244{
246 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MipEquivalentCut", m_mipEquivalentCut));
247
249 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCellLengthScale", m_minCellLengthScale));
250
252 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxCellLengthScale", m_maxCellLengthScale));
253
254 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SearchRegion1D", m_searchRegion1D));
255
256 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxEventHits", m_maxEventHits));
257
259 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "OnlyAvailableCaloHits", m_onlyAvailableCaloHits));
260
262 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "InputCaloHitListName", m_inputCaloHitListName));
263
264 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputCaloHitListNameU", m_outputCaloHitListNameU));
265
266 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputCaloHitListNameV", m_outputCaloHitListNameV));
267
268 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputCaloHitListNameW", m_outputCaloHitListNameW));
269
270 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "FilteredCaloHitListName", m_filteredCaloHitListName));
271
272 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "CurrentCaloHitListReplacement", m_currentCaloHitListReplacement));
273
274 return STATUS_CODE_SUCCESS;
275}
276
277} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the kd tree linker algo template class.
Header file for the cluster helper class.
Header file for the pre processing algorithm class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
static pandora::StatusCode SaveList(const pandora::Algorithm &algorithm, const T &t, const std::string &newListName)
Save a provided input object list under a new name.
static bool IsAvailable(const pandora::Algorithm &algorithm, const T *const pT)
Is object, or a list of objects, available as a building block.
static pandora::StatusCode ReplaceCurrentList(const pandora::Algorithm &algorithm, const std::string &newListName)
Replace the current list with a pre-saved list; use this new list as a permanent replacement for the ...
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > &region)
Build the KD tree from the "eltList" in the space define by "region".
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
void ProcessCaloHits()
Build separate CaloHitLists for each view.
std::string m_currentCaloHitListReplacement
The name of the calo hit list to replace the current list (optional)
void PopulateVoidCaloHitLists() noexcept
Build empty calo hit lists.
void GetFilteredCaloHitList(const pandora::CaloHitList &inputList, pandora::CaloHitList &outputList)
Clean up the input CaloHitList.
std::string m_outputCaloHitListNameW
The output calo hit list name for TPC_VIEW_W hits.
std::string m_outputCaloHitListNameV
The output calo hit list name for TPC_VIEW_V hits.
float m_mipEquivalentCut
Minimum mip equivalent energy for calo hit.
std::string m_inputCaloHitListName
The input calo hit list name.
float m_searchRegion1D
Search region, applied to each dimension, for look-up from kd-trees.
pandora::StatusCode Run()
Run the algorithm.
pandora::CaloHitSet m_processedHits
The set of all previously processed calo hits.
bool m_onlyAvailableCaloHits
Whether to only include available calo hits.
float m_minCellLengthScale
The minimum length scale for calo hit.
unsigned int m_maxEventHits
The maximum number of hits in an event to proceed with the reconstruction.
std::string m_filteredCaloHitListName
The output calo hit list name for all U, V and W hits.
float m_maxCellLengthScale
The maximum length scale for calo hit.
std::vector< HitKDNode2D > HitKDNode2DList
std::string m_outputCaloHitListNameU
The output calo hit list name for TPC_VIEW_U hits.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
pandora::StatusCode Reset()
Perform any operations when pandora is reset, typically at the end of each event.
CaloHit class.
Definition CaloHit.h:26
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:350
float GetMipEquivalentEnergy() const
Get the calibrated mip equivalent energy.
Definition CaloHit.h:476
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 > > &nodes)
fill_and_bound_2d_kd_tree
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.