9 #include "Pandora/AlgorithmHeaders.h"
10 #include "Pandora/StatusCodes.h"
27 TwoDShowerFitFeatureTool::TwoDShowerFitFeatureTool() : m_slidingShowerFitWindow(3), m_slidingLinearFitWindow(10000)
35 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
36 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
42 const float straightLineLength =
44 if (straightLineLength > std::numeric_limits<float>::epsilon())
47 catch (
const StatusCodeException &)
51 featureVector.push_back(ratio);
57 const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster)
60 this->
Run(toolFeatureVec, pAlgorithm, pCluster);
62 if (featureMap.find(featureToolName +
"_WidthLenRatio") != featureMap.end())
64 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
65 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
68 featureOrder.push_back(featureToolName +
"_WidthLenRatio");
69 featureMap[featureToolName +
"_WidthLenRatio"] = toolFeatureVec[0].Get();
76 PANDORA_RETURN_RESULT_IF_AND_IF(
77 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingShowerFitWindow",
m_slidingShowerFitWindow));
79 PANDORA_RETURN_RESULT_IF_AND_IF(
80 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
82 return STATUS_CODE_SUCCESS;
96 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
97 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
99 float dTdLWidth(-1.f), straightLineLengthLarge(-1.f), diffWithStraightLineMean(-1.f), diffWithStraightLineSigma(-1.f),
100 maxFitGapLength(-1.f), rmsSlidingLinearFit(-1.f);
102 dTdLWidth, maxFitGapLength, rmsSlidingLinearFit);
104 if (straightLineLengthLarge > std::numeric_limits<float>::epsilon())
106 diffWithStraightLineMean /= straightLineLengthLarge;
107 diffWithStraightLineSigma /= straightLineLengthLarge;
108 dTdLWidth /= straightLineLengthLarge;
109 maxFitGapLength /= straightLineLengthLarge;
110 rmsSlidingLinearFit /= straightLineLengthLarge;
113 featureVector.push_back(straightLineLengthLarge);
114 featureVector.push_back(diffWithStraightLineMean);
115 featureVector.push_back(diffWithStraightLineSigma);
116 featureVector.push_back(dTdLWidth);
117 featureVector.push_back(maxFitGapLength);
118 featureVector.push_back(rmsSlidingLinearFit);
124 const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster)
127 this->
Run(toolFeatureVec, pAlgorithm, pCluster);
129 if (featureMap.find(featureToolName +
"_StLineLenLarge") != featureMap.end() ||
130 featureMap.find(featureToolName +
"_DiffStLineMean") != featureMap.end() ||
131 featureMap.find(featureToolName +
"_DiffStLineSigma") != featureMap.end() ||
132 featureMap.find(featureToolName +
"_dTdLWidth") != featureMap.end() ||
133 featureMap.find(featureToolName +
"_MaxFitGapLen") != featureMap.end() ||
134 featureMap.find(featureToolName +
"_rmsSlidingLinFit") != featureMap.end())
136 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
137 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
140 featureOrder.push_back(featureToolName +
"_StLineLenLarge");
141 featureOrder.push_back(featureToolName +
"_DiffStLineMean");
142 featureOrder.push_back(featureToolName +
"_DiffStLineSigma");
143 featureOrder.push_back(featureToolName +
"_dTdLWidth");
144 featureOrder.push_back(featureToolName +
"_MaxFitGapLen");
145 featureOrder.push_back(featureToolName +
"_rmsSlidingLinFit");
147 featureMap[featureToolName +
"_StLineLenLarge"] = toolFeatureVec[0].Get();
148 featureMap[featureToolName +
"_DiffStLineMean"] = toolFeatureVec[1].Get();
149 featureMap[featureToolName +
"_DiffStLineSigma"] = toolFeatureVec[2].Get();
150 featureMap[featureToolName +
"_dTdLWidth"] = toolFeatureVec[3].Get();
151 featureMap[featureToolName +
"_MaxFitGapLen"] = toolFeatureVec[4].Get();
152 featureMap[featureToolName +
"_rmsSlidingLinFit"] = toolFeatureVec[5].Get();
158 float &diffWithStraightLineMean,
float &diffWithStraightLineSigma,
float &dTdLWidth,
float &maxFitGapLength,
float &rmsSlidingLinearFit)
const
167 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
169 straightLineLengthLarge =
171 rmsSlidingLinearFit = 0.f;
173 FloatVector diffWithStraightLineVector;
176 float dTdLMin(+std::numeric_limits<float>::max()), dTdLMax(-std::numeric_limits<float>::max());
181 rmsSlidingLinearFit += layerFitResult.
GetRms();
183 CartesianVector thisFitPosition(0.f, 0.f, 0.f);
186 LayerFitResultMap::const_iterator iterLarge =
190 throw StatusCodeException(STATUS_CODE_FAILURE);
192 diffWithStraightLineVector.push_back(static_cast<float>(std::fabs(layerFitResult.
GetFitT() - iterLarge->second.GetFitT())));
194 const float thisGapLength((thisFitPosition - previousFitPosition).GetMagnitude());
195 const float minZ(std::min(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
196 const float maxZ(std::max(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
198 if ((maxZ - minZ) > std::numeric_limits<float>::epsilon())
201 const float correctedGapLength(thisGapLength * (1.f - gapZ / (maxZ - minZ)));
203 if (correctedGapLength > maxFitGapLength)
204 maxFitGapLength = correctedGapLength;
207 dTdLMin = std::min(dTdLMin, static_cast<float>(layerFitResult.
GetGradient()));
208 dTdLMax = std::max(dTdLMax, static_cast<float>(layerFitResult.
GetGradient()));
209 previousFitPosition = thisFitPosition;
212 if (diffWithStraightLineVector.empty())
213 throw StatusCodeException(STATUS_CODE_FAILURE);
215 diffWithStraightLineMean = 0.f;
216 diffWithStraightLineSigma = 0.f;
218 for (
const float diffWithStraightLine : diffWithStraightLineVector)
219 diffWithStraightLineMean += diffWithStraightLine;
221 diffWithStraightLineMean /=
static_cast<float>(diffWithStraightLineVector.size());
223 for (
const float diffWithStraightLine : diffWithStraightLineVector)
224 diffWithStraightLineSigma += (diffWithStraightLine - diffWithStraightLineMean) * (diffWithStraightLine - diffWithStraightLineMean);
226 if (diffWithStraightLineSigma < 0.f)
227 throw StatusCodeException(STATUS_CODE_FAILURE);
229 diffWithStraightLineSigma = std::sqrt(diffWithStraightLineSigma / static_cast<float>(diffWithStraightLineVector.size()));
230 dTdLWidth = dTdLMax - dTdLMin;
232 catch (
const StatusCodeException &)
234 straightLineLengthLarge = -1.f;
235 diffWithStraightLineMean = -1.f;
236 diffWithStraightLineSigma = -1.f;
238 maxFitGapLength = -1.f;
239 rmsSlidingLinearFit = -1.f;
247 PANDORA_RETURN_RESULT_IF_AND_IF(
248 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
250 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
253 return STATUS_CODE_SUCCESS;
268 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
269 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
271 float straightLineLength(-1.f), ratio(-1.f);
276 if (straightLineLength > std::numeric_limits<float>::epsilon())
279 catch (
const StatusCodeException &)
283 featureVector.push_back(ratio);
289 const std::string &featureToolName,
const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster)
292 this->
Run(toolFeatureVec, pAlgorithm, pCluster);
294 if (featureMap.find(featureToolName +
"_DistLenRatio") != featureMap.end())
296 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
297 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
300 featureOrder.push_back(featureToolName +
"_DistLenRatio");
301 featureMap[featureToolName +
"_DistLenRatio"] = toolFeatureVec[0].Get();
308 PANDORA_RETURN_RESULT_IF_AND_IF(
309 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
311 return STATUS_CODE_SUCCESS;
326 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
327 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
329 CaloHitList parent3DHitList;
331 const unsigned int nParentHits3D(parent3DHitList.size());
333 PfoList allDaughtersPfoList;
335 const unsigned int nDaughterPfos(allDaughtersPfoList.empty() ? 0 : allDaughtersPfoList.size() - 1);
337 unsigned int nDaughterHits3DTotal(0);
339 if (nDaughterPfos > 0)
342 allDaughtersPfoList.pop_front();
344 for (
const ParticleFlowObject *
const pDaughterPfo : allDaughtersPfoList)
346 CaloHitList daughter3DHitList;
348 nDaughterHits3DTotal += daughter3DHitList.size();
355 (nParentHits3D > 0) ? static_cast<double>(nDaughterHits3DTotal) / static_cast<double>(nParentHits3D) : 0.);
357 featureVector.push_back(nDaughters);
358 featureVector.push_back(nDaughterHits3D);
359 featureVector.push_back(daughterParentNHitsRatio);
365 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
368 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
370 if (featureMap.find(featureToolName +
"_NDaughters") != featureMap.end() ||
371 featureMap.find(featureToolName +
"_NDaughterHits3D") != featureMap.end() ||
372 featureMap.find(featureToolName +
"_DaughterParentHitRatio") != featureMap.end())
374 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
375 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
378 featureOrder.push_back(featureToolName +
"_NDaughters");
379 featureOrder.push_back(featureToolName +
"_NDaughterHits3D");
380 featureOrder.push_back(featureToolName +
"_DaughterParentHitRatio");
382 featureMap[featureToolName +
"_NDaughters"] = toolFeatureVec[0].Get();
383 featureMap[featureToolName +
"_NDaughterHits3D"] = toolFeatureVec[1].Get();
384 featureMap[featureToolName +
"_DaughterParentHitRatio"] = toolFeatureVec[2].Get();
391 return STATUS_CODE_SUCCESS;
400 m_conFracRange(0.2f),
401 m_MoliereRadius(10.1f),
402 m_MoliereRadiusFrac(0.2f)
411 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
412 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
414 ClusterList clusterListW;
419 if (!clusterListW.empty())
421 CaloHitList clusterCaloHitList;
422 clusterListW.front()->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
424 const CartesianVector &pfoStart(clusterCaloHitList.front()->GetPositionVector());
425 CartesianVector centroid(0.f, 0.f, 0.f);
430 float chargeCore(0.f), chargeHalo(0.f), chargeCon(0.f);
432 haloTotalRatio = (chargeCore + chargeHalo > std::numeric_limits<float>::epsilon()) ? chargeHalo / (chargeCore + chargeHalo) : -1.f;
433 concentration = (chargeCore + chargeHalo > std::numeric_limits<float>::epsilon()) ? chargeCon / (chargeCore + chargeHalo) : -1.f;
435 conicalness = (pfoLength > std::numeric_limits<float>::epsilon())
440 featureVector.push_back(haloTotalRatio);
441 featureVector.push_back(concentration);
442 featureVector.push_back(conicalness);
448 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
451 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
453 if (featureMap.find(featureToolName +
"_HaloTotalRatio") != featureMap.end() ||
454 featureMap.find(featureToolName +
"_Concentration") != featureMap.end() ||
455 featureMap.find(featureToolName +
"_Conicalness") != featureMap.end())
457 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
458 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
461 featureOrder.push_back(featureToolName +
"_HaloTotalRatio");
462 featureOrder.push_back(featureToolName +
"_Concentration");
463 featureOrder.push_back(featureToolName +
"_Conicalness");
465 featureMap[featureToolName +
"_HaloTotalRatio"] = toolFeatureVec[0].Get();
466 featureMap[featureToolName +
"_Concentration"] = toolFeatureVec[1].Get();
467 featureMap[featureToolName +
"_Conicalness"] = toolFeatureVec[2].Get();
473 const CartesianVector &pfoDir,
float &chargeCore,
float &chargeHalo,
float &chargeCon)
475 for (
const CaloHit *
const pCaloHit : caloHitList)
477 const float distFromTrackFit(((pCaloHit->GetPositionVector() - pfoStart).GetCrossProduct(pfoDir)).GetMagnitude());
480 chargeCore += pCaloHit->GetInputEnergy();
482 chargeHalo += pCaloHit->GetInputEnergy();
484 chargeCon += pCaloHit->GetInputEnergy() / std::max(1.
E-2f, distFromTrackFit);
491 const CaloHitList &caloHitList,
const CartesianVector &pfoStart,
const CartesianVector &pfoDir,
const float pfoLength)
493 float totalChargeStart(0.f), totalChargeEnd(0.f);
494 float chargeConStart(0.f), chargeConEnd(0.f);
495 unsigned int nHitsConStart(0), nHitsConEnd(0);
497 for (
const CaloHit *
const pCaloHit : caloHitList)
499 const float distFromTrackFit(((pCaloHit->GetPositionVector() - pfoStart).GetCrossProduct(pfoDir)).GetMagnitude());
500 const float hitLength(std::fabs((pCaloHit->GetPositionVector() - pfoStart).GetDotProduct(pfoDir)));
504 chargeConStart += distFromTrackFit * distFromTrackFit * pCaloHit->GetInputEnergy();
506 totalChargeStart += pCaloHit->GetInputEnergy();
510 chargeConEnd += distFromTrackFit * distFromTrackFit * pCaloHit->GetInputEnergy();
512 totalChargeEnd += pCaloHit->GetInputEnergy();
516 float conicalness(1.f);
520 conicalness = (std::sqrt(chargeConEnd / chargeConStart)) / (totalChargeEnd / totalChargeStart);
529 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConMinHits",
m_conMinHits));
530 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCharge",
m_minCharge));
531 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConFracRange",
m_conFracRange));
532 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MoliereRadius",
m_MoliereRadius));
533 PANDORA_RETURN_RESULT_IF_AND_IF(
534 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MoliereRadiusFrac",
m_MoliereRadiusFrac));
536 return STATUS_CODE_SUCCESS;
551 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
552 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
554 ClusterList clusterList;
556 float diffWithStraightLineMean(0.f), maxFitGapLength(0.f), rmsSlidingLinearFit(0.f);
558 unsigned int nClustersUsed(0);
560 for (
const Cluster *
const pCluster : clusterList)
562 float straightLineLengthLargeCluster(-1.f), diffWithStraightLineMeanCluster(-1.f), maxFitGapLengthCluster(-1.f),
563 rmsSlidingLinearFitCluster(-1.f);
566 pCluster, straightLineLengthLargeCluster, diffWithStraightLineMeanCluster, maxFitGapLengthCluster, rmsSlidingLinearFitCluster);
568 if (straightLineLengthLargeCluster > std::numeric_limits<float>::epsilon())
570 diffWithStraightLineMeanCluster /= straightLineLengthLargeCluster;
571 maxFitGapLengthCluster /= straightLineLengthLargeCluster;
572 rmsSlidingLinearFitCluster /= straightLineLengthLargeCluster;
574 diffWithStraightLineMean += diffWithStraightLineMeanCluster;
575 maxFitGapLength += maxFitGapLengthCluster;
576 rmsSlidingLinearFit += rmsSlidingLinearFitCluster;
582 if (nClustersUsed > 0)
584 const float nClusters(static_cast<float>(nClustersUsed));
586 diff = diffWithStraightLineMean / nClusters;
587 gap = maxFitGapLength / nClusters;
588 rms = rmsSlidingLinearFit / nClusters;
591 featureVector.push_back(length);
592 featureVector.push_back(diff);
593 featureVector.push_back(gap);
594 featureVector.push_back(rms);
600 const std::string &featureToolName,
const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
603 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
605 if (featureMap.find(featureToolName +
"_Length") != featureMap.end() ||
606 featureMap.find(featureToolName +
"_DiffStraightLineMean") != featureMap.end() ||
607 featureMap.find(featureToolName +
"_MaxFitGapLength") != featureMap.end() ||
608 featureMap.find(featureToolName +
"_SlidingLinearFitRMS") != featureMap.end())
610 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
611 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
614 featureOrder.push_back(featureToolName +
"_Length");
615 featureOrder.push_back(featureToolName +
"_DiffStraightLineMean");
616 featureOrder.push_back(featureToolName +
"_MaxFitGapLength");
617 featureOrder.push_back(featureToolName +
"_SlidingLinearFitRMS");
619 featureMap[featureToolName +
"_Length"] = toolFeatureVec[0].Get();
620 featureMap[featureToolName +
"_DiffStraightLineMean"] = toolFeatureVec[1].Get();
621 featureMap[featureToolName +
"_MaxFitGapLength"] = toolFeatureVec[2].Get();
622 featureMap[featureToolName +
"_SlidingLinearFitRMS"] = toolFeatureVec[3].Get();
628 float &diffWithStraightLineMean,
float &maxFitGapLength,
float &rmsSlidingLinearFit)
const
637 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
639 straightLineLengthLarge =
641 rmsSlidingLinearFit = 0.f;
643 FloatVector diffWithStraightLineVector;
646 float dTdLMin(+std::numeric_limits<float>::max()), dTdLMax(-std::numeric_limits<float>::max());
651 rmsSlidingLinearFit += layerFitResult.
GetRms();
653 CartesianVector thisFitPosition(0.f, 0.f, 0.f);
656 LayerFitResultMap::const_iterator iterLarge =
660 throw StatusCodeException(STATUS_CODE_FAILURE);
662 diffWithStraightLineVector.push_back(static_cast<float>(std::fabs(layerFitResult.
GetFitT() - iterLarge->second.GetFitT())));
664 const float thisGapLength((thisFitPosition - previousFitPosition).GetMagnitude());
665 const float minZ(std::min(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
666 const float maxZ(std::max(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
668 if ((maxZ - minZ) > std::numeric_limits<float>::epsilon())
671 const float correctedGapLength(thisGapLength * (1.f - gapZ / (maxZ - minZ)));
673 if (correctedGapLength > maxFitGapLength)
674 maxFitGapLength = correctedGapLength;
678 maxFitGapLength = 0.f;
681 dTdLMin = std::min(dTdLMin, static_cast<float>(layerFitResult.
GetGradient()));
682 dTdLMax = std::max(dTdLMax, static_cast<float>(layerFitResult.
GetGradient()));
683 previousFitPosition = thisFitPosition;
686 if (diffWithStraightLineVector.empty())
687 throw StatusCodeException(STATUS_CODE_FAILURE);
689 diffWithStraightLineMean = 0.f;
691 for (
const float diffWithStraightLine : diffWithStraightLineVector)
692 diffWithStraightLineMean += diffWithStraightLine;
694 diffWithStraightLineMean /=
static_cast<float>(diffWithStraightLineVector.size());
696 catch (
const StatusCodeException &)
698 straightLineLengthLarge = -1.f;
699 diffWithStraightLineMean = -1.f;
700 maxFitGapLength = -1.f;
701 rmsSlidingLinearFit = -1.f;
709 PANDORA_RETURN_RESULT_IF_AND_IF(
710 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
712 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
715 return STATUS_CODE_SUCCESS;
730 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
731 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
736 (
void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
738 if (!pVertexList || pVertexList->empty())
740 featureVector.push_back(vertexDistance);
744 unsigned int nInteractionVertices(0);
745 const Vertex *pInteractionVertex(
nullptr);
747 for (
const Vertex *pVertex : *pVertexList)
749 if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
751 ++nInteractionVertices;
752 pInteractionVertex = pVertex;
756 if (pInteractionVertex && (1 == nInteractionVertices))
760 vertexDistance = (pInteractionVertex->GetPosition() -
LArPfoHelper::GetVertex(pInputPfo)->GetPosition()).GetMagnitude();
762 catch (
const StatusCodeException &)
764 CaloHitList threeDCaloHitList;
767 if (!threeDCaloHitList.empty())
768 vertexDistance = (pInteractionVertex->GetPosition() - (threeDCaloHitList.front())->GetPositionVector()).GetMagnitude();
772 featureVector.push_back(vertexDistance);
778 const std::string &featureToolName,
const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
781 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
783 if (featureMap.find(featureToolName +
"_VertexDistance") != featureMap.end())
785 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
786 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
789 featureOrder.push_back(featureToolName +
"_VertexDistance");
791 featureMap[featureToolName +
"_VertexDistance"] = toolFeatureVec[0].Get();
798 return STATUS_CODE_SUCCESS;
813 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
814 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
817 CaloHitList threeDCaloHitList;
821 if (!threeDCaloHitList.empty())
823 CartesianPointVector pointVectorStart, pointVectorEnd;
824 this->
Divide3DCaloHitList(pAlgorithm, threeDCaloHitList, pointVectorStart, pointVectorEnd);
827 if ((pointVectorStart.size() > 1) && (pointVectorEnd.size() > 1))
832 CartesianVector centroidStart(0.f, 0.f, 0.f), centroidEnd(0.f, 0.f, 0.f);
839 const float openingAngle(this->
OpeningAngle(eigenVecsStart.at(0), eigenVecsStart.at(1), eigenValuesStart));
840 const float closingAngle(this->
OpeningAngle(eigenVecsEnd.at(0), eigenVecsEnd.at(1), eigenValuesEnd));
841 diffAngle = std::fabs(openingAngle - closingAngle);
843 catch (
const StatusCodeException &)
853 featureVector.push_back(diffAngle);
859 const std::string &featureToolName,
const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
862 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
864 if (featureMap.find(featureToolName +
"_AngleDiff") != featureMap.end())
866 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
867 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
870 featureOrder.push_back(featureToolName +
"_AngleDiff");
872 featureMap[featureToolName +
"_AngleDiff"] = toolFeatureVec[0].Get();
878 CartesianPointVector &pointVectorStart, CartesianPointVector &pointVectorEnd)
881 (
void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
883 if (threeDCaloHitList.empty() || !pVertexList || pVertexList->empty())
886 unsigned int nInteractionVertices(0);
887 const Vertex *pInteractionVertex(
nullptr);
889 for (
const Vertex *pVertex : *pVertexList)
891 if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
893 ++nInteractionVertices;
894 pInteractionVertex = pVertex;
898 if (pInteractionVertex && (1 == nInteractionVertices))
901 CaloHitVector threeDCaloHitVector(threeDCaloHitList.begin(), threeDCaloHitList.end());
902 std::sort(threeDCaloHitVector.begin(), threeDCaloHitVector.end(),
905 unsigned int iHit(1);
906 const unsigned int nHits(threeDCaloHitVector.size());
908 for (
const CaloHit *
const pCaloHit : threeDCaloHitVector)
910 if (static_cast<float>(iHit) /
static_cast<float>(nHits) <=
m_hitFraction)
911 pointVectorStart.push_back(pCaloHit->GetPositionVector());
913 if (static_cast<float>(iHit) /
static_cast<float>(nHits) >= 1.f -
m_hitFraction)
914 pointVectorEnd.push_back(pCaloHit->GetPositionVector());
925 const float principalMagnitude(principal.GetMagnitude());
926 const float secondaryMagnitude(secondary.GetMagnitude());
928 if (std::fabs(principalMagnitude) < std::numeric_limits<float>::epsilon())
930 std::cout <<
"ThreeDOpeningAngleFeatureTool::OpeningAngle - The principal eigenvector is 0." << std::endl;
931 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
933 else if (std::fabs(secondaryMagnitude) < std::numeric_limits<float>::epsilon())
938 const float cosTheta(principal.GetDotProduct(secondary) / (principalMagnitude * secondaryMagnitude));
942 std::cout <<
"PcaShowerParticleBuildingAlgorithm::OpeningAngle - cos(theta) reportedly greater than 1." << std::endl;
943 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
946 const float sinTheta(std::sqrt(1.f - cosTheta * cosTheta));
948 if (eigenValues.GetX() < std::numeric_limits<float>::epsilon())
950 std::cout <<
"PcaShowerParticleBuildingAlgorithm::OpeningAngle - principal eigenvalue less than or equal to 0." << std::endl;
951 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
953 else if (eigenValues.GetY() < std::numeric_limits<float>::epsilon())
958 return std::atan(std::sqrt(eigenValues.GetY()) * sinTheta / std::sqrt(eigenValues.GetX()));
965 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HitFraction",
m_hitFraction));
967 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultValue",
m_defaultValue));
969 return STATUS_CODE_SUCCESS;
984 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
985 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
990 CaloHitList threeDCaloHitList;
993 if (!threeDCaloHitList.empty())
997 CartesianVector centroid(0.f, 0.f, 0.f);
1002 const float principalEigenvalue(eigenValues.GetX()), secondaryEigenvalue(eigenValues.GetY()), tertiaryEigenvalue(eigenValues.GetZ());
1004 if (principalEigenvalue > std::numeric_limits<float>::epsilon())
1006 pca1 = secondaryEigenvalue / principalEigenvalue;
1007 pca2 = tertiaryEigenvalue / principalEigenvalue;
1016 catch (
const StatusCodeException &)
1021 featureVector.push_back(pca1);
1022 featureVector.push_back(pca2);
1028 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
1031 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
1033 if (featureMap.find(featureToolName +
"_SecondaryPCARatio") != featureMap.end() ||
1034 featureMap.find(featureToolName +
"_TertiaryPCARatio") != featureMap.end())
1036 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
1037 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
1040 featureOrder.push_back(featureToolName +
"_SecondaryPCARatio");
1041 featureOrder.push_back(featureToolName +
"_TertiaryPCARatio");
1043 featureMap[featureToolName +
"_SecondaryPCARatio"] = toolFeatureVec[0].Get();
1044 featureMap[featureToolName +
"_TertiaryPCARatio"] = toolFeatureVec[1].Get();
1051 return STATUS_CODE_SUCCESS;
1066 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
1067 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
1069 float totalCharge(-1.f), chargeSigma(-1.f), chargeMean(-1.f), endCharge(-1.f);
1072 ClusterList clusterListW;
1075 if (!clusterListW.empty())
1078 if (chargeMean > std::numeric_limits<float>::epsilon())
1079 charge1 = chargeSigma / chargeMean;
1081 if (totalCharge > std::numeric_limits<float>::epsilon())
1082 charge2 = endCharge / totalCharge;
1084 featureVector.push_back(charge1);
1085 featureVector.push_back(charge2);
1091 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
1094 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
1096 if (featureMap.find(featureToolName +
"_FractionalSpread") != featureMap.end() ||
1097 featureMap.find(featureToolName +
"_EndFraction") != featureMap.end())
1099 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
1100 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
1103 featureOrder.push_back(featureToolName +
"_FractionalSpread");
1104 featureOrder.push_back(featureToolName +
"_EndFraction");
1106 featureMap[featureToolName +
"_FractionalSpread"] = toolFeatureVec[0].Get();
1107 featureMap[featureToolName +
"_EndFraction"] = toolFeatureVec[1].Get();
1113 float &totalCharge,
float &chargeSigma,
float &chargeMean,
float &endCharge)
1120 CaloHitList orderedCaloHitList;
1123 FloatVector chargeVector;
1124 unsigned int hitCounter(0);
1125 const unsigned int nTotalHits(orderedCaloHitList.size());
1127 for (
const CaloHit *
const pCaloHit : orderedCaloHitList)
1130 const float pCaloHitCharge(pCaloHit->GetInputEnergy());
1132 if (pCaloHitCharge >= 0.f)
1134 totalCharge += pCaloHitCharge;
1135 chargeVector.push_back(pCaloHitCharge);
1137 if (hitCounter >= std::floor(static_cast<float>(nTotalHits) * (1.f -
m_endChargeFraction)))
1138 endCharge += pCaloHitCharge;
1142 if (!chargeVector.empty())
1144 chargeMean = totalCharge /
static_cast<float>(chargeVector.size());
1146 for (
const float charge : chargeVector)
1147 chargeSigma += (charge - chargeMean) * (charge - chargeMean);
1149 chargeSigma = std::sqrt(chargeSigma / static_cast<float>(chargeVector.size()));
1156 const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster, CaloHitList &caloHitList)
1159 (
void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
1161 if (!pVertexList || pVertexList->empty())
1164 unsigned int nInteractionVertices(0);
1165 const Vertex *pInteractionVertex(
nullptr);
1167 for (
const Vertex *pVertex : *pVertexList)
1169 if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
1171 ++nInteractionVertices;
1172 pInteractionVertex = pVertex;
1176 if (pInteractionVertex && (1 == nInteractionVertices))
1181 CaloHitList clusterCaloHitList;
1182 pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
1185 caloHitList.insert(caloHitList.end(), clusterCaloHitList.begin(), clusterCaloHitList.end());
1193 PANDORA_RETURN_RESULT_IF_AND_IF(
1194 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"EndChargeFraction",
m_endChargeFraction));
1196 return STATUS_CODE_SUCCESS;
1210 const float distanceL((left->GetPositionVector() - m_neutrinoVertex).GetMagnitudeSquared());
1211 const float distanceR((right->GetPositionVector() - m_neutrinoVertex).GetMagnitudeSquared());
1212 return distanceL < distanceR;
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void OrderCaloHitsByDistanceToVertex(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, pandora::CaloHitList &caloHitList)
Function to order the calo hit list by distance to neutrino vertex.
Header file for the pfo helper class.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
Header file for the cut based cluster characterisation algorithm class.
MvaTypes::MvaFeatureVector MvaFeatureVector
float m_hitFraction
Fraction of hits in start and end of pfo.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
pandora::CartesianVector EigenValues
static float GetThreeDLengthSquared(const pandora::ParticleFlowObject *const pPfo)
Calculate length of Pfo using 3D clusters.
static float CalculateGapDeltaZ(const pandora::Pandora &pandora, const float minZ, const float maxZ, const pandora::HitType hitType)
Calculate the total distance within a given 2D region that is composed of detector gaps...
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetVertexDistance(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
Get the distance between the interaction vertex (if present in the current vertex list) and a provide...
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
unsigned int m_slidingShowerFitWindow
The sliding shower fit window.
Header file for the principal curve analysis helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
ThreeDOpeningAngleFeatureTool()
Default constructor.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
TwoDLinearFitFeatureTool()
Default constructor.
ThreeDLinearFitFeatureTool()
Default constructor.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
MvaTypes::MvaFeatureMap MvaFeatureMap
unsigned int m_conMinHits
Configurable parameters to calculate cone charge variables.
void CalculateVariablesSlidingLinearFit(const pandora::Cluster *const pCluster, float &straightLineLengthLarge, float &diffWithStraigthLineMean, float &maxFitGapLength, float &rmsSlidingLinearFit) const
Calculation of several variables related to sliding linear fit.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
Header file for the geometry helper class.
ThreeDPCAFeatureTool()
Default constructor.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
bool operator()(const pandora::CaloHit *const left, const pandora::CaloHit *const right) const
operator <
double GetFitT() const
Get the fitted t coordinate.
InitializedDouble class used to define mva features.
unsigned int m_slidingLinearFitWindowLarge
The sliding linear fit window - should be large, providing a simple linear fit.
Header file for the cluster helper class.
float OpeningAngle(const pandora::CartesianVector &principal, const pandora::CartesianVector &secondary, const pandora::CartesianVector &eigenValues) const
Use the results of principal component analysis to calculate an opening angle.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
TwoDVertexDistanceFeatureTool()
Default constructor.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
float m_MoliereRadiusFrac
Header file for the lar two dimensional sliding fit result class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
double GetGradient() const
Get the fitted gradient dt/dz.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
VertexComparator class for comparison of two points wrt neutrino vertex position. ...
double GetRms() const
Get the rms of the fit residuals.
static void RunPca(const T &t, pandora::CartesianVector ¢roid, EigenValues &outputEigenValues, EigenVectors &outputEigenVectors)
Run principal component analysis using input calo hits (TPC_VIEW_U,V,W or TPC_3D; all treated as 3D p...
VertexComparator(const pandora::CartesianVector vertexPosition2D)
Constructor.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::vector< pandora::CartesianVector > EigenVectors
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...
void GetGlobalPosition(const float rL, const float rT, pandora::CartesianVector &position) const
Get global coordinates for given sliding linear fit coordinates.
unsigned int m_slidingLinearFitWindowLarge
The sliding linear fit window - should be large, providing a simple linear fit.
float m_defaultValue
Default value to return, in case calculation not feasible.
void CalculateChargeVariables(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, float &totalCharge, float &chargeSigma, float &chargeMean, float &endCharge)
Calculation of the charge variables.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
ConeChargeFeatureTool()
Default constructor.
void Divide3DCaloHitList(const pandora::Algorithm *const pAlgorithm, const pandora::CaloHitList &threeDCaloHitList, pandora::CartesianPointVector &pointVectorStart, pandora::CartesianPointVector &pointVectorEnd)
Obtain positions at the vertex and non-vertex end of a list of three dimensional calo hits...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
ThreeDVertexDistanceFeatureTool()
Default constructor.
float m_endChargeFraction
Fraction of hits that will be considered to calculate end charge (default 10%)
double GetL() const
Get the l coordinate.
static float GetShowerFitWidth(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, const unsigned int showerFitWindow)
Get a measure of the width of a cluster, using a sliding shower fit result.
float CalculateConicalness(const pandora::CaloHitList &caloHitList, const pandora::CartesianVector &pfoStart, const pandora::CartesianVector &pfoDir, const float pfoLength)
Calculate conicalness as a ratio of charge distribution at the end and start of pfo.
ThreeDChargeFeatureTool()
Default constructor.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
void CalculateVariablesSlidingLinearFit(const pandora::Cluster *const pCluster, float &straightLineLengthLarge, float &diffWithStraigthLineMean, float &diffWithStraightLineSigma, float &dTdLWidth, float &maxFitGapLength, float &rmsSlidingLinearFit) const
Calculation of several variables related to sliding linear fit.
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.
PfoHierarchyFeatureTool()
Default constructor.
void CalculateChargeDistribution(const pandora::CaloHitList &caloHitList, const pandora::CartesianVector &pfoStart, const pandora::CartesianVector &pfoDir, float &chargeCore, float &chargeHalo, float &chargeCon)
Calculate charge distribution in relation to the Moeliere radius.
std::list< Vertex > VertexList
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
TwoDSlidingFitResult class.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
BEGIN_PROLOG could also be cout
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)