9 #include "Pandora/AlgorithmHeaders.h" 
   23 TwoViewTransverseTracksAlgorithm::TwoViewTransverseTracksAlgorithm() :
 
   24     m_nMaxMatrixToolRepeats(1000),
 
   25     m_downsampleFactor(5),
 
   27     m_nPermutations(1000),
 
   28     m_localMatchingScoreThreshold(0.99f),
 
   29     m_maxDotProduct(0.998f),
 
   30     m_minOverallMatchingScore(0.1f),
 
   31     m_minOverallLocallyMatchedFraction(0.1f),
 
   32     m_randomNumberGenerator(static_cast<
std::mt19937::result_type>(0))
 
   41         static_cast<std::mt19937::result_type>(pCluster1->GetOrderedCaloHitList().size() + pCluster2->GetOrderedCaloHitList().size()));
 
   44     PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->
CalculateOverlapResult(pCluster1, pCluster2, overlapResult));
 
   53     const Cluster *
const pCluster1, 
const Cluster *
const pCluster2, TwoViewTransverseOverlapResult &overlapResult)
 
   55     UIntSet daughterVolumeIntersection;
 
   58     if (daughterVolumeIntersection.empty())
 
   59         return STATUS_CODE_NOT_FOUND;
 
   62         return STATUS_CODE_NOT_FOUND;
 
   64     float xMin1(0.f), xMax1(0.f), xMin2(0.f), xMax2(0.f);
 
   65     pCluster1->GetClusterSpanX(xMin1, xMax1);
 
   66     pCluster2->GetClusterSpanX(xMin2, xMax2);
 
   68     const TwoViewXOverlap twoViewXOverlap(xMin1, xMax1, xMin2, xMax2);
 
   69     if (twoViewXOverlap.GetXSpan0() < std::numeric_limits<float>::epsilon() || twoViewXOverlap.GetXSpan1() < std::numeric_limits<float>::epsilon())
 
   70         throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
 
   72     if (twoViewXOverlap.GetTwoViewXOverlapSpan() < std::numeric_limits<float>::epsilon())
 
   73         return STATUS_CODE_NOT_FOUND;
 
   75     float xOverlapMin(twoViewXOverlap.GetTwoViewXOverlapMin());
 
   76     float xOverlapMax(twoViewXOverlap.GetTwoViewXOverlapMax());
 
   77     float zMin1(0.f), zMax1(0.f);
 
   78     float zMin2(0.f), zMax2(0.f);
 
   79     pCluster1->GetClusterSpanZ(xMin1, xMax1, zMin1, zMax1);
 
   80     pCluster2->GetClusterSpanZ(xMin2, xMax2, zMin2, zMax2);
 
   81     const CartesianVector boundingBoxMin1(xOverlapMin, 0.f, zMin1), boundingBoxMax1(xOverlapMax, 0.f, zMax1);
 
   82     const CartesianVector boundingBoxMin2(xOverlapMin, 0.f, zMin2), boundingBoxMax2(xOverlapMax, 0.f, zMax2);
 
   84     pandora::CaloHitList overlapHits1, overlapHits2;
 
   88     if (
m_minSamples > std::min(overlapHits1.size(), overlapHits2.size()))
 
   89         return STATUS_CODE_NOT_FOUND;
 
   92         throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
 
   93     const unsigned int nSamples(
 
   97     for (
const pandora::CaloHit *
const pCaloHit : overlapHits1)
 
   98         inputData1.emplace_back(pCaloHit->GetPositionVector().GetX(), pCaloHit->GetInputEnergy());
 
  101     for (
const pandora::CaloHit *
const pCaloHit : overlapHits2)
 
  102         inputData2.emplace_back(pCaloHit->GetPositionVector().GetX(), pCaloHit->GetInputEnergy());
 
  104     const DiscreteProbabilityVector discreteProbabilityVector1(inputData1, xOverlapMax, 
false);
 
  105     const DiscreteProbabilityVector discreteProbabilityVector2(inputData2, xOverlapMax, 
false);
 
  108     for (
unsigned int iSample = 0; iSample < nSamples; ++iSample)
 
  110         resamplingPointsX.emplace_back(
 
  111             (xOverlapMin + (xOverlapMax - xOverlapMin) * static_cast<float>(iSample + 1) / static_cast<float>(nSamples + 1)));
 
  114     const DiscreteProbabilityVector resampledDiscreteProbabilityVector1(discreteProbabilityVector1, resamplingPointsX);
 
  115     const DiscreteProbabilityVector resampledDiscreteProbabilityVector2(discreteProbabilityVector2, resamplingPointsX);
 
  117     const float correlation(
 
  123     const float matchingScore(1.f - pvalue);
 
  125         return STATUS_CODE_NOT_FOUND;
 
  129     const int nComparisons(static_cast<int>(resampledDiscreteProbabilityVector1.GetSize()) - (static_cast<int>(
m_minSamples) - 1));
 
  130     if (1 > nComparisons)
 
  131         throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
 
  133     const float locallyMatchedFraction(static_cast<float>(nLocallyMatchedSamplingPoints) / static_cast<float>(nComparisons));
 
  135         return STATUS_CODE_NOT_FOUND;
 
  137     overlapResult = TwoViewTransverseOverlapResult(
 
  138         matchingScore, 
m_downsampleFactor, nComparisons, nLocallyMatchedSamplingPoints, correlation, twoViewXOverlap);
 
  140     return STATUS_CODE_SUCCESS;
 
  148     if (discreteProbabilityVector1.
GetSize() != discreteProbabilityVector2.
GetSize() ||
 
  149         0 == discreteProbabilityVector1.
GetSize() * discreteProbabilityVector2.
GetSize())
 
  150         throw STATUS_CODE_INVALID_PARAMETER;
 
  153         throw STATUS_CODE_INVALID_PARAMETER;
 
  155     pandora::FloatVector localValues1, localValues2;
 
  156     unsigned int nMatchedComparisons(0);
 
  158     for (
unsigned int iValue = 0; iValue < discreteProbabilityVector1.
GetSize(); ++iValue)
 
  160         localValues1.emplace_back(discreteProbabilityVector1.
GetProbability(iValue));
 
  161         localValues2.emplace_back(discreteProbabilityVector2.
GetProbability(iValue));
 
  164             float localPValue(0);
 
  170             catch (
const StatusCodeException &)
 
  172                 std::cout << 
"TwoViewTransverseTracksAlgorithm: failed to calculate correlation coefficient p-value for these numbers" << std::endl;
 
  175                 for (
unsigned int iElement = 0; iElement < localValues1.size(); ++iElement)
 
  176                     std::cout << localValues1.at(iElement) << 
" ";
 
  179                 for (
unsigned int iElement = 0; iElement < localValues2.size(); ++iElement)
 
  180                     std::cout << localValues2.at(iElement) << 
" ";
 
  185                 nMatchedComparisons++;
 
  187             localValues1.erase(localValues1.begin());
 
  188             localValues2.erase(localValues2.begin());
 
  191     return nMatchedComparisons;
 
  198     pandora::CartesianPointVector pointVector;
 
  201     pandora::CartesianVector centroid(0.f, 0.f, 0.f);
 
  206     const pandora::CartesianVector primaryAxis(eigenVecs.at(0));
 
  207     const pandora::CartesianVector driftAxis(1.f, 0.f, 0.f);
 
  208     return primaryAxis.GetDotProduct(driftAxis);
 
  215     unsigned int repeatCounter(0);
 
  218         if ((*iter)->Run(
this, 
this->GetMatchingControl().GetOverlapMatrix()))
 
  236     AlgorithmToolVector algorithmToolVector;
 
  237     PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle, 
"TrackTools", algorithmToolVector));
 
  239     for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
 
  243         if (!pTransverseMatrixTool)
 
  244             return STATUS_CODE_INVALID_PARAMETER;
 
  249     PANDORA_RETURN_RESULT_IF_AND_IF(
 
  250         STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"NMaxMatrixToolRepeats", 
m_nMaxMatrixToolRepeats));
 
  252     PANDORA_RETURN_RESULT_IF_AND_IF(
 
  253         STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"DownsampleFactor", 
m_downsampleFactor));
 
  255     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"MinSamples", 
