9 #include "Pandora/AlgorithmHeaders.h"    22 CosmicRayVertexBuildingAlgorithm::CosmicRayVertexBuildingAlgorithm() :
    23     m_useParentShowerVertex(false),
    25     m_halfWindowLayers(30),
    26     m_maxVertexDisplacementFromTrack(1.
f)
    34     const PfoList *pPfoList = NULL;
    35     PANDORA_THROW_RESULT_IF_AND_IF(
    36         STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this, 
m_parentPfoListName, pPfoList));
    40         if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
    41             std::cout << 
"CosmicRayVertexBuildingAlgorithm: pfo list unavailable." << 
std::endl;
    43         return STATUS_CODE_SUCCESS;
    53     return STATUS_CODE_SUCCESS;
    65             throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
    70     for (
PfoList::const_iterator pIter = outputList.begin(), pIterEnd = outputList.end(); pIter != pIterEnd; ++pIter)
    72         ClusterList clusterList;
    75         if (clusterList.empty())
    78         pfoVector.push_back(*pIter);
    90         const ParticleFlowObject *
const pPfo = *pIter;
    95         ClusterList clusterList;
   100             const Cluster *
const pCluster = *cIter;
   106                 if (!pointingClusterMap.insert(LArPointingClusterMap::value_type(pCluster, pointingCluster)).second)
   107                     throw StatusCodeException(STATUS_CODE_FAILURE);
   109             catch (StatusCodeException &statusCodeException)
   111                 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
   112                     throw statusCodeException;
   124         const ParticleFlowObject *
const pPfo = *iter;
   141     ClusterList clusterList;
   144     if (clusterList.empty())
   148     bool foundVtx(
false);
   149     CartesianVector vtxPosition(0.
f, 0.
f, 0.
f);
   150     CartesianVector vtxDirection(0.
f, 0.
f, 0.
f);
   152     bool foundEnd(
false);
   153     CartesianVector endPosition(0.
f, 0.
f, 0.
f);
   154     CartesianVector endDirection(0.
f, 0.
f, 0.
f);
   158         const Cluster *
const pCluster = *cIter1;
   162             CartesianVector minPosition(0.
f, 0.
f, 0.
f), maxPosition(0.
f, 0.
f, 0.
f);
   163             CartesianVector minDirection(0.
f, 0.
f, 0.
f), maxDirection(0.
f, 0.
f, 0.
f);
   167             if (pointingClusterMap.end() != cIter2)
   179                 minDirection = (maxPosition - minPosition).GetUnitVector();
   180                 maxDirection = (minPosition - maxPosition).GetUnitVector();
   183             if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
   184                 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
   187             const float minVerticalCoordinate(
m_isDualPhase ? minPosition.GetX() : minPosition.GetY());
   188             const float maxVerticalCoordinate(
m_isDualPhase ? maxPosition.GetX() : maxPosition.GetY());
   189             const float vtxVerticalCoordinate(
m_isDualPhase ? vtxPosition.GetX() : vtxPosition.GetY());
   190             const float endVerticalCoordinate(
m_isDualPhase ? endPosition.GetX() : endPosition.GetY());
   192             if (!foundVtx || (minVerticalCoordinate > 
std::max(maxVerticalCoordinate, vtxVerticalCoordinate)))
   195                 vtxPosition = minPosition;
   196                 vtxDirection = minDirection;
   199             if (!foundVtx || (maxVerticalCoordinate > 
std::max(minVerticalCoordinate, vtxVerticalCoordinate)))
   202                 vtxPosition = maxPosition;
   203                 vtxDirection = maxDirection;
   206             if (!foundEnd || (minVerticalCoordinate < 
std::min(maxVerticalCoordinate, endVerticalCoordinate)))
   209                 endPosition = minPosition;
   210                 endDirection = minDirection;
   213             if (!foundEnd || (maxVerticalCoordinate < 
std::min(minVerticalCoordinate, endVerticalCoordinate)))
   216                 endPosition = maxPosition;
   217                 endDirection = maxDirection;
   220         catch (StatusCodeException &statusCodeException)
   222             if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
   223                 throw statusCodeException;
   229     if (!(foundVtx && foundEnd))
   239     if (pDaughterPfo->GetParentPfoList().size() != 1)
   240         throw StatusCodeException(STATUS_CODE_FAILURE);
   242     const ParticleFlowObject *
