Class TrackClusterBuilder

Inheritance Relationships

Base Type

  • public larcv_base

Derived Types

Class Documentation

class TrackClusterBuilder : public larcv_base

Make tracks by associating clusters based on principle components.

We approach this as a graph traveral problem. We use the first principle component of the clusters to define a line segment. The ends of the line segments serve as our nodes in the graph. We have two types of edges in the graph

  • segment edges (stored in _segedge_m): that connect the end points on the same line segment
  • connection edges (stored in _connect_m): that connect end points on different line segments

We use depth-first traveral to define paths from a given segment end point, to all connected segments. When we traverse onto a new segment via a connection edge, we then must travel to the end point on the same segment via a segment edge. The method performing the traversal is the recursive function, _recursiveFollowPath().

Traversal stops when we hit a segment endpoint with no connection edges.

Also, when we traverse across a connection edge, we only do so under certain conditions. These conditions are based on the length of the edge (i.e. distance between the segment end points) and the relative direction of the segments.

Subclassed by larflow::reco::CosmicTrackBuilder, larflow::reco::NuTrackBuilder

Public Functions

TrackClusterBuilder()
virtual ~TrackClusterBuilder()
void process(larcv::IOManager &iolcv, larlite::storage_manager &ioll)

Build tracks using clusters in the event data managers.

Parameters
  • iolcv: LArCV IOManager containing event data
  • ioll: larlite storage_manager containing event data

void loadClusterLibrary(const larlite::event_larflowcluster &cluster_v, const larlite::event_pcaxis &pcaxis_v)

store given clusters and associated principle component info as Segment_t and NodePos_t

Parameters
  • cluster_v: Vector of clusters in the form of larflowcluster
  • pcaxis_v: Principle component analysis info for the clusters in cluster_v

void buildNodeConnections()

build possible connections between end points of different segments

nodes are connected as long as they are less than 100 cm from one another. we also only allow a node (i.e. segment end point) to connect to only one of the end points of another segment.

void buildTracksFromPoint(const std::vector<float> &startpoint)

Seed the tracking algorithm with a startig point.

The initial point will be used to find the closest line segment. The keypoint must be within 3 cm of the line segment, else no track(s) will be made.

From there, the depth-first traversal is run twice, once for each end point of the segment (unless one of the end points are veto’d).

Resulting track(s) are stored in _track_proposal_v.

Parameters
  • startpoint: Position in 3D to find segment that will seed track(s).

void clear()

Clears internal event data containers.

void clearProposals()

clear track proposal container _track_proposal_v

void fillLarliteTrackContainer(larlite::event_track &ev_track)

store paths we’ve found as larlite::track objects in the provided event container

We must convert a track defined as a sequence of NodePos_t instances into a larlite track for storage into the output larlite ROOT file.

Parameters
  • evout_track: Node paths stored in _track_proposal_v are stored into this container

void set_output_one_track_per_startpoint(bool output_only_one)

set flag that if true, reduces many possible paths down to one

std::string str(const Segment_t &seg)

print segment info to standatd out

Parameters
  • seg: Segment whose info. will be printed

Protected Functions

void _recursiveFollowPath(NodePos_t &node, std::vector<float> &path_dir, std::vector<NodePos_t *> &path, std::vector<const std::vector<float> *> path_dir_v, std::vector<std::vector<NodePos_t *>> &complete)

recursive function the implements depth-first graph traversal

For given node, we check possible nodes (not on the same segment) to connect to. Nodes are connected based on

  • distance between nodes
  • direction between the nodes
  • direction between the segments the two nodes sit on

If two nodes on different segments are connected, we automatically make an additional traversal to the other end of the new segment.

Descent stops on leaf nodes, defined as nodes (i.e. end points on line segments) with no valid connections.

When a leaf node is reached, we save the path of nodes to the leaf node and go up one level in the graph.

We enforce a maximum of 1000 possible completed paths to leaf nodes.

Parameters
  • node: Current Node of path
  • path_dir: Current direction of path
  • path: Sequence of node pointers along path
  • path_dir_v: Sequence of directions along all nodes on path
  • complete: Collection of paths that have reached leaf nodes

void _choose_best_paths(std::vector<std::vector<NodePos_t *>> &complete_v, std::vector<std::vector<NodePos_t *>> &filtered_v)

choose the best path among the several created after the recursive graph traversal is finished

from a given start point, several completed paths to various leaf nodes are possible and returned. from these we want to pick the “best” path from the start point to one or more of the leaf nodes.

we narrow down in phases

  • phase 1: we group completed paths by leaf segment, choosing min-dist path + paths within 20 cm of min dist
  • phase 2: we choose one path among the leaf group, by the highest fraction of the path length is from cluster segment lengths
    in other words the path with the least amount of gap connections.
  • phase 3: we choose the path with the longest length if _one_track_per_startpoint is true.

Parameters
  • complete_v: A vector containing all paths to leaf nodes from a single start point
  • filtered_v: A vector where we store all selected paths, based on several criteria

void _buildTracksFromSegments()

Make tracks from the stored collection of cluster line segments.

Intended to be used after making tracks from keypoints. Mark existing segments in paths as “used”.

Tracks are seeded with segments based on their distance to the edge of the TPC walls. The walls tested are the upstream, downstream, top and bottom. The distance to the anode and cathode are not used.

The algorithm is greedy in that, once a segment is include in a path, the segment is not allowed to a part of any other path.

Possible segments to seed the tracks are from _segment_v.

Protected Attributes

std::vector<Segment_t> _segment_v

container of segments made from larflowcluster instances

std::vector<NodePos_t> _nodepos_v

container of end points serving as nodes in our graph

std::map<std::pair<int, int>, Connection_t> _connect_m

map from _nodepos_v index to connection edge that connect end points on different segments; index is directional, index1->index2

std::map<std::pair<int, int>, Connection_t> _segedge_m

map from _nodepos_v indices to segment edge that connect end points on the same segment; index is directional, index1->index2

std::vector<std::vector<NodePos_t *>> _track_proposal_v

sequence of NodePos_t pointers, representing a track or path

bool _one_track_per_startpoint

if flag is true, reduce many possible paths down to one

struct Connection_t

represents a connection (edge) between segments (node)

Public Members

Segment_t *node

pointer to segment

int from_seg_idx

from node

int to_seg_idx

to node

int endidx

end of the segment we are connected to

float dist

distance between ends, i.e. length of connection

float cosine

cosine between segment direction and endpt-connections

float cosine_seg

cosine between two segment directions

std::vector<float> dir

direction of connection

struct NodePos_t

represents a segment end point. serves as a node.

Public Functions

NodePos_t()

Public Members

int nodeidx

node index

int segidx

segment index

bool inpath

flag indicating it is currently part of a path

bool veto

flag that if true, we skip this node when connecting paths

std::vector<float> pos

position of the node (segment end)

struct Segment_t

represents a cluster through a line segment made from the first principle component

Public Functions

Segment_t()
Segment_t(std::vector<float> &s, std::vector<float> &e)

constructor with start and end points of segment

Parameters
  • s: start point of segment
  • e: end point of segment

Public Members

const larlite::larflowcluster *cluster

pointer to cluster this segment derives from

const larlite::pcaxis *pca

pointer to principle component for the cluster instance

std::vector<float> start

start of the line segment

std::vector<float> end

end of the line segment

std::vector<float> dir

direction from start to end

std::vector<Connection_t *> con_start

pointer to Connection_t (edges) connected to the segment start point

std::vector<Connection_t *> con_end

pointer to Connection_t (edges) connected to the segment end point

float len

length of the line segment

int idx

index of the segment

bool inpath

flag indicating segment is currently part of a path

bool visited

flag indicating segment has been visited at least once