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;
79 if (nuSliceHypotheses.size() != crSliceHypotheses.size())
80 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
82 const unsigned int nSlices(nuSliceHypotheses.size());
87 this->
GetSliceFeatures(nuSliceHypotheses, crSliceHypotheses, sliceFeaturesVector);
92 this->
SelectAllPfos(pAlgorithm, crSliceHypotheses, selectedPfos);
97 for (
unsigned int sliceIndex = 0; sliceIndex < nSlices; ++sliceIndex)
99 const SliceFeatures &features(sliceFeaturesVector.at(sliceIndex));
100 if (!features.IsFeatureVectorAvailable())
109 catch (
const StatusCodeException &statusCodeException)
111 std::cout <<
"BdtBeamParticleIdTool::SelectOutputPfos - unable to fill feature vector" << std::endl;
115 bool isGoodTrainingSlice(
false);
116 if (std::find(bestSliceIndices.begin(), bestSliceIndices.end(), sliceIndex) != bestSliceIndices.end())
117 isGoodTrainingSlice =
true;
125 this->
SelectPfosByAdaBDTScore(pAlgorithm, nuSliceHypotheses, crSliceHypotheses, sliceFeaturesVector, selectedPfos);
133 for (
unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
141 for (
const PfoList &pfos : hypotheses)
143 for (
const ParticleFlowObject *
const pPfo : pfos)
145 object_creation::ParticleFlowObject::Metadata metadata;
146 metadata.m_propertiesToAdd[
"TestBeamScore"] = -1.f;
147 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
158 selectedPfos.insert(selectedPfos.end(), pfos.begin(), pfos.end());
167 const CaloHitList *pAllReconstructedCaloHitList(
nullptr);
168 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm,
m_caloHitListName, pAllReconstructedCaloHitList));
170 const MCParticleList *pMCParticleList(
nullptr);
171 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm,
m_mcParticleListName, pMCParticleList));
178 CaloHitList reconstructableCaloHitList;
186 const CaloHitSet reconstructableCaloHitSet(reconstructableCaloHitList.begin(), reconstructableCaloHitList.end());
188 for (
unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
191 CaloHitList reconstructedCaloHitList;
192 this->
Collect2DHits(crSliceHypotheses.at(sliceIndex), reconstructedCaloHitList, reconstructableCaloHitSet);
194 if (nuSliceHypotheses.at(sliceIndex).size() == 1)
196 const PfoList &nuFinalStates(nuSliceHypotheses.at(sliceIndex).front()->GetDaughterPfoList());
197 this->
Collect2DHits(nuFinalStates, reconstructedCaloHitList, reconstructableCaloHitSet);
200 const unsigned int nRecoHits(reconstructedCaloHitList.size());
206 if (mcParticleToHitsInSliceMap.empty())
210 const MCParticle *pBestMCParticle(
nullptr);
211 unsigned int nSharedHits(0);
213 for (
const auto &iter : mcParticleToHitsInSliceMap)
215 if (iter.second > static_cast<int>(nSharedHits))
217 pBestMCParticle = iter.first;
218 nSharedHits = iter.second;
226 const unsigned int nMCHits(mcParticleToReconstructableHitsMap.at(pBestMCParticle));
227 const float purity(nRecoHits > 0 ? static_cast<float>(nSharedHits) / static_cast<float>(nRecoHits) : 0.
f);
228 const float completeness(nMCHits > 0 ? static_cast<float>(nSharedHits) / static_cast<float>(nMCHits) : 0.f);
231 bestSliceIndices.push_back(sliceIndex);
240 for (
const CaloHit *
const pCaloHit : caloHitList)
247 if (iter != mcParticleToIntMap.end())
253 mcParticleToIntMap.insert(MCParticleToIntMap::value_type(pParentMCParticle, 1));
256 catch (
const StatusCodeException &statusCodeException)
258 if (STATUS_CODE_NOT_INITIALIZED != statusCodeException.GetStatusCode())
259 throw statusCodeException;
268 CaloHitList collectedHits;
273 for (
const CaloHit *
const pCaloHit : collectedHits)
276 const CaloHit *pParentCaloHit(static_cast<const CaloHit *>(pCaloHit->GetParentAddress()));
278 if (!reconstructableCaloHitSet.count(pParentCaloHit))
282 if (std::find(reconstructedCaloHitList.begin(), reconstructedCaloHitList.end(), pParentCaloHit) == reconstructedCaloHitList.end())
283 reconstructedCaloHitList.push_back(pParentCaloHit);
303 std::vector<UintFloatPair> sliceIndexAdaBDTScorePairs;
304 for (
unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
306 const float nuAdaBDTScore(sliceFeaturesVector.at(sliceIndex).GetAdaBoostDecisionTreeScore(
m_adaBoostDecisionTree));
308 for (
const ParticleFlowObject *
const pPfo : crSliceHypotheses.at(sliceIndex))
310 object_creation::ParticleFlowObject::Metadata metadata;
311 metadata.m_propertiesToAdd[
"TestBeamScore"] = nuAdaBDTScore;
312 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
315 for (
const ParticleFlowObject *
const pPfo : nuSliceHypotheses.at(sliceIndex))
317 object_creation::ParticleFlowObject::Metadata metadata;
318 metadata.m_propertiesToAdd[
"TestBeamScore"] = nuAdaBDTScore;
319 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
324 this->
SelectPfos(crSliceHypotheses.at(sliceIndex), selectedPfos);
328 sliceIndexAdaBDTScorePairs.push_back(
UintFloatPair(sliceIndex, nuAdaBDTScore));
332 std::sort(sliceIndexAdaBDTScorePairs.begin(), sliceIndexAdaBDTScorePairs.end(),
336 unsigned int nNuSlices(0);
337 for (
const UintFloatPair &slice : sliceIndexAdaBDTScorePairs)
341 this->
SelectPfos(nuSliceHypotheses.at(slice.first), selectedPfos);
346 this->
SelectPfos(crSliceHypotheses.at(slice.first), selectedPfos);
354 m_unitNormal(0.
f, 0.
f, 0.
f),
356 m_d(-1. * static_cast<double>(normal.GetDotProduct(point)))
362 catch (
const StatusCodeException &statusCodeException)
364 std::cout <<
"BdtBeamParticleIdTool::Plane::Plane - normal vector to plane has a magnitude of zero" << std::endl;
365 throw statusCodeException;
373 if (std::fabs(direction.GetDotProduct(
m_unitNormal)) < std::numeric_limits<float>::epsilon())
374 return CartesianVector(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
376 const float denominator(direction.GetDotProduct(
m_unitNormal));
378 if (std::fabs(denominator) < std::numeric_limits<float>::epsilon())
379 throw StatusCodeException(STATUS_CODE_OUT_OF_RANGE);
381 const double t(-1. * (static_cast<double>(point.GetDotProduct(
m_unitNormal)) +
m_d) /
static_cast<double>(denominator));
382 return (point + (direction * t));
389 m_larTPCMinX(
std::numeric_limits<float>::max()),
390 m_larTPCMaxX(
std::numeric_limits<float>::max()),
391 m_larTPCMinY(
std::numeric_limits<float>::max()),
392 m_larTPCMaxY(
std::numeric_limits<float>::max()),
393 m_larTPCMinZ(
std::numeric_limits<float>::max()),
394 m_larTPCMaxZ(
std::numeric_limits<float>::max()),
395 m_beamLArTPCIntersection(0.
f, 0.
f, 0.
f),
396 m_beamDirection(0.
f, 0.
f, 0.
f),
397 m_selectedFraction(10.
f),
398 m_nSelectedHits(100),
399 m_containmentLimit(0.01
f)
406 const float larTPCMaxY,
const float larTPCMinZ,
const float larTPCMaxZ)
415 const CartesianVector normalTop(0.
f, 0.
f, 1.
f), pointTop(0.
f, 0.
f,
m_larTPCMaxZ);
416 const CartesianVector normalBottom(0.
f, 0.
f, -1.
f), pointBottom(0.
f, 0.
f,
m_larTPCMinZ);
417 const CartesianVector normalRight(1.
f, 0.
f, 0.
f), pointRight(
m_larTPCMaxX, 0.
f, 0.
f);
418 const CartesianVector normalLeft(-1.
f, 0.
f, 0.
f), pointLeft(
m_larTPCMinX, 0.
f, 0.
f);
419 const CartesianVector normalBack(0.
f, 1.
f, 0.
f), pointBack(0.
f,
m_larTPCMaxY, 0.
f);
420 const CartesianVector normalFront(0.
f, -1.
f, 0.
f), pointFront(0.
f,
m_larTPCMinY, 0.
f);
434 m_isAvailable(
false),
439 double closestDistanceNu(std::numeric_limits<double>::max()), closestDistanceCr(std::numeric_limits<double>::max()),
440 supplementaryAngleToBeamNu(std::numeric_limits<double>::max()), supplementaryAngleToBeamCr(std::numeric_limits<double>::max()),
441 separationNu(std::numeric_limits<double>::max()), separationCr(std::numeric_limits<double>::max());
443 CaloHitList caloHitList3DNu, caloHitList3DCr, selectedCaloHitListNu, selectedCaloHitListCr;
444 PfoList allConnectedPfoListNu, allConnectedPfoListCr;
453 this->GetLeadingCaloHits(caloHitList3DNu, selectedCaloHitListNu, closestDistanceNu);
454 this->GetLeadingCaloHits(caloHitList3DCr, selectedCaloHitListCr, closestDistanceCr);
456 if (!selectedCaloHitListNu.empty() && !selectedCaloHitListCr.empty())
458 float maxYNu(-std::numeric_limits<float>::max()), maxYCr(-std::numeric_limits<float>::max());
459 CartesianVector centroidNu(0.
f, 0.
f, 0.
f), interceptOneNu(0.
f, 0.
f, 0.
f), interceptTwoNu(0.
f, 0.
f, 0.
f),
460 centroidCr(0.
f, 0.
f, 0.
f), interceptOneCr(0.
f, 0.
f, 0.
f), interceptTwoCr(0.
f, 0.
f, 0.
f);
465 const CartesianVector &majorAxisNu(eigenVecsNu.front());
468 this->GetLArTPCIntercepts(centroidNu, majorAxisNu, interceptOneNu, interceptTwoNu);
471 separationNu = std::min(separationOneNu, separationTwoNu);
476 const CartesianVector &majorAxisCr(eigenVecsCr.front());
479 this->GetLArTPCIntercepts(centroidCr, majorAxisCr, interceptOneCr, interceptTwoCr);
482 separationCr = std::min(separationOneCr, separationTwoCr);
484 for (
const CaloHit *pCaloHit : caloHitList3DNu)
486 if (maxYNu < pCaloHit->GetPositionVector().GetY())
487 maxYNu = pCaloHit->GetPositionVector().GetY();
490 for (
const CaloHit *pCaloHit : caloHitList3DCr)
492 if (maxYCr < pCaloHit->GetPositionVector().GetY())
493 maxYCr = pCaloHit->GetPositionVector().GetY();
496 m_featureVector.push_back(closestDistanceNu);
497 m_featureVector.push_back(supplementaryAngleToBeamNu);
498 m_featureVector.push_back(separationNu);
499 m_featureVector.push_back(eigenValuesNu.GetX());
500 m_featureVector.push_back(eigenValuesNu.GetY());
501 m_featureVector.push_back(eigenValuesNu.GetZ());
502 m_featureVector.push_back(maxYNu);
503 m_featureVector.push_back(allConnectedPfoListNu.size());
505 m_featureVector.push_back(closestDistanceCr);
506 m_featureVector.push_back(supplementaryAngleToBeamCr);
507 m_featureVector.push_back(separationCr);
508 m_featureVector.push_back(eigenValuesCr.GetX());
509 m_featureVector.push_back(eigenValuesCr.GetY());
510 m_featureVector.push_back(eigenValuesCr.GetZ());
511 m_featureVector.push_back(maxYCr);
512 m_featureVector.push_back(allConnectedPfoListCr.size());
514 m_isAvailable =
true;
517 catch (
const StatusCodeException &)
526 const CaloHitList &inputCaloHitList, CaloHitList &outputCaloHitList,
double &closestHitToFaceDistance)
const 528 if (inputCaloHitList.empty())
530 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - empty calo hit list" << std::endl;
531 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
534 typedef std::pair<const CaloHit *, float> HitDistancePair;
535 typedef std::vector<HitDistancePair> HitDistanceVector;
536 HitDistanceVector hitDistanceVector;
538 for (
const CaloHit *
const pCaloHit : inputCaloHitList)
539 hitDistanceVector.emplace_back(
542 std::sort(hitDistanceVector.begin(), hitDistanceVector.end(),
543 [](
const HitDistancePair &lhs,
const HitDistancePair &rhs) ->
bool {
return (lhs.second < rhs.second); });
545 if (hitDistanceVector.front().second < 0.f)
547 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - unphysical magnitude of a vector" << std::endl;
548 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
551 closestHitToFaceDistance = std::sqrt(hitDistanceVector.front().second);
553 const unsigned int nInputHits(inputCaloHitList.size());
558 for (
const HitDistancePair &hitDistancePair : hitDistanceVector)
560 outputCaloHitList.push_back(hitDistancePair.first);
562 if (outputCaloHitList.size() >= nSelectedCaloHits)
570 const CartesianVector &
a0,
const CartesianVector &lineDirection, CartesianVector &interceptOne, CartesianVector &interceptTwo)
const 572 CartesianPointVector intercepts;
573 CartesianVector lineUnitVector(0.
f, 0.
f, 0.
f);
577 lineUnitVector = lineDirection.GetUnitVector();
579 catch (
const StatusCodeException &statusCodeException)
581 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - normal vector to plane has a magnitude of zero" << std::endl;
582 throw statusCodeException;
587 const CartesianVector intercept(plane.GetLineIntersection(a0, lineUnitVector));
590 intercepts.push_back(intercept);
593 if (intercepts.size() > 1)
595 float maximumSeparationSquared(0.
f);
596 bool interceptsSet(
false);
598 for (
unsigned int i = 0; i < intercepts.size(); i++)
600 for (
unsigned int j = i + 1; j < intercepts.size(); j++)
602 const CartesianVector &candidateInterceptOne(intercepts.at(i));
603 const CartesianVector &candidateInterceptTwo(intercepts.at(j));
604 const float separationSquared((candidateInterceptOne - candidateInterceptTwo).GetMagnitudeSquared());
606 if (separationSquared > maximumSeparationSquared)
608 maximumSeparationSquared = separationSquared;
609 interceptOne = candidateInterceptOne;
610 interceptTwo = candidateInterceptTwo;
611 interceptsSet =
true;
618 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - unable to set the intercepts between a line and the LArTPC" 620 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
625 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - inconsistent number of intercepts between a line and the LArTPC" 627 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
653 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
655 if (!featureVector.empty())
657 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::FillFeatureVector - feature vector already populated" << std::endl;
658 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
661 featureVector.insert(featureVector.end(), m_featureVector.begin(), m_featureVector.end());
670 if (!this->IsFeatureVectorAvailable())
677 this->FillFeatureVector(featureVector);
679 catch (
const StatusCodeException &statusCodeException)
681 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetAdaBoostDecisionTreeScore - unable to fill feature vector" << std::endl;
694 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"UseTrainingMode",
m_useTrainingMode));
698 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingOutputFileName",
m_trainingOutputFile));
700 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
702 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MCParticleListName",
m_mcParticleListName));
707 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"BdtName", bdtName));
709 std::string bdtFileName;
710 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"BdtFileName", bdtFileName));
712 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MinAdaBDTScore",
m_minAdaBDTScore));
717 if (STATUS_CODE_SUCCESS != statusCode)
719 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - unable to load bdt" << std::endl;
724 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinimumPurity",
m_minPurity));
726 PANDORA_RETURN_RESULT_IF_AND_IF(
727 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinimumCompleteness",
m_minCompleteness));
729 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
732 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaximumNeutrinos",
m_maxNeutrinos));
735 FloatVector beamLArTPCIntersection;
736 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
737 XmlHelper::ReadVectorOfValues(xmlHandle,
"BeamTPCIntersection", beamLArTPCIntersection));
739 if (3 == beamLArTPCIntersection.size())
741 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(
742 beamLArTPCIntersection.at(0), beamLArTPCIntersection.at(1), beamLArTPCIntersection.at(2));
745 else if (!beamLArTPCIntersection.empty())
747 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamTPCIntersection specified " << std::endl;
748 return STATUS_CODE_INVALID_PARAMETER;
753 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(-33.051
f, 461.06
f, 0.
f);
757 FloatVector beamDirection;
758 PANDORA_RETURN_RESULT_IF_AND_IF(
759 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"BeamDirection", beamDirection));
761 if (3 == beamDirection.size())
763 CartesianVector beamDirectionCartesianVector(beamDirection.at(0), beamDirection.at(1), beamDirection.at(2));
766 else if (!beamDirection.empty())
768 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamDirection specified " << std::endl;
769 return STATUS_CODE_INVALID_PARAMETER;
774 const float thetaXZ0(-11.844
f * M_PI / 180.
f);
775 CartesianVector beamDirectionCartesianVector(std::sin(thetaXZ0), 0.
f, std::cos(thetaXZ0));
779 float selectedFraction(0.
f);
781 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SelectedFraction", selectedFraction));
783 if (selectedFraction > std::numeric_limits<float>::epsilon())
786 unsigned int nSelectedHits(0);
788 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NSelectedHits", nSelectedHits));
790 if (nSelectedHits > 0)
793 float containmentLimit(0.
f);
795 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ContainmentLimit", containmentLimit));
797 if (containmentLimit < 0.
f)
799 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid ContainmentLimit specified " << std::endl;
800 return STATUS_CODE_INVALID_PARAMETER;
802 else if (containmentLimit > 0.
f)
807 return STATUS_CODE_SUCCESS;
void SetBeamLArTPCIntersection(const pandora::CartesianVector &beamLArTPCIntersection)
Set m_beamLArTPCIntersection.
double m_d
Parameter defining a plane.
std::vector< pandora::PfoList > SliceHypotheses
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.
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TCONTAINER &&featureContainer)
Produce a training example with the given features and result.
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
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.
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.
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.
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.
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. ...
std::unordered_map< const pandora::MCParticle *, int > MCParticleToIntMap
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.
static double CalculateClassificationScore(const MvaInterface &classifier, TCONTAINER &&featureContainer)
Use the trained classifer to calculate the classification score of an example (>0 means boolean class...
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
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.
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
AdaBoostDecisionTree m_adaBoostDecisionTree
The adaptive boost decision tree.
float GetLArTPCMinY() const
Get m_larTPCMinY.
SliceFeatureParameters m_sliceFeatureParameters
Geometry information block.
static void SelectCaloHits(const pandora::CaloHitList *const pCaloHitList, const MCRelationMap &mcToTargetMCMap, pandora::CaloHitList &selectedCaloHitList, const bool selectInputHits, const float maxPhotonPropagation)
Select a subset of calo hits representing those that represent "reconstructable" regions of the event...