LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
lar_content::LArGraph Class Reference

LArGraph class. More...

#include "LArGraph.h"

Classes

class  Edge
 

Public Types

typedef std::vector< const Edge * > EdgeVector
 

Public Member Functions

 LArGraph (const bool fullyConnect=true, const int nSourceEdges=2, const float maxSecondaryCosine=0.996f, const float maxSecondaryDistance=3.f)
 Constructor. More...
 
 ~LArGraph ()
 Destructor. More...
 
const EdgeVectorGetEdges () const
 Retrieve the edges for this graph. More...
 
void MakeGraph (const pandora::CaloHitList &caloHitList)
 Construct a graph from a list of calo hits. More...
 
void Walk (const pandora::CaloHit *const pCaloHit, const HitEdgeMap &hitToEdgesMap, pandora::CaloHitList &graph, HitUseMap &connectedHits) const
 Walk along node edges to define a connected graph. More...
 

Private Types

typedef std::map< const pandora::CaloHit *, EdgeVectorHitEdgeMap
 
typedef std::map< const pandora::CaloHit *, pandora::CaloHitList > HitConnectionsMap
 
typedef std::map< const pandora::CaloHit *, bool > HitUseMap
 

Private Member Functions

void IdentifyDisconnectedRegions (const HitEdgeMap &hitToEdgesMap, HitConnectionsMap &graphs) const
 Identify the different disconnected sub graphs in a set of eges. More...
 
void ConnectRegions (const HitConnectionsMap &graphs, HitEdgeMap &hitToEdgesMap)
 Identify the different disconnected sub graphs in a set of eges. More...
 
void Vectorize (const pandora::CaloHitList &caloHitList, Eigen::MatrixXf &hitMatrix) const
 Convert a list of calo hits into an Eigen matrix. More...
 

Private Attributes

EdgeVector m_edges
 The edges defining the graph. More...
 
bool m_fullyConnect
 Whether or not to connect any disconnected regions. More...
 
int m_nSourceEdges
 The number of edges to consider emerging from a source. More...
 
float m_maxSecondaryCosine
 The number of edges to consider emerging from a source. More...
 
float m_maxSecondaryDistance
 The number of edges to consider emerging from a source. More...
 

Detailed Description

LArGraph class.

Definition at line 21 of file LArGraph.h.

Member Typedef Documentation

typedef std::vector<const Edge *> lar_content::LArGraph::EdgeVector

Definition at line 57 of file LArGraph.h.

typedef std::map<const pandora::CaloHit *, pandora::CaloHitList> lar_content::LArGraph::HitConnectionsMap
private

Definition at line 61 of file LArGraph.h.

typedef std::map<const pandora::CaloHit *, EdgeVector> lar_content::LArGraph::HitEdgeMap
private

Definition at line 60 of file LArGraph.h.

typedef std::map<const pandora::CaloHit *, bool> lar_content::LArGraph::HitUseMap
private

Definition at line 62 of file LArGraph.h.

Constructor & Destructor Documentation

lar_content::LArGraph::LArGraph ( const bool  fullyConnect = true,
const int  nSourceEdges = 2,
const float  maxSecondaryCosine = 0.996f,
const float  maxSecondaryDistance = 3.f 
)

Constructor.

Parameters
fullyConnectWhether or not to connect disconnected regions
nSourceEdgesThe number of edges emerging from a source node
maxSecondaryCosineThe maximum cosine of the opening angle between non-primary edges with the same source hit
maxSecondaryDistanceThe maximum distance for a non-primary edge between hits

Definition at line 20 of file LArGraph.cc.

References m_maxSecondaryCosine, m_maxSecondaryDistance, and m_nSourceEdges.