const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
   244     ClusterList parentList, daughterList;
   248     if (daughterList.empty() || parentList.empty())
   253     CartesianVector closestMaxVerticalVertex(0.
f, 0.
f, 0.
f), maxVerticalVertex(0.
f, 0.
f, 0.
f);
   255     for (
const Cluster *
const pDaughterCluster : daughterList)
   257         CaloHitList daughterCaloHitList;
   258         pDaughterCluster->GetOrderedCaloHitList().FillCaloHitList(daughterCaloHitList);
   260         for (
const Cluster *
const pParentCluster : parentList)
   262             CaloHitList parentCaloHitList;
   263             pParentCluster->GetOrderedCaloHitList().FillCaloHitList(parentCaloHitList);
   265             for (
const CaloHit *
const pDaughterCaloHit : daughterCaloHitList)
   267                 const CartesianVector &daughterPosition(pDaughterCaloHit->GetPositionVector());
   269                 for (
const CaloHit *
const pParentCaloHit : parentCaloHitList)
   271                     const CartesianVector &parentPosition(pParentCaloHit->GetPositionVector());
   272                     const float separationSquared((daughterPosition - parentPosition).GetMagnitudeSquared());
   273                     const float verticalCoordinate(
m_isDualPhase ? daughterPosition.GetX() : daughterPosition.GetY());
   275                     if (verticalCoordinate > maxVerticalCoordinate)
   277                         maxVerticalCoordinate = verticalCoordinate;
   278                         maxVerticalVertex = daughterPosition;
   283                         if (verticalCoordinate > closestMaxVerticalCoordinate)
   286                             closestMaxVerticalCoordinate = verticalCoordinate;
   287                             closestMaxVerticalVertex = daughterPosition;
   295     const CartesianVector &daughterVertex(found ? closestMaxVerticalVertex : maxVerticalVertex);
   304     const CartesianVector &vtxPosition, 
const CartesianVector &vtxDirection, 
const ParticleFlowObject *
const pPfo)
 const   306     if (!pPfo->GetVertexList().empty())
   307         throw StatusCodeException(STATUS_CODE_FAILURE);
   309     PandoraContentApi::ParticleFlowObject::Metadata 
metadata;
   310     metadata.m_momentum = vtxDirection;
   311     PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*
this, pPfo, metadata));
   315     PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*
this, pVertexList, vertexListName));
   317     PandoraContentApi::Vertex::Parameters parameters;
   318     parameters.m_position = vtxPosition;
   319     parameters.m_vertexLabel = VERTEX_START;
   320     parameters.m_vertexType = VERTEX_3D;
   322     const Vertex *pVertex(NULL);
   323     PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*
this, parameters, pVertex));
   325     if (!pVertexList->empty())
   327         PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*
this, 
m_vertexListName));
   328         PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*
this, pPfo, pVertex));
   336     PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, 
"InputPfoListName", 
m_parentPfoListName));
   338     PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, 
"OutputVertexListName", 
m_vertexListName));
   340     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
   343     PANDORA_RETURN_RESULT_IF_AND_IF(
   344         STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"SlidingFitHalfWindow", 
m_halfWindowLayers));
   346     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, 
"IsDualPhase", 
m_isDualPhase));
   348     PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
   351     return STATUS_CODE_SUCCESS;
 std::unordered_map< const pandora::Cluster *, LArPointingCluster > LArPointingClusterMap
 
Header file for the pfo helper class. 
 
bool m_useParentShowerVertex
use the parent pfo for the shower vertices 
 
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos. 
 
void SetParticleParameters(const pandora::CartesianVector &vtxPosition, const pandora::CartesianVector &vtxDirection, const pandora::ParticleFlowObject *const pPfo) const 
Set the vertex and direction of the Pfos. 
 
bool m_isDualPhase
type of geometry 
 
LArPointingCluster class. 
 
std::string m_vertexListName
The name of the output vertex list. 
 
Header file for the cosmic-ray vertex building algorithm class. 
 
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID. 
 
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch. 
 
void BuildCosmicRayParent(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pPfo) const 
Reconstruct the vertex and direction of a parent cosmic-ray Pfo. 
 
Header file for the geometry helper class. 
 
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
 
void BuildCosmicRayParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const 
Reconstruct the vertex and direction of a list of cosmic-ray Pfos. 
 
pandora::StatusCode Run()
 
Header file for the cluster helper class. 
 
const Vertex & GetOuterVertex() const 
Get the outer vertex. 
 
const Vertex & GetInnerVertex() const 
Get the inner vertex. 
 
static int max(int a, int b)
 
std::string m_parentPfoListName
The name of the input pfo list. 
 
const pandora::CartesianVector & GetDirection() const 
Get the vertex direction. 
 
unsigned int m_halfWindowLayers
number of layers to use for half-window of sliding fit 
 
static void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z) ...
 
float m_maxVertexDisplacementFromTrack
The maximum separation of a close vertex from the cosmic ray track. 
 
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
 
static bool IsFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a primary parent particle. 
 
static void GetAllDownstreamPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively, of all daughters associated with those pfos in an input lis...
 
void GetCosmicPfos(const pandora::PfoList *const pPfoList, pandora::PfoVector &pfoVector) const 
Get the list of input pfos to this algorithm. 
 
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
 
static pandora::CartesianVector GetClosestPosition(const pandora::CartesianVector &position, const pandora::ClusterList &clusterList)
Get closest position in a list of clusters to a specified input position vector. 
 
void BuildCosmicRayDaughter(const pandora::ParticleFlowObject *const pPfo) const 
Reconstruct the vertex and direction of a daughter cosmic-ray Pfo. 
 
void BuildPointingClusterMap(const pandora::PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const 
Build a map of 3D sliding fits from the input Pfos. 
 
std::list< Vertex > VertexList
 
const pandora::CartesianVector & GetPosition() const 
Get the vertex position. 
 
QTextStream & endl(QTextStream &s)