9 #include "Pandora/AlgorithmHeaders.h" 10 #include "Pandora/StatusCodes.h" 27 TwoDShowerFitFeatureTool::TwoDShowerFitFeatureTool() :
28 m_slidingShowerFitWindow(3),
29 m_slidingLinearFitWindow(10000)
37 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
38 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
44 const float straightLineLength =
46 if (straightLineLength > std::numeric_limits<float>::epsilon())
49 catch (
const StatusCodeException &)
53 featureVector.push_back(ratio);
59 const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster)
62 this->
Run(toolFeatureVec, pAlgorithm, pCluster);
64 if (featureMap.find(featureToolName +
"_WidthLenRatio") != featureMap.end())
66 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
67 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
70 featureOrder.push_back(featureToolName +
"_WidthLenRatio");
71 featureMap[featureToolName +
"_WidthLenRatio"] = toolFeatureVec[0];
78 PANDORA_RETURN_RESULT_IF_AND_IF(
79 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingShowerFitWindow",
m_slidingShowerFitWindow));
81 PANDORA_RETURN_RESULT_IF_AND_IF(
82 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
84 return STATUS_CODE_SUCCESS;
92 m_slidingLinearFitWindowLarge(10000)
100 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
101 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
103 float dTdLWidth(-1.
f), straightLineLengthLarge(-1.
f), diffWithStraightLineMean(-1.
f), diffWithStraightLineSigma(-1.
f),
104 maxFitGapLength(-1.
f), rmsSlidingLinearFit(-1.
f);
106 dTdLWidth, maxFitGapLength, rmsSlidingLinearFit);
108 if (straightLineLengthLarge > std::numeric_limits<float>::epsilon())
110 diffWithStraightLineMean /= straightLineLengthLarge;
111 diffWithStraightLineSigma /= straightLineLengthLarge;
112 dTdLWidth /= straightLineLengthLarge;
113 maxFitGapLength /= straightLineLengthLarge;
114 rmsSlidingLinearFit /= straightLineLengthLarge;
117 featureVector.push_back(straightLineLengthLarge);
118 featureVector.push_back(diffWithStraightLineMean);
119 featureVector.push_back(diffWithStraightLineSigma);
120 featureVector.push_back(dTdLWidth);
121 featureVector.push_back(maxFitGapLength);
122 featureVector.push_back(rmsSlidingLinearFit);
128 const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster)
131 this->
Run(toolFeatureVec, pAlgorithm, pCluster);
133 if (featureMap.find(featureToolName +
"_StLineLenLarge") != featureMap.end() ||
134 featureMap.find(featureToolName +
"_DiffStLineMean") != featureMap.end() ||
135 featureMap.find(featureToolName +
"_DiffStLineSigma") != featureMap.end() ||
136 featureMap.find(featureToolName +
"_dTdLWidth") != featureMap.end() ||
137 featureMap.find(featureToolName +
"_MaxFitGapLen") != featureMap.end() ||
138 featureMap.find(featureToolName +
"_rmsSlidingLinFit") != featureMap.end())
140 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
141 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
144 featureOrder.push_back(featureToolName +
"_StLineLenLarge");
145 featureOrder.push_back(featureToolName +
"_DiffStLineMean");
146 featureOrder.push_back(featureToolName +
"_DiffStLineSigma");
147 featureOrder.push_back(featureToolName +
"_dTdLWidth");
148 featureOrder.push_back(featureToolName +
"_MaxFitGapLen");
149 featureOrder.push_back(featureToolName +
"_rmsSlidingLinFit");
151 featureMap[featureToolName +
"_StLineLenLarge"] = toolFeatureVec[0];
152 featureMap[featureToolName +
"_DiffStLineMean"] = toolFeatureVec[1];
153 featureMap[featureToolName +
"_DiffStLineSigma"] = toolFeatureVec[2];
154 featureMap[featureToolName +
"_dTdLWidth"] = toolFeatureVec[3];
155 featureMap[featureToolName +
"_MaxFitGapLen"] = toolFeatureVec[4];
156 featureMap[featureToolName +
"_rmsSlidingLinFit"] = toolFeatureVec[5];
162 float &diffWithStraightLineMean,
float &diffWithStraightLineSigma,
float &dTdLWidth,
float &maxFitGapLength,
float &rmsSlidingLinearFit)
const 171 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
173 straightLineLengthLarge =
175 rmsSlidingLinearFit = 0.f;
177 FloatVector diffWithStraightLineVector;
180 float dTdLMin(+std::numeric_limits<float>::max()), dTdLMax(-std::numeric_limits<float>::max());
185 rmsSlidingLinearFit += layerFitResult.
GetRms();
187 CartesianVector thisFitPosition(0.
f, 0.
f, 0.
f);
194 throw StatusCodeException(STATUS_CODE_FAILURE);
196 diffWithStraightLineVector.push_back(static_cast<float>(std::fabs(layerFitResult.
GetFitT() - iterLarge->second.GetFitT())));
198 const float thisGapLength((thisFitPosition - previousFitPosition).GetMagnitude());
199 const float minZ(std::min(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
200 const float maxZ(std::max(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
202 if ((maxZ - minZ) > std::numeric_limits<float>::epsilon())
205 const float correctedGapLength(thisGapLength * (1.
f - gapZ / (maxZ - minZ)));
207 if (correctedGapLength > maxFitGapLength)
208 maxFitGapLength = correctedGapLength;
211 dTdLMin = std::min(dTdLMin, static_cast<float>(layerFitResult.
GetGradient()));
212 dTdLMax = std::max(dTdLMax, static_cast<float>(layerFitResult.
GetGradient()));
213 previousFitPosition = thisFitPosition;
216 if (diffWithStraightLineVector.empty())
217 throw StatusCodeException(STATUS_CODE_FAILURE);
219 diffWithStraightLineMean = 0.f;
220 diffWithStraightLineSigma = 0.f;
222 for (
const float diffWithStraightLine : diffWithStraightLineVector)
223 diffWithStraightLineMean += diffWithStraightLine;
225 diffWithStraightLineMean /=
static_cast<float>(diffWithStraightLineVector.size());
227 for (
const float diffWithStraightLine : diffWithStraightLineVector)
228 diffWithStraightLineSigma += (diffWithStraightLine - diffWithStraightLineMean) * (diffWithStraightLine - diffWithStraightLineMean);
230 if (diffWithStraightLineSigma < 0.
f)
231 throw StatusCodeException(STATUS_CODE_FAILURE);
233 diffWithStraightLineSigma = std::sqrt(diffWithStraightLineSigma / static_cast<float>(diffWithStraightLineVector.size()));
234 dTdLWidth = dTdLMax - dTdLMin;
236 catch (
const StatusCodeException &)
238 straightLineLengthLarge = -1.f;
239 diffWithStraightLineMean = -1.f;
240 diffWithStraightLineSigma = -1.f;
242 maxFitGapLength = -1.f;
243 rmsSlidingLinearFit = -1.f;
251 PANDORA_RETURN_RESULT_IF_AND_IF(
252 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
254 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
257 return STATUS_CODE_SUCCESS;
273 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
274 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
276 float straightLineLength(-1.
f), ratio(-1.
f);
281 if (straightLineLength > std::numeric_limits<float>::epsilon())
284 catch (
const StatusCodeException &)
288 featureVector.push_back(ratio);
294 const std::string &featureToolName,
const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster)
297 this->
Run(toolFeatureVec, pAlgorithm, pCluster);
299 if (featureMap.find(featureToolName +
"_DistLenRatio") != featureMap.end())
301 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
302 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
305 featureOrder.push_back(featureToolName +
"_DistLenRatio");
306 featureMap[featureToolName +
"_DistLenRatio"] = toolFeatureVec[0];
313 PANDORA_RETURN_RESULT_IF_AND_IF(
314 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
316 return STATUS_CODE_SUCCESS;
331 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
332 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
334 CaloHitList parent3DHitList;
336 const unsigned int nParentHits3D(parent3DHitList.size());
338 PfoList allDaughtersPfoList;
340 const unsigned int nDaughterPfos(allDaughtersPfoList.empty() ? 0 : allDaughtersPfoList.size() - 1);
342 unsigned int nDaughterHits3DTotal(0);
344 if (nDaughterPfos > 0)
347 allDaughtersPfoList.pop_front();
349 for (
const ParticleFlowObject *
const pDaughterPfo : allDaughtersPfoList)
351 CaloHitList daughter3DHitList;
353 nDaughterHits3DTotal += daughter3DHitList.size();
360 (nParentHits3D > 0) ? static_cast<double>(nDaughterHits3DTotal) / static_cast<double>(nParentHits3D) : 0.);
362 featureVector.push_back(nDaughters);
363 featureVector.push_back(nDaughterHits3D);
364 featureVector.push_back(daughterParentNHitsRatio);
370 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
373 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
375 if (featureMap.find(featureToolName +
"_NDaughters") != featureMap.end() ||
376 featureMap.find(featureToolName +
"_NDaughterHits3D") != featureMap.end() ||
377 featureMap.find(featureToolName +
"_DaughterParentHitRatio") != featureMap.end())
379 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
380 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
383 featureOrder.push_back(featureToolName +
"_NDaughters");
384 featureOrder.push_back(featureToolName +
"_NDaughterHits3D");
385 featureOrder.push_back(featureToolName +
"_DaughterParentHitRatio");
387 featureMap[featureToolName +
"_NDaughters"] = toolFeatureVec[0];
388 featureMap[featureToolName +
"_NDaughterHits3D"] = toolFeatureVec[1];
389 featureMap[featureToolName +
"_DaughterParentHitRatio"] = toolFeatureVec[2];
396 return STATUS_CODE_SUCCESS;
405 m_conFracRange(0.2
f),
406 m_MoliereRadius(10.1
f),
407 m_MoliereRadiusFrac(0.2
f)
416 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
417 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
419 ClusterList clusterListW;
424 if (!clusterListW.empty())
426 CaloHitList clusterCaloHitList;
427 clusterListW.front()->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
429 const CartesianVector &pfoStart(clusterCaloHitList.front()->GetPositionVector());
430 CartesianVector centroid(0.
f, 0.
f, 0.
f);
435 float chargeCore(0.
f), chargeHalo(0.
f), chargeCon(0.
f);
437 haloTotalRatio = (chargeCore + chargeHalo > std::numeric_limits<float>::epsilon()) ? chargeHalo / (chargeCore + chargeHalo) : -1.f;
438 concentration = (chargeCore + chargeHalo > std::numeric_limits<float>::epsilon()) ? chargeCon / (chargeCore + chargeHalo) : -1.f;
440 conicalness = (pfoLength > std::numeric_limits<float>::epsilon())
445 featureVector.push_back(haloTotalRatio);
446 featureVector.push_back(concentration);
447 featureVector.push_back(conicalness);
453 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
456 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
458 if (featureMap.find(featureToolName +
"_HaloTotalRatio") != featureMap.end() ||
459 featureMap.find(featureToolName +
"_Concentration") != featureMap.end() ||
460 featureMap.find(featureToolName +
"_Conicalness") != featureMap.end())
462 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
463 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
466 featureOrder.push_back(featureToolName +
"_HaloTotalRatio");
467 featureOrder.push_back(featureToolName +
"_Concentration");
468 featureOrder.push_back(featureToolName +
"_Conicalness");
470 featureMap[featureToolName +
"_HaloTotalRatio"] = toolFeatureVec[0];
471 featureMap[featureToolName +
"_Concentration"] = toolFeatureVec[1];
472 featureMap[featureToolName +
"_Conicalness"] = toolFeatureVec[2];
478 const CartesianVector &pfoDir,
float &chargeCore,
float &chargeHalo,
float &chargeCon)
480 for (
const CaloHit *
const pCaloHit : caloHitList)
482 const float distFromTrackFit(((pCaloHit->GetPositionVector() - pfoStart).GetCrossProduct(pfoDir)).GetMagnitude());
485 chargeCore += pCaloHit->GetInputEnergy();
487 chargeHalo += pCaloHit->GetInputEnergy();
489 chargeCon += pCaloHit->GetInputEnergy() / std::max(1.
E-2
f, distFromTrackFit);
496 const CaloHitList &caloHitList,
const CartesianVector &pfoStart,
const CartesianVector &pfoDir,
const float pfoLength)
498 float totalChargeStart(0.
f), totalChargeEnd(0.
f);
499 float chargeConStart(0.
f), chargeConEnd(0.
f);
500 unsigned int nHitsConStart(0), nHitsConEnd(0);
502 for (
const CaloHit *
const pCaloHit : caloHitList)
504 const float distFromTrackFit(((pCaloHit->GetPositionVector() - pfoStart).GetCrossProduct(pfoDir)).GetMagnitude());
505 const float hitLength(std::fabs((pCaloHit->GetPositionVector() - pfoStart).GetDotProduct(pfoDir)));
509 chargeConStart += distFromTrackFit * distFromTrackFit * pCaloHit->GetInputEnergy();
511 totalChargeStart += pCaloHit->GetInputEnergy();
515 chargeConEnd += distFromTrackFit * distFromTrackFit * pCaloHit->GetInputEnergy();
517 totalChargeEnd += pCaloHit->GetInputEnergy();
521 float conicalness(1.
f);
525 conicalness = (std::sqrt(chargeConEnd / chargeConStart)) / (totalChargeEnd / totalChargeStart);
534 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConMinHits",
m_conMinHits));
535 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinCharge",
m_minCharge));
536 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ConFracRange",
m_conFracRange));
537 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MoliereRadius",
m_MoliereRadius));
538 PANDORA_RETURN_RESULT_IF_AND_IF(
539 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MoliereRadiusFrac",
m_MoliereRadiusFrac));
541 return STATUS_CODE_SUCCESS;
548 m_slidingLinearFitWindow(3),
549 m_slidingLinearFitWindowLarge(10000)
558 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
559 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
561 ClusterList clusterList;
563 float diffWithStraightLineMean(0.
f), maxFitGapLength(0.
f), rmsSlidingLinearFit(0.
f);
565 unsigned int nClustersUsed(0);
567 for (
const Cluster *
const pCluster : clusterList)
569 float straightLineLengthLargeCluster(-1.
f), diffWithStraightLineMeanCluster(-1.
f), maxFitGapLengthCluster(-1.
f),
570 rmsSlidingLinearFitCluster(-1.
f);
573 pCluster, straightLineLengthLargeCluster, diffWithStraightLineMeanCluster, maxFitGapLengthCluster, rmsSlidingLinearFitCluster);
575 if (straightLineLengthLargeCluster > std::numeric_limits<float>::epsilon())
577 diffWithStraightLineMeanCluster /= straightLineLengthLargeCluster;
578 maxFitGapLengthCluster /= straightLineLengthLargeCluster;
579 rmsSlidingLinearFitCluster /= straightLineLengthLargeCluster;
581 diffWithStraightLineMean += diffWithStraightLineMeanCluster;
582 maxFitGapLength += maxFitGapLengthCluster;
583 rmsSlidingLinearFit += rmsSlidingLinearFitCluster;
589 if (nClustersUsed > 0)
591 const float nClusters(static_cast<float>(nClustersUsed));
593 diff = diffWithStraightLineMean / nClusters;
594 gap = maxFitGapLength / nClusters;
595 rms = rmsSlidingLinearFit / nClusters;
598 featureVector.push_back(length);
599 featureVector.push_back(diff);
600 featureVector.push_back(gap);
601 featureVector.push_back(rms);
607 const std::string &featureToolName,
const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
610 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
612 if (featureMap.find(featureToolName +
"_Length") != featureMap.end() ||
613 featureMap.find(featureToolName +
"_DiffStraightLineMean") != featureMap.end() ||
614 featureMap.find(featureToolName +
"_MaxFitGapLength") != featureMap.end() ||
615 featureMap.find(featureToolName +
"_SlidingLinearFitRMS") != featureMap.end())
617 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
618 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
621 featureOrder.push_back(featureToolName +
"_Length");
622 featureOrder.push_back(featureToolName +
"_DiffStraightLineMean");
623 featureOrder.push_back(featureToolName +
"_MaxFitGapLength");
624 featureOrder.push_back(featureToolName +
"_SlidingLinearFitRMS");
626 featureMap[featureToolName +
"_Length"] = toolFeatureVec[0];
627 featureMap[featureToolName +
"_DiffStraightLineMean"] = toolFeatureVec[1];
628 featureMap[featureToolName +
"_MaxFitGapLength"] = toolFeatureVec[2];
629 featureMap[featureToolName +
"_SlidingLinearFitRMS"] = toolFeatureVec[3];
635 float &diffWithStraightLineMean,
float &maxFitGapLength,
float &rmsSlidingLinearFit)
const 644 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
646 straightLineLengthLarge =
648 rmsSlidingLinearFit = 0.f;
650 FloatVector diffWithStraightLineVector;
653 float dTdLMin(+std::numeric_limits<float>::max()), dTdLMax(-std::numeric_limits<float>::max());
658 rmsSlidingLinearFit += layerFitResult.
GetRms();
660 CartesianVector thisFitPosition(0.
f, 0.
f, 0.
f);
667 throw StatusCodeException(STATUS_CODE_FAILURE);
669 diffWithStraightLineVector.push_back(static_cast<float>(std::fabs(layerFitResult.
GetFitT() - iterLarge->second.GetFitT())));
671 const float thisGapLength((thisFitPosition - previousFitPosition).GetMagnitude());
672 const float minZ(std::min(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
673 const float maxZ(std::max(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
675 if ((maxZ - minZ) > std::numeric_limits<float>::epsilon())
678 const float correctedGapLength(thisGapLength * (1.
f - gapZ / (maxZ - minZ)));
680 if (correctedGapLength > maxFitGapLength)
681 maxFitGapLength = correctedGapLength;
685 maxFitGapLength = 0.f;
688 dTdLMin = std::min(dTdLMin, static_cast<float>(layerFitResult.
GetGradient()));
689 dTdLMax = std::max(dTdLMax, static_cast<float>(layerFitResult.
GetGradient()));
690 previousFitPosition = thisFitPosition;
693 if (diffWithStraightLineVector.empty())
694 throw StatusCodeException(STATUS_CODE_FAILURE);
696 diffWithStraightLineMean = 0.f;
698 for (
const float diffWithStraightLine : diffWithStraightLineVector)
699 diffWithStraightLineMean += diffWithStraightLine;
701 diffWithStraightLineMean /=
static_cast<float>(diffWithStraightLineVector.size());
703 catch (
const StatusCodeException &)
705 straightLineLengthLarge = -1.f;
706 diffWithStraightLineMean = -1.f;
707 maxFitGapLength = -1.f;
708 rmsSlidingLinearFit = -1.f;
716 PANDORA_RETURN_RESULT_IF_AND_IF(
717 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingLinearFitWindow",
m_slidingLinearFitWindow));
719 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
722 return STATUS_CODE_SUCCESS;
737 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
738 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
743 (void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
745 if (!pVertexList || pVertexList->empty())
747 featureVector.push_back(vertexDistance);
751 unsigned int nInteractionVertices(0);
752 const Vertex *pInteractionVertex(
nullptr);
754 for (
const Vertex *pVertex : *pVertexList)
756 if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
758 ++nInteractionVertices;
759 pInteractionVertex = pVertex;
763 if (pInteractionVertex && (1 == nInteractionVertices))
767 vertexDistance = (pInteractionVertex->GetPosition() -
LArPfoHelper::GetVertex(pInputPfo)->GetPosition()).GetMagnitude();
769 catch (
const StatusCodeException &)
771 CaloHitList threeDCaloHitList;
774 if (!threeDCaloHitList.empty())
775 vertexDistance = (pInteractionVertex->GetPosition() - (threeDCaloHitList.front())->GetPositionVector()).GetMagnitude();
779 featureVector.push_back(vertexDistance);
785 const std::string &featureToolName,
const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
788 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
790 if (featureMap.find(featureToolName +
"_VertexDistance") != featureMap.end())
792 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
793 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
796 featureOrder.push_back(featureToolName +
"_VertexDistance");
798 featureMap[featureToolName +
"_VertexDistance"] = toolFeatureVec[0];
805 return STATUS_CODE_SUCCESS;
822 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
823 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
826 CaloHitList threeDCaloHitList;
830 if (!threeDCaloHitList.empty())
832 CartesianPointVector pointVectorStart, pointVectorEnd;
833 this->
Divide3DCaloHitList(pAlgorithm, threeDCaloHitList, pointVectorStart, pointVectorEnd);
836 if ((pointVectorStart.size() > 1) && (pointVectorEnd.size() > 1))
841 CartesianVector centroidStart(0.
f, 0.
f, 0.
f), centroidEnd(0.
f, 0.
f, 0.
f);
848 const float openingAngle(this->
OpeningAngle(eigenVecsStart.at(0), eigenVecsStart.at(1), eigenValuesStart));
849 const float closingAngle(this->
OpeningAngle(eigenVecsEnd.at(0), eigenVecsEnd.at(1), eigenValuesEnd));
850 diffAngle = std::fabs(openingAngle - closingAngle);
852 catch (
const StatusCodeException &)
862 featureVector.push_back(diffAngle);
868 const std::string &featureToolName,
const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
871 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
873 if (featureMap.find(featureToolName +
"_AngleDiff") != featureMap.end())
875 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
876 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
879 featureOrder.push_back(featureToolName +
"_AngleDiff");
881 featureMap[featureToolName +
"_AngleDiff"] = toolFeatureVec[0];
887 CartesianPointVector &pointVectorStart, CartesianPointVector &pointVectorEnd)
890 (void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
892 if (threeDCaloHitList.empty() || !pVertexList || pVertexList->empty())
895 unsigned int nInteractionVertices(0);
896 const Vertex *pInteractionVertex(
nullptr);
898 for (
const Vertex *pVertex : *pVertexList)
900 if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
902 ++nInteractionVertices;
903 pInteractionVertex = pVertex;
907 if (pInteractionVertex && (1 == nInteractionVertices))
910 CaloHitVector threeDCaloHitVector(threeDCaloHitList.begin(), threeDCaloHitList.end());
911 std::sort(threeDCaloHitVector.begin(), threeDCaloHitVector.end(),
914 unsigned int iHit(1);
915 const unsigned int nHits(threeDCaloHitVector.size());
917 for (
const CaloHit *
const pCaloHit : threeDCaloHitVector)
919 if (static_cast<float>(iHit) /
static_cast<float>(nHits) <=
m_hitFraction)
920 pointVectorStart.push_back(pCaloHit->GetPositionVector());
922 if (static_cast<float>(iHit) /
static_cast<float>(nHits) >= 1.
f -
m_hitFraction)
923 pointVectorEnd.push_back(pCaloHit->GetPositionVector());
934 const float principalMagnitude(principal.GetMagnitude());
935 const float secondaryMagnitude(secondary.GetMagnitude());
937 if (std::fabs(principalMagnitude) < std::numeric_limits<float>::epsilon())
939 std::cout <<
"ThreeDOpeningAngleFeatureTool::OpeningAngle - The principal eigenvector is 0." << std::endl;
940 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
942 else if (std::fabs(secondaryMagnitude) < std::numeric_limits<float>::epsilon())
947 const float cosTheta(principal.GetDotProduct(secondary) / (principalMagnitude * secondaryMagnitude));
951 std::cout <<
"PcaShowerParticleBuildingAlgorithm::OpeningAngle - cos(theta) reportedly greater than 1." << std::endl;
952 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
955 const float sinTheta(std::sqrt(1.
f - cosTheta * cosTheta));
957 if (eigenValues.GetX() < std::numeric_limits<float>::epsilon())
959 std::cout <<
"PcaShowerParticleBuildingAlgorithm::OpeningAngle - principal eigenvalue less than or equal to 0." << std::endl;
960 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
962 else if (eigenValues.GetY() < std::numeric_limits<float>::epsilon())
967 return std::atan(std::sqrt(eigenValues.GetY()) * sinTheta / std::sqrt(eigenValues.GetX()));
974 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HitFraction",
m_hitFraction));
976 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultValue",
m_defaultValue));
978 return STATUS_CODE_SUCCESS;
993 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
994 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
999 CaloHitList threeDCaloHitList;
1002 if (!threeDCaloHitList.empty())
1006 CartesianVector centroid(0.
f, 0.
f, 0.
f);
1011 const float principalEigenvalue(eigenValues.GetX()), secondaryEigenvalue(eigenValues.GetY()), tertiaryEigenvalue(eigenValues.GetZ());
1013 if (principalEigenvalue > std::numeric_limits<float>::epsilon())
1015 pca1 = secondaryEigenvalue / principalEigenvalue;
1016 pca2 = tertiaryEigenvalue / principalEigenvalue;
1025 catch (
const StatusCodeException &)
1030 featureVector.push_back(pca1);
1031 featureVector.push_back(pca2);
1037 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
1040 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
1042 if (featureMap.find(featureToolName +
"_SecondaryPCARatio") != featureMap.end() ||
1043 featureMap.find(featureToolName +
"_TertiaryPCARatio") != featureMap.end())
1045 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
1046 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
1049 featureOrder.push_back(featureToolName +
"_SecondaryPCARatio");
1050 featureOrder.push_back(featureToolName +
"_TertiaryPCARatio");
1052 featureMap[featureToolName +
"_SecondaryPCARatio"] = toolFeatureVec[0];
1053 featureMap[featureToolName +
"_TertiaryPCARatio"] = toolFeatureVec[1];
1060 return STATUS_CODE_SUCCESS;
1067 m_endChargeFraction(0.1
f)
1076 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
1077 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
1079 float totalCharge(-1.
f), chargeSigma(-1.
f), chargeMean(-1.
f), endCharge(-1.
f);
1082 ClusterList clusterListW;
1085 if (!clusterListW.empty())
1088 if (chargeMean > std::numeric_limits<float>::epsilon())
1089 charge1 = chargeSigma / chargeMean;
1091 if (totalCharge > std::numeric_limits<float>::epsilon())
1092 charge2 = endCharge / totalCharge;
1094 featureVector.push_back(charge1);
1095 featureVector.push_back(charge2);
1101 const pandora::Algorithm *
const pAlgorithm,
const pandora::ParticleFlowObject *
const pInputPfo)
1104 this->
Run(toolFeatureVec, pAlgorithm, pInputPfo);
1106 if (featureMap.find(featureToolName +
"_FractionalSpread") != featureMap.end() ||
1107 featureMap.find(featureToolName +
"_EndFraction") != featureMap.end())
1109 std::cout <<
"Already wrote this feature into map! Not writing again." << std::endl;
1110 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
1113 featureOrder.push_back(featureToolName +
"_FractionalSpread");
1114 featureOrder.push_back(featureToolName +
"_EndFraction");
1116 featureMap[featureToolName +
"_FractionalSpread"] = toolFeatureVec[0];
1117 featureMap[featureToolName +
"_EndFraction"] = toolFeatureVec[1];
1123 float &totalCharge,
float &chargeSigma,
float &chargeMean,
float &endCharge)
1130 CaloHitList orderedCaloHitList;
1133 FloatVector chargeVector;
1134 unsigned int hitCounter(0);
1135 const unsigned int nTotalHits(orderedCaloHitList.size());
1137 for (
const CaloHit *
const pCaloHit : orderedCaloHitList)
1140 const float pCaloHitCharge(pCaloHit->GetInputEnergy());
1142 if (pCaloHitCharge >= 0.
f)
1144 totalCharge += pCaloHitCharge;
1145 chargeVector.push_back(pCaloHitCharge);
1148 endCharge += pCaloHitCharge;
1152 if (!chargeVector.empty())
1154 chargeMean = totalCharge /
static_cast<float>(chargeVector.size());
1156 for (
const float charge : chargeVector)
1157 chargeSigma += (charge - chargeMean) * (charge - chargeMean);
1159 chargeSigma = std::sqrt(chargeSigma / static_cast<float>(chargeVector.size()));
1166 const Algorithm *
const pAlgorithm,
const pandora::Cluster *
const pCluster, CaloHitList &caloHitList)
1169 (void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
1171 if (!pVertexList || pVertexList->empty())
1174 unsigned int nInteractionVertices(0);
1175 const Vertex *pInteractionVertex(
nullptr);
1177 for (
const Vertex *pVertex : *pVertexList)
1179 if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
1181 ++nInteractionVertices;
1182 pInteractionVertex = pVertex;
1186 if (pInteractionVertex && (1 == nInteractionVertices))
1191 CaloHitList clusterCaloHitList;
1192 pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
1195 caloHitList.insert(caloHitList.end(), clusterCaloHitList.begin(), clusterCaloHitList.end());
1203 PANDORA_RETURN_RESULT_IF_AND_IF(
1204 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"EndChargeFraction",
m_endChargeFraction));
1206 return STATUS_CODE_SUCCESS;
1213 m_neutrinoVertex(vertexPosition2D)
1221 const float distanceL((left->GetPositionVector() -
m_neutrinoVertex).GetMagnitudeSquared());
1222 const float distanceR((right->GetPositionVector() -
m_neutrinoVertex).GetMagnitudeSquared());
1223 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.
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
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)
pandora::CartesianVector m_neutrinoVertex
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. ...
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
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.
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.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
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.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)