20  :
21  m_fullyConnect{fullyConnect},
22  m_nSourceEdges{nSourceEdges},
23  m_maxSecondaryCosine{maxSecondaryCosine},
24  m_maxSecondaryDistance{maxSecondaryDistance}
25 {
26 }
int m_nSourceEdges
The number of edges to consider emerging from a source.
Definition: LArGraph.h:131
float m_maxSecondaryCosine
The number of edges to consider emerging from a source.
Definition: LArGraph.h:132
float m_maxSecondaryDistance
The number of edges to consider emerging from a source.
Definition: LArGraph.h:133
bool m_fullyConnect
Whether or not to connect any disconnected regions.
Definition: LArGraph.h:130
lar_content::LArGraph::~LArGraph ( )

Destructor.

Definition at line 30 of file LArGraph.cc.

References m_edges.

31 {
32  for (const Edge *pEdge : m_edges)
33  delete pEdge;
34 }
boost::graph_traits< ModuleGraph >::edge_descriptor Edge
Definition: ModuleGraph.h:24
EdgeVector m_edges
The edges defining the graph.
Definition: LArGraph.h:129

Member Function Documentation

void lar_content::LArGraph::ConnectRegions ( const HitConnectionsMap graphs,
HitEdgeMap hitToEdgesMap 
)
private

Identify the different disconnected sub graphs in a set of eges.

Parameters
graphsthe map between a root calo hit and all connected hits
hitToEdgesMapthe (updatable) map from calo hits to edges

Definition at line 174 of file LArGraph.cc.

References lar::dump::array(), util::begin(), util::end(), m_edges, and Vectorize().

Referenced by MakeGraph().

175 {
176  std::map<int, std::vector<int>> connectedGraphMap;
177  int i{0}, idx1{0}, idx2{0};
178  for (const auto &[pCaloHit1, caloHitList1] : graphs)
179  {
180  ++i;
181  Eigen::MatrixXf subGraphMatrix(caloHitList1.size(), 2);
182  this->Vectorize(caloHitList1, subGraphMatrix);
183  float closestApproach{std::numeric_limits<float>::max()};
184  const CaloHit *pClosestHit1{nullptr};
185  const CaloHit *pClosestHit2{nullptr};
186  int j{0};
187  for (const auto &[pCaloHit2, caloHitList2] : graphs)
188  {
189  ++j;
190  auto begin{connectedGraphMap[i].begin()}, end{connectedGraphMap[i].end()};
191  if (pCaloHit1 == pCaloHit2 || std::find(begin, end, j) != end)
192  continue;
193  for (const CaloHit *const pCaloHit : caloHitList2)
194  {
195  const CartesianVector &pos{pCaloHit->GetPositionVector()};
196  Eigen::RowVectorXf row(2);
197  row << pos.GetX(), pos.GetZ();
198  Eigen::MatrixXf norms((subGraphMatrix.rowwise() - row).array().pow(2).rowwise().sum());
199  Eigen::Index index;
200  float val{norms.col(0).minCoeff(&index)};
201  if (val < closestApproach)
202  {
203  auto iter{caloHitList1.begin()};
204  std::advance(iter, index);
205  pClosestHit1 = *iter;
206  pClosestHit2 = pCaloHit;
207  closestApproach = val;
208  idx1 = i;
209  idx2 = j;
210  }
211  }
212  }
213  if (pClosestHit1 && pClosestHit2)
214  {
215  const Edge *pEdge{new Edge(pClosestHit1, pClosestHit2)};
216  this->m_edges.emplace_back(pEdge);
217  hitToEdgesMap[pEdge->m_v0].emplace_back(pEdge);
218  hitToEdgesMap[pEdge->m_v1].emplace_back(pEdge);
219  connectedGraphMap[idx1].emplace_back(idx2);
220  connectedGraphMap[idx2].emplace_back(idx1);
221  }
222  }
223 }
boost::graph_traits< ModuleGraph >::edge_descriptor Edge
Definition: ModuleGraph.h:24
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:250
EdgeVector m_edges
The edges defining the graph.
Definition: LArGraph.h:129
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
void Vectorize(const pandora::CaloHitList &caloHitList, Eigen::MatrixXf &hitMatrix) const
Convert a list of calo hits into an Eigen matrix.
Definition: LArGraph.cc:227
const LArGraph::EdgeVector & lar_content::LArGraph::GetEdges ( ) const

