Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ThreeDHitCreationAlgorithm.cc
Go to the documentation of this file.
1
10
14
16
19
20#include <algorithm>
21
22using namespace pandora;
23
24namespace lar_content
25{
26
28 m_iterateTrackHits(true),
29 m_iterateShowerHits(false),
30 m_slidingFitHalfWindow(10),
31 m_nHitRefinementIterations(10),
32 m_sigma3DFitMultiplier(0.2),
33 m_iterationMaxChi2Ratio(1.)
34{
35}
36
37//------------------------------------------------------------------------------------------------------------------------------------------
38
39void ThreeDHitCreationAlgorithm::FilterCaloHitsByType(const CaloHitVector &inputCaloHitVector, const HitType hitType, CaloHitVector &outputCaloHitVector) const
40{
41 for (const CaloHit *const pCaloHit : inputCaloHitVector)
42 {
43 if (hitType == pCaloHit->GetHitType())
44 outputCaloHitVector.push_back(pCaloHit);
45 }
46}
47
48//------------------------------------------------------------------------------------------------------------------------------------------
49
51{
52 const PfoList *pPfoList(nullptr);
54 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_inputPfoListName, pPfoList));
55
56 if (!pPfoList || pPfoList->empty())
57 {
59 std::cout << "ThreeDHitCreationAlgorithm: unable to find pfo list " << m_inputPfoListName << std::endl;
60
61 return STATUS_CODE_SUCCESS;
62 }
63
64 CaloHitList allNewThreeDHits;
65
66 PfoVector pfoVector(pPfoList->begin(), pPfoList->end());
67 std::sort(pfoVector.begin(), pfoVector.end(), LArPfoHelper::SortByNHits);
68
69 for (const ParticleFlowObject *const pPfo : pfoVector)
70 {
71 ProtoHitVector protoHitVector;
72
73 for (HitCreationBaseTool *const pHitCreationTool : m_algorithmToolVector)
74 {
75 CaloHitVector remainingTwoDHits;
76 this->SeparateTwoDHits(pPfo, protoHitVector, remainingTwoDHits);
77
78 if (remainingTwoDHits.empty())
79 break;
80
81 pHitCreationTool->Run(this, pPfo, remainingTwoDHits, protoHitVector);
82 }
83
85 this->IterativeTreatment(protoHitVector);
86
87 if (protoHitVector.empty())
88 continue;
89
90 CaloHitList newThreeDHits;
91 this->CreateThreeDHits(protoHitVector, newThreeDHits);
92 this->AddThreeDHitsToPfo(pPfo, newThreeDHits);
93
94 allNewThreeDHits.insert(allNewThreeDHits.end(), newThreeDHits.begin(), newThreeDHits.end());
95 }
96
97 if (!allNewThreeDHits.empty())
98 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList(*this, allNewThreeDHits, m_outputCaloHitListName));
99
100 return STATUS_CODE_SUCCESS;
101}
102
103//------------------------------------------------------------------------------------------------------------------------------------------
104
106 const ParticleFlowObject *const pPfo, const ProtoHitVector &protoHitVector, CaloHitVector &remainingHitVector) const
107{
108 ClusterList twoDClusterList;
109 LArPfoHelper::GetTwoDClusterList(pPfo, twoDClusterList);
110 CaloHitList remainingHitList;
111
112 for (const Cluster *const pCluster : twoDClusterList)
113 {
115 throw StatusCodeException(STATUS_CODE_FAILURE);
116
117 pCluster->GetOrderedCaloHitList().FillCaloHitList(remainingHitList);
118 }
119
120 CaloHitSet remainingHitSet(remainingHitList.begin(), remainingHitList.end());
121
122 for (const ProtoHit &protoHit : protoHitVector)
123 {
124 CaloHitSet::iterator eraseIter = remainingHitSet.find(protoHit.GetParentCaloHit2D());
125
126 if (remainingHitSet.end() == eraseIter)
127 throw StatusCodeException(STATUS_CODE_FAILURE);
128
129 remainingHitSet.erase(eraseIter);
130 }
131
132 remainingHitVector.insert(remainingHitVector.end(), remainingHitSet.begin(), remainingHitSet.end());
133 std::sort(remainingHitVector.begin(), remainingHitVector.end(), LArClusterHelper::SortHitsByPosition);
134}
135
136//------------------------------------------------------------------------------------------------------------------------------------------
137
139{
140 const float layerPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
141 const unsigned int layerWindow(m_slidingFitHalfWindow);
142
143 double originalChi2(0.);
144 CartesianPointVector currentPoints3D;
145 this->ExtractResults(protoHitVector, originalChi2, currentPoints3D);
146
147 try
148 {
149 const ThreeDSlidingFitResult originalSlidingFitResult(&currentPoints3D, layerWindow, layerPitch);
150 const double originalChi2WrtFit(this->GetChi2WrtFit(originalSlidingFitResult, protoHitVector));
151 double currentChi2(originalChi2 + originalChi2WrtFit);
152
153 unsigned int nIterations(0);
154
155 while (nIterations++ < m_nHitRefinementIterations)
156 {
157 ProtoHitVector newProtoHitVector(protoHitVector);
158 const ThreeDSlidingFitResult newSlidingFitResult(&currentPoints3D, layerWindow, layerPitch);
159 this->RefineHitPositions(newSlidingFitResult, newProtoHitVector);
160
161 double newChi2(0.);
162 CartesianPointVector newPoints3D;
163 this->ExtractResults(newProtoHitVector, newChi2, newPoints3D);
164
165 if (newChi2 > m_iterationMaxChi2Ratio * currentChi2)
166 break;
167
168 currentChi2 = newChi2;
169 currentPoints3D = newPoints3D;
170 protoHitVector = newProtoHitVector;
171 }
172 }
173 catch (const StatusCodeException &)
174 {
175 }
176}
177
178//------------------------------------------------------------------------------------------------------------------------------------------
179
180void ThreeDHitCreationAlgorithm::ExtractResults(const ProtoHitVector &protoHitVector, double &chi2, CartesianPointVector &pointVector) const
181{
182 chi2 = 0.;
183 pointVector.clear();
184
185 for (const ProtoHit &protoHit : protoHitVector)
186 {
187 chi2 += protoHit.GetChi2();
188 pointVector.push_back(protoHit.GetPosition3D());
189 }
190}
191
192//------------------------------------------------------------------------------------------------------------------------------------------
193
194double ThreeDHitCreationAlgorithm::GetChi2WrtFit(const ThreeDSlidingFitResult &slidingFitResult, const ProtoHitVector &protoHitVector) const
195{
196 const double sigmaUVW(LArGeometryHelper::GetSigmaUVW(this->GetPandora()));
197 const double sigma3DFit(sigmaUVW * m_sigma3DFitMultiplier);
198
199 double chi2WrtFit(0.);
200
201 for (const ProtoHit &protoHit : protoHitVector)
202 {
203 CartesianVector pointOnFit(0.f, 0.f, 0.f);
204 const double rL(slidingFitResult.GetLongitudinalDisplacement(protoHit.GetPosition3D()));
205
206 if (STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitPosition(rL, pointOnFit))
207 continue;
208
209 const double uFit(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoU(pointOnFit.GetY(), pointOnFit.GetZ()));
210 const double vFit(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoV(pointOnFit.GetY(), pointOnFit.GetZ()));
211 const double wFit(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoW(pointOnFit.GetY(), pointOnFit.GetZ()));
212
213 const double outputU(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoU(
214 protoHit.GetPosition3D().GetY(), protoHit.GetPosition3D().GetZ()));
215 const double outputV(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoV(
216 protoHit.GetPosition3D().GetY(), protoHit.GetPosition3D().GetZ()));
217 const double outputW(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoW(
218 protoHit.GetPosition3D().GetY(), protoHit.GetPosition3D().GetZ()));
219
220 const double deltaUFit(uFit - outputU), deltaVFit(vFit - outputV), deltaWFit(wFit - outputW);
221 chi2WrtFit += ((deltaUFit * deltaUFit) / (sigma3DFit * sigma3DFit)) + ((deltaVFit * deltaVFit) / (sigma3DFit * sigma3DFit)) +
222 ((deltaWFit * deltaWFit) / (sigma3DFit * sigma3DFit));
223 }
224
225 return chi2WrtFit;
226}
227
228//------------------------------------------------------------------------------------------------------------------------------------------
229
231{
232 const double sigmaUVW(LArGeometryHelper::GetSigmaUVW(this->GetPandora()));
233 double hitMovementChi2(0.);
234
235 for (const ProtoHit &protoHit : protoHitVector)
236 {
237 const CaloHit *const pCaloHit2D(protoHit.GetParentCaloHit2D());
238 const HitType hitType(pCaloHit2D->GetHitType());
239
240 const CartesianVector projectedPosition(LArGeometryHelper::ProjectPosition(this->GetPandora(), protoHit.GetPosition3D(), hitType));
241 const double delta(static_cast<double>(pCaloHit2D->GetPositionVector().GetZ() - projectedPosition.GetZ()));
242
243 hitMovementChi2 += (delta * delta) / (sigmaUVW * sigmaUVW);
244 }
245
246 return hitMovementChi2;
247}
248
249//------------------------------------------------------------------------------------------------------------------------------------------
250
252{
253 const double sigmaUVW(LArGeometryHelper::GetSigmaUVW(this->GetPandora()));
254 const double sigmaFit(sigmaUVW); // ATTN sigmaFit and sigmaHit here should agree with treatment in HitCreation tools
255 const double sigmaHit(sigmaUVW);
256 const double sigma3DFit(sigmaUVW * m_sigma3DFitMultiplier);
257
258 for (ProtoHit &protoHit : protoHitVector)
259 {
260 CartesianVector pointOnFit(0.f, 0.f, 0.f);
261 const double rL(slidingFitResult.GetLongitudinalDisplacement(protoHit.GetPosition3D()));
262
263 if (STATUS_CODE_SUCCESS != slidingFitResult.GetGlobalFitPosition(rL, pointOnFit))
264 continue;
265
266 const CaloHit *const pCaloHit2D(protoHit.GetParentCaloHit2D());
267 const HitType hitType(pCaloHit2D->GetHitType());
268
269 const double uFit(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoU(pointOnFit.GetY(), pointOnFit.GetZ()));
270 const double vFit(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoV(pointOnFit.GetY(), pointOnFit.GetZ()));
271 const double wFit(PandoraContentApi::GetPlugins(*this)->GetLArTransformationPlugin()->YZtoW(pointOnFit.GetY(), pointOnFit.GetZ()));
272
273 const double sigmaU((TPC_VIEW_U == hitType) ? sigmaHit : sigmaFit);
274 const double sigmaV((TPC_VIEW_V == hitType) ? sigmaHit : sigmaFit);
275 const double sigmaW((TPC_VIEW_W == hitType) ? sigmaHit : sigmaFit);
276
277 CartesianVector position3D(0.f, 0.f, 0.f);
278 double chi2(std::numeric_limits<double>::max());
279 double u(std::numeric_limits<double>::max()), v(std::numeric_limits<double>::max()), w(std::numeric_limits<double>::max());
280
281 if (protoHit.GetNTrajectorySamples() == 2)
282 {
283 u = (TPC_VIEW_U == hitType) ? pCaloHit2D->GetPositionVector().GetZ()
284 : (TPC_VIEW_U == protoHit.GetFirstTrajectorySample().GetHitType())
285 ? protoHit.GetFirstTrajectorySample().GetPosition().GetZ()
286 : protoHit.GetLastTrajectorySample().GetPosition().GetZ();
287 v = (TPC_VIEW_V == hitType) ? pCaloHit2D->GetPositionVector().GetZ()
288 : (TPC_VIEW_V == protoHit.GetFirstTrajectorySample().GetHitType())
289 ? protoHit.GetFirstTrajectorySample().GetPosition().GetZ()
290 : protoHit.GetLastTrajectorySample().GetPosition().GetZ();
291 w = (TPC_VIEW_W == hitType) ? pCaloHit2D->GetPositionVector().GetZ()
292 : (TPC_VIEW_W == protoHit.GetFirstTrajectorySample().GetHitType())
293 ? protoHit.GetFirstTrajectorySample().GetPosition().GetZ()
294 : protoHit.GetLastTrajectorySample().GetPosition().GetZ();
295 }
296 else if (protoHit.GetNTrajectorySamples() == 1)
297 {
299 protoHit.GetPosition3D().GetY(), protoHit.GetPosition3D().GetZ());
301 protoHit.GetPosition3D().GetY(), protoHit.GetPosition3D().GetZ());
303 protoHit.GetPosition3D().GetY(), protoHit.GetPosition3D().GetZ());
304 }
305 else
306 {
307 std::cout << "ThreeDHitCreationAlgorithm::IterativeTreatment - Unexpected number of trajectory samples" << std::endl;
308 throw StatusCodeException(STATUS_CODE_FAILURE);
309 }
310
311 double bestY(std::numeric_limits<double>::max()), bestZ(std::numeric_limits<double>::max());
313 u, v, w, sigmaU, sigmaV, sigmaW, uFit, vFit, wFit, sigma3DFit, bestY, bestZ, chi2);
314 position3D.SetValues(pCaloHit2D->GetPositionVector().GetX(), static_cast<float>(bestY), static_cast<float>(bestZ));
315
316 protoHit.SetPosition3D(position3D, chi2);
317 }
318}
319
320//------------------------------------------------------------------------------------------------------------------------------------------
321
322void ThreeDHitCreationAlgorithm::CreateThreeDHits(const ProtoHitVector &protoHitVector, CaloHitList &newThreeDHits) const
323{
324 for (const ProtoHit &protoHit : protoHitVector)
325 {
326 const CaloHit *pCaloHit3D(nullptr);
327 this->CreateThreeDHit(protoHit, pCaloHit3D);
328
329 if (!pCaloHit3D)
330 throw StatusCodeException(STATUS_CODE_FAILURE);
331
332 newThreeDHits.push_back(pCaloHit3D);
333 }
334}
335
336//------------------------------------------------------------------------------------------------------------------------------------------
337
338void ThreeDHitCreationAlgorithm::CreateThreeDHit(const ProtoHit &protoHit, const CaloHit *&pCaloHit3D) const
339{
340 if (!this->CheckThreeDHit(protoHit))
341 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
342
343 PandoraContentApi::CaloHit::Parameters parameters;
344 parameters.m_positionVector = protoHit.GetPosition3D();
345 parameters.m_hitType = TPC_3D;
346
347 const CaloHit *const pCaloHit2D(protoHit.GetParentCaloHit2D());
348 parameters.m_pParentAddress = static_cast<const void *>(pCaloHit2D);
349
350 // TODO Check these parameters, especially new cell dimensions
351 parameters.m_cellThickness = pCaloHit2D->GetCellThickness();
352 parameters.m_cellGeometry = RECTANGULAR;
353 parameters.m_cellSize0 = pCaloHit2D->GetCellLengthScale();
354 parameters.m_cellSize1 = pCaloHit2D->GetCellLengthScale();
355 parameters.m_cellNormalVector = pCaloHit2D->GetCellNormalVector();
356 parameters.m_expectedDirection = pCaloHit2D->GetExpectedDirection();
357 parameters.m_nCellRadiationLengths = pCaloHit2D->GetNCellRadiationLengths();
358 parameters.m_nCellInteractionLengths = pCaloHit2D->GetNCellInteractionLengths();
359 parameters.m_time = pCaloHit2D->GetTime();
360 parameters.m_inputEnergy = pCaloHit2D->GetInputEnergy();
361 parameters.m_mipEquivalentEnergy = pCaloHit2D->GetMipEquivalentEnergy();
362 parameters.m_electromagneticEnergy = pCaloHit2D->GetElectromagneticEnergy();
363 parameters.m_hadronicEnergy = pCaloHit2D->GetHadronicEnergy();
364 parameters.m_isDigital = pCaloHit2D->IsDigital();
365 parameters.m_hitRegion = pCaloHit2D->GetHitRegion();
366 parameters.m_layer = pCaloHit2D->GetLayer();
367 parameters.m_isInOuterSamplingLayer = pCaloHit2D->IsInOuterSamplingLayer();
368 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CaloHit::Create(*this, parameters, pCaloHit3D));
369}
370
371//------------------------------------------------------------------------------------------------------------------------------------------
372
374{
375 try
376 {
377 // Check that corresponding pseudo layer is within range - TODO use full LArTPC geometry here
379 }
380 catch (StatusCodeException &)
381 {
382 return false;
383 }
384
385 // TODO Check against detector geometry
386 return true;
387}
388
389//------------------------------------------------------------------------------------------------------------------------------------------
390
392{
393 if (caloHitList.empty())
394 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
395
396 ClusterList threeDClusterList;
397 LArPfoHelper::GetThreeDClusterList(pPfo, threeDClusterList);
398
399 if (!threeDClusterList.empty())
400 throw StatusCodeException(STATUS_CODE_FAILURE);
401
402 const ClusterList *pClusterList(nullptr);
403 std::string clusterListName;
404 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pClusterList, clusterListName));
405
406 PandoraContentApi::Cluster::Parameters parameters;
407 parameters.m_caloHitList.insert(parameters.m_caloHitList.end(), caloHitList.begin(), caloHitList.end());
408
409 const Cluster *pCluster3D(nullptr);
410 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pCluster3D));
411
412 if (!pCluster3D || !pClusterList || pClusterList->empty())
413 throw StatusCodeException(STATUS_CODE_FAILURE);
414
416 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pPfo, pCluster3D));
417}
418
419//------------------------------------------------------------------------------------------------------------------------------------------
420//------------------------------------------------------------------------------------------------------------------------------------------
421
423{
424 if (!m_isPositionSet)
425 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
426
427 return m_position3D;
428}
429
430//------------------------------------------------------------------------------------------------------------------------------------------
431
433{
434 if (!m_isPositionSet)
435 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
436
437 return m_chi2;
438}
439
440//------------------------------------------------------------------------------------------------------------------------------------------
441
443{
444 if (m_trajectorySampleVector.empty())
445 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
446
447 return m_trajectorySampleVector.front();
448}
449
450//------------------------------------------------------------------------------------------------------------------------------------------
451
453{
454 if (m_trajectorySampleVector.size() < 2)
455 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
456
457 return m_trajectorySampleVector.back();
458}
459
460//------------------------------------------------------------------------------------------------------------------------------------------
461//------------------------------------------------------------------------------------------------------------------------------------------
462
464{
465 AlgorithmToolVector algorithmToolVector;
466 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "HitCreationTools", algorithmToolVector));
467
468 for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
469 {
470 HitCreationBaseTool *const pHitCreationTool(dynamic_cast<HitCreationBaseTool *>(*iter));
471
472 if (!pHitCreationTool)
473 return STATUS_CODE_INVALID_PARAMETER;
474
475 m_algorithmToolVector.push_back(pHitCreationTool);
476 }
477
478 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputPfoListName", m_inputPfoListName));
479 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputCaloHitListName", m_outputCaloHitListName));
480 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputClusterListName", m_outputClusterListName));
481
483 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "IterateTrackHits", m_iterateTrackHits));
484
486 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "IterateShowerHits", m_iterateShowerHits));
487
489 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitHalfWindow", m_slidingFitHalfWindow));
490
491 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
492 XmlHelper::ReadValue(xmlHandle, "NHitRefinementIterations", m_nHitRefinementIterations));
493
495 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Sigma3DFitMultiplier", m_sigma3DFitMultiplier));
496
498 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "IterationMaxChi2Ratio", m_iterationMaxChi2Ratio));
499
500 return STATUS_CODE_SUCCESS;
501}
502
503} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the hit creation base tool.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the pfo helper class.
Header file for the lar three dimensional sliding fit result 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
Header file for the three dimensional hit creation algorithm class.
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 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 AddToPfo(const pandora::Algorithm &algorithm, const pandora::ParticleFlowObject *const pPfo, const T *const pT)
Add a cluster to a particle flow object.
static pandora::StatusCode CreateTemporaryListAndSetCurrent(const pandora::Algorithm &algorithm, const T *&pT, std::string &temporaryListName)
Create a temporary list and set it to be the current list, enabling object creation.
static const pandora::PluginManager * GetPlugins(const pandora::Algorithm &algorithm)
Get the pandora plugin instance, providing access to user registered functions and calculators.
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.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
static float GetSigmaUVW(const pandora::Pandora &pandora, const float maxSigmaDiscrepancy=0.01)
Find the sigmaUVW value for the detector geometry.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
static void GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
static bool IsShower(const pandora::ParticleFlowObject *const pPfo)
Return shower flag based on Pfo Particle ID.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Proto hits are temporary constructs to be used during iterative 3D hit procedure.
const TrajectorySample & GetFirstTrajectorySample() const
Get the first trajectory sample.
const pandora::CaloHit * GetParentCaloHit2D() const
Get the address of the parent 2D calo hit.
pandora::CartesianVector m_position3D
The output 3D position.
const TrajectorySample & GetLastTrajectorySample() const
Get the last trajectory sample.
bool m_isPositionSet
Whether the output 3D position has been set.
const pandora::CartesianVector & GetPosition3D() const
Get the output 3D position.
Trajectory samples record the results of sampling a particles in a particular view.
bool m_iterateTrackHits
Whether to enable iterative improvement of 3D hits for track trajectories.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
bool CheckThreeDHit(const ProtoHit &protoHit) const
Check that a new three dimensional position is not unphysical.
void IterativeTreatment(ProtoHitVector &protoHitVector) const
Improve initial 3D hits by fitting proto hits and iteratively creating consisted 3D hit trajectory.
std::string m_inputPfoListName
The name of the input pfo list.
pandora::StatusCode Run()
Run the algorithm.
double GetChi2WrtFit(const ThreeDSlidingFitResult &slidingFitResult, const ProtoHitVector &protoHitVector) const
Receive a chi2 value indicating consistency of a list of proto hits with a provided 3D sliding fit tr...
void SeparateTwoDHits(const pandora::ParticleFlowObject *const pPfo, const ProtoHitVector &protoHitVector, pandora::CaloHitVector &remainingHitVector) const
Get the list of 2D calo hits in a pfo for which 3D hits have and have not been created.
void RefineHitPositions(const ThreeDSlidingFitResult &slidingFitResult, ProtoHitVector &protoHitVector) const
Refine the 3D hit positions (and chi2) for a list of proto hits, in accordance with a provided 3D sli...
void CreateThreeDHits(const ProtoHitVector &protoHitVector, pandora::CaloHitList &newThreeDHits) const
Create new three dimensional hits from two dimensional hits.
bool m_iterateShowerHits
Whether to enable iterative improvement of 3D hits for showers.
void FilterCaloHitsByType(const pandora::CaloHitVector &inputCaloHitVector, const pandora::HitType hitType, pandora::CaloHitVector &outputCaloHitVector) const
Get the subset of a provided calo hit vector corresponding to a specified hit type.
double GetHitMovementChi2(const ProtoHitVector &protoHitVector) const
Receive a chi2 value indicating consistency of a list of proto hits with the original,...
void ExtractResults(const ProtoHitVector &protoHitVector, double &chi2, pandora::CartesianPointVector &pointVector) const
Extract key results from a provided proto hit vector.
HitCreationToolVector m_algorithmToolVector
The algorithm tool vector.
unsigned int m_slidingFitHalfWindow
The sliding linear fit half window.
unsigned int m_nHitRefinementIterations
The maximum number of hit refinement iterations.
double m_sigma3DFitMultiplier
Multiplicative factor: sigmaUVW (same as sigmaHit and sigma2DFit) to sigma3DFit.
std::string m_outputCaloHitListName
The name of the output calo hit list.
void AddThreeDHitsToPfo(const pandora::ParticleFlowObject *const pPfo, const pandora::CaloHitList &caloHitList) const
Add a specified list of three dimensional hits to a cluster in a pfo, creating the new cluster if req...
void CreateThreeDHit(const ProtoHit &protoHit, const pandora::CaloHit *&pCaloHit3D) const
Create a new three dimensional hit from a two dimensional hit.
std::string m_outputClusterListName
The name of the output cluster list.
double m_iterationMaxChi2Ratio
Max ratio between current and previous chi2 values to cease iterations.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
float GetLongitudinalDisplacement(const pandora::CartesianVector &position) const
Get longitudinal projection onto primary axis.
CaloHit class.
Definition CaloHit.h:26
float GetElectromagneticEnergy() const
Get the calibrated electromagnetic energy measure.
Definition CaloHit.h:483
HitType GetHitType() const
Get the calorimeter hit type.
Definition CaloHit.h:441
bool IsInOuterSamplingLayer() const
Whether cell is in one of the outermost detector sampling layers.
Definition CaloHit.h:469
HitRegion GetHitRegion() const
Get the region of the detector in which the calo hit is located.
Definition CaloHit.h:448
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:350
unsigned int GetLayer() const
Get the subdetector readout layer number.
Definition CaloHit.h:455
float GetMipEquivalentEnergy() const
Get the calibrated mip equivalent energy.
Definition CaloHit.h:476
float GetNCellRadiationLengths() const
Get the absorber material in front of cell, units radiation lengths.
Definition CaloHit.h:406
float GetNCellInteractionLengths() const
Get the absorber material in front of cell, units interaction lengths.
Definition CaloHit.h:413
float GetCellThickness() const
Get the thickness of cell, units mm.
Definition CaloHit.h:399
float GetCellLengthScale() const
Get the typical length scale of cell, units mm.
Definition CaloHit.h:497
bool IsDigital() const
Whether cell should be treated as digital.
Definition CaloHit.h:434
const CartesianVector & GetCellNormalVector() const
Get the unit vector normal to the sampling layer, pointing outwards from the origin.
Definition CaloHit.h:371
float GetHadronicEnergy() const
Get the calibrated hadronic energy measure.
Definition CaloHit.h:490
float GetInputEnergy() const
Get the corrected energy of the calorimeter cell, units GeV, as supplied by the user.
Definition CaloHit.h:420
float GetTime() const
Get the time of (earliest) energy deposition in this cell, units ns.
Definition CaloHit.h:427
const CartesianVector & GetExpectedDirection() const
Get the unit vector in direction of expected hit propagation.
Definition CaloHit.h:364
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
float GetY() const
Get the cartesian y coordinate.
Cluster class.
Definition Cluster.h:31
virtual void GetMinChiSquaredYZ(const double u, const double v, const double w, const double sigmaU, const double sigmaV, const double sigmaW, double &y, double &z, double &chiSquared) const =0
Get the y, z position that yields the minimum chi squared value with respect to specified u,...
virtual double YZtoU(const double y, const double z) const =0
Transform from (Y,Z) to U position.
virtual double YZtoW(const double y, const double z) const =0
Transform from (Y,Z) to W position.
virtual double YZtoV(const double y, const double z) const =0
Transform from (Y,Z) to V position.
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
ParticleFlowObject class.
const LArTransformationPlugin * GetLArTransformationPlugin() const
Get the address of the lar transformation plugin.
const PseudoLayerPlugin * GetPseudoLayerPlugin() const
Get the address of the pseudo layer plugin.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
virtual unsigned int GetPseudoLayer(const CartesianVector &positionVector) const =0
Get the appropriate pseudolayer for a specified position vector.
StatusCodeException class.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
static StatusCode ProcessAlgorithmToolList(const Algorithm &algorithm, const TiXmlHandle &xmlHandle, const std::string &listName, AlgorithmToolVector &algorithmToolVector)
Process a list of algorithms tools in an xml file.
Definition XmlHelper.cc:101
HitType
Calorimeter hit type enum.
std::vector< const CaloHit * > CaloHitVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< const ParticleFlowObject * > PfoVector
std::vector< CartesianVector > CartesianPointVector
std::vector< AlgorithmTool * > AlgorithmToolVector
std::unordered_set< const CaloHit * > CaloHitSet
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList