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(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),
434 CaloHitList caloHitList3DNu, caloHitList3DCr, selectedCaloHitListNu, selectedCaloHitListCr;
435 PfoList allConnectedPfoListNu, allConnectedPfoListCr;
444 this->GetLeadingCaloHits(caloHitList3DNu, selectedCaloHitListNu, closestDistanceNu);
445 this->GetLeadingCaloHits(caloHitList3DCr, selectedCaloHitListCr, closestDistanceCr);
447 if (!selectedCaloHitListNu.empty() && !selectedCaloHitListCr.empty())
450 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);
455 const CartesianVector &majorAxisNu(eigenVecsNu.front());
458 this->GetLArTPCIntercepts(centroidNu, majorAxisNu, interceptOneNu, interceptTwoNu);
461 separationNu =
std::min(separationOneNu, separationTwoNu);
466 const CartesianVector &majorAxisCr(eigenVecsCr.front());
469 this->GetLArTPCIntercepts(centroidCr, majorAxisCr, interceptOneCr, interceptTwoCr);
472 separationCr =
std::min(separationOneCr, separationTwoCr);
474 for (
const CaloHit *pCaloHit : caloHitList3DNu)
476 if (maxYNu < pCaloHit->GetPositionVector().GetY())
477 maxYNu = pCaloHit->GetPositionVector().GetY();
480 for (
const CaloHit *pCaloHit : caloHitList3DCr)
482 if (maxYCr < pCaloHit->GetPositionVector().GetY())
483 maxYCr = pCaloHit->GetPositionVector().GetY();
486 m_featureVector.push_back(closestDistanceNu);
487 m_featureVector.push_back(supplementaryAngleToBeamNu);
488 m_featureVector.push_back(separationNu);
489 m_featureVector.push_back(eigenValuesNu.GetX());
490 m_featureVector.push_back(eigenValuesNu.GetY());
491 m_featureVector.push_back(eigenValuesNu.GetZ());
492 m_featureVector.push_back(maxYNu);
493 m_featureVector.push_back(allConnectedPfoListNu.size());
495 m_featureVector.push_back(closestDistanceCr);
496 m_featureVector.push_back(supplementaryAngleToBeamCr);
497 m_featureVector.push_back(separationCr);
498 m_featureVector.push_back(eigenValuesCr.GetX());
499 m_featureVector.push_back(eigenValuesCr.GetY());
500 m_featureVector.push_back(eigenValuesCr.GetZ());
501 m_featureVector.push_back(maxYCr);
502 m_featureVector.push_back(allConnectedPfoListCr.size());
504 m_isAvailable =
true;
507 catch (
const StatusCodeException &)
516 double &closestHitToFaceDistance)
const 518 if (inputCaloHitList.empty())
520 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - empty calo hit list" << std::endl;
521 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
524 typedef std::pair<const CaloHit*, float> HitDistancePair;
525 typedef std::vector<HitDistancePair> HitDistanceVector;
526 HitDistanceVector hitDistanceVector;
528 for (
const CaloHit *
const pCaloHit : inputCaloHitList)
531 std::sort(hitDistanceVector.begin(), hitDistanceVector.end(), [](
const HitDistancePair &lhs,
const HitDistancePair &rhs) ->
bool {
return (lhs.second < rhs.second);});
533 if (hitDistanceVector.front().second < 0.f)
535 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - unphysical magnitude of a vector" << std::endl;
536 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
539 closestHitToFaceDistance = std::sqrt(hitDistanceVector.front().second);
541 const unsigned int nInputHits(inputCaloHitList.size());
545 for (
const HitDistancePair &hitDistancePair : hitDistanceVector)
547 outputCaloHitList.push_back(hitDistancePair.first);
549 if (outputCaloHitList.size() >= nSelectedCaloHits)
557 CartesianVector &interceptOne, CartesianVector &interceptTwo)
const 559 CartesianPointVector intercepts;
560 CartesianVector lineUnitVector(0.
f, 0.
f, 0.
f);
564 lineUnitVector = lineDirection.GetUnitVector();
566 catch (
const StatusCodeException &statusCodeException)
568 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - normal vector to plane has a magnitude of zero" << std::endl;
569 throw statusCodeException;
574 const CartesianVector intercept(plane.GetLineIntersection(a0, lineUnitVector));
577 intercepts.push_back(intercept);
580 if (intercepts.size() > 1)
582 float maximumSeparationSquared(0.
f);
583 bool interceptsSet(
false);
585 for (
unsigned int i = 0; i < intercepts.size(); i++)
587 for (
unsigned int j = i + 1; j < intercepts.size(); j++)
589 const CartesianVector &candidateInterceptOne(intercepts.at(i));
590 const CartesianVector &candidateInterceptTwo(intercepts.at(j));
591 const float separationSquared((candidateInterceptOne - candidateInterceptTwo).GetMagnitudeSquared());
593 if (separationSquared > maximumSeparationSquared)
595 maximumSeparationSquared = separationSquared;
596 interceptOne = candidateInterceptOne;
597 interceptTwo = candidateInterceptTwo;
598 interceptsSet =
true;
605 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - unable to set the intercepts between a line and the LArTPC" << std::endl;
606 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
611 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - inconsistent number of intercepts between a line and the LArTPC" << std::endl;
612 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
635 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
637 if (!featureVector.empty())
639 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::FillFeatureVector - feature vector already populated" << std::endl;
640 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
643 featureVector.insert(featureVector.end(), m_featureVector.begin(), m_featureVector.end());
652 if (!this->IsFeatureVectorAvailable())
return -1.f;
658 this->FillFeatureVector(featureVector);
660 catch (
const StatusCodeException &statusCodeException)
662 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetAdaBoostDecisionTreeScore - unable to fill feature vector" << std::endl;
675 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
680 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
683 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
686 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
692 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
693 "BdtName", bdtName));
695 std::string bdtFileName;
696 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
697 "BdtFileName", bdtFileName));
699 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
705 if (STATUS_CODE_SUCCESS != statusCode)
707 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - unable to load bdt" << std::endl;
712 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
715 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
718 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
721 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
725 FloatVector beamLArTPCIntersection;
726 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
727 "BeamTPCIntersection", beamLArTPCIntersection));
729 if (3 == beamLArTPCIntersection.size())
731 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(beamLArTPCIntersection.at(0), beamLArTPCIntersection.at(1), beamLArTPCIntersection.at(2));
734 else if (!beamLArTPCIntersection.empty())
736 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamTPCIntersection specified " << std::endl;
737 return STATUS_CODE_INVALID_PARAMETER;
742 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(-33.051
f, 461.06
f, 0.
f);
746 FloatVector beamDirection;
747 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
748 "BeamDirection", beamDirection));
750 if (3 == beamDirection.size())
752 CartesianVector beamDirectionCartesianVector(beamDirection.at(0), beamDirection.at(1), beamDirection.at(2));
755 else if (!beamDirection.empty())
757 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamDirection specified " << std::endl;
758 return STATUS_CODE_INVALID_PARAMETER;
763 const float thetaXZ0(-11.844
f * M_PI / 180.
f);
764 CartesianVector beamDirectionCartesianVector(std::sin(thetaXZ0), 0.
f, std::cos(thetaXZ0));
768 float selectedFraction(0.
f);
770 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
771 "SelectedFraction", selectedFraction));
773 if (selectedFraction > std::numeric_limits<float>::epsilon())
776 unsigned int nSelectedHits(0);
778 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
779 "NSelectedHits", nSelectedHits));
781 if (nSelectedHits > 0)
784 float containmentLimit(0.
f);
786 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
787 "ContainmentLimit", containmentLimit));
789 if (containmentLimit < 0.
f)
791 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid ContainmentLimit specified " << std::endl;
792 return STATUS_CODE_INVALID_PARAMETER;
794 else if (containmentLimit > 0.
f)
799 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...
SliceFeatures(const pandora::PfoList &nuPfos, const pandora::PfoList &crPfos, const SliceFeatureParameters &sliceFeatureParameters)
Constructor.
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.
void GetSliceFeatures(const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, SliceFeaturesVector &sliceFeaturesVector) const
Get the features of each slice.
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 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.
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.
AdaBoostDecisionTree m_adaBoostDecisionTree
The adaptive boost decision tree.
float GetLArTPCMinY() const
Get m_larTPCMinY.
SliceFeatureParameters m_sliceFeatureParameters
Geometry information block.