Retrieve the edges for this graph.

Returns
The edges for this graph

Definition at line 38 of file LArGraph.cc.

References m_edges.

39 {
40  return this->m_edges;
41 }
EdgeVector m_edges
The edges defining the graph.
Definition: LArGraph.h:129
void lar_content::LArGraph::IdentifyDisconnectedRegions ( const HitEdgeMap hitToEdgesMap,
HitConnectionsMap graphs 
) const
private

Identify the different disconnected sub graphs in a set of eges.

Parameters
hitToEdgesMapthe input maps from calo hits to edges
graphsthe output map between a root calo hit and all connected hits

Definition at line 153 of file LArGraph.cc.

References Walk().

Referenced by MakeGraph().

154 {
155  HitUseMap connectedHits;
156  for (const auto &[pCaloHit, assocEdges] : hitToEdgesMap)
157  {
158  if (connectedHits.find(pCaloHit) != connectedHits.end())
159  continue;
160  graphs[pCaloHit] = CaloHitList{pCaloHit};
161  connectedHits[pCaloHit] = true;
162  for (const Edge *const edge : assocEdges)
163  {
164  if (pCaloHit == edge->m_v0)
165  this->Walk(edge->m_v1, hitToEdgesMap, graphs[pCaloHit], connectedHits);
166  else
167  this->Walk(edge->m_v0, hitToEdgesMap, graphs[pCaloHit], connectedHits);
168  }
169  }
170 }
std::map< const pandora::CaloHit *, bool > HitUseMap
Definition: LArGraph.h:62
boost::graph_traits< ModuleGraph >::edge_descriptor Edge
Definition: ModuleGraph.h:24
void Walk(const pandora::CaloHit *const pCaloHit, const HitEdgeMap &hitToEdgesMap, pandora::CaloHitList &graph, HitUseMap &connectedHits) const
Walk along node edges to define a connected graph.
Definition: LArGraph.cc:135
void lar_content::LArGraph::MakeGraph ( const pandora::CaloHitList &  caloHitList)

Construct a graph from a list of calo hits.

Parameters
caloHitListthe calo hit list containing the hits from which to construct a graph

Definition at line 45 of file LArGraph.cc.

References lar::dump::array(), ConnectRegions(), IdentifyDisconnectedRegions(), m_edges, m_fullyConnect, m_maxSecondaryCosine, m_maxSecondaryDistance, m_nSourceEdges, fhicl::other, r, and Vectorize().

