pkgs/ClusterMakerSS (NOvA offline)

  • Input: rb::Cluster (default) or rb::CellHit. Will use the full hitlist if no clusters are found first time through the producer module.
  • Output: a list of rb::Cluster, separated by views




MakeClusterSS is a module to do a first pass at 2D clustering. The default configuration is provided in .fcl. Typical usage:

<node module="MakeClusterSS" config="default" ana="0" reco="1"/>

There is an Ana() implemented, which will print out the clusters found in Reco().

The 2d Cluster reconstruction can be run on any MC file from /nova/data/mc using a single job as follows:

% ana -x makeclusters.xml -n ### -i mcfile.root -o cluster.root

which runs CalHit and the Slicer for you. The resulting clusters are saved in the Reco() folder in SSClusterX or SSClusterY depending on the view.

The package currently has the following configurable parameters:

Name Type Default Description
PrintLevel int 0 0 prints only the bare minimum, 1 prints a LOT more
RunOverSlices bool true True means run over slices. False will run over all CellHits in Cal(). If no slices are found the first time through Reco(), the code will revert to running over all CellHits for the rest of the job
SliceDir string "./Slices/" which directory to find slices
CellHitPHThresh double 0. A threshold on CellHit PECorr values, below which Hits will not be considered for clustering
LongWindowMipCut double 0. PulseHeight threshold for determining what is a longitudnal gap. Despite the name, the cut is made on summed PECorr in a plane.
LongWindowGapPlaneCut int 3 Length of a gap before a longitudnal window is terminated
UseAlexHough bool true Use the new Hough Algorithm defined in Utilities/HoughCalc
SetWidthTolerance double 1.0 Define the width tolerance for a good Hough solution when it gets checked in CheckCurrSoln. Only used with the AlexHough
SecondGuessAlexHough bool true If true, check the solution from Hough Algorithm (CheckCurrSoln) and remove planes from the Hough Cluster. Only works if using the AlexHough.
AlexHoughThresh double 0. Gets passed to Utilities::HoughCalc. If a weight is below this threshold, it isn't used the the Houghing.
AlexHoughGoodScore double 2.1 Define a good AlexHough find.
UseAlexHoughPH bool true If true, use pulseheight weighing in AlexHough
AlexHoughRVal double 4.0 Determine how far a point can be from the AlexHoughLine to be included in a AlexHoughCluster
SlopeTooBig double 1.4 Threshold over which the AlexHough Slope is too large to be a real cluster
MinHoughPlanes int 5 Minimum number of planes found by Hough to be a good cluster. Only used by old Hough code, will be phased out.
MinHoughPH double 1.0 minimum ph in cluster for hough to call it good. Only used by old Hough code, will be phased out.
BestHoughMaxPHFrac double 0.75 I don't really know what this one does. Only used by old Hough code, will be phased out.
MaxHoughIter int 5 number of times you want to try houghing. Only used by old Hough code, will be phased out.

Technical description

The producer module does the following:

  • If running over slices, loop over slices
    • Get a list of CellHits (either the total hitlist, or from a Slice)
    • Split list of CellHits into X and Y views
    • Loop over views
      • "DoCluster" until you fail to find a new cluster or you run out of cell hits:
DoCluster() does the following:
  • Groups CellHits by plane
  • Finds the boundary of an appropriate longitudinal window by looking for gaps
  • Clusters Cells within each plane in the longitudinal window to make transverse windows
  • Clusters transverse windows within a plane with windows in nearby planes to build up a cluster.

Transverse windows are made in each plane using code in MakePlaneClusters. Windows are defined by an upper and lower boundary. Upper(lower) edges of windows are defined either by a Cell that has no signal in the Cell above(below) or by a cell that has less pulseheight in it than either of its neighbors (in which case, that current cell becomes both upper and lower edge of different windows). Transverse windows in a plane are clustered with windows in nearby planes using a Hough Transform (or another fall through case if the Hough Transform fails).

The proto-cluster from the Hough Transform is "checked" in CheckCurrSoln. If the center of the transverse window in a given plane is too far away from the expected position, as given by the Hough slope, the transverse window is removed from the proto-cluster. After windows are removed, we try to add new windows to the protocluster in TryRefill. In TryRefill, we step through planes in the proto-cluster that do not have a transverse window. We consider the left over transverse windows for a given plane to see if they are close enough to the transverse windows in the planes adjacent to the candidate plane. If so, they get added to the proto-cluster (in TryRefill, we are doing a local comparison, instead of a global comparison to the whole proto-cluster).

CellHits that are within the transverse windows that were a part of the proto-cluster are added to the real Cluster and removed from the master list of Cells. If we found a cluster, we go around again, this time with the smaller master list of Cells.

Using MakeClusterSS to make 3D prongs

To create 3D prongs run prongmergejob.fcl.
The chain of modules in this code are calhit -> slicer -> makeclusterss -> clustermerge -> prongmerge
The configurable parameters are in the corresponding .fcl files.


  • Takes the 2D clusters produced by MakeClusterSS as input
  • Sorts all the clusters in a view by size from larges to smallest
  • A loop is then performed over all clusters defined as "large", which is currently greater then 3 hits
    • First the largest remaining cluster is fit with a line, and is a candidate to absorb smaller clusters.
    • Then the smaller clusters are looped over, so that each one in turn is compared with the candidate.
    • To determine if a merge is acceptable we take the chi2 of both clusters together fitted to a line, and subtract the chi2 of each cluster individually. So if adding a new cluster does not significantly alter the linefit (this is an adjustable parameter called Goodness) then the merge is allowed.
      *When large clusters are compared to clusters with 1 or 2 hits the merge is allowed as long as the hit is less then 10 cm from the line.
      *Candidates for merging have to have at least 1 cell that is within 12 planes of eachother
  • After the merging is complete, these clusters are turned into 2D prongs
    *The module produces 2D prongs and 2D clusters


  • Takes the 2D tracks produced by ClusterMerge as input.
  • Builds an array of all possible matches between xz and yz tracks.
    • For each possible combination a score is created.
    • This score adds up the difference in start position, stop position and chi2 between the two tracks.
  • Then in order starting with the lowest score the 2D tracks are merged to 3D tracks.
  • This module then produces 3D tracks