My favorites | Sign in
Project Home Wiki Issues Source
READ-ONLY: This project has been archived. For more information see this post.
Search
for
sPHENIX_tutorial  
Basic information useful for those working on sPHENIX
Updated Mar 24, 2014 by alan.d...@gmail.com

example code

test_sPHENIX.cpp provides an example of running the helixhough tracking over simulated data. This particular program runs over toy MC files generated by fastTrackMC, which is included in the svn repository.

Classes to be used for sPHENIX tracking

SimpleHit3D

SimpleHit3D is the basic representation of a detector hit for the helixhough package. It contains x,y,z positions and uncertainties, a detector layer (counting starts at 0), and a unique index.

SimpleTrack3D

SimpleTrack3D contains information about reconstructed tracks. It stores a vector of SimpleHit3D for a track, the 5 helix parameters, and a unique index.

HelixResolution

HelixResolution contains, for each of the 5 helix parameters, the maximum resolution (minimum value) that the hough transform will try to distinguish. This is passed to each instance of the HelixHough class

HelixRange

HelixRange contains, for each helix parameter, a minimum and maximum value between which the hough transform will search for tracks.

sPHENIXTracker

sPHENIXTracker, which derives from HelixHough, is the class which actually performs the pattern recognition. It implements HelixHough::findTracks to do combinatorial tracking on groups of hits passed from the hough transform routines, and fits tracks using a Kalman Filter.

VertexFitFunc

VertexFitFunc represents a function to be minimized in order to find the collision vertex. It derives from the FitNewton::FunctionGradHessian class from fitnewton.

Overview of how the sPHENIX tracking works

The basic philosophy of the helixhough package is to use a recursive hough transform to find small groups of hits which are likely to contains tracks, and then pass those groups of hits to another tracking routine to actually find and fit the tracks. In the case that the second routine simply calls each group of hits a track, the algorithm performs like a standard hough transform. However, interaction of particles with the detector renders the helical tracks model incomplete, and in the limit of few, thick layers (like that proposed for sPHENIX), further evaluation past the level of a hough transform is needed.

The sPHENIXTracker class is also written to have the option of doing the tracking in two stages, and this option has so far given better runtime speed for the default sPHENIX geometry. In the first stage, tracks are found using the inner 4 layers only. In the second stage, those tracks are combined with hits from the outer layers to make further tracks. This approach has a few advantages :

  • Since the outer layers may be (and are by default) far away from the inner 4 layers, multiple scattering in the inner layers leads to a large spatial distance between the actual and expected position of a hit in the outer layers. For low momentum tracks, the Hough transform would have to stop with low resolution in order to find tracks.
  • The outer layers have very poor resolution in the z direction, so the Hough voting performs qualitatively differently for these hits
  • This allows simultaneous evaluation of tracking performance with and without additional layers

Vertex finding

Vertexing works by minimizing a function of reconstructed tracks. However, it is good to have a vertex before tracking. The recommended way around this circular problem is to perform tracking with very loose constraints on the vertex position until a specified number of tracks have been found, and using those tracks to find the vertex. After further tracking is done, the vertex can be found even more precisely. When a target number of tracks to be found is given to an instance of HelixHough, the class attempts to find that that number of tracks uniformly distributed in angular space.

Helix Parameters

The helix parameters used by the Hough Transform are

  • phi : the angle at which a track reaches its distance of closest approach to the origin
  • d : the distance of closest approach of the track to the vertex in 2D. Negative values indicate that the track surrounds the origin in 2D space
  • kappa : the curvature of the track in 2D space
  • z0 : the z-value at the DCA in 2D space.
  • dzdl : the rate of change of the z coordinate of the track with respect to the path length of the track

The color-coded image below shows the parameters in 2D space, and also explains a bit of how the hough voting works.

A Walkthrough of an Example Tracking Routine

test_sPHENIX.cpp provides a basic example of running the tracking. In this example, no vertex finding is performed, and a vertex is implicitly assumed to be at 0,0,0. This is by no means necessary, but this example is meant to be as simple as possible.

The range of helix parameters which will be considered by the hough transform needs to be decided. This information is encapsulated by the class HelixRange. In the code below, all phi are considered, tracks with d and z0 in between += 1 mm are considered, dzdl between +- 0.9 is considered, and tracks with kappa between 0 and 0.03 cm-1 are considered :