46 {
47  Eigen::MatrixXf hitMatrix(caloHitList.size(), 2);
48  this->Vectorize(caloHitList, hitMatrix);
49  // Edges can be double-counted, so use map of maps to avoid this
50  std::map<const CaloHit *, std::map<const CaloHit *, bool>> edgeMap;
51  for (int r = 0; r < hitMatrix.rows(); ++r)
52  {
53  Eigen::RowVectorXf row(2);
54  row << hitMatrix(r, 0), hitMatrix(r, 1);
55  Eigen::MatrixXf norms((hitMatrix.rowwise() - row).array().pow(2).rowwise().sum());
56  norms(r, 0) = std::numeric_limits<float>::max();
57  Eigen::Index index;
58  norms.col(0).minCoeff(&index);
59  auto iter0{caloHitList.begin()};
60  std::advance(iter0, r);
61  auto iter1{caloHitList.begin()};
62  std::advance(iter1, index);
63  edgeMap[*iter0][*iter1] = true;
64  edgeMap[*iter1][*iter0] = true;
65  norms(index, 0) = std::numeric_limits<float>::max();
66  // Create a limited number of additional edges within a maximum distance and avoiding colinearity with existing edges
67  int nEdges{1};
68  CartesianPointVector sourceEdges({((*iter1)->GetPositionVector() - (*iter0)->GetPositionVector()).GetUnitVector()});
69  for (int i = 1; i <= std::min(2 * this->m_nSourceEdges, 5 + this->m_nSourceEdges); ++i)
70  {
71  if (nEdges >= this->m_nSourceEdges)
72  break;
73  auto val{norms.col(0).minCoeff(&index)};
74  if (val > this->m_maxSecondaryDistance)
75  continue;
76  auto iter2{caloHitList.begin()};
77  std::advance(iter2, index);
78  norms(index, 0) = std::numeric_limits<float>::max();
79  const CartesianVector &vec{((*iter2)->GetPositionVector() - (*iter0)->GetPositionVector()).GetUnitVector()};
80  bool notColinear{true};
81  for (const CartesianVector &other : sourceEdges)
82  {
83  if (vec.GetDotProduct(other) > m_maxSecondaryCosine)
84  {
85  notColinear = false;
86  break;
87  }
88  }
89  if (notColinear)
90  {
91  sourceEdges.emplace_back(vec);
92  edgeMap[*iter0][*iter2] = true;
93  edgeMap[*iter2][*iter0] = true;
94  ++nEdges;
95  }
96  }
97  }
98  std::map<const CaloHit *, std::map<const CaloHit *, bool>> usedEdges;
99  for (const auto &[pCaloHit1, map] : edgeMap)
100  {
101  for (const auto &[pCaloHit2, dummy] : map)
102  {
103  if (usedEdges.find(pCaloHit1) != usedEdges.end())
104  {
105  std::map<const CaloHit *, bool> &innerMap{usedEdges[pCaloHit1]};
106  if (innerMap.find(pCaloHit2) != innerMap.end())
107  continue;
108  }
109  usedEdges[pCaloHit1][pCaloHit2] = true;
110  usedEdges[pCaloHit2][pCaloHit1] = true;
111  this->m_edges.emplace_back(new Edge(pCaloHit1, pCaloHit2));
112  }
113  }
114  if (m_fullyConnect)
115  {
116  HitEdgeMap hitToEdgesMap;
117  for (const Edge *const pEdge : this->m_edges)
118  {
119  hitToEdgesMap[pEdge->m_v0].emplace_back(pEdge);
120  hitToEdgesMap[pEdge->m_v1].emplace_back(pEdge);
121  }
122  HitConnectionsMap graphs;
123  this->IdentifyDisconnectedRegions(hitToEdgesMap, graphs);
124  while (graphs.size() > 1)
125  {
126  this->ConnectRegions(graphs, hitToEdgesMap);
127  graphs.clear();
128  this->IdentifyDisconnectedRegions(hitToEdgesMap, graphs);
129  }
130  }
131 }
int m_nSourceEdges
The number of edges to consider emerging from a source.
Definition: LArGraph.h:131
TRandom r
Definition: spectrum.C:23
float m_maxSecondaryCosine
The number of edges to consider emerging from a source.
Definition: LArGraph.h:132
boost::graph_traits< ModuleGraph >::edge_descriptor Edge
Definition: ModuleGraph.h:24
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:250
void ConnectRegions(const HitConnectionsMap &graphs, HitEdgeMap &hitToEdgesMap)
Identify the different disconnected sub graphs in a set of eges.
Definition: LArGraph.cc:174
float m_maxSecondaryDistance
The number of edges to consider emerging from a source.
Definition: LArGraph.h:133
EdgeVector m_edges
The edges defining the graph.
Definition: LArGraph.h:129
std::map< const pandora::CaloHit *, pandora::CaloHitList > HitConnectionsMap
Definition: LArGraph.h:61
void IdentifyDisconnectedRegions(const HitEdgeMap &hitToEdgesMap, HitConnectionsMap &graphs) const
Identify the different disconnected sub graphs in a set of eges.
Definition: LArGraph.cc:153
void Vectorize(const pandora::CaloHitList &caloHitList, Eigen::MatrixXf &hitMatrix) const
Convert a list of calo hits into an Eigen matrix.
Definition: LArGraph.cc:227
std::map< const pandora::CaloHit *, EdgeVector > HitEdgeMap
Definition: LArGraph.h:60
bool m_fullyConnect
Whether or not to connect any disconnected regions.
Definition: LArGraph.h:130
void lar_content::LArGraph::Vectorize ( const pandora::CaloHitList &  caloHitList,
Eigen::MatrixXf &  hitMatrix 
) const
private

