9 #include "Pandora/AlgorithmHeaders.h" 23 BdtBeamParticleIdTool::BdtBeamParticleIdTool() :
24 m_useTrainingMode(false),
25 m_trainingOutputFile(
""),
27 m_minCompleteness(0.8
f),
29 m_filePathEnvironmentVariable(
"FW_SEARCH_PATH"),
30 m_maxNeutrinos(
std::numeric_limits<int>::
max()),
31 m_minAdaBDTScore(0.
f),
41 const LArTPCMap &larTPCMap(this->GetPandora().GetGeometry()->GetLArTPCMap());
42 const LArTPC *
const pFirstLArTPC(larTPCMap.begin()->second);
43 float parentMinX(pFirstLArTPC->GetCenterX() - 0.5f * pFirstLArTPC->GetWidthX());
44 float parentMaxX(pFirstLArTPC->GetCenterX() + 0.5f * pFirstLArTPC->GetWidthX());
45 float parentMinY(pFirstLArTPC->GetCenterY() - 0.5f * pFirstLArTPC->GetWidthY());
46 float parentMaxY(pFirstLArTPC->GetCenterY() + 0.5f * pFirstLArTPC->GetWidthY());
47 float parentMinZ(pFirstLArTPC->GetCenterZ() - 0.5f * pFirstLArTPC->GetWidthZ());
48 float parentMaxZ(pFirstLArTPC->GetCenterZ() + 0.5f * pFirstLArTPC->GetWidthZ());
50 for (
const LArTPCMap::value_type &mapEntry : larTPCMap)
52 const LArTPC *
const pLArTPC(mapEntry.second);
53 parentMinX =
std::min(parentMinX, pLArTPC->GetCenterX() - 0.5f * pLArTPC->GetWidthX());
54 parentMaxX =
std::max(parentMaxX, pLArTPC->GetCenterX() + 0.5f * pLArTPC->GetWidthX());
55 parentMinY =
std::min(parentMinY, pLArTPC->GetCenterY() - 0.5f * pLArTPC->GetWidthY());
56 parentMaxY =
std::max(parentMaxY, pLArTPC->GetCenterY() + 0.5f * pLArTPC->GetWidthY());
57 parentMinZ =
std::min(parentMinZ, pLArTPC->GetCenterZ() - 0.5f * pLArTPC->GetWidthZ());
58 parentMaxZ =
std::max(parentMaxZ, pLArTPC->GetCenterZ() + 0.5f * pLArTPC->GetWidthZ());
65 catch (
const StatusCodeException &statusCodeException)
67 std::cout <<
"BdtBeamParticleIdTool::Initialize - unable to initialize LArTPC geometry parameters" << std::endl;
68 return STATUS_CODE_FAILURE;
71 return STATUS_CODE_SUCCESS;
78 if (nuSliceHypotheses.size() != crSliceHypotheses.size())
79 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
81 const unsigned int nSlices(nuSliceHypotheses.size());
82 if (nSlices == 0)
return;
85 this->
GetSliceFeatures(
this, nuSliceHypotheses, crSliceHypotheses, sliceFeaturesVector);
90 this->
SelectAllPfos(pAlgorithm, crSliceHypotheses, selectedPfos);
95 for (
unsigned int sliceIndex = 0; sliceIndex < nSlices; ++sliceIndex)
97 const SliceFeatures &features(sliceFeaturesVector.at(sliceIndex));
98 if (!features.IsFeatureVectorAvailable())
continue;
106 catch (
const StatusCodeException &statusCodeException)
108 std::cout <<
"BdtBeamParticleIdTool::SelectOutputPfos - unable to fill feature vector" << std::endl;
112 bool isGoodTrainingSlice(
false);
113 if (std::find(bestSliceIndices.begin(), bestSliceIndices.end(), sliceIndex) != bestSliceIndices.end())
114 isGoodTrainingSlice =
true;
122 this->
SelectPfosByAdaBDTScore(pAlgorithm, nuSliceHypotheses, crSliceHypotheses, sliceFeaturesVector, selectedPfos);
129 for (
unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
137 for (
const PfoList &pfos : hypotheses)
139 for (
const ParticleFlowObject *
const pPfo : pfos)
141 object_creation::ParticleFlowObject::Metadata metadata;
142 metadata.m_propertiesToAdd[
"TestBeamScore"] = -1.f;
143 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
154 selectedPfos.insert(selectedPfos.end(), pfos.begin(), pfos.end());
162 const CaloHitList *pAllReconstructedCaloHitList(
nullptr);
163 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm,
m_caloHitListName, pAllReconstructedCaloHitList));
165 const MCParticleList *pMCParticleList(
nullptr);
166 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm,
m_mcParticleListName, pMCParticleList));
173 CaloHitList reconstructableCaloHitList;
180 const CaloHitSet reconstructableCaloHitSet(reconstructableCaloHitList.begin(), reconstructableCaloHitList.end());
182 for (
unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
185 CaloHitList reconstructedCaloHitList;
186 this->
Collect2DHits(crSliceHypotheses.at(sliceIndex), reconstructedCaloHitList, reconstructableCaloHitSet);
188 if (nuSliceHypotheses.at(sliceIndex).size() == 1)
190 const PfoList &nuFinalStates(nuSliceHypotheses.at(sliceIndex).front()->GetDaughterPfoList());
191 this->
Collect2DHits(nuFinalStates, reconstructedCaloHitList, reconstructableCaloHitSet);
194 const unsigned int nRecoHits(reconstructedCaloHitList.size());
200 if (mcParticleToHitsInSliceMap.empty())
204 const MCParticle *pBestMCParticle(
nullptr);
205 unsigned int nSharedHits(0);
207 for (
const auto &iter : mcParticleToHitsInSliceMap)
209 if (iter.second > static_cast<int>(nSharedHits))
211 pBestMCParticle = iter.first;
212 nSharedHits = iter.second;
220 const unsigned int nMCHits(mcParticleToReconstructableHitsMap.at(pBestMCParticle));
221 const float purity(nRecoHits > 0 ? static_cast<float>(nSharedHits) / static_cast<float>(nRecoHits) : 0.
f);
222 const float completeness(nMCHits > 0 ? static_cast<float>(nSharedHits) / static_cast<float>(nMCHits) : 0.f);
225 bestSliceIndices.push_back(sliceIndex);
234 for (
const CaloHit *
const pCaloHit : caloHitList)
241 if (iter != mcParticleToIntMap.end())
247 mcParticleToIntMap.insert(MCParticleToIntMap::value_type(pParentMCParticle, 1));
250 catch (
const StatusCodeException &statusCodeException)
252 if (STATUS_CODE_NOT_INITIALIZED != statusCodeException.GetStatusCode())
253 throw statusCodeException;
262 CaloHitList collectedHits;
267 for (
const CaloHit *
const pCaloHit : collectedHits)
270 const CaloHit *pParentCaloHit(static_cast<const CaloHit *>(pCaloHit->GetParentAddress()));
272 if (!reconstructableCaloHitSet.count(pParentCaloHit))
276 if (std::find(reconstructedCaloHitList.begin(), reconstructedCaloHitList.end(), pParentCaloHit) == reconstructedCaloHitList.end())
277 reconstructedCaloHitList.push_back(pParentCaloHit);
295 std::vector<UintFloatPair> sliceIndexAdaBDTScorePairs;
296 for (
unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
298 const float nuAdaBDTScore(sliceFeaturesVector.at(sliceIndex).GetAdaBoostDecisionTreeScore(
m_adaBoostDecisionTree));
300 for (
const ParticleFlowObject *
const pPfo : crSliceHypotheses.at(sliceIndex))
302 object_creation::ParticleFlowObject::Metadata metadata;
303 metadata.m_propertiesToAdd[
"TestBeamScore"] = nuAdaBDTScore;
304 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
307 for (
const ParticleFlowObject *
const pPfo : nuSliceHypotheses.at(sliceIndex))
309 object_creation::ParticleFlowObject::Metadata metadata;
310 metadata.m_propertiesToAdd[
"TestBeamScore"] = nuAdaBDTScore;
311 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
316 this->
SelectPfos(crSliceHypotheses.at(sliceIndex), selectedPfos);
320 sliceIndexAdaBDTScorePairs.push_back(
UintFloatPair(sliceIndex, nuAdaBDTScore));
324 std::sort(sliceIndexAdaBDTScorePairs.begin(), sliceIndexAdaBDTScorePairs.end(), [] (
const UintFloatPair &a,
const UintFloatPair &b)
326 return (a.second > b.second);
330 unsigned int nNuSlices(0);
331 for (
const UintFloatPair &slice : sliceIndexAdaBDTScorePairs)
335 this->
SelectPfos(nuSliceHypotheses.at(slice.first), selectedPfos);
340 this->
SelectPfos(crSliceHypotheses.at(slice.first), selectedPfos);
348 m_unitNormal(0.
f, 0.
f, 0.
f),
350 m_d(-1. * static_cast<double>(normal.GetDotProduct(point)))
356 catch (
const StatusCodeException &statusCodeException)
358 std::cout <<
"BdtBeamParticleIdTool::Plane::Plane - normal vector to plane has a magnitude of zero" << std::endl;
359 throw statusCodeException;
367 if (std::fabs(direction.GetDotProduct(
m_unitNormal)) < std::numeric_limits<float>::epsilon())
370 const float denominator(direction.GetDotProduct(
m_unitNormal));
372 if (std::fabs(denominator) < std::numeric_limits<float>::epsilon())
373 throw StatusCodeException(STATUS_CODE_OUT_OF_RANGE);
375 const double t(-1. * (static_cast<double>(point.GetDotProduct(
m_unitNormal)) +
m_d) /
static_cast<double>(denominator));
376 return (point + (direction * t));
383 m_larTPCMinX(
std::numeric_limits<float>::
max()),
384 m_larTPCMaxX(
std::numeric_limits<float>::
max()),
385 m_larTPCMinY(
std::numeric_limits<float>::
max()),
386 m_larTPCMaxY(
std::numeric_limits<float>::
max()),
387 m_larTPCMinZ(
std::numeric_limits<float>::
max()),
388 m_larTPCMaxZ(
std::numeric_limits<float>::
max()),
389 m_beamLArTPCIntersection(0.
f, 0.
f, 0.
f),
390 m_beamDirection(0.
f, 0.
f, 0.
f),
391 m_selectedFraction(10.
f),
392 m_nSelectedHits(100),
393 m_containmentLimit(0.01
f)
408 const CartesianVector normalTop(0.
f, 0.
f, 1.
f), pointTop(0.
f, 0.
f,
m_larTPCMaxZ);
409 const CartesianVector normalBottom(0.
f, 0.
f, -1.
f), pointBottom(0.
f, 0.
f,
m_larTPCMinZ);
410 const CartesianVector normalRight(1.
f, 0.
f, 0.
f), pointRight(
m_larTPCMaxX, 0.
f, 0.
f);
411 const CartesianVector normalLeft(-1.
f, 0.
f, 0.
f), pointLeft(
m_larTPCMinX, 0.
f, 0.
f);
412 const CartesianVector normalBack(0.
f, 1.
f, 0.
f), pointBack(0.
f,
m_larTPCMaxY, 0.
f);
413 const CartesianVector normalFront(0.
f, -1.
f, 0.
f), pointFront(0.
f,
m_larTPCMinY, 0.
f);
427 m_isAvailable(
false),
435 CaloHitList caloHitList3DNu, caloHitList3DCr, selectedCaloHitListNu, selectedCaloHitListCr;
436 PfoList allConnectedPfoListNu, allConnectedPfoListCr;
445 this->GetLeadingCaloHits(caloHitList3DNu, selectedCaloHitListNu, closestDistanceNu);
446 this->GetLeadingCaloHits(caloHitList3DCr, selectedCaloHitListCr, closestDistanceCr);
448 if (!selectedCaloHitListNu.empty() && !selectedCaloHitListCr.empty())
451 CartesianVector centroidNu(0.
f, 0.
f, 0.
f), interceptOneNu(0.
f, 0.
f, 0.
f), interceptTwoNu(0.
f, 0.
f, 0.
f), centroidCr(0.
f, 0.
f, 0.
f), interceptOneCr(0.
f, 0.
f, 0.
f), interceptTwoCr(0.
f, 0.
f, 0.
f);
456 const CartesianVector &majorAxisNu(eigenVecsNu.front());
459 this->GetLArTPCIntercepts(centroidNu, majorAxisNu, interceptOneNu, interceptTwoNu);
462 separationNu =
std::min(separationOneNu, separationTwoNu);
467 const CartesianVector &majorAxisCr(eigenVecsCr.front());
470 this->GetLArTPCIntercepts(centroidCr, majorAxisCr, interceptOneCr, interceptTwoCr);
473 separationCr =
std::min(separationOneCr, separationTwoCr);
475 for (
const CaloHit *pCaloHit : caloHitList3DNu)
477 if (maxYNu < pCaloHit->GetPositionVector().GetY())
478 maxYNu = pCaloHit->GetPositionVector().GetY();
481 for (
const CaloHit *pCaloHit : caloHitList3DCr)
483 if (maxYCr < pCaloHit->GetPositionVector().GetY())
484 maxYCr = pCaloHit->GetPositionVector().GetY();
487 m_featureVector.push_back(closestDistanceNu);
488 m_featureVector.push_back(supplementaryAngleToBeamNu);
489 m_featureVector.push_back(separationNu);
490 m_featureVector.push_back(eigenValuesNu.GetX());
491 m_featureVector.push_back(eigenValuesNu.GetY());
492 m_featureVector.push_back(eigenValuesNu.GetZ());
493 m_featureVector.push_back(maxYNu);
494 m_featureVector.push_back(allConnectedPfoListNu.size());
496 m_featureVector.push_back(closestDistanceCr);
497 m_featureVector.push_back(supplementaryAngleToBeamCr);
498 m_featureVector.push_back(separationCr);
499 m_featureVector.push_back(eigenValuesCr.GetX());
500 m_featureVector.push_back(eigenValuesCr.GetY());
501 m_featureVector.push_back(eigenValuesCr.GetZ());
502 m_featureVector.push_back(maxYCr);
503 m_featureVector.push_back(allConnectedPfoListCr.size());
505 m_isAvailable =
true;
508 catch (
const StatusCodeException &)
517 double &closestHitToFaceDistance)
const 519 if (inputCaloHitList.empty())
521 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - empty calo hit list" << std::endl;
522 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
525 typedef std::pair<const CaloHit*, float> HitDistancePair;
526 typedef std::vector<HitDistancePair> HitDistanceVector;
527 HitDistanceVector hitDistanceVector;
529 for (
const CaloHit *
const pCaloHit : inputCaloHitList)
532 std::sort(hitDistanceVector.begin(), hitDistanceVector.end(), [](
const HitDistancePair &lhs,
const HitDistancePair &rhs) ->
bool {
return (lhs.second < rhs.second);});
534 if (hitDistanceVector.front().second < 0.f)
536 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - unphysical magnitude of a vector" << std::endl;
537 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
540 closestHitToFaceDistance = std::sqrt(hitDistanceVector.front().second);
542 const unsigned int nInputHits(inputCaloHitList.size());
546 for (
const HitDistancePair &hitDistancePair : hitDistanceVector)
548 outputCaloHitList.push_back(hitDistancePair.first);
550 if (outputCaloHitList.size() >= nSelectedCaloHits)
558 CartesianVector &interceptOne, CartesianVector &interceptTwo)
const 560 CartesianPointVector intercepts;
561 CartesianVector lineUnitVector(0.
f, 0.
f, 0.
f);
565 lineUnitVector = lineDirection.GetUnitVector();
567 catch (
const StatusCodeException &statusCodeException)
569 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - normal vector to plane has a magnitude of zero" << std::endl;
570 throw statusCodeException;
575 const CartesianVector intercept(plane.GetLineIntersection(a0, lineUnitVector));
578 intercepts.push_back(intercept);
581 if (intercepts.size() > 1)
583 float maximumSeparationSquared(0.
f);
584 bool interceptsSet(
false);
586 for (
unsigned int i = 0; i < intercepts.size(); i++)
588 for (
unsigned int j = i + 1; j < intercepts.size(); j++)
590 const CartesianVector &candidateInterceptOne(intercepts.at(i));
591 const CartesianVector &candidateInterceptTwo(intercepts.at(j));
592 const float separationSquared((candidateInterceptOne - candidateInterceptTwo).GetMagnitudeSquared());
594 if (separationSquared > maximumSeparationSquared)
596 maximumSeparationSquared = separationSquared;
597 interceptOne = candidateInterceptOne;
598 interceptTwo = candidateInterceptTwo;
599 interceptsSet =
true;
606 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - unable to set the intercepts between a line and the LArTPC" << std::endl;
607 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
612 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - inconsistent number of intercepts between a line and the LArTPC" << std::endl;
613 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
636 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
638 if (!featureVector.empty())
640 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::FillFeatureVector - feature vector already populated" << std::endl;
641 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
644 featureVector.insert(featureVector.end(), m_featureVector.begin(), m_featureVector.end());
653 if (!this->IsFeatureVectorAvailable())
return -1.f;
659 this->FillFeatureVector(featureVector);
661 catch (
const StatusCodeException &statusCodeException)
663 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetAdaBoostDecisionTreeScore - unable to fill feature vector" << std::endl;
676 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
681 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
684 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
687 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
693 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
694 "BdtName", bdtName));
696 std::string bdtFileName;
697 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
698 "BdtFileName", bdtFileName));
700 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
706 if (STATUS_CODE_SUCCESS != statusCode)
708 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - unable to load bdt" << std::endl;
713 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
716 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
719 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
722 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
726 FloatVector beamLArTPCIntersection;
727 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
728 "BeamTPCIntersection", beamLArTPCIntersection));
730 if (3 == beamLArTPCIntersection.size())
732 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(beamLArTPCIntersection.at(0), beamLArTPCIntersection.at(1), beamLArTPCIntersection.at(2));
735 else if (!beamLArTPCIntersection.empty())
737 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamTPCIntersection specified " << std::endl;
738 return STATUS_CODE_INVALID_PARAMETER;
743 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(-33.051
f, 461.06
f, 0.
f);
747 FloatVector beamDirection;
748 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
749 "BeamDirection", beamDirection));
751 if (3 == beamDirection.size())
753 CartesianVector beamDirectionCartesianVector(beamDirection.at(0), beamDirection.at(1), beamDirection.at(2));
756 else if (!beamDirection.empty())
758 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamDirection specified " << std::endl;
759 return STATUS_CODE_INVALID_PARAMETER;
764 const float thetaXZ0(-11.844
f * M_PI / 180.
f);
765 CartesianVector beamDirectionCartesianVector(std::sin(thetaXZ0), 0.
f, std::cos(thetaXZ0));
769 float selectedFraction(0.
f);
771 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
772 "SelectedFraction", selectedFraction));
774 if (selectedFraction > std::numeric_limits<float>::epsilon())
777 unsigned int nSelectedHits(0);
779 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
780 "NSelectedHits", nSelectedHits));
782 if (nSelectedHits > 0)
785 float containmentLimit(0.
f);
787 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
788 "ContainmentLimit", containmentLimit));
790 if (containmentLimit < 0.
f)
792 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid ContainmentLimit specified " << std::endl;
793 return STATUS_CODE_INVALID_PARAMETER;
795 else if (containmentLimit > 0.
f)
800 return STATUS_CODE_SUCCESS;
void SetBeamLArTPCIntersection(const pandora::CartesianVector &beamLArTPCIntersection)
Set m_beamLArTPCIntersection.
double m_d
Parameter defining a plane.
Header file for the pfo helper class.
float GetLArTPCMinZ() const
Get m_larTPCMinZ.
bool m_selectInputHits
whether to select input hits
MvaTypes::MvaFeatureVector MvaFeatureVector
pandora::StatusCode Initialize()
std::string m_filePathEnvironmentVariable
The environment variable providing a list of paths to bdt files.
std::string m_mcParticleListName
Name of input MC particle list.
float m_larTPCMinY
Global LArTPC volume minimum y extent.
Plane(const pandora::CartesianVector &normal, const pandora::CartesianVector &point)
Constructor, using equation of plane: m_a*x + m_b*y + m_c*z + m_d = 0.
float m_minAdaBDTScore
Minimum score required to classify a slice as a beam particle.
float m_larTPCMaxX
Global LArTPC volume maximum x extent.
float GetSelectedFraction() const
Get m_selectedFraction.
unsigned int GetNSelectedHits() const
Get m_nSelectedHits.
pandora::CartesianVector GetLineIntersection(const pandora::CartesianVector &point, const pandora::CartesianVector &direction) const
Return the intersection between the plane and a line.
float GetAdaBoostDecisionTreeScore(const AdaBoostDecisionTree &adaBoostDecisionTree) const
Get the probability that this slice contains a beam particle.
float GetLArTPCMaxZ() const
Get m_larTPCMaxZ.
pandora::CartesianVector EigenValues
PlaneVector m_larTPCPlanes
Vector of all planes making up global LArTPC volume.
bool m_useTrainingMode
Should use training mode. If true, training examples will be written to the output file...
void SelectPfosByAdaBDTScore(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, const SliceFeaturesVector &sliceFeaturesVector, pandora::PfoList &selectedPfos) const
Select pfos based on the AdaBDT score that the slice contains a beam particle interaction.
float GetLArTPCMaxY() const
Get m_larTPCMaxY.
std::vector< SliceFeatures > SliceFeaturesVector
void SelectAllPfos(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &hypotheses, pandora::PfoList &selectedPfos) const
Select all pfos under the same hypothesis.
Header file for the principal curve analysis helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::vector< int > IntVector
void FillFeatureVector(LArMvaHelper::MvaFeatureVector &featureVector) const
Get the feature vector for the SVM.
static void GetMCPrimaryMap(const pandora::MCParticleList *const pMCParticleList, MCRelationMap &mcPrimaryMap)
Get mapping from individual mc particles (in a provided list) and their primary parent mc particles...
float m_larTPCMaxY
Global LArTPC volume maximum y extent.
static unsigned int GetNuanceCode(const pandora::MCParticle *const pMCParticle)
Get the nuance code of an MCParticle.
void SelectPfos(const pandora::PfoList &pfos, pandora::PfoList &selectedPfos) const
Add the given pfos to the selected Pfo list.
AdaBoostDecisionTree class.
bool PassesQualityCuts(const float purity, const float completeness) const
Determine if the event passes the selection cuts for training.
float GetLArTPCMaxX() const
Get m_larTPCMaxX.
float m_maxPhotonPropagation
the maximum photon propagation length
static void SelectCaloHits(const pandora::CaloHitList *const pCaloHitList, const MCRelationMap &mcToPrimaryMCMap, pandora::CaloHitList &selectedCaloHitList, const bool selectInputHits, const float maxPhotonPropagation)
Select a subset of calo hits representing those that represent "reconstructable" regions of the event...
void SetBeamDirection(const pandora::CartesianVector &beamDirection)
Set m_beamDirection.
void SetNSelectedHits(const unsigned int nSelectedHits)
Set m_nSelectedHits.
static double CalculateClassificationScore(const MvaInterface &classifier, TLISTS &&...featureLists)
Use the trained classifer to calculate the classification score of an example (>0 means boolean class...
bool IsContained(const pandora::CartesianVector &spacePoint, const float limit) const
Check if a given 3D spacepoint is inside the global LArTPC volume.
const pandora::CartesianVector & GetBeamDirection() const
Get the beam direction.
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TLISTS &&...featureLists)
Produce a training example with the given features and result.
Header file for the beam particle id tool class.
float GetContainmentLimit() const
Get m_containmentLimit.
Header file for the lar monte carlo particle helper helper class.
std::string m_trainingOutputFile
Output file name for training examples.
SliceFeatureParameters class.
void SetSelectedFraction(const float selectedFraction)
Set m_selectedFraction.
float m_minPurity
Minimum purity of the best slice to use event for training.
std::vector< pandora::PfoList > SliceHypotheses
void Collect2DHits(const pandora::PfoList &pfos, pandora::CaloHitList &caloHitList, const pandora::CaloHitSet &reconstructableCaloHitSet) const
Collect all 2D hits in a supplied list of Pfos and push them on to an existing hit list...
void GetBestMCSliceIndices(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, pandora::IntVector &bestSliceIndices) const
Get the slice with the most neutrino induced hits using Monte-Carlo information.
float m_minCompleteness
Minimum completeness of the best slice to use event for training.
void PopulateMCParticleToHitsMap(MCParticleToIntMap &mcParticleToIntMap, const pandora::CaloHitList &caloHitList) const
Fill mc particle to nHits map from calo hit list.
static const pandora::MCParticle * GetParentMCParticle(const pandora::MCParticle *const pMCParticle)
Get the parent mc particle.
const pandora::CartesianVector & GetBeamLArTPCIntersection() const
Get the beam LArTPC intersection.
pandora::CartesianVector m_unitNormal
Unit normal to plane.
static std::string FindFileInPath(const std::string &unqualifiedFileName, const std::string &environmentVariable, const std::string &delimiter=":")
Find the fully-qualified file name by searching through a list of delimiter-separated paths in a name...
Header file for the file helper class.
void Initialize(const float larTPCMinX, const float larTPCMaxX, const float larTPCMinY, const float larTPCMaxY, const float larTPCMinZ, const float larTPCMaxZ)
Set LArTPC geometry information.
SliceFeatureParameters()
Constructor.
void SetContainmentLimit(const float containmentLimit)
Set m_containmentLimit.
const PlaneVector & GetPlanes() const
Get vector of planes.
float GetLArTPCMinX() const
Get m_larTPCMinX.
float m_larTPCMinX
Global LArTPC volume minimum x extent.
std::unordered_map< const pandora::MCParticle *, int > MCParticleToIntMap
float m_larTPCMaxZ
Global LArTPC volume maximum z extent.
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...
std::vector< pandora::CartesianVector > EigenVectors
void GetLeadingCaloHits(const pandora::CaloHitList &inputCaloHitList, pandora::CaloHitList &outputCaloHitList, double &closestHitToFaceDistance) const
Select a given fraction of a slice's calo hits that are closest to the beam spot. ...
void GetSliceFeatures(const BdtBeamParticleIdTool *const pTool, const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, SliceFeaturesVector &sliceFeaturesVector) const
Get the features of each slice.
void SelectOutputPfos(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &beamSliceHypotheses, const SliceHypotheses &crSliceHypotheses, pandora::PfoList &selectedPfos)
Select which reconstruction hypotheses to use; neutrino outcomes or cosmic-ray muon outcomes for each...
pandora::StatusCode Initialize(const std::string ¶meterLocation, const std::string &bdtName)
Initialize the bdt model.
BdtBeamParticleIdTool class.
unsigned int m_maxNeutrinos
The maximum number of neutrinos to select in any one event.
std::string m_caloHitListName
Name of input calo hit list.
void GetLArTPCIntercepts(const pandora::CartesianVector &a0, const pandora::CartesianVector &majorAxis, pandora::CartesianVector &interceptOne, pandora::CartesianVector &interceptTwo) const
Find the intercepts of a line with the protoDUNE detector.
std::pair< unsigned int, float > UintFloatPair
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
static void GetAllConnectedPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively including all daughters and parents associated with those pf...
float m_larTPCMinZ
Global LArTPC volume minimum z extent.
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.
SliceFeatures(const pandora::PfoList &nuPfos, const pandora::PfoList &crPfos, const BdtBeamParticleIdTool *const pTool, const SliceFeatureParameters &sliceFeatureParameters)
Constructor.
AdaBoostDecisionTree m_adaBoostDecisionTree
The adaptive boost decision tree.
float GetLArTPCMinY() const
Get m_larTPCMinY.
SliceFeatureParameters m_sliceFeatureParameters
Geometry information block.