float kappa_max = 0.03;
float rho_max = pow(kappa_max,1.);
// the parameter order is phi,d,kappa,dzdl,z0
HelixRange top_range(0.,2.*M_PI,   -0.1, 0.1,   0.0, rho_max, -0.9, 0.9,   -0.1, 0.1);

A HelixHough instance requires a recursive binning strategy. One way to specify this is with a vector<vector<unsigned int> > which specifies how many bins to use for each of the 5 helix parameters at each recursion level. For example

vector<unsigned int> onezoom(5,0);
vector<vector<unsigned int> > zoomprofile;
zoomprofile.assign(6,onezoom);
// the parameter order is phi,d,kappa,dzdl,z0
for(unsigned int i=0;i<=2;++i)
{
  zoomprofile[i][0] = 5;
  zoomprofile[i][1] = 1;
  zoomprofile[i][2] = 2;
  zoomprofile[i][3] = 4;
  zoomprofile[i][4] = 1;
}

Here, there are a maximum of 6 recursion steps. At each step, the phi variable is split into 5 bins, kappa into 2 bins, dzdl into 4 bins, and d and z0 just have one bin for all steps.

Now we can specify an instance of sPHENIXTracker, giving it a binning and parameter range, as above, as well as a minimum level of recursion to use.

sPHENIXTracker tracker(zoomprofile, 3, top_range);

In this example, the sPHENIX tracker constructed above will be used for finding track seeds from the 4 inner layers. We specify some more parameters below for the tracker below :

// only the first 4 layers are used for this tracker
tracker.setNLayers(4);
unsigned int max_hits_seed = 36;
unsigned int min_hits_seed = 4;
// no ghost rejection : that will be done after seeding
tracker.setRejectGhosts(false);
tracker.setChi2Cut(10.0);
tracker.setPrintTimings(true);
tracker.setVerbosity(1);
tracker.setCutOnDca(false);
// we want our seeds to use all 4 layers
tracker.requireLayers(4);
// don't smooth back the Kalman Filter to near the collision : since we are seeding we want the track parameters at the outer-most hit
tracker.setSmoothBack(false);

max_hits_seed and max_hits_seed will be used later when the tracking routine is actually called. This specifies that at most 36 and at least 4 hits must be in a parameter bin before any combinatorial algorithm is called on that group of hits. See the comments in the above code snippet for explanations of the other parameters set to the tracker.

Next we will set up another instance of sPHENIXTracker to add hits from the outer two layers to the seeds.

HelixRange top_range_2(0., 2.*M_PI,   -0.2, 0.2,   0.0, rho_max,   -0.9, 0.9,   -0.3, 0.3);
sPHENIXTracker tracker_seeded(zoomprofile, 3, top_range_2);
unsigned int max_hits = 36;
unsigned int min_hits = 2;
tracker_seeded.setRejectGhosts(true);
tracker_seeded.setChi2Cut(4.0);
tracker_seeded.setPrintTimings(true);
tracker_seeded.setVerbosity(1);
tracker_seeded.setCutOnDca(false);
tracker_seeded.setSmoothBack(true);

Here we have expanded the d and z0 range, to account a bit more for multiple scattering.

The next step in the tracking routine, not fully expanded here, is to read over the input file and convert the data there to a std::vector<SimpleHit3D>. Two vectors are filled, one for the first 4 layer called hits_0_3 and the other for the outer layers called hits_4_5. Each SimpleHit3D corresponds to one detector hit, or cluster of hits, and needs the following public variables filled :

  • x,y,z specify a global position for the Track in Euclidean coordinates
  • dx,dy,dz specify uncertainties on those coodinates
  • layer specifies which tracking chamber the hit lies in
  • index should be a unique global specifier for the hit

Once the input files have been converted, we can run the tracking :

vector<SimpleTrack3D> tracks_seed;
tracker.findHelices(hits_0_3, min_hits_seed, max_hits_seed, tracks_seed);
tracker_seeded.setSeedStates(tracker.getKalmanStates());

Now tracks_seed is filled with some 4-hit track candidates, and the Kalman covariance matrices for those candidates are set to the seeded tracker.

And finally, the outer layers can be added to the track candidates :

vector<SimpleTrack3D> tracks;
tracker_seeded.findSeededHelices(tracks_seed, hits_4_5, min_hits, max_hits, tracks);

tracks is a list of the final tracks for this event. The rest of the example converts the tracks to a format more suitable for output to a ROOT file.

Powered by Google Project Hosting