Convert a list of calo hits into an Eigen matrix.

Parameters
caloHitListthe calo hit list containing the hits from which to construct a graph
hitMatrixthe output Eigen matrix

Definition at line 227 of file LArGraph.cc.

Referenced by ConnectRegions(), and MakeGraph().

228 {
229  int i{0};
230  for (const CaloHit *const pCaloHit : caloHitList)
231  {
232  const CartesianVector &pos{pCaloHit->GetPositionVector()};
233  hitMatrix(i, 0) = pos.GetX();
234  hitMatrix(i, 1) = pos.GetZ();
235  ++i;
236  }
237 }
void lar_content::LArGraph::Walk ( const pandora::CaloHit *const  pCaloHit,
const HitEdgeMap hitToEdgesMap,
pandora::CaloHitList &  graph,
HitUseMap connectedHits 
) const

Walk along node edges to define a connected graph.

Parameters
pCaloHitthe root calo hit of the current subgraph
hitToEdgesMapthe map of hits to the edges for which they are a vertex
graphthe current graph to be augmented
connectedHitsthe map of hits in use

Definition at line 135 of file LArGraph.cc.

Referenced by IdentifyDisconnectedRegions().

136 {
137  if (connectedHits.find(pRootCaloHit) != connectedHits.end())
138  return;
139  graph.emplace_back(pRootCaloHit);
140  connectedHits[pRootCaloHit] = true;
141  const EdgeVector &assocEdges{hitToEdgesMap.at(pRootCaloHit)};
142  for (const Edge *const edge : assocEdges)
143  {
144  if (pRootCaloHit == edge->m_v0)
145  this->Walk(edge->m_v1, hitToEdgesMap, graph, connectedHits);
146  else
147  this->Walk(edge->m_v0, hitToEdgesMap, graph, connectedHits);
148  }
149 }
boost::graph_traits< ModuleGraph >::edge_descriptor Edge
Definition: ModuleGraph.h:24
std::vector< const Edge * > EdgeVector
Definition: LArGraph.h:57
void Walk(const pandora::CaloHit *const pCaloHit, const HitEdgeMap &hitToEdgesMap, pandora::CaloHitList &graph, HitUseMap &connectedHits) const
Walk along node edges to define a connected graph.
Definition: LArGraph.cc:135

Member Data Documentation

EdgeVector lar_content::LArGraph::m_edges
private

The edges defining the graph.

Definition at line 129 of file LArGraph.h.

Referenced by ConnectRegions(), GetEdges(), MakeGraph(), and ~LArGraph().

bool lar_content::LArGraph::m_fullyConnect
private

Whether or not to connect any disconnected regions.

Definition at line 130 of file LArGraph.h.

Referenced by MakeGraph().

float lar_content::LArGraph::m_maxSecondaryCosine
private

The number of edges to consider emerging from a source.

Definition at line 132 of file LArGraph.h.

Referenced by LArGraph(), and MakeGraph().

float lar_content::LArGraph::m_maxSecondaryDistance
private

The number of edges to consider emerging from a source.

Definition at line 133 of file LArGraph.h.

Referenced by LArGraph(), and MakeGraph().

int lar_content::LArGraph::m_nSourceEdges
private

The number of edges to consider emerging from a source.

Definition at line 131 of file LArGraph.h.

Referenced by LArGraph(), and MakeGraph().


The documentation for this class was generated from the following files: