9 #include "Pandora/AlgorithmHeaders.h" 10 #include "Pandora/StatusCodes.h" 25 InitialRegionFeatureTool::InitialRegionFeatureTool() :
26 m_defaultFloat(-10.
f),
27 m_nHitsToConsider(10),
28 m_maxInitialGapSizeLimit(4.
f),
29 m_minLargestGapSizeLimit(2.
f)
36 const ParticleFlowObject *
const ,
const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
37 const CartesianPointVector & )
57 const Algorithm *
const pAlgorithm,
const ParticleFlowObject *
const pShowerPfo,
const CartesianVector &nuVertex3D,
58 const ProtoShowerMatch &protoShowerMatch,
const CartesianPointVector &showerStarts3D)
61 this->
Run(toolFeatureVec, pAlgorithm, pShowerPfo, nuVertex3D, protoShowerMatch, showerStarts3D);
63 if (featureMap.find(featureToolName +
"_initialGapSize") != featureMap.end())
65 std::cout <<
"Already wrote initialGapSize feature into map! Not writing again." << std::endl;
66 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
69 featureOrder.push_back(featureToolName +
"_initialGapSize");
70 featureMap[featureToolName +
"_initialGapSize"] = toolFeatureVec[0];
72 if (featureMap.find(featureToolName +
"_largestGapSize") != featureMap.end())
74 std::cout <<
"Already wrote largestGapSize feature into map! Not writing again." << std::endl;
75 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
78 featureOrder.push_back(featureToolName +
"_largestGapSize");
79 featureMap[featureToolName +
"_largestGapSize"] = toolFeatureVec[1];
85 const ProtoShowerMatch &protoShowerMatch,
const HitType hitType,
float &initialGapSize,
float &largestGapSize)
const 87 const ProtoShower &protoShower(hitType == TPC_VIEW_U
97 initialGapSize = (nuVertex2D - spineHitVector.front()->GetPositionVector()).GetMagnitude();
102 std::vector<float> longitudinalProjections;
105 longitudinalProjections.push_back(startDirection.GetDotProduct(pCaloHit->GetPositionVector() - nuVertex2D));
107 std::sort(longitudinalProjections.begin(), longitudinalProjections.end());
109 const unsigned int nIterations(std::min(longitudinalProjections.size(),
static_cast<long unsigned int>(
m_nHitsToConsider)) - 1);
111 for (
unsigned int i = 0; i < nIterations; ++i)
112 largestGapSize = std::max(std::fabs(longitudinalProjections[i] - longitudinalProjections[i + 1]), largestGapSize);
119 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"nHitsToConsider",
m_nHitsToConsider));
121 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultFloat",
m_defaultFloat));
123 PANDORA_RETURN_RESULT_IF_AND_IF(
124 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxInitialGapSizeLimit",
m_maxInitialGapSizeLimit));
126 PANDORA_RETURN_RESULT_IF_AND_IF(
127 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinLargestGapSizeLimit",
m_minLargestGapSizeLimit));
129 return STATUS_CODE_SUCCESS;
137 m_spineFitWindow(10),
138 m_nLayersHalfWindow(5),
139 m_pathwayLengthLimit(30.
f),
140 m_pathwayScatteringAngle2DLimit(10.
f)
147 const ParticleFlowObject *
const ,
const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
148 const CartesianPointVector &showerStarts3D)
150 const float pathwayLength = (nuVertex3D - showerStarts3D.front()).GetMagnitude();
151 const float pathwayScatteringAngle2D = this->
Get2DKink(pAlgorithm, protoShowerMatch, showerStarts3D.back());
160 const std::string &featureToolName,
const Algorithm *
const pAlgorithm,
const ParticleFlowObject *
const pShowerPfo,
161 const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
const CartesianPointVector &showerStarts3D)
164 this->
Run(toolFeatureVec, pAlgorithm, pShowerPfo, nuVertex3D, protoShowerMatch, showerStarts3D);
166 if (featureMap.find(featureToolName +
"_pathwayLength") != featureMap.end())
168 std::cout <<
"Already wrote pathwayLength feature into map! Not writing again." << std::endl;
169 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
172 featureOrder.push_back(featureToolName +
"_pathwayLength");
173 featureMap[featureToolName +
"_pathwayLength"] = toolFeatureVec[0];
175 if (featureMap.find(featureToolName +
"_pathwayScatteringAngle2D") != featureMap.end())
177 std::cout <<
"Already wrote pathwayScatteringAngle2D feature into map! Not writing again." << std::endl;
178 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
181 featureOrder.push_back(featureToolName +
"_pathwayScatteringAngle2D");
182 featureMap[featureToolName +
"_pathwayScatteringAngle2D"] = toolFeatureVec[1];
188 const Algorithm *
const pAlgorithm,
const ProtoShowerMatch &protoShowerMatch,
const CartesianVector &showerStart3D)
const 192 CartesianPointVector spinePositionsU, spinePositionsV, spinePositionsW;
194 for (
HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
196 const ProtoShower &protoShower(hitType == TPC_VIEW_U
199 CartesianPointVector &spinePositions(hitType == TPC_VIEW_U ? spinePositionsU : (hitType == TPC_VIEW_V ? spinePositionsV : spinePositionsW));
202 spinePositions.push_back(pCaloHit->GetPositionVector());
216 return middleScatterAngle;
228 const HitType hitType,
const CartesianVector &showerStart3D)
const 231 const int minLayer(layerFitResultMap.begin()->first), maxLayer(layerFitResultMap.rbegin()->first);
232 const int nLayersSpanned(1 + maxLayer - minLayer);
239 float showerStartL(0.
f), showerStartT(0.
f);
240 spineFit.
GetLocalPosition(projectedShowerStart, showerStartL, showerStartT);
246 CartesianVector kinkPosition(0.
f, 0.
f, 0.
f);
247 CartesianVector highestKinkPosition(0.
f, 0.
f, 0.
f);
251 const int layer(iter->first);
253 if (layer < minCentralLayer)
256 if (layer > maxCentralLayer)
260 float openingAngle2D(std::numeric_limits<float>::max());
263 CartesianVector thisHighestKinkPosition(0.
f, 0.
f, 0.
f);
267 const int testLayer(layer + i);
268 const float rL(spineFit.
GetL(testLayer));
269 const float rL1(spineFit.
GetL(testLayer - m_nLayersHalfWindow));
270 const float rL2(spineFit.
GetL(testLayer + m_nLayersHalfWindow));
272 CartesianVector firstPosition(0.
f, 0.
f, 0.
f), centralPosition(0.
f, 0.
f, 0.
f), secondPosition(0.
f, 0.
f, 0.
f);
281 const CartesianVector firstDirection((centralPosition - firstPosition).GetUnitVector());
282 const CartesianVector secondDirection((secondPosition - centralPosition).GetUnitVector());
284 const float testOpeningAngle2D(secondDirection.GetOpeningAngle(firstDirection) * 180.f / M_PI);
286 if (testOpeningAngle2D < openingAngle2D)
288 openingAngle2D = testOpeningAngle2D;
292 if (testOpeningAngle2D > thisHighestOpeningAngle)
294 thisHighestOpeningAngle = openingAngle2D;
295 thisHighestKinkPosition = centralPosition;
301 if (openingAngle2D > highestOpeningAngle)
303 highestOpeningAngle = openingAngle2D;
304 highestKinkPosition = thisHighestKinkPosition;
309 return highestOpeningAngle;
316 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultFloat",
m_defaultFloat));
318 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SpineFitWindow",
m_spineFitWindow));
320 PANDORA_RETURN_RESULT_IF_AND_IF(
321 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NLayersHalfWindow",
m_nLayersHalfWindow));
323 PANDORA_RETURN_RESULT_IF_AND_IF(
324 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PathwayLengthLimit",
m_pathwayLengthLimit));
326 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
329 return STATUS_CODE_SUCCESS;
337 m_defaultRatio(-0.5
f),
339 m_showerRadius(14.
f),
340 m_showerFitWindow(1000),
342 m_moliereFraction(0.9
f),
343 m_maxNHitsLimit(2000.
f),
344 m_maxFoundHitRatioLimit(1.5
f),
345 m_maxScatterAngleLimit(40.
f),
346 m_maxOpeningAngleLimit(20.
f),
347 m_maxNuVertexEnergyWeightedMeanRadialDistanceLimit(20.
f),
348 m_minShowerStartMoliereRadiusLimit(10.
f)
355 const ParticleFlowObject *
const pShowerPfo,
const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
356 const CartesianPointVector &showerStarts3D)
363 foundHitRatioU, scatterAngleU, openingAngleU, nuVertexEnergyAsymmetryU, nuVertexEnergyWeightedMeanRadialDistanceU,
364 showerStartEnergyAsymmetryU, showerStartMoliereRadiusU);
371 foundHitRatioV, scatterAngleV, openingAngleV, nuVertexEnergyAsymmetryV, nuVertexEnergyWeightedMeanRadialDistanceV,
372 showerStartEnergyAsymmetryV, showerStartMoliereRadiusV);
379 foundHitRatioW, scatterAngleW, openingAngleW, nuVertexEnergyAsymmetryW, nuVertexEnergyWeightedMeanRadialDistanceW,
380 showerStartEnergyAsymmetryW, showerStartMoliereRadiusW);
399 minNuVertexEnergyAsymmetry, middleNuVertexEnergyAsymmetry, maxNuVertexEnergyAsymmetry);
401 nuVertexEnergyWeightedMeanRadialDistanceW, minNuVertexEnergyWeightedMeanRadialDistance,
402 middleNuVertexEnergyWeightedMeanRadialDistance, maxNuVertexEnergyWeightedMeanRadialDistance);
404 minShowerStartEnergyAsymmetry, middleShowerStartEnergyAsymmetry, maxShowerStartEnergyAsymmetry);
406 minShowerStartMoliereRadius, middleShowerStartMoliereRadius, maxShowerStartMoliereRadius);
412 featureVector.push_back(maxNuVertexEnergyAsymmetry);
414 featureVector.push_back(maxShowerStartEnergyAsymmetry);
421 const Algorithm *
const pAlgorithm,
const ParticleFlowObject *
const pShowerPfo,
const CartesianVector &nuVertex3D,
422 const ProtoShowerMatch &protoShowerMatch,
const CartesianPointVector &showerStarts3D)
425 this->
Run(toolFeatureVec, pAlgorithm, pShowerPfo, nuVertex3D, protoShowerMatch, showerStarts3D);
427 if (featureMap.find(featureToolName +
"_nShowerHits") != featureMap.end())
429 std::cout <<
"Already wrote nShowerHits feature into map! Not writing again." << std::endl;
430 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
433 featureOrder.push_back(featureToolName +
"_nShowerHits");
434 featureMap[featureToolName +
"_nShowerHits"] = toolFeatureVec[0];
436 if (featureMap.find(featureToolName +
"_foundHitRatio") != featureMap.end())
438 std::cout <<
"Already wrote foundHitRatio feature into map! Not writing again." << std::endl;
439 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
442 featureOrder.push_back(featureToolName +
"_foundHitRatio");
443 featureMap[featureToolName +
"_foundHitRatio"] = toolFeatureVec[1];
445 if (featureMap.find(featureToolName +
"_scatterAngle") != featureMap.end())
447 std::cout <<
"Already wrote scatterAngle feature into map! Not writing again." << std::endl;
448 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
451 featureOrder.push_back(featureToolName +
"_scatterAngle");
452 featureMap[featureToolName +
"_scatterAngle"] = toolFeatureVec[2];
454 if (featureMap.find(featureToolName +
"_openingAngle") != featureMap.end())
456 std::cout <<
"Already wrote openingAngle feature into map! Not writing again." << std::endl;
457 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
460 featureOrder.push_back(featureToolName +
"_openingAngle");
461 featureMap[featureToolName +
"_openingAngle"] = toolFeatureVec[3];
463 if (featureMap.find(featureToolName +
"_nuVertexEnergyAsymmetry") != featureMap.end())
465 std::cout <<
"Already wrote nuVertexEnergyAsymmetry feature into map! Not writing again." << std::endl;
466 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
469 featureOrder.push_back(featureToolName +
"_nuVertexEnergyAsymmetry");
470 featureMap[featureToolName +
"_nuVertexEnergyAsymmetry"] = toolFeatureVec[4];
472 if (featureMap.find(featureToolName +
"_nuVertexEnergyWeightedMeanRadialDistance") != featureMap.end())
474 std::cout <<
"Already wrote nuVertexEnergyWeightedMeanRadialDistance feature into map! Not writing again." << std::endl;
475 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
478 featureOrder.push_back(featureToolName +
"_nuVertexEnergyWeightedMeanRadialDistance");
479 featureMap[featureToolName +
"_nuVertexEnergyWeightedMeanRadialDistance"] = toolFeatureVec[5];
481 if (featureMap.find(featureToolName +
"_showerStartEnergyAsymmetry") != featureMap.end())
483 std::cout <<
"Already wrote showerStartEnergyAsymmetry feature into map! Not writing again." << std::endl;
484 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
487 featureOrder.push_back(featureToolName +
"_showerStartEnergyAsymmetry");
488 featureMap[featureToolName +
"_showerStartEnergyAsymmetry"] = toolFeatureVec[6];
490 if (featureMap.find(featureToolName +
"_showerStartMoliereRadius") != featureMap.end())
492 std::cout <<
"Already wrote showerStartMoliereRadius feature into map! Not writing again." << std::endl;
493 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
496 featureOrder.push_back(featureToolName +
"_showerStartMoliereRadius");
497 featureMap[featureToolName +
"_showerStartMoliereRadius"] = toolFeatureVec[7];
503 const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
const HitType hitType,
const CartesianVector &showerStart3D,
504 float &nHits,
float &foundHitRatio,
float &scatterAngle,
float &openingAngle,
float &nuVertexEnergyAsymmetry,
505 float &nuVertexEnergyWeightedMeanRadialDistance,
float &showerStartEnergyAsymmetry,
float &showerStartMoliereRadius)
507 CaloHitList viewHitList;
512 const bool isDownstream(showerStart2D.GetZ() > nuVertex2D.GetZ());
521 CartesianPointVector spinePositions;
522 for (
const CaloHit *
const pCaloHit : spineHitList)
523 spinePositions.push_back(pCaloHit->GetPositionVector());
528 CaloHitList postShowerHitList;
529 CartesianPointVector postShowerPositions;
531 this->
BuildViewShower(pShowerPfo, spineFitResult, hitType, showerStart2D, nuVertex2D, postShowerHitList, postShowerPositions);
533 this->
GetShowerHitVariables(spineHitList, postShowerHitList, pShowerPfo, hitType, nHits, foundHitRatio);
543 for (
const CaloHit *
const pCaloHit : viewHitList)
545 if (std::find(postShowerHitList.begin(), postShowerHitList.end(), pCaloHit) != postShowerHitList.end())
548 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
549 const CartesianVector displacement(hitPosition - showerStart2D);
553 if (((isDownstream && (l > 0.
f)) || (!isDownstream && (l < 0.
f))) && (t <
m_showerRadius))
555 postShowerHitList.push_back(pCaloHit);
556 postShowerPositions.push_back(pCaloHit->GetPositionVector());
560 this->
GetShowerHitVariables(spineHitList, postShowerHitList, pShowerPfo, hitType, nHits, foundHitRatio);
567 spineFitResult, postShowerHitList, isDownstream, nuVertex2D, nuVertexEnergyAsymmetry, nuVertexEnergyWeightedMeanRadialDistance);
570 showerFitResult, postShowerHitList, isShowerDownstream, showerStartEnergyAsymmetry, showerStartMoliereRadius);
580 const CartesianVector &showerStart2D,
const CartesianVector &nuVertex2D, CaloHitList &postShowerHitList, CartesianPointVector &postShowerPositions)
583 float lShowerStart(0.
f), tShowerStart(0.
f);
587 const int showerStartLayer(spineFit.
GetLayer(lShowerStart));
588 int closestLayer(std::numeric_limits<int>::max());
590 for (
const auto &entry : layerFitResultMap)
592 if (std::fabs(entry.first - showerStartLayer) < std::fabs(entry.first - closestLayer))
593 closestLayer = entry.first;
596 const float gradient(layerFitResultMap.at(closestLayer).GetGradient());
597 CartesianVector showerDirection(0.
f, 0.
f, 0.
f);
602 const bool isDownstream(showerStart2D.GetZ() > nuVertex2D.GetZ());
603 CaloHitList caloHitList;
607 for (
const CaloHit *
const pCaloHit : caloHitList)
609 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
610 const CartesianVector displacement(hitPosition - showerStart2D);
611 const float l(showerDirection.GetDotProduct(displacement));
612 const float t(showerDirection.GetCrossProduct(displacement).GetMagnitude());
614 if (((isDownstream && (l > 0.
f)) || (!isDownstream && (l < 0.
f))) && (t <
m_showerRadius))
616 postShowerHitList.push_back(pCaloHit);
617 postShowerPositions.push_back(pCaloHit->GetPositionVector());
625 const ParticleFlowObject *
const pShowerPfo,
const HitType hitType,
float &nHits,
float &foundHitRatio)
627 int foundHits(spineHitList.size());
629 for (
const CaloHit *
const pCaloHit : postShowerHitList)
631 if (std::find(spineHitList.begin(), spineHitList.end(), pCaloHit) == spineHitList.end())
635 CaloHitList viewHitList;
638 foundHitRatio =
static_cast<float>(foundHits) / static_cast<float>(viewHitList.size());
639 nHits = postShowerHitList.size();
645 const CartesianVector &showerStart2D,
const TwoDSlidingFitResult &showerFitResult,
float &scatterAngle)
647 const bool isDownstream(showerStart2D.GetZ() > nuVertex2D.GetZ());
648 const CartesianVector streamCorrectedConnectionPathwayDirection(
653 const CartesianVector streamCorrectedShowerDirection(
656 scatterAngle = streamCorrectedConnectionPathwayDirection.GetOpeningAngle(streamCorrectedShowerDirection) * 180.f / M_PI;
662 const CartesianVector &showerStart2D,
float &openingAngle)
667 const CartesianVector orthoAxis = directionAxis.GetCrossProduct(CartesianVector(0.
f, 1.
f, 0.
f));
669 std::map<int, float> positiveEdges, negativeEdges;
671 for (
const CaloHit *
const pCaloHit : postShowerHitList)
673 const CartesianVector position(pCaloHit->GetPositionVector() - showerStart2D);
674 const float thisT(directionAxis.GetCrossProduct(position).GetMagnitude());
675 const float thisL(directionAxis.GetDotProduct(position));
676 const float orthoL(orthoAxis.GetDotProduct(position));
678 std::map<int, float> &edgeMap(orthoL > 0.
f ? positiveEdges : negativeEdges);
680 const int lIndex(std::floor(thisL /
m_edgeStep));
682 edgeMap[lIndex] = (edgeMap.find(lIndex) == edgeMap.end() ? thisT : std::max(edgeMap[lIndex], thisT));
685 CartesianPointVector positiveEdgePositions, negativeEdgePositions;
687 for (
auto &entry : positiveEdges)
688 positiveEdgePositions.push_back(CartesianVector(entry.second, 0.f, entry.first));
690 for (
auto &entry : negativeEdges)
691 negativeEdgePositions.push_back(CartesianVector(entry.second, 0.f, entry.first));
696 const CartesianVector positiveMinLayer(positiveEdgeFit.GetGlobalMinLayerPosition());
697 const CartesianVector positiveMaxLayer(positiveEdgeFit.GetGlobalMaxLayerPosition());
698 const CartesianVector negativeMinLayer(negativeEdgeFit.GetGlobalMinLayerPosition());
699 const CartesianVector negativeMaxLayer(negativeEdgeFit.GetGlobalMaxLayerPosition());
701 const CartesianVector globalPositiveMinLayer(
702 showerStart2D + (directionAxis * positiveMinLayer.GetZ()) + (orthoAxis * positiveMinLayer.GetX()));
703 const CartesianVector globalPositiveMaxLayer(
704 showerStart2D + (directionAxis * positiveMaxLayer.GetZ()) + (orthoAxis * positiveMaxLayer.GetX()));
705 const CartesianVector globalNegativeMinLayer(
706 showerStart2D + (directionAxis * negativeMinLayer.GetZ()) - (orthoAxis * negativeMinLayer.GetX()));
707 const CartesianVector globalNegativeMaxLayer(
708 showerStart2D + (directionAxis * negativeMaxLayer.GetZ()) - (orthoAxis * negativeMaxLayer.GetX()));
710 const CartesianVector positiveEdgeVector((globalPositiveMaxLayer - globalPositiveMinLayer).GetUnitVector());
711 const CartesianVector negativeEdgeVector((globalNegativeMaxLayer - globalNegativeMinLayer).GetUnitVector());
713 const float positiveOpeningAngle = directionAxis.GetOpeningAngle(positiveEdgeVector) * 180.f / M_PI;
714 const float negativeOpeningAngle = directionAxis.GetOpeningAngle(negativeEdgeVector) * 180.f / M_PI;
716 openingAngle = std::max(positiveOpeningAngle, negativeOpeningAngle);
726 const bool isDownstream,
const CartesianVector &nuVertex2D,
float &nuVertexEnergyAsymmetry,
float &nuVertexEnergyWeightedMeanRadialDistance)
729 const CartesianVector orthoAxis = directionAxis.GetCrossProduct(CartesianVector(0.
f, 1.
f, 0.
f));
731 float totalEnergy(0.
f);
734 nuVertexEnergyAsymmetry = 0.f;
736 for (
const CaloHit *
const pCaloHit : postShowerHitList)
738 const float hitEnergy(std::fabs(pCaloHit->GetElectromagneticEnergy()));
740 totalEnergy += hitEnergy;
742 const CartesianVector position(pCaloHit->GetPositionVector() - nuVertex2D);
743 const float thisL(orthoAxis.GetDotProduct(position));
745 nuVertexEnergyAsymmetry += (thisL < 0.f) ? (-1.
f * hitEnergy) : hitEnergy;
748 nuVertexEnergyAsymmetry = (totalEnergy < std::numeric_limits<float>::epsilon()) ?
m_defaultRatio : (nuVertexEnergyAsymmetry / totalEnergy);
749 nuVertexEnergyAsymmetry = std::fabs(nuVertexEnergyAsymmetry);
752 nuVertexEnergyWeightedMeanRadialDistance = 0.f;
754 for (
const CaloHit *
const pCaloHit : postShowerHitList)
756 const CartesianVector position(pCaloHit->GetPositionVector() - nuVertex2D);
757 const float hitEnergy(std::fabs(pCaloHit->GetElectromagneticEnergy()));
759 nuVertexEnergyWeightedMeanRadialDistance += (directionAxis.GetCrossProduct(position).GetMagnitude() * hitEnergy);
762 nuVertexEnergyWeightedMeanRadialDistance =
763 (totalEnergy < std::numeric_limits<float>::epsilon()) ?
m_defaultFloat : nuVertexEnergyWeightedMeanRadialDistance / totalEnergy;
769 const CaloHitList &postShowerHitList,
const bool isShowerDownstream,
float &showerStartEnergyAsymmetry,
float &showerStartMoliereRadius)
772 const CartesianVector directionAxis(
774 const CartesianVector orthoAxis = directionAxis.GetCrossProduct(CartesianVector(0.
f, 1.
f, 0.
f));
776 float totalEnergy(0.
f);
779 showerStartEnergyAsymmetry = 0.f;
781 for (
const CaloHit *
const pCaloHit : postShowerHitList)
783 const float hitEnergy(std::fabs(pCaloHit->GetElectromagneticEnergy()));
785 totalEnergy += hitEnergy;
787 const CartesianVector position(pCaloHit->GetPositionVector() - fitShowerStart);
788 const float thisL(orthoAxis.GetDotProduct(position));
790 showerStartEnergyAsymmetry += (thisL < 0.f) ? (-1.
f * hitEnergy) : hitEnergy;
793 showerStartEnergyAsymmetry = (totalEnergy < std::numeric_limits<float>::epsilon()) ?
m_defaultRatio : (showerStartEnergyAsymmetry / totalEnergy);
794 showerStartEnergyAsymmetry = std::fabs(showerStartEnergyAsymmetry);
799 CaloHitVector showerStartPostShowerHitVector(postShowerHitList.begin(), postShowerHitList.end());
801 std::sort(showerStartPostShowerHitVector.begin(), showerStartPostShowerHitVector.end(),
802 [&fitShowerStart, &directionAxis](
const CaloHit *
const pCaloHitA,
const CaloHit *
const pCaloHitB) ->
bool 804 const CartesianVector positionA(pCaloHitA->GetPositionVector() - fitShowerStart);
805 const CartesianVector positionB(pCaloHitB->GetPositionVector() - fitShowerStart);
807 const float tA(directionAxis.GetCrossProduct(positionA).GetMagnitude());
808 const float tB(directionAxis.GetCrossProduct(positionB).GetMagnitude());
813 float showerStartRunningEnergySum(0.
f);
815 for (
const CaloHit *
const pCaloHit : showerStartPostShowerHitVector)
817 const float hitEnergy(std::fabs(pCaloHit->GetElectromagneticEnergy()));
818 showerStartRunningEnergySum += hitEnergy;
822 const CartesianVector position(pCaloHit->GetPositionVector() - fitShowerStart);
823 showerStartMoliereRadius = directionAxis.GetCrossProduct(position).GetMagnitude();
833 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultFloat",
m_defaultFloat));
835 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultRatio",
m_defaultRatio));
837 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SpineFitWindow",
m_spineFitWindow));
839 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerRadius",
m_showerRadius));
841 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerFitWindow",
m_showerFitWindow));
843 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"EdgeStep",
m_edgeStep));
845 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MoliereFraction",
m_moliereFraction));
847 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxNHitsLimit",
m_maxNHitsLimit));
849 PANDORA_RETURN_RESULT_IF_AND_IF(
850 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxFoundHitRatioLimit",
m_maxFoundHitRatioLimit));
852 PANDORA_RETURN_RESULT_IF_AND_IF(
853 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxScatterAngleLimit",
m_maxScatterAngleLimit));
855 PANDORA_RETURN_RESULT_IF_AND_IF(
856 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxOpeningAngleLimit",
m_maxOpeningAngleLimit));
858 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
861 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
864 return STATUS_CODE_SUCCESS;
872 m_caloHitListNameU(
"CaloHitListU"),
873 m_caloHitListNameV(
"CaloHitListV"),
874 m_caloHitListNameW(
"CaloHitListW"),
875 m_maxTransverseDistance(0.75
f),
877 m_maxHitSeparation(1.
f),
878 m_maxTrackFraction(0.8
f)
885 const ParticleFlowObject *
const ,
const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
886 const CartesianPointVector & )
888 float nAmbiguousViews(0.
f);
895 maxUnaccountedEnergy = std::max(maxUnaccountedEnergy, unaccountedHitEnergyU);
898 maxUnaccountedEnergy = std::max(maxUnaccountedEnergy, unaccountedHitEnergyV);
901 maxUnaccountedEnergy = std::max(maxUnaccountedEnergy, unaccountedHitEnergyW);
903 featureVector.push_back(nAmbiguousViews);
904 featureVector.push_back(maxUnaccountedEnergy);
910 const std::string &featureToolName,
const Algorithm *
const pAlgorithm,
const ParticleFlowObject *
const pShowerPfo,
911 const CartesianVector &nuVertex3D,
const ProtoShowerMatch &protoShowerMatch,
const CartesianPointVector &showerStarts3D)
914 this->
Run(toolFeatureVec, pAlgorithm, pShowerPfo, nuVertex3D, protoShowerMatch, showerStarts3D);
916 if (featureMap.find(featureToolName +
"_nAmbiguousViews") != featureMap.end())
918 std::cout <<
"Already wrote nAmbiguousViews feature into map! Not writing again." << std::endl;
919 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
922 featureOrder.push_back(featureToolName +
"_nAmbiguousViews");
923 featureMap[featureToolName +
"_nAmbiguousViews"] = toolFeatureVec[0];
925 if (featureMap.find(featureToolName +
"_maxUnaccountedEnergy") != featureMap.end())
927 std::cout <<
"Already wrote maxUnaccountedEnergy feature into map! Not writing again." << std::endl;
928 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
931 featureOrder.push_back(featureToolName +
"_maxUnaccountedEnergy");
932 featureMap[featureToolName +
"_maxUnaccountedEnergy"] = toolFeatureVec[1];
939 nAmbiguousViews = 0.f;
942 nAmbiguousViews += (nAmbiguousHitsU == 0) ? 0.
f : 1.
f;
945 nAmbiguousViews += (nAmbiguousHitsV == 0) ? 0.
f : 1.
f;
948 nAmbiguousViews += (nAmbiguousHitsW == 0) ? 0.
f : 1.
f;
954 const HitType hitType,
const CartesianVector &nuVertex3D,
float &unaccountedHitEnergy)
956 std::map<int, CaloHitList> ambiguousHitSpines;
957 CaloHitList hitsToExcludeInEnergyCalcs;
959 const ProtoShower &protoShower(hitType == TPC_VIEW_U
963 this->
BuildAmbiguousSpines(pAlgorithm, hitType, protoShower, nuVertex2D, ambiguousHitSpines, hitsToExcludeInEnergyCalcs);
965 if (ambiguousHitSpines.empty())
969 float startL(-std::numeric_limits<float>::max());
970 float ambiguousHitEnergyMean(0.
f);
975 const float thisT(startDirection.GetCrossProduct(pAmbiguousCaloHit->GetPositionVector() - nuVertex2D).GetMagnitude());
976 const float thisL(startDirection.GetDotProduct(pAmbiguousCaloHit->GetPositionVector() - nuVertex2D));
981 ambiguousHitEnergyMean += pAmbiguousCaloHit->GetElectromagneticEnergy() * 1000.f;
987 float otherEnergyMeanSum(0.
f);
989 for (
const auto &entry : ambiguousHitSpines)
991 int nOtherEnergyHits(0);
992 float otherEnergyMean(0.
f);
994 for (
const CaloHit *
const pOtherCaloHit : entry.second)
996 if (std::find(hitsToExcludeInEnergyCalcs.begin(), hitsToExcludeInEnergyCalcs.end(), pOtherCaloHit) != hitsToExcludeInEnergyCalcs.end())
999 otherEnergyMean += pOtherCaloHit->GetElectromagneticEnergy() * 1000.f;
1003 if (nOtherEnergyHits == 0)
1006 otherEnergyMean /=
static_cast<float>(nOtherEnergyHits);
1007 otherEnergyMeanSum += otherEnergyMean;
1011 float spineEnergyMean(0.
f);
1012 unsigned int nSpineEnergyHits(0);
1014 for (
const CaloHit *
const pSpineCaloHit : protoShower.
GetSpineHitList())
1020 const float thisL(startDirection.GetDotProduct(pSpineCaloHit->GetPositionVector() - nuVertex2D));
1024 spineEnergyMean += pSpineCaloHit->GetElectromagneticEnergy() * 1000.f;
1029 if (nSpineEnergyHits == 0)
1032 spineEnergyMean /=
static_cast<float>(nSpineEnergyHits);
1033 unaccountedHitEnergy = ambiguousHitEnergyMean - otherEnergyMeanSum - spineEnergyMean;
1041 const CartesianVector &nuVertex2D, std::map<int, CaloHitList> &ambiguousHitSpines, CaloHitList &hitsToExcludeInEnergyCalcs)
1043 const CaloHitList *pCaloHitList;
1045 if (this->
GetHitListOfType(pAlgorithm, hitType, pCaloHitList) != STATUS_CODE_SUCCESS)
1048 std::map<int, CaloHitList> ambiguousHitSpinesTemp;
1050 for (
const CaloHit *
const pCaloHit : *pCaloHitList)
1062 const CartesianVector displacement(pCaloHit->GetPositionVector() - nuVertex2D);
1063 const float thisT(significantDirection.GetCrossProduct(displacement).GetMagnitude());
1064 const float thisL(significantDirection.GetDotProduct(displacement));
1069 ambiguousHitSpinesTemp[i].push_back(pCaloHit);
1073 hitsToExcludeInEnergyCalcs.push_back(pCaloHit);
1077 if (ambiguousHitSpinesTemp.empty())
1081 for (
const auto &entry : ambiguousHitSpinesTemp)
1085 if (continuousSpine.size() > 0)
1086 ambiguousHitSpines[entry.first] = continuousSpine;
1098 PANDORA_THROW_RESULT_IF_AND_IF(
1099 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*pAlgorithm, typeHitListName, pCaloHitList));
1101 if (!pCaloHitList || pCaloHitList->empty())
1102 return STATUS_CODE_NOT_INITIALIZED;
1104 return STATUS_CODE_SUCCESS;
1110 const CaloHitList &caloHitList,
const CaloHitList &ambiguousHitList,
const CartesianVector &nuVertex2D)
1112 CaloHitList continuousHitList;
1114 CaloHitVector caloHitVector(caloHitList.begin(), caloHitList.end());
1117 for (
unsigned int i = 0; i < caloHitVector.size(); ++i)
1119 CaloHitList connectedHitList;
1120 connectedHitList.push_back(caloHitVector[i]);
1131 for (
unsigned int j = (i + 1); j < caloHitVector.size(); ++j)
1133 const CaloHit *
const pCaloHit(caloHitVector[j]);
1135 if (std::find(connectedHitList.begin(), connectedHitList.end(), pCaloHit) != connectedHitList.end())
1141 if (static_cast<float>(connectedHitList.size()) < static_cast<float>(caloHitVector.size() *
m_maxTrackFraction))
1144 connectedHitList.push_back(pCaloHit);
1152 if (connectedHitList.size() >= 2)
1154 continuousHitList.insert(continuousHitList.begin(), connectedHitList.begin(), connectedHitList.end());
1159 return continuousHitList;
1166 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DefaultFloat",
m_defaultFloat));
1168 PANDORA_RETURN_RESULT_IF_AND_IF(
1169 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListNameU",
m_caloHitListNameU));
1171 PANDORA_RETURN_RESULT_IF_AND_IF(
1172 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListNameV",
m_caloHitListNameV));
1174 PANDORA_RETURN_RESULT_IF_AND_IF(
1175 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListNameW",
m_caloHitListNameW));
1177 PANDORA_RETURN_RESULT_IF_AND_IF(
1178 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxTransverseDistance",
m_maxTransverseDistance));
1180 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxSampleHits",
m_maxSampleHits));
1182 PANDORA_RETURN_RESULT_IF_AND_IF(
1183 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxHitSeparation",
m_maxHitSeparation));
1185 PANDORA_RETURN_RESULT_IF_AND_IF(
1186 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxTrackFraction",
m_maxTrackFraction));
1188 return STATUS_CODE_SUCCESS;
float m_maxTransverseDistance
The max. proximity of a hits, included in a trajectory energy calcs.
const ProtoShower & GetProtoShowerU() const
Get the U view ProtoShower.
void CalculateNAmbiguousViews(const ProtoShowerMatch &protoShowerMatch, float &nAmbiguousViews)
Count the number of views with ambiguous hits.
float m_edgeStep
The binning of the shower boundaries.
std::string m_caloHitListNameW
The event W view hit list.
const ProtoShower & GetProtoShowerV() const
Get the V view ProtoShower.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianPointVector &showerStarts3D)
float m_maxFoundHitRatioLimit
maxFoundHitRatio max. limit
void CalculateViewShowerStartConsistencyVariables(const TwoDSlidingFitResult &showerFitResult, const pandora::CaloHitList &postShowerHitList, const bool isShowerDownstream, float &showerStartEnergyAsymmetry, float &showerStartMoliereRadius)
Evaluate the shower start consistency variables.
Header file for the pfo helper class.
Header file for the ProtoShower class.
float m_maxInitialGapSizeLimit
maxInitialGapSizeLimit max. limit
const pandora::CartesianPointVector & GetAmbiguousDirectionVector() const
Get the ambiguous direction vector.
Header file for the connection pathway helper class.
bool GetViewAmbiguousHitVariables(const pandora::Algorithm *const pAlgorithm, const ProtoShowerMatch &protoShowerMatch, const pandora::HitType hitType, const pandora::CartesianVector &nuVertex3D, float &unaccountedHitEnergy)
Calculate the ambiguous region variables for the input view.
MvaTypes::MvaFeatureVector MvaFeatureVector
ShowerRegionFeatureTool()
Default constructor.
const pandora::CaloHitList & GetAmbiguousHitList() const
Get the ambiguous hit list.
void CalculateViewNuVertexConsistencyVariables(const TwoDSlidingFitResult &spineFitResult, const pandora::CaloHitList &postShowerHitList, const bool isDownstream, const pandora::CartesianVector &nuVertex2D, float &nuVertexEnergyAsymmetry, float &nuVertexEnergyWeightedMeanRadialDistance)
Evaluate the neutrino vertex consistency variables.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_maxNuVertexEnergyWeightedMeanRadialDistanceLimit
maxNuVertexEnergyWeightedMeanRadialDistance max. limit
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianPointVector &showerStarts3D)
void GetViewShowerRegionVariables(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const ProtoShowerMatch &protoShowerMatch, const pandora::HitType hitType, const pandora::CartesianVector &showerStart3D, float &nHits, float &foundHitRatio, float &scatterAngle, float &openingAngle, float &nuVertexEnergyAsymmetry, float &nuVertexEnergyWeightedMeanRadialDistance, float &showerStartEnergyAsymmetry, float &showerStartMoliereRadius)
Calculate the shower region variables for the input view.
float m_maxOpeningAngleLimit
maxOpeningAngle max. limit
const ConnectionPathway & GetConnectionPathway() const
Get the connection pathway.
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_spineFitWindow
The spine fit window.
float m_maxScatterAngleLimit
maxScatterAngle max. limit
unsigned int m_showerFitWindow
The shower fit window.
MvaTypes::MvaFeatureMap MvaFeatureMap
pandora::CartesianVector GetGlobalMinLayerDirection() const
Get global direction corresponding to the fit result in minimum fit layer.
const pandora::CaloHitList & GetSpineHitList() const
Get the spine hit list.
unsigned int m_spineFitWindow
The spine fit window.
float m_maxNHitsLimit
maxNHits max. limit
std::string m_caloHitListNameU
The event U view hit list.
Header file for the geometry helper class.
float m_defaultRatio
Default float value for ratios.
float m_minLargestGapSizeLimit
minLargestGapSizeLimit max. limit
pandora::StatusCode GetHitListOfType(const pandora::Algorithm *const pAlgorithm, const pandora::HitType hitType, const pandora::CaloHitList *&pCaloHitList) const
Obtain the event hit list of a given view.
float m_showerRadius
The max. separation distance between a shower region hit and the shower core.
void GetShowerHitVariables(const pandora::CaloHitList &spineHitList, const pandora::CaloHitList &postShowerHitList, const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, float &nHits, float &foundHitRatio)
Evaluate the variables associated with the shower region hit multiplicity.
Header file for the cluster helper class.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
unsigned int m_nHitsToConsider
The number of hits which defines the initial region.
float m_pathwayScatteringAngle2DLimit
pathwayScatteringAngle2DLimit max. limit
void GetViewInitialRegionVariables(const pandora::Algorithm *const pAlgorithm, const pandora::CartesianVector &nuVertex3D, const ProtoShowerMatch &protoShowerMatch, const pandora::HitType hitType, float &initialGapSize, float &largestGapSize) const
Calculate the initial region variables for the input view.
float m_moliereFraction
The energy fraction which corresponds to minShowerStartMoliereRadius.
float m_defaultFloat
Default float value.
std::map< int, LayerFitResult > LayerFitResultMap
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianPointVector &showerStarts3D)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float GetLayerPitch() const
Get the layer pitch, units cm.
float m_defaultFloat
Default float value.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
unsigned int m_maxSampleHits
The max. number of hits considered in the spine energy calcs.
void GetGlobalDirection(const float dTdL, pandora::CartesianVector &direction) const
Get global direction coordinates for given sliding linear fit gradient.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
void BuildAmbiguousSpines(const pandora::Algorithm *const pAlgorithm, const pandora::HitType hitType, const ProtoShower &protoShower, const pandora::CartesianVector &nuVertex2D, std::map< int, pandora::CaloHitList > &ambiguousHitSpines, pandora::CaloHitList &hitsToExcludeInEnergyCalcs)
Determine the spine hits of the particles with which the ambiguous hits are shared.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
SortByDistanceToPoint class.
float m_pathwayLengthLimit
pathwayLengthLimit max. limit
AmbiguousRegionFeatureTool()
Default constructor.
pandora::CaloHitList FindAmbiguousContinuousSpine(const pandora::CaloHitList &caloHitList, const pandora::CaloHitList &ambiguousHitList, const pandora::CartesianVector &nuVertex2D)
Determine a continuous pathway of an ambigous particle's spine hits.
float m_maxHitSeparation
The max. separation of connected hits.
static void GetMinMiddleMax(const float value1, const float value2, const float value3, float &minValue, float &middleValue, float &maxValue)
Determine the lowest, median and highest value from an input of three numbers.
pandora::CartesianVector GetGlobalMaxLayerDirection() const
Get global direction corresponding to the fit result in maximum fit layer.
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
float m_defaultFloat
Default float value.
std::string m_caloHitListNameV
The event V view hit list.
float m_defaultFloat
Default float value.
void CalculateViewOpeningAngle(const TwoDSlidingFitResult &showerFitResult, const pandora::CaloHitList &postShowerHitList, const pandora::CartesianVector &showerStart2D, float &openingAngle)
Calculate the opening angle of the shower region.
float m_maxTrackFraction
The fraction of found hits which are considered in the energy calcs.
void BuildViewShower(const pandora::ParticleFlowObject *const pShowerPfo, const TwoDSlidingFitResult &spineFit, const pandora::HitType hitType, const pandora::CartesianVector &showerStart2D, const pandora::CartesianVector &nuVertex2D, pandora::CaloHitList &postShowerHitList, pandora::CartesianPointVector &postShowerPositions)
Collect the shower region hits in a given view.
const ProtoShower & GetProtoShowerW() const
Get the W view ProtoShower.
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.
ConnectionRegionFeatureTool()
Default constructor.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &nuVertex3D, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianPointVector &showerStarts3D)
int m_nLayersHalfWindow
The half window of each segment.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
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.
float Get2DKink(const pandora::Algorithm *const pAlgorithm, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianVector &showerStart3D) const
Obtain a cautious estimate of the largest 2D deflection of the connection pathway.
float GetLargest2DKinkFromView(const pandora::Algorithm *const pAlgorithm, const TwoDSlidingFitResult &spineFit, const pandora::HitType hitType, const pandora::CartesianVector &showerStart3D) const
Obtain a cautious estimate of the largest 2D deflection of a connection pathway in a given view...
void CalculateViewScatterAngle(const pandora::CartesianVector &nuVertex2D, const TwoDSlidingFitResult &spineFitResult, const pandora::CartesianVector &showerStart2D, const TwoDSlidingFitResult &showerFitResult, float &scatterAngle)
Calculate the connection pathway-shower region scatter angle.
const pandora::CartesianVector & GetStartDirection() const
Get the start direction of the connection pathway.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
float m_minShowerStartMoliereRadiusLimit
minShowerStartMoliereRadius max. limit