9 #include "Pandora/AlgorithmHeaders.h"
23 BdtBeamParticleIdTool::BdtBeamParticleIdTool() :
24 m_useTrainingMode(
false),
25 m_trainingOutputFile(
""),
27 m_minCompleteness(0.8f),
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)
245 MCParticleToIntMap::iterator iter(mcParticleToIntMap.find(pParentMCParticle));
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.01f)
406 const float larTPCMaxY,
const float larTPCMinZ,
const float larTPCMaxZ)
408 m_larTPCMinX = larTPCMinX;
409 m_larTPCMaxX = larTPCMaxX;
410 m_larTPCMinY = larTPCMinY;
411 m_larTPCMaxY = larTPCMaxY;
412 m_larTPCMinZ = larTPCMinZ;
413 m_larTPCMaxZ = 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);
422 m_larTPCPlanes.emplace_back(normalTop, pointTop);
423 m_larTPCPlanes.emplace_back(normalBottom, pointBottom);
424 m_larTPCPlanes.emplace_back(normalRight, pointRight);
425 m_larTPCPlanes.emplace_back(normalLeft, pointLeft);
426 m_larTPCPlanes.emplace_back(normalBack, pointBack);
427 m_larTPCPlanes.emplace_back(normalFront, pointFront);
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());
554 const unsigned int nSelectedCaloHits(
559 for (
const HitDistancePair &hitDistancePair : hitDistanceVector)
561 outputCaloHitList.push_back(hitDistancePair.first);
563 if (outputCaloHitList.size() >= nSelectedCaloHits)
571 const CartesianVector &
a0,
const CartesianVector &lineDirection, CartesianVector &interceptOne, CartesianVector &interceptTwo)
const
573 CartesianPointVector intercepts;
574 CartesianVector lineUnitVector(0.f, 0.f, 0.f);
578 lineUnitVector = lineDirection.GetUnitVector();
580 catch (
const StatusCodeException &statusCodeException)
582 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - normal vector to plane has a magnitude of zero" << std::endl;
583 throw statusCodeException;
588 const CartesianVector intercept(plane.GetLineIntersection(a0, lineUnitVector));
591 intercepts.push_back(intercept);
594 if (intercepts.size() > 1)
596 float maximumSeparationSquared(0.f);
597 bool interceptsSet(
false);
599 for (
unsigned int i = 0; i < intercepts.size(); i++)
601 for (
unsigned int j = i + 1; j < intercepts.size(); j++)
603 const CartesianVector &candidateInterceptOne(intercepts.at(i));
604 const CartesianVector &candidateInterceptTwo(intercepts.at(j));
605 const float separationSquared((candidateInterceptOne - candidateInterceptTwo).GetMagnitudeSquared());
607 if (separationSquared > maximumSeparationSquared)
609 maximumSeparationSquared = separationSquared;
610 interceptOne = candidateInterceptOne;
611 interceptTwo = candidateInterceptTwo;
612 interceptsSet =
true;
619 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - unable to set the intercepts between a line and the LArTPC"
621 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
626 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - inconsistent number of intercepts between a line and the LArTPC"
628 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
654 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
656 if (!featureVector.empty())
658 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::FillFeatureVector - feature vector already populated" << std::endl;
659 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
662 featureVector.insert(featureVector.end(), m_featureVector.begin(), m_featureVector.end());
671 if (!this->IsFeatureVectorAvailable())
678 this->FillFeatureVector(featureVector);
680 catch (
const StatusCodeException &statusCodeException)
682 std::cout <<
"BdtBeamParticleIdTool::SliceFeatures::GetAdaBoostDecisionTreeScore - unable to fill feature vector" << std::endl;
695 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"UseTrainingMode",
m_useTrainingMode));
699 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"TrainingOutputFileName",
m_trainingOutputFile));
701 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitListName",
m_caloHitListName));
703 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MCParticleListName",
m_mcParticleListName));
708 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"BdtName", bdtName));
710 std::string bdtFileName;
711 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"BdtFileName", bdtFileName));
713 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MinAdaBDTScore",
m_minAdaBDTScore));
718 if (STATUS_CODE_SUCCESS != statusCode)
720 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - unable to load bdt" << std::endl;
725 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinimumPurity",
m_minPurity));
727 PANDORA_RETURN_RESULT_IF_AND_IF(
728 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinimumCompleteness",
m_minCompleteness));
730 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
733 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaximumNeutrinos",
m_maxNeutrinos));
736 FloatVector beamLArTPCIntersection;
737 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
738 XmlHelper::ReadVectorOfValues(xmlHandle,
"BeamTPCIntersection", beamLArTPCIntersection));
740 if (3 == beamLArTPCIntersection.size())
742 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(
743 beamLArTPCIntersection.at(0), beamLArTPCIntersection.at(1), beamLArTPCIntersection.at(2));
746 else if (!beamLArTPCIntersection.empty())
748 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamTPCIntersection specified " << std::endl;
749 return STATUS_CODE_INVALID_PARAMETER;
754 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(-33.051f, 461.06f, 0.f);
758 FloatVector beamDirection;
759 PANDORA_RETURN_RESULT_IF_AND_IF(
760 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
"BeamDirection", beamDirection));
762 if (3 == beamDirection.size())
764 CartesianVector beamDirectionCartesianVector(beamDirection.at(0), beamDirection.at(1), beamDirection.at(2));
767 else if (!beamDirection.empty())
769 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid BeamDirection specified " << std::endl;
770 return STATUS_CODE_INVALID_PARAMETER;
775 const float thetaXZ0(-11.844f * M_PI / 180.f);
776 CartesianVector beamDirectionCartesianVector(std::sin(thetaXZ0), 0.f, std::cos(thetaXZ0));
780 float selectedFraction(0.f);
782 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SelectedFraction", selectedFraction));
784 if (selectedFraction > std::numeric_limits<float>::epsilon())
787 unsigned int nSelectedHits(0);
789 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NSelectedHits", nSelectedHits));
791 if (nSelectedHits > 0)
794 float containmentLimit(0.f);
796 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ContainmentLimit", containmentLimit));
798 if (containmentLimit < 0.f)
800 std::cout <<
"BdtBeamParticleIdTool::ReadSettings - invalid ContainmentLimit specified " << std::endl;
801 return STATUS_CODE_INVALID_PARAMETER;
803 else if (containmentLimit > 0.f)
808 return STATUS_CODE_SUCCESS;
void SetBeamLArTPCIntersection(const pandora::CartesianVector &beamLArTPCIntersection)
Set m_beamLArTPCIntersection.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
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.
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 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
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...
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.
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.
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...
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
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...
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.
BEGIN_PROLOG could also be cout
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...