m_minSamples));
 
  257     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"NPermutations", 
m_nPermutations));
 
  259     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
 
  262     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"MaxDotProduct", 
m_maxDotProduct));
 
  264     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
 
  267     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
 
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
bool IsInitialized() const 
Whether the track overlap result has been initialized. 
TwoViewTransverseOverlapResult class. 
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
DiscreteProbabilityVector class. 
std::mt19937 m_randomNumberGenerator
The random number generator. 
pandora::CartesianVector EigenValues
MatrixType & GetOverlapMatrix()
Get the overlap matrix. 
static float CalculateCorrelationCoefficientPValueFromPermutationTest(const T &t1, const T &t2, std::mt19937 &randomNumberGenerator, const unsigned int nPermutations)
Calculate P value for measured correlation coefficient between two datasets via a permutation test...
Header file for the principal curve analysis helper class. 
float m_localMatchingScoreThreshold
The minimum score to classify a local region as matching. 
MatrixToolVector m_algorithmToolVector
The algorithm tool vector. 
static float CalculateCorrelationCoefficient(const T &t1, const T &t2)
Calculate the correlation coefficient between two datasets. 
MatchingType & GetMatchingControl()
Get the matching control. 
Header file for the discrete probability helper class. 
Header file for the geometry helper class. 
Header file for the cluster helper class. 
InputData< float, float > AllFloatInputData
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static void GetCaloHitListInBoundingBox(const pandora::Cluster *const pCluster, const pandora::CartesianVector &lowerBound, const pandora::CartesianVector &upperBound, pandora::CaloHitList &caloHitList)
Get list of Calo hits from an input cluster that are contained in a bounding box. The hits are sorted...
float GetProbability(const unsigned int index) const 
Get the probability value of the element in the vector. 
float GetPrimaryAxisDotDriftAxis(const pandora::Cluster *const pCluster)
Get the dot product between the cluster's primary axis and the drift axis. 
unsigned int m_nPermutations
The number of permutations for calculating p-values. 
Header file for the two view transverse tracks algorithm class. 
void SetOverlapResult(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const OverlapResult &overlapResult)
Set overlap result. 
unsigned int CalculateNumberOfLocallyMatchingSamplingPoints(const DiscreteProbabilityVector &discreteProbabilityVector1, const DiscreteProbabilityVector &discreteProbabilityVector2, std::mt19937 &randomNumberGenerator)
Calculates the number of the sliding windows that contains charge bins that locally match...
unsigned int m_minSamples
The minimum number of samples needed for comparing charges. 
float m_minOverallMatchingScore
M The maximum allowed cluster primary qxis Dot drift axis to fill the overlap result. 
float m_minOverallLocallyMatchedFraction
The minimum required lcoally matched fraction to fill the overlap result. 
TransverseMatrixTool class. 
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...
void ExamineOverlapContainer()
Examine contents of overlap container, collect together best-matching 2D particles and modify cluster...
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::vector< pandora::CartesianVector > EigenVectors
unsigned int m_downsampleFactor
The downsampling (hit merging) applied to hits in the overlap region. 
unsigned int GetSize() const 
Get the size of the probability vector. 
static void GetCoordinateVector(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &coordinateVector)
Get vector of hit coordinates from an input cluster. 
void CalculateOverlapResult(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::Cluster *const)
Calculate cluster overlap result and store in container. 
pandora::FloatVector ResamplingPoints
unsigned int m_nMaxMatrixToolRepeats
The maximum number of repeat loops over matrix tools. 
std::set< unsigned int > UIntSet
BEGIN_PROLOG could also be cout
static void GetCommonDaughterVolumes(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, UIntSet &intersect)
Return the set of common daughter volumes between two 2D clusters.