LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  October 2014

HPS-SVN October 2014

Subject:

r1342 - /java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Thu, 30 Oct 2014 15:16:15 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1719 lines)

Author: mgraham
Date: Thu Oct 30 08:16:13 2014
New Revision: 1342

Log:
Straight track fitting

Added:
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrack2DFitter.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackConfirmerExtender.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFitter.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackReconDriver.java
      - copied, changed from r1321, java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTracker.java
Removed:
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/HitOnTrackChecker.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrack.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/TrackChecker.java
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/TrackCollectionUtilities.java
Modified:
    java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFinder.java

Added: java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrack2DFitter.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrack2DFitter.java	(added)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrack2DFitter.java	Thu Oct 30 08:16:13 2014
@@ -0,0 +1,131 @@
+package org.hps.recon.tracking.nobfield;
+
+import hep.physics.matrix.SymmetricMatrix;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.helicaltrack.HelicalTrackHit;
+import org.lcsim.fit.helicaltrack.HitUtils;
+import org.lcsim.fit.helicaltrack.MultipleScatter;
+import org.lcsim.fit.line.SlopeInterceptLineFit;
+import org.lcsim.fit.line.SlopeInterceptLineFitter;
+
+/**
+ *
+ * @author mgraham
+ */
+public class StraightTrack2DFitter {
+
+    SlopeInterceptLineFitter _lfitter = new SlopeInterceptLineFitter();
+    HelicalTrackFit _fit;
+
+    /**
+     * Status of the HelicalTrackFit.
+     */
+    public enum FitStatus {
+
+        /**
+         * Successful Fit.
+         */
+        Success,
+        /**
+         * Inconsistent seed hits
+         */
+        InconsistentSeed,
+        /**
+         * s-z line fit failed.
+         */
+        SZLineFitFailed,
+        /**
+         * ZSegmentFit failed.
+         */
+        XYLineFitFailed
+    };
+
+    public void StraightTrack2DFitter() {
+
+    }
+
+    public FitStatus fit(List<HelicalTrackHit> hits) {
+        Map<HelicalTrackHit, MultipleScatter> msmap = new HashMap<HelicalTrackHit, MultipleScatter>();
+        return fit(hits, msmap, null);
+    }
+
+    public FitStatus fit(List<HelicalTrackHit> hits, Map<HelicalTrackHit, MultipleScatter> msmap, HelicalTrackFit oldfit) {
+        //  Check that we have at least 3 hits
+        boolean success = false;
+        int nhit = hits.size();
+        if (nhit < 3)
+            return FitStatus.InconsistentSeed;
+
+        //  Create the objects that will hold the fit output
+        double[] chisq = new double[2];
+        int[] ndof = new int[2];
+        double[] par = new double[5];
+        SymmetricMatrix cov = new SymmetricMatrix(5);
+
+        //  Setup for the line fit
+        double[] s = new double[nhit];
+        double[] z = new double[nhit];
+        double[] y = new double[nhit];
+        double[] x = new double[nhit];
+        double[] dz = new double[nhit];
+        double[] dy = new double[nhit];
+        Map<HelicalTrackHit, Double> smap = new HashMap<>();
+
+        //  Store the coordinates and errors for the XY line fit
+        for (int i = 0; i < nhit; i++) {
+            HelicalTrackHit hit = hits.get(i);
+            y[i] = hit.y();
+            dy[i] = HitUtils.zres(hit, msmap, oldfit);
+            double drphi_ms = 0;
+            if (msmap.containsKey(hit))
+                drphi_ms = msmap.get(hit).drphi();
+            double dyHitSq = hit.getCorrectedCovMatrix().e(1, 1);
+            dy[i] = Math.sqrt(dyHitSq + drphi_ms * drphi_ms);
+            x[i] = hit.x();
+        }
+        //  Call the line fitter and check for success
+        success = _lfitter.fit(x, y, dy, nhit);
+        if (!success)
+            return FitStatus.XYLineFitFailed;
+        SlopeInterceptLineFit xyFit = _lfitter.getFit();        
+        par[0] = xyFit.intercept();
+        par[1] = xyFit.slope();
+        cov.setElement(0, 0, Math.pow(xyFit.interceptUncertainty(), 2));
+        cov.setElement(1, 1, Math.pow(xyFit.slopeUncertainty(), 2));
+        cov.setElement(0, 1, Math.pow(xyFit.covariance(), 2));
+        chisq[0] = xyFit.chisquared();
+        ndof[0] = xyFit.ndf();
+        //  Store the coordinates and errors for the SZ line fit
+        for (int i = 0; i < nhit; i++) {
+            HelicalTrackHit hit = hits.get(i);
+            z[i] = hit.z();
+            dz[i] = HitUtils.zres(hit, msmap, oldfit); //MG  this works even in msmap is null
+            s[i] = Math.sqrt(hit.x() * hit.x() + hit.y() * hit.y());
+            smap.put(hit, s[i]);
+        }
+        //  Call the line fitter and check for success
+        success = _lfitter.fit(s, z, dz, nhit);
+        if (!success)
+            return FitStatus.SZLineFitFailed;
+        SlopeInterceptLineFit szFit = _lfitter.getFit();
+        par[3] = szFit.intercept();
+        par[4] = szFit.slope();
+        cov.setElement(3, 3, Math.pow(szFit.interceptUncertainty(), 2));
+        cov.setElement(4, 4, Math.pow(szFit.slopeUncertainty(), 2));
+        cov.setElement(3, 4, Math.pow(szFit.covariance(), 2));
+        chisq[1] = szFit.chisquared();
+        ndof[1] = szFit.ndf();        
+        par[2] = 1e-50;
+        //  Create the HelicalTrackFit for this helix
+        _fit = new HelicalTrackFit(par, cov, chisq, ndof, smap, msmap);
+        return FitStatus.Success;
+    }
+
+    public HelicalTrackFit getFit() {
+        return _fit;
+    }
+
+}

Added: java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackConfirmerExtender.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackConfirmerExtender.java	(added)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackConfirmerExtender.java	Thu Oct 30 08:16:13 2014
@@ -0,0 +1,356 @@
+/*
+ * StraightTrackConfirmerExtender.java
+ */
+package org.hps.recon.tracking.nobfield;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.helicaltrack.HelicalTrackHit;
+import org.lcsim.recon.tracking.seedtracker.HitManager;
+import org.lcsim.recon.tracking.seedtracker.MergeSeedLists;
+import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
+import org.lcsim.recon.tracking.seedtracker.SeedLayer;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.SortHits;
+import org.lcsim.recon.tracking.seedtracker.SortLayers;
+import org.lcsim.recon.tracking.seedtracker.diagnostic.ISeedTrackerDiagnostics;
+
+/**
+ * The StraightTrackConfirmerExtender class attempts to add hits to an input seed.  While the
+ * algorithms used for the confirm and extend phases are identical, there are
+ * small differences in procedures when there are no more tracker layers to check.
+ * The confirm phase simply outputs a list of SeedCandidates that have at least
+ * the minimum number of confirm hits added to the track.  The extend phases
+ * completes track finding and imposes the merge criteria to eliminate inferior
+ * track candidates when a pair of candidates shares more than one hit.
+ *
+ * @author cozzy, Richard Partridge
+ * Modified for HPS straight track fitting by Matt Graham 10/29/2014
+ */
+public class StraightTrackConfirmerExtender {
+
+    public enum Task {
+
+        CONFIRM,
+        EXTEND;
+    }
+    private int _nfit;
+    private int _maxfit = 1000000000;  // initialize maximum number of fits to 10^9
+    private HitManager _hmanager;
+    private StraightTrackFitter _fitter;
+    private MergeSeedLists _merger;
+    private List<SeedCandidate> _result;
+    private ISeedTrackerDiagnostics _diag = null;
+
+
+    /**
+     * Constructor for the ConfirmerExtender class.
+     *
+     * @param hitmanager hit manager that provides access to hits sorted by layer / sector
+     * @param helixfitter helix fitter
+     */
+    public StraightTrackConfirmerExtender(HitManager hitmanager, StraightTrackFitter helixfitter) {
+
+        _hmanager = hitmanager;
+        _fitter = helixfitter;
+        _merger = new MergeSeedLists();
+    }
+
+    /**
+     * Retrieves the result of the confirmation or extension.
+     *
+     * @return result The list of confirmed/extended seeds..
+     */
+    public List<SeedCandidate> getResult() {
+
+        return _result;
+    }
+    /**
+     * Set the maximum number of fit trials for a given seed to be confirmed/extended.
+     *
+     * @param maxfit maximum number of trials
+     */
+    public void setMaxFit(int maxfit) {
+        _maxfit = maxfit;
+    }
+
+    /**
+     * Get the number of fit trials for the last confirm/extend.
+     *
+     * @return number of helix fits
+     */
+    public int getNFit() {
+        return _nfit;
+    }
+
+    /**
+     * Set the diagnostic class to be used (null for no diagnostics).
+     *
+     * @param d diagnostic class
+     */
+    public void setDiagnostics(ISeedTrackerDiagnostics d) {
+        _diag = d;
+        _merger.setDiagnostic(_diag);
+    }
+
+    /**
+     * Try to confirm a seed using a specified strategy.  The strategy specifies
+     * the layers to use in trying to confirm the seed as well as the minimum number
+     * of confirm layers that were added to the seed.  Typically, there will be a
+     * single confirm layer that is required for a seed to be confirmed.  Confirmed
+     * seeds must also pass the chisq cut and other constraints specified in the strategy.
+     *
+     * @param seed seed to be confirmed
+     * @param strategy strategy to use for confirming this seed
+     * @param bfield magnetic field
+     * @return true if seed was confirmed
+     */
+    public boolean Confirm(SeedCandidate seed, SeedStrategy strategy, double bfield) {
+
+        //  Create a list to hold the confirmed / extended seeds
+        _result = new ArrayList<SeedCandidate>();
+
+        //  Establish which layers are to be checked
+        seed.setUncheckedLayers(strategy.getLayers(SeedLayer.SeedType.Confirm));
+
+        //  Process the seed
+        doTask(seed, Task.CONFIRM, strategy, bfield);
+
+        //  Return true if we found at least one confirming seed candidate
+        return _result.size() > 0;
+    }
+
+    /**
+     * Try to extend a seed using a specified strategy.  The strategy specifies
+     * the layers to use in extending the seed as well as the minimum number of
+     * layers required for a seed to be a track candidate.  Any track candidates
+     * found as a result of the extend operation are merged with the list of
+     * track candidates found so far to eliminate inferior fits when a pair of
+     * track candidates shares more than one hit.
+     *
+     * @param seed seed to be extended
+     * @param strategy strategy to use
+     * @param bfield magnetic field
+     * @param foundseeds list of track candidates found so far
+     */
+    public void Extend(SeedCandidate seed, SeedStrategy strategy, double bfield,
+            List<SeedCandidate> foundseeds) {
+
+        //  Initialize the list of extended seed candidates to those already found
+        _result = foundseeds;
+
+        //  Establish which layers are to be checked
+        seed.setUncheckedLayers(strategy.getLayers(SeedLayer.SeedType.Extend));
+
+        //  Extend the seed and return
+        doTask(seed, Task.EXTEND, strategy, bfield);
+        return;
+    }
+
+    /**
+     * Perform the confirm or extend step.
+     *
+     * @param inputseed seed to be confirmed/extended
+     * @param task confirm or extend (enum)
+     * @param strategy strategy to use
+     * @param bfield magnetic field
+     */
+    private void doTask(SeedCandidate inputseed, Task task, SeedStrategy strategy, double bfield) {
+
+        //  Initialize the counter for the number of fits performed on this seed
+        _nfit = 0;
+
+//        //  Instantiate the fast hit checker
+//        FastCheck checker = new FastCheck(strategy, bfield, _diag);
+//        if(this._applySectorBinning) checker.setDoSectorBinCheck(this._hmanager.getSectorManager());
+
+        //  Calculate the minimum number of hits to succeed, retrieve the chisq cuts
+        int minhits = strategy.getMinHits();
+        if (task == Task.CONFIRM) minhits = strategy.getMinConfirm() + 3;
+        double badhitchisq = strategy.getBadHitChisq();
+        double maxchisq = strategy.getMaxChisq();
+
+        //  Create a LIFO queue of seeds to be searched for a confirmation/extension
+        // hit (note that a LIFO queue is used to minimize memory usage)
+        LinkedList<SeedCandidate> seedlist = new LinkedList<SeedCandidate>();
+
+        //  The bestseed is a SeedCandidate the meets the requirements for becoming
+        //  a track, shares at least one hit with the inputseed, and has been deemed
+        //  the best such seed by the track merging criteria
+        //
+        //  Initialize the best seed to null
+        SeedCandidate bestseed = null;
+        
+        //  If we have already found track candidates, check for duplicates
+        //  that share hits with the seed, finding the best such duplicate candidate.
+        for (SeedCandidate trkcand : _result) {
+            if (_merger.isDuplicate(inputseed, trkcand))
+                bestseed = findBestCandidate(trkcand, bestseed, strategy);
+        }
+
+        //  Create a map between the SeedLayers to be checked and a list of hits on the layer to check
+        Map<SeedLayer, List<HelicalTrackHit>> hitmap = new HashMap<SeedLayer, List<HelicalTrackHit>>();
+
+        //  Loop over the layers to be checked
+        for (SeedLayer lyr : inputseed.getUncheckedLayers()) {
+
+           hitmap.put(lyr, _hmanager.getTrackerHits(lyr));
+        }
+
+        //  Create a list of layers that have hits to check
+        List<SeedLayer> lyrlist = new ArrayList<SeedLayer>();
+        lyrlist.addAll(hitmap.keySet());
+
+        //  Sort the layers in order of increasing number of hits
+        SortLayers lyrsort = new SortLayers(hitmap);
+        Collections.sort(lyrlist, lyrsort);
+
+        //  Store the layers to check in the seed
+        inputseed.setUncheckedLayers(lyrlist);
+
+        //  Start with the input seed
+        seedlist.add(inputseed);
+
+        //  Keep looping until we have fully processed all seed candidates
+        while (seedlist.size() > 0) {
+
+            //  If we have exceeded the maximum number of fits, print warning and stop processing seed candidates
+            if (_nfit > _maxfit) {
+                System.out.println("Maximum number of fits exceeded in "+task.toString()+" step");
+                if (bestseed == null) {
+                    System.out.println("No track candidates are associated with the seed hits");
+                } else {
+                    System.out.println("Track candidate with "+bestseed.getHits().size()+
+                            " hits and chisq of "+bestseed.getHelix().chisqtot()+
+                            " associated with the seed hits");
+                }
+                break;
+            }
+
+            //  Pull the last seed off the queue (use a LIFO queue to minimize queue length)
+            SeedCandidate seed = seedlist.poll();
+
+            //  Check if there are enough unchecked layers to meet the minimum number of hits
+            int lyrsleft = seed.getUncheckedLayers().size();
+            int possiblehits = lyrsleft + seed.getHits().size();
+            if (possiblehits < minhits) continue;
+
+            //  If there is a best fit candidate, see if there is still a chance of beating it
+            if (bestseed != null) {
+
+                //  If the maximimum hits we can achieve is >1 fewer than the best fit, skip this candidate
+                int besthits = bestseed.getHits().size();
+                if (possiblehits < besthits - 1) continue;
+
+                //  If the maximum hits we can achieve equals the best fit, skip if we have a worse chi2
+                double chisq = seed.getHelix().chisqtot();
+                double bestchisq = seed.getHelix().chisqtot();
+                if ((possiblehits == besthits) && chisq > bestchisq) continue;
+
+                //  If the maximum hits we can achieve is 1 fewer than the best fit, skip if the bad hit criteria can't be met
+                if ((possiblehits == besthits - 1) && (chisq > bestchisq - badhitchisq)) continue;
+            }
+
+            //  See if there are any layers left for confirm/extend
+            if (lyrsleft == 0) {
+
+                //  Take final action on this seed
+                if (task == Task.CONFIRM) {
+
+                    //  No more layers and min hit requirement is met, seed is confirmed
+                    _result.add(seed);
+                    
+                } else if (task == Task.EXTEND) {
+
+                    //  Merge the seed into the list of extended seeds
+                    boolean merged = _merger.Merge(_result, seed, strategy);
+
+                    //  If the seed survived the merge, make it our new best candidate
+                    if (merged) bestseed = findBestCandidate(seed, bestseed, strategy);
+                    }
+
+                //  Done with this seed
+                continue;
+            }
+
+            //  Pull the next layer off the queue
+            SeedLayer lyr = seed.getNextLayer();
+            HelicalTrackFit helix = seed.getHelix();
+
+            //  Retrieve the chisq for the last fit and initialize the best fit chisq for this layer
+            double oldchisq = helix.chisqtot();
+            double oldcirclechisq = helix.chisq()[0];
+            double chisqbest = 1.e99;
+
+            //  Get the list of hits to check for this layer and sort them by x-y distance from current helix
+            List<HelicalTrackHit> hitlist = hitmap.get(lyr);
+            SortHits comp = new SortHits(helix);
+            Collections.sort(hitlist, comp);
+
+            //  Loop over the sorted hits in this layer
+            for (HelicalTrackHit hit : hitlist) {
+
+                //  Make a test seed including the new hit
+                SeedCandidate test = new SeedCandidate(seed);
+                test.addHit(hit);
+
+//                //  Check that this hit is potentially viable
+//                if (!checker.CheckHitSeed(hit, seed)) {
+//                    if (_diag != null) _diag.fireCheckHitFailed(hit, test);
+//                    continue;
+//                }
+
+                //  Fit the test seed
+                boolean success = _fitter.FitCandidate(test, strategy);
+                _nfit++;
+
+
+                //  Check if the fit was successful
+                if (success) {
+
+                    //  Success - attach the fit to the test seed
+                    HelicalTrackFit newhelix = _fitter.getHelix();
+                    test.setHelix(newhelix);
+
+                    //  Add the seed to the LIFO queue of seed candidates and update the best chisq
+                    seedlist.addFirst(test);
+                    chisqbest = Math.min(chisqbest, newhelix.chisqtot());
+
+                } 
+            }
+
+            //  Finished checking hits in the current layer.  If all the fit trials for
+            //  this layer are potentially bad hits, include the starting seed (less the
+            //  current layer, which was popped off the layer queue) in the seed list.
+            if (chisqbest - oldchisq > strategy.getBadHitChisq()) seedlist.addFirst(seed);
+        }
+
+        //  Finished looping over the seeds in the LIFO candidate queue - we are done!
+        return;
+    }
+
+    /**
+     * Check two track candidates and return the best one subject to the merging criteria.
+     *
+     * @param trial new candidate to try
+     * @param oldbest previous best candidate (or null if no best candidate has been found)
+     * @param strategy strategy in use
+     * @return best track candidate
+     */
+    private SeedCandidate findBestCandidate(SeedCandidate trial, SeedCandidate oldbest, SeedStrategy strategy) {
+
+        //  If the old best candidate is null, return the trial candidate
+        if (oldbest == null) return trial;
+        
+        //  If the trial candidate is better, return it
+        if (_merger.isBetter(trial, oldbest, strategy)) return trial;
+
+        //  If no improvement, return the old candidate
+        return oldbest;
+    }
+}

Modified: java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFinder.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFinder.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFinder.java	Thu Oct 30 08:16:13 2014
@@ -1,272 +1,252 @@
+/*
+ * SeedTrackFinder.java
+ *
+ * Created on January 22, 2008, 9:39 AM
+ *
+ */
 package org.hps.recon.tracking.nobfield;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
-import org.hps.recon.tracking.HitCollectionUtilites;
-import org.hps.recon.tracking.nobfield.TrackCollectionUtilities;
-import org.lcsim.event.EventHeader;
-import org.lcsim.event.Track;
-import org.lcsim.event.TrackerHit;
+import java.util.Set;
+import org.lcsim.event.MCParticle;
 import org.lcsim.fit.helicaltrack.HelicalTrackHit;
-import org.lcsim.fit.line.SlopeInterceptLineFit;
-import org.lcsim.fit.line.SlopeInterceptLineFitter;
-import org.lcsim.geometry.Detector;
-import org.lcsim.util.Driver;
+import org.lcsim.recon.tracking.seedtracker.HitManager;
+import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
+import org.lcsim.recon.tracking.seedtracker.SeedLayer;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.TrackCheck;
+import org.lcsim.recon.tracking.seedtracker.diagnostic.ISeedTrackerDiagnostics;
 
 /**
  *
- * @author mgraham
+ * @author Richard Partridge
+ * @version 1.0
  */
-public class StraightTrackFinder extends Driver {
-
-    // Debug flag.
-    private boolean debug = true;
-    // Tracks found across all events.
-    int ntracks = 0;
-    // Number of events processed.
-    int nevents = 0;
-    // Cache detector object.
-    Detector detector = null;
-    // Tracking strategies resource path.
-    private String strategyResource = "HPS-Test-4pt1.xml";
-    // Output track collection.
-    private String trackCollectionName = "StraightTracks";
-    // HelicalTrackHit input collection.
-    private String stInputCollectionName = "HelicalTrackHits";
-    // Include MS (done by removing XPlanes from the material manager results)
-    private boolean includeMS = true;
-    // number of repetitive fits on confirmed/extended tracks
-    private int _iterativeConfirmed = 3;
-    // use HPS implementation of material manager
-    private boolean _useHPSMaterialManager = true;
-
-    private TrackChecker checkerTrack = new TrackChecker();
-    private HitOnTrackChecker checkerHOT = new HitOnTrackChecker();
-
-    private SlopeInterceptLineFitter _lfitter = new SlopeInterceptLineFitter();
-
-    public void setDebug(boolean debug) {
-        this.debug = debug;
-    }
-
-    /**
-     * Set the tracking strategy resource.
-     *
-     * @param strategyResource The absolute path to the strategy resource in the
-     * hps-java jar.
-     */
-    public void setStrategyResource(String strategyResource) {
-        this.strategyResource = strategyResource;
-    }
-
-    public void setInputHitCollectionName(String inputHitCollectionName) {
-        this.stInputCollectionName = inputHitCollectionName;
-    }
-
-    public void setTrackCollectionName(String trackCollectionName) {
-        this.trackCollectionName = trackCollectionName;
-    }
-
-    public void setIncludeMS(boolean incMS) {
-        this.includeMS = incMS;
-    }
-
-    /**
-     * Set to enable the use of the HPS material manager implementation
-     *
-     * @param useHPSMaterialManager switch
-     */
-    public void setUseHPSMaterialManager(boolean useHPSMaterialManager) {
-        this._useHPSMaterialManager = useHPSMaterialManager;
-    }
-
-    @Override
-    public void detectorChanged(Detector detector) {
-        // Cache Detector object.
-        this.detector = detector;
-//        initialize();
-        super.detectorChanged(detector);
-    }
-
-    @Override
-    public void process(EventHeader event) {
-        if (!event.hasCollection(HelicalTrackHit.class, stInputCollectionName))
-            return;
-
-        List<HelicalTrackHit> allHits = event.get(HelicalTrackHit.class, stInputCollectionName);
-
-        List<List<HelicalTrackHit>> splitTopBot = HitCollectionUtilites.SplitTopBottomHits(allHits);
-        // will always have top(=0) and bottom(=1) lists (though they may be empty)
-        List<HelicalTrackHit> topHits = splitTopBot.get(0);
-        List<HelicalTrackHit> bottomHits = splitTopBot.get(1);
-        //a simple strategy...eventually implement SeedTracker strategies?
-        int nTotLayers = 6;
-        int nSeed = 3;
-        int nExtra = nTotLayers - nSeed;
-        int[] seedStrategy = {1, 3, 5};
-        int[] extendStrategy = {7, 9, 11};
-        int minHits = 4;
-
-        TrackChecker checkerTrack = new TrackChecker();
-        HitOnTrackChecker checkerHOT = new HitOnTrackChecker();
-
-//        List<StraightTrack> seeds = getSeeds(seedStrategy, topHits);
-        List<StraightTrack> seeds = getSeeds(seedStrategy, allHits);
-        System.out.println("Found " + seeds.size() + " seeds");
-
-        List<StraightTrack> extendedSeeds = new ArrayList<>();
-        for (StraightTrack seed : seeds)
-            extendTrack(extendStrategy, 0, seed, allHits, extendedSeeds);
-//            extendTrack(extendStrategy, 0, seed, topHits, extendedSeeds);
-
-        System.out.println("Prepruning  :Found " + extendedSeeds.size() + " extended seeds");
-
-        //remove tracks with more than m overlaping hits...pick best chi2
-        //...
-        List<StraightTrack> finalTracks = new ArrayList<>();
-        for (StraightTrack track : extendedSeeds) {
-            boolean isbest = TrackCollectionUtilities.pruneTrackList((ArrayList<Track>) (ArrayList) extendedSeeds, track, 1);
-            if (isbest)
-                finalTracks.add(track);
-        }
-
-        System.out.println("Postpruning  :Found " + finalTracks.size() + " extended seeds");
-        event.put(trackCollectionName, finalTracks);
-    }
-
-    public SlopeInterceptLineFit FitToLine(List<HelicalTrackHit> hits, int projection) {
-        SlopeInterceptLineFit _lfit;
-        int npix = hits.size();
-        double[] s = new double[npix];
-        double[] q = new double[npix];
-        double[] dq = new double[npix];
-
-        //  Store the coordinates and errors for the line fit
-        for (int i = 0; i < npix; i++) {
-            HelicalTrackHit hit = hits.get(i);
-            s[i] = hit.z();//probably isn't quite right...track length is not z
-            if (projection == 0) { //do x vs z;
-                q[i] = hit.x();
-                dq[i] = Math.sqrt(hit.getCorrectedCovMatrix().e(0, 0));
-            } else {
-                q[i] = hit.y();
-                dq[i] = Math.sqrt(hit.getCorrectedCovMatrix().e(1, 1));
-            }
-        }
-
-        //  Call the line fitter and check for success
-        boolean success = _lfitter.fit(s, q, dq, npix);
-
-        if (!success)
-            System.out.println("Something is broken in the line fit");
-        //  Save the line fit, chi^2, and DOF
-        _lfit = _lfitter.getFit();
-        return _lfit;
-
-    }
-
-    private StraightTrack makeTrack(List<HelicalTrackHit> hits, SlopeInterceptLineFit xfit, SlopeInterceptLineFit yfit) {
-        StraightTrack track = new StraightTrack();
-        double[] pars = {-99, -99, -99, -99, -99};//this needs to have 5 fields to implement Track
-        pars[0] = xfit.intercept();
-        pars[1] = xfit.slope();
-        pars[2] = yfit.intercept();
-        pars[3] = yfit.slope();
-        track.setTrackParameters(pars);
-        track.setChi2(xfit.chisquared(), yfit.chisquared());
-        track.setNDF(xfit.ndf()+yfit.ndf());
-        for (TrackerHit hit : hits)
-            track.addHit(hit);        
-        // TODO:  set convariance, 
-        return track;
-    }
-
-    private StraightTrack makeTrack(List<HelicalTrackHit> hits) {
-        SlopeInterceptLineFit xfit = FitToLine(hits, 0);
-        SlopeInterceptLineFit yfit = FitToLine(hits, 1);
-        if (debug)
-            System.out.println("xfit = " + xfit.toString());
-        if (debug)
-            System.out.println("yfit = " + yfit.toString());        
-        return makeTrack(hits, xfit, yfit);
-    }
-
-    /*
-     *   Get all seed combinations that make sense (pass checkSeed)
-     *   currently, just assume there are 3 seed layers (don't have to be first 3 though.  
-     */
-    private List<StraightTrack> getSeeds(int[] seedLayers, List<HelicalTrackHit> hits) {
-        List<StraightTrack> seeds = new ArrayList<>();
-        int nseeds = seedLayers.length;
-        if (nseeds == 3)//TODO ... set this up so that this works for arbitrary nseeds...use recursion
-            for (HelicalTrackHit h1 : HitCollectionUtilites.GetSortedHits(hits, seedLayers[0])) {
-                if (debug)
-                    System.out.println(h1.toString());
-                for (HelicalTrackHit h2 : HitCollectionUtilites.GetSortedHits(hits, seedLayers[1])) {
-                    if (debug)
-                        System.out.println(h2.toString());
-                    for (HelicalTrackHit h3 : HitCollectionUtilites.GetSortedHits(hits, seedLayers[2])) {
-                        if (debug)
-                            System.out.println(h3.toString());
-                        //make a 3-hit test track...see if it passes CheckTrack 
-                        List<HelicalTrackHit> testTrack = new ArrayList<HelicalTrackHit>();
-                        testTrack.add(h1);
-                        testTrack.add(h2);
-                        testTrack.add(h3);                       
-                        StraightTrack trk = makeTrack(testTrack);
-                        if (!checkerTrack.checkSeed(trk))
-                            break;
-                        seeds.add(trk);
+public class StraightTrackFinder {
+
+    private HitManager _hitmanager;
+    private StraightTrackFitter _helixfitter;
+    private StraightTrackConfirmerExtender _confirmer;
+    private List<SeedCandidate> _trackseeds;
+    private ISeedTrackerDiagnostics _diag = null;
+    private Set<MCParticle> _seededmcp;
+    private Set<MCParticle> _confirmedmcp;
+    TrackCheck _trackCheck; // set by SeedTracker
+    private boolean _debug = false;
+   
+
+    /**
+     * Creates a new instance of SeedTrackFinder
+     */
+    public StraightTrackFinder(HitManager hitmanager, StraightTrackFitter helixfitter) {
+
+        //  Save the pointers to the hit manager and helix fitter classes
+        _hitmanager = hitmanager;
+        _helixfitter = helixfitter;
+
+        //  Instantiate the Confirmer/Extender and Seed Candidate merging classes
+        _confirmer = new StraightTrackConfirmerExtender(_hitmanager, _helixfitter);
+
+        //  Create a list of track seeds that have been found
+        _trackseeds = new ArrayList<SeedCandidate>();
+
+        //  Create a set of MC Particles that have been seeded, confirmed
+        _seededmcp = new HashSet<MCParticle>();
+        _confirmedmcp = new HashSet<MCParticle>();
+
+    }
+
+    public void setDiagnostic(ISeedTrackerDiagnostics d) {
+
+        //  Setup the diagnostics for this class and the classes used by this class
+        _diag = d;
+        _confirmer.setDiagnostics(_diag);
+    }
+
+    public boolean FindTracks(SeedStrategy strategy, double bfield) {
+
+        //  Instantiate the fast hit checker
+        //   FastCheck checker = new FastCheck(strategy, bfield, _diag);
+        //   if(_applySectorBinning) checker.setDoSectorBinCheck(_hitmanager.getSectorManager());
+//        SeedSectoring ss = new SeedSectoring(_hitmanager, strategy, bfield, _applySectorBinning);
+        List<SeedLayer> seeds = strategy.getLayers(SeedLayer.SeedType.Seed);
+
+//        List<List<Sector>> sslist = ss.SeedSectors();
+//        if(_debug)
+//            System.out.println(this.getClass().getSimpleName()+": number of SeedSectors="+sslist.size());
+        //  Loop over the valid sector combinations
+        //      for (List<Sector> slist : sslist) {
+            //  Loop over the first seed layer
+        for (HelicalTrackHit hit1 : _hitmanager.getTrackerHits(seeds.get(0)))
+
+            //  Loop over the second seed layer and check that we have a hit pair consistent with our strategy
+            for (HelicalTrackHit hit2 : _hitmanager.getTrackerHits(seeds.get(1))) {
+
+                //  Call _trackCheck if set
+                if (_trackCheck != null) {
+                    SeedCandidate tempseed = new SeedCandidate(strategy, bfield);
+                    tempseed.addHit(hit1);
+                    tempseed.addHit(hit2);
+                    if (!_trackCheck.checkSeed(tempseed))
+                        continue;
+                }
+
+//                    //  Check if the pair of hits is consistent with the current strategy
+//                    if (!checker.TwoPointCircleCheck(hit1, hit2, null)) {
+//                        if (_diag != null) _diag.fireCheckHitPairFailed(hit1, hit2);
+//                        continue;
+//                    }
+                //  Loop over the third seed layer and check that we have a hit triplet consistent with our strategy
+                for (HelicalTrackHit hit3 : _hitmanager.getTrackerHits(seeds.get(2))) {
+                    //  Call _trackCheck if set
+                    if (_trackCheck != null) {
+                        SeedCandidate tempseed2 = new SeedCandidate(strategy, bfield);
+                        tempseed2.addHit(hit1);
+                        tempseed2.addHit(hit3);
+                        if (!_trackCheck.checkSeed(tempseed2))
+                            continue;
+
+                        SeedCandidate tempseed3 = new SeedCandidate(strategy, bfield);
+                        tempseed3.addHit(hit2);
+                        tempseed3.addHit(hit3);
+                        if (!_trackCheck.checkSeed(tempseed3))
+                            continue;
                     }
+
+                    //  Form a seed candidate from the seed hits
+                    SeedCandidate seed = new SeedCandidate(strategy, bfield);
+                    seed.addHit(hit1);
+                    seed.addHit(hit2);
+                    seed.addHit(hit3);
+
+//                        //  Check if the triplet of hits is consistent with the current strategy
+//                        if (!checker.ThreePointHelixCheck(hit1, hit2, hit3)) {
+//
+//                            if (_diag != null) {
+//                                if (seed.isTrueSeed())
+//                                _diag.fireCheckHitTripletFailed(hit1, hit2, hit3);
+//                            }
+//                            continue;
+//                        }
+                        //  Form a seed candidate from the seed hits
+                    //  If it's a true seed, add the MC Particle to those that were seeded
+                    if (_diag != null)
+                        if (seed.isTrueSeed())
+                            _seededmcp.addAll(seed.getMCParticles());
+
+                    if (_debug)
+                        System.out.println(this.getClass().getSimpleName() + ": fit the candidate");
+
+                    //  See if we can fit a helix to this seed candidate
+                    boolean success = _helixfitter.FitCandidate(seed, strategy);
+
+                    if (!success)
+                        continue;
+
+                    if (_debug)
+                        System.out.println(this.getClass().getSimpleName() + ": fit success");
+
+                    //  Save the helix fit
+                    seed.setHelix(_helixfitter.getHelix());
+
+                    // Check the seed - hook for plugging in external constraint
+                    if (_trackCheck != null)
+                        if (!_trackCheck.checkSeed(seed))
+                            continue;
+
+                    //  See if we can confirm this seed candidate
+                    success = _confirmer.Confirm(seed, strategy, bfield);
+                    if (!success)
+                        continue;
+
+                    if (_debug)
+                        System.out.println(this.getClass().getSimpleName() + ": confirmed seed");
+
+                    //  Confirmed a seed - if it's a true seed, add the MC Particle to those that were confirmed
+                    if (_diag != null)
+                        if (seed.isTrueSeed())
+                            _confirmedmcp.addAll(seed.getMCParticles());
+
+                    if (_debug)
+                        System.out.println(this.getClass().getSimpleName() + ": try to extend");
+
+                    //  Try to extend each confirmed seed candidates to make a track candidate
+                    List<SeedCandidate> confirmedlist = _confirmer.getResult();
+                    for (SeedCandidate confirmedseed : confirmedlist)
+
+                        //  See if we can extend this seed candidate
+                        _confirmer.Extend(confirmedseed, strategy, bfield, _trackseeds);
                 }
             }
-        return seeds;
-    }
-
-    /*
-     * recursively extend the seeds through all of the extend layers..
-     * ...I think this should work...
-     */
-    private void extendTrack(int[] extendLayers, int n, StraightTrack origTrack, List<HelicalTrackHit> hits, List<StraightTrack> trackList) {
-        if (n >= extendLayers.length) {
-            if (debug)
-                System.out.println("Done finding this track through all " + n + " extra layers");
-            trackList.add(origTrack);
-            return;
-        }
-
-        boolean cannotExtendThisLayer = true;
-        if (debug)
-            System.out.println("Extending to layer " + extendLayers[n]);
-        for (HelicalTrackHit h : HitCollectionUtilites.GetSortedHits(hits, extendLayers[n])) {
-            //let's see if this hit makes sense to add to original track
-            if (!checkerHOT.checkNewHit(origTrack, h))
-                continue;
-
-            List<TrackerHit> origHits = origTrack.getTrackerHits();
-            //make a new list and cast them as HelicalTrackHits (Track only stores TrackerHits)
-            List<HelicalTrackHit> newHits = new ArrayList<>();
-            for (TrackerHit oh : origHits) {
-                HelicalTrackHit hoh = (HelicalTrackHit) oh;
-                System.out.println(hoh.getPosition()[0]);
-                newHits.add(hoh);
-            }
-            //add the new hit to the list & make new track
-            newHits.add(h);
-            StraightTrack newTrack = makeTrack(newHits);
-            //check the new track after we've added this hit
-            if (!checkerTrack.checkTrack(newTrack))
-                continue;
-            cannotExtendThisLayer = false;
-            //extend again to the next layer
-            extendTrack(extendLayers, n + 1, newTrack, hits, trackList);
-        }
-
-        //didn't find any hits in this layer that match the track...but let's try the next one
-        if (cannotExtendThisLayer)
-            extendTrack(extendLayers, n + 1, origTrack, hits, trackList);
-
-        return;
+
+//        //  Done with track finding for this strategy
+//        if (_diag != null)
+//            _diag.fireFinderDone(_trackseeds, _seededmcp);
+        return _trackseeds.size() > 0;
+    }
+
+    /**
+     * Return the list of track candidates.
+     *
+     * @return track candidates
+     */
+    public List<SeedCandidate> getTrackSeeds() {
+        return _trackseeds;
+    }
+
+    /**
+     * Clear the list of track candidates accumulated from previous calls to
+     * SeedTrackFinder (typically done before starting a new event).
+     */
+    public void clearTrackSeedList() {
+        _trackseeds.clear();
+        _seededmcp.clear();
+        _confirmedmcp.clear();
+    }
+
+    /**
+     * Set the maximum number of fits for a given seed in a confirm or extend
+     * step.
+     *
+     * @param maxfits maximum number of fits
+     */
+    public void setMaxFit(int maxfits) {
+        _confirmer.setMaxFit(maxfits);
+    }
+
+    /**
+     * Return the list of MCParticles that formed valid 3-hit seeds.
+     *
+     * @return list of seeded MCParticles
+     */
+    public Set<MCParticle> getSeededMCParticles() {
+        return _seededmcp;
+    }
+
+    /**
+     * Return the list of confirmed MCParticles.
+     *
+     * @return confirmed MCParticles
+     */
+    public Set<MCParticle> getConfirmedMCParticles() {
+        return _confirmedmcp;
+    }
+
+    /**
+     * Return the StraightTrackConfirmerExtender
+     *
+     * @return confirmer/extender object
+     *
+     */
+    public StraightTrackConfirmerExtender getConfirmer() {
+        return _confirmer;
+    }
+
+    public void setDebug(boolean debug) {
+        System.out.println("Setting " + this.getClass().getSimpleName() + " debug to " + debug);
+        _debug = debug;
     }
 
 }

Added: java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFitter.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFitter.java	(added)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackFitter.java	Thu Oct 30 08:16:13 2014
@@ -0,0 +1,261 @@
+/*
+ * HelixFitter.java
+ *
+ * Created on January 22, 2008, 9:25 AM
+ *
+ */
+package org.hps.recon.tracking.nobfield;
+
+import java.util.List;
+import java.util.Map;
+import org.hps.recon.tracking.MaterialManager;
+import org.hps.recon.tracking.MultipleScattering;
+import org.hps.recon.tracking.nobfield.StraightTrack2DFitter.FitStatus;
+import org.lcsim.fit.circle.CircleFit;
+import org.lcsim.fit.helicaltrack.HelicalTrackCross;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.helicaltrack.HelicalTrackHit;
+import org.lcsim.fit.helicaltrack.MultipleScatter;
+import org.lcsim.fit.line.SlopeInterceptLineFit;
+import org.lcsim.fit.line.SlopeInterceptLineFitter;
+import org.lcsim.fit.zsegment.ZSegmentFit;
+import org.lcsim.recon.tracking.seedtracker.ConstrainHelix;
+import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.TrackCheck;
+import org.lcsim.recon.tracking.seedtracker.diagnostic.ISeedTrackerDiagnostics;
+
+/**
+ *
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class StraightTrackFitter {
+
+    private StraightTrack2DFitter _fitter = new StraightTrack2DFitter();
+    protected MultipleScattering _scattering;
+    private HelicalTrackFit _helix;//still use HelicalTrackFit...
+    private MaterialManager _materialmanager;
+    //private ConstrainHelix _constrain;
+    private double _bfield = 0.;
+    private CircleFit _circlefit;
+    private SlopeInterceptLineFit _linefit;
+    private ZSegmentFit _zsegmentfit;
+    private FitStatus _status;
+    private ISeedTrackerDiagnostics _diag = null;
+    TrackCheck _trackCheck; // set by SeedTracker
+    private boolean _debug = false;
+
+    /**
+     * Creates a new instance of StraightTrackFitter
+     */
+    public StraightTrackFitter(MaterialManager materialmanager) {
+        _materialmanager = materialmanager;
+
+        _scattering = new MultipleScattering(_materialmanager);
+
+        //   _constrain = new ConstrainHelix();
+    }
+
+    //   public boolean FitCandidate(SeedCandidate seed, SeedStrategy strategy) {
+    public boolean FitCandidate(SeedCandidate seed, SeedStrategy strategy) {// change this to something reasonable
+        if (_debug)
+            System.out.printf("%s: FitCandidate() with strategy: \"%s\"\n", this.getClass().getSimpleName(), strategy.getName());
+
+        //  Initialize fit results to null objects
+        _helix = null;
+
+        //  Check that we have set the magnetic field
+        if (_bfield != 0.)
+            throw new RuntimeException("B Field should be zero for the straight track fitter");
+
+        //  Set the tolerance in the fitter
+        //  _fitter.setTolerance(Math.sqrt(strategy.getMaxChisq()));
+        //  Retrieve list of hits to be fit
+        List<HelicalTrackHit> hitlist = seed.getHits();
+
+        if (_debug) {
+            System.out.println(this.getClass().getSimpleName() + ": hitlist size " + hitlist.size() + ":");
+            double z_prev = -99999999.9;
+            for (HelicalTrackHit hit : hitlist) {
+                System.out.printf("%s: (%.2f,%.2f,%.2f) corrected  %s\n",
+                        this.getClass().getSimpleName(), hit.getPosition()[0], hit.getPosition()[1], hit.getPosition()[2],
+                        hit.getCorrectedPosition().toString());
+                if (z_prev < -99999999.0)
+                    z_prev = hit.getPosition()[2];
+                else {
+                    if (Math.signum(z_prev) != Math.signum(hit.getPosition()[2]))
+                        System.out.printf("%s: topBotHits in event\n", this.getClass().getSimpleName());
+                    z_prev = hit.getPosition()[2];
+                }
+            }
+        }
+        //  Retrieve the old helix
+        HelicalTrackFit oldhelix = seed.getHelix();
+
+        //  If this is the candidate's first helix fit, first do a fit without MS errors
+        if (oldhelix == null) {
+
+            if (_debug)
+                System.out.println(this.getClass().getSimpleName() + ": no old helix do the fit without MS scattering map");
+
+            //  Reset the stereo hit positions to their nominal value
+            for (HelicalTrackHit hit : hitlist)
+                if (hit instanceof HelicalTrackCross)
+                    ((HelicalTrackCross) hit).resetTrackDirection();
+            //  Do the fit
+            _status = _fitter.fit(hitlist);
+            SaveFit();
+
+            //  Retrieve the helix parameters from this fit and save them in the seed
+            oldhelix = _fitter.getFit();
+            seed.setHelix(oldhelix);
+
+            if (_debug)
+                System.out.printf("%s: fit succeeded, will be used as seed, with chi2=%.3f and helix:\n%s \n", this.getClass().getSimpleName(), oldhelix.chisqtot(), oldhelix.toString());
+
+            //  Calculate the multiple scattering angles for this helix
+            try {
+               seed.setScatterAngles(_scattering.FindScatters(oldhelix)); 
+            } catch (Exception e) {
+               System.err.println(e);
+               if(_debug)
+               {
+                   e.printStackTrace();
+               }
+               return false;
+            }
+            
+            if(_debug) {
+                System.out.printf("%s: after calculating the MS map it has %d size:\n",this.getClass().getSimpleName(),seed.getMSMap().size());
+                for(Map.Entry<HelicalTrackHit, MultipleScatter> ms : seed.getMSMap().entrySet()) {
+                    System.out.printf("%s: Hit at layer %d and position %s has MS drpdhi=%f and dz=%f\n",
+                                    this.getClass().getSimpleName(),ms.getKey().Layer(),ms.getKey().getCorrectedPosition().toString(),ms.getValue().drphi(),ms.getValue().dz());
+                }
+            }
+
+        }
+
+        if (_debug)
+            System.out.printf("%s: update the stereo hit positions with the old helix:\n%s \n", this.getClass().getSimpleName(), oldhelix.toString());
+
+        //  Update the stereo hit positions and covariance matrices
+        CorrectStereoHits(hitlist, oldhelix);
+
+        //  Do a helix fit including MS errors
+        if(_debug) {
+            System.out.printf("%s: do the helix fit including MS map this time: \n",this.getClass().getSimpleName());
+            for(Map.Entry<HelicalTrackHit, MultipleScatter> ms : seed.getMSMap().entrySet()) {
+                    System.out.printf("%s: Hit at layer %d and position %s has MS drpdhi=%f and dz=%f\n",
+                                    this.getClass().getSimpleName(),ms.getKey().Layer(),ms.getKey().getCorrectedPosition().toString(),ms.getValue().drphi(),ms.getValue().dz());
+            }
+        }
+        _status = _fitter.fit(hitlist, seed.getMSMap(), oldhelix);
+        SaveFit();
+
+        //  Retrieve and save the new helix fit
+        _helix = _fitter.getFit();
+        seed.setHelix(_helix);
+        if ((_trackCheck != null) && (!_trackCheck.checkSeed(seed)))
+            return false;
+
+        //  Set the non-holonomic constraint chi square...don't worry about this for now-- MG 10/29/2014
+        //       _constrain.setConstraintChisq(strategy, _helix, hitlist);
+        //  If the total chi square is below the cut, we have a successful fit
+        boolean success = _helix.chisqtot() <= strategy.getMaxChisq();
+        if (!success)
+            if (_diag != null)
+                _diag.fireFailedChisqCut(seed);
+
+//        //  If fit was successful, set the new multiple scattering angles
+        if (success) {
+            seed.setScatterAngles(_scattering.FindScatters(_helix));
+            if (_debug)
+                System.out.printf("%s: this fit was successful, chi2=%f with resulting helix paramaters:\n%s\n", this.getClass().getSimpleName(), _helix.chisqtot(), _helix.toString()); //                System.out.printf("%s: updated MS map before returning from fitCandidate():\n",this.getClass().getSimpleName());       
+            //                for(Map.Entry<HelicalTrackHit, MultipleScatter> ms : seed.getMSMap().entrySet()) {
+            //                    System.out.printf("%s: Hit at layer %d and position %s has MS drpdhi=%f and dz=%f\n",
+            //                                    this.getClass().getSimpleName(),ms.getKey().Layer(),ms.getKey().getCorrectedPosition().toString(),ms.getValue().drphi(),ms.getValue().dz());
+
+        } else if (_debug)
+            System.out.printf("%s: this fit with chi2=%f failed!\n", this.getClass().getSimpleName(), _helix.chisqtot());
+
+        return success;
+    }
+
+    public void setDiagnostics(ISeedTrackerDiagnostics d) {
+        _diag = d;
+        return;
+    }
+
+    public HelicalTrackFit getHelix() {
+        return _helix;
+    }
+
+    public FitStatus getFitStatus() {
+        return _status;
+    }
+
+    public CircleFit getCircleFit() {
+        return _circlefit;
+    }
+
+    public SlopeInterceptLineFit getLineFit() {
+        return _linefit;
+    }
+
+    public ZSegmentFit getZSegmentFit() {
+        return _zsegmentfit;
+    }
+
+    public void setBField(double bfield) {
+        _bfield = bfield;
+        _scattering.setBField(_bfield);
+        //   _constrain.setBField(_bfield);
+        return;
+    }
+
+    public void setReferencePoint(double x, double y) {
+        //      _fitter.setReferencePoint(x, y);
+        return;
+    }
+
+    private void SaveFit() {
+
+        //  Default to no fit results when circle fit fails
+        _circlefit = null;
+        _linefit = null;
+        _zsegmentfit = null;
+
+        //  If we have a circle fit, try to save the line fit / zsegment fit results
+        if (_status == FitStatus.InconsistentSeed)
+            return;
+        if (_status == FitStatus.XYLineFitFailed)
+            return;
+        if (_status == FitStatus.SZLineFitFailed)
+            return;
+        //     _linefit = _fitter.getLineFit();
+//        _zsegmentfit = _fitter.getZSegmentFit();
+
+        return;
+    }
+
+    private void CorrectStereoHits(List<HelicalTrackHit> hitlist, HelicalTrackFit helix) {
+
+        //  Get the PathMap - used to find the track direction at the hit location
+        Map<HelicalTrackHit, Double> pathmap = helix.PathMap();
+
+        //  Loop over the hits and look for stereo hits
+        for (HelicalTrackHit hit : hitlist)
+            if (hit instanceof HelicalTrackCross)
+                if (pathmap.containsKey(hit)) {                   
+                    //  Found a stereo hit - calculate the track direction and pass it to the hit
+                    ((HelicalTrackCross) hit).setTrackDirection(helix);
+                }
+        return;
+    }
+
+    public void setDebug(boolean debug) {
+        this._debug = debug;
+        _scattering.setDebug(true);
+    }
+}

Copied: java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackReconDriver.java (from r1321, java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java)
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java	(original)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTrackReconDriver.java	Thu Oct 30 08:16:13 2014
@@ -1,9 +1,9 @@
-package org.hps.recon.tracking;
+package org.hps.recon.tracking.nobfield;
 
 import hep.physics.vec.BasicHep3Vector;
-
 import java.util.List;
-
+import org.hps.recon.tracking.CoordinateTransformations;
+import org.hps.recon.tracking.nobfield.StraightTracker;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.Track;
 import org.lcsim.event.base.BaseTrack;
@@ -21,7 +21,7 @@
  *
  * @author Matt Graham
  */
-public final class TrackerReconDriver extends Driver {
+public final class StraightTrackReconDriver extends Driver {
 
     // Debug flag.
     private boolean debug = false;
@@ -34,9 +34,9 @@
     // Default B-field value.
     private double bfield = 0.5;
     // Tracking strategies resource path.
-    private String strategyResource = "HPS-Test-4pt1.xml";
+    private String strategyResource = "HPS-Full.xml";
     // Output track collection.
-    private String trackCollectionName = "MatchedTracks";
+    private String trackCollectionName = "StraightTracks";
     // HelicalTrackHit input collection.
     private String stInputCollectionName = "RotatedHelicalTrackHits";
     // Include MS (done by removing XPlanes from the material manager results)
@@ -49,7 +49,7 @@
     private boolean _applySectorBinning = true;
     private double rmsTimeCut = -1;
 
-    public TrackerReconDriver() {
+    public StraightTrackReconDriver() {
     }
 
     public void setDebug(boolean debug) {
@@ -134,15 +134,15 @@
      */
     private void initialize() {
 
-        //
+        // 
         // 1) Driver to run Seed Tracker.
         //
         if (!strategyResource.startsWith("/")) {
             strategyResource = "/org/hps/recon/tracking/strategies/" + strategyResource;
         }
         List<SeedStrategy> sFinallist = StrategyXMLUtils.getStrategyListFromInputStream(this.getClass().getResourceAsStream(strategyResource));
-        SeedTracker stFinal = new SeedTracker(sFinallist, this._useHPSMaterialManager, this.includeMS);
-        stFinal.setApplySectorBinning(_applySectorBinning);
+        StraightTracker stFinal = new StraightTracker(sFinallist, this._useHPSMaterialManager, this.includeMS);
+//        stFinal.setApplySectorBinning(_applySectorBinning);
         stFinal.setUseDefaultXPlane(false);
         stFinal.setDebug(this.debug);
         stFinal.setIterativeConfirmed(_iterativeConfirmed);
@@ -156,10 +156,10 @@
         // stFinal.setSectorParams(false); //this doesn't actually seem to do anything
         stFinal.setSectorParams(1, 10000);
         add(stFinal);
-
-        if (rmsTimeCut > 0) {
-            stFinal.setTrackCheck(new HitTimeTrackCheck(rmsTimeCut));
-        }
+//
+//        if (rmsTimeCut > 0) {
+//            stFinal.setTrackCheck(new HitTimeTrackCheck(rmsTimeCut));
+//        }
     }
 
     /**

Added: java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTracker.java
 =============================================================================
--- java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTracker.java	(added)
+++ java/trunk/tracking/src/main/java/org/hps/recon/tracking/nobfield/StraightTracker.java	Thu Oct 30 08:16:13 2014
@@ -0,0 +1,328 @@
+/*
+ * SeedTracker.java
+ *
+ * Created on August 16, 2005, 8:54 AM
+ *
+ */
+package org.hps.recon.tracking.nobfield;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.*;
+import org.hps.recon.tracking.MaterialManager;
+import org.hps.recon.tracking.MaterialSupervisor;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.fit.helicaltrack.HelicalTrackHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.recon.tracking.seedtracker.DefaultStrategy;
+import org.lcsim.recon.tracking.seedtracker.HitManager;
+import org.lcsim.recon.tracking.seedtracker.MakeTracks;
+import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.TrackCheck;
+import org.lcsim.recon.tracking.seedtracker.diagnostic.ISeedTrackerDiagnostics;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * Tracking algorithm based on forming track seeds from all 3-hit combinations,
+ * confirming this tentantive helix by requiring additional hits, and extending
+ * the track to additional layers. The operation of the algorithm is controlled
+ * by a list of SeedStrategy that define the tracker layers to be used and the
+ * cuts on the tracking algorithm.
+ *
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class StraightTracker extends Driver {
+
+    protected List<SeedStrategy> _strategylist;
+    protected ISeedTrackerDiagnostics _diag = null;
+    protected MaterialManager _materialmanager = new MaterialManager();
+    protected HitManager _hitmanager;
+    protected StraightTrackFitter _helixfitter;
+    protected StraightTrackFinder _finder;
+    protected MakeTracks _maketracks;
+    protected Hep3Vector _IP = new BasicHep3Vector(0., 0., 0.);
+    protected double _bfield = 0.;
+    protected boolean _forceBField = false;
+    protected double _rtrk = 1000.;
+    protected boolean _autosectoring = false;
+    protected AIDA aida = AIDA.defaultInstance();
+    protected boolean _timing = false;
+    protected String _inputCol = "HelicalTrackHits";
+    private int _iterativeConfirmedFits = 0;
+    private boolean _debug = false;
+
+    /**
+     * Creates a new instance of SeedTracker
+     */
+    public StraightTracker() {
+        this(new DefaultStrategy().getStrategyList(), true, true);
+    }
+
+    public StraightTracker(List<SeedStrategy> strategylist, boolean includeMS) {
+        initialize(strategylist, true, includeMS);
+    }
+
+    public StraightTracker(List<SeedStrategy> strategylist, boolean useHPSMaterialManager, boolean includeMS) {
+        initialize(strategylist, useHPSMaterialManager, includeMS);
+    }
+
+    private void initialize(List<SeedStrategy> strategylist, boolean useHPSMaterialManager, boolean includeMS) {
+        _strategylist = strategylist;
+        //  Instantiate the hit manager
+        _hitmanager = new HitManager();
+        //  Instantiate the material manager for HPS,  the helix fitter and seed track finder as tey depends on the material manager
+        if (useHPSMaterialManager) {
+            MaterialSupervisor materialSupervisor = new MaterialSupervisor(includeMS);
+            _materialmanager = materialSupervisor;
+            _helixfitter = new StraightTrackFitter(materialSupervisor);
+        } else {
+            MaterialManager materialmanager = new MaterialManager(includeMS);
+            _materialmanager = materialmanager; //mess around with types here...
+            _helixfitter = new StraightTrackFitter(materialmanager);
+        }
+        //  Instantiate the Seed Finder
+        _finder = new StraightTrackFinder(_hitmanager, _helixfitter);
+        //  Instantiate the Track Maker
+        _maketracks = new MakeTracks();
+    }
+
+    /**
+     * Set to enable debug output
+     *
+     * @param debug switch
+     */
+    public void setDebug(boolean debug) {
+        _debug = true;
+        _materialmanager.setDebug(debug);
+        _helixfitter.setDebug(debug);
+        _finder.setDebug(debug);
+    }
+
+    @Override
+    protected void process(EventHeader event) {
+
+//        System.out.println("New event");
+        //  Pass the event to the diagnostics package
+        if (_diag != null)
+            _diag.setEvent(event);
+
+        //  Initialize timing
+        long last_time = System.currentTimeMillis();
+
+        //  Get the hit collection from the event
+        List<HelicalTrackHit> hitcol = event.get(HelicalTrackHit.class, _inputCol);
+        if (_debug)
+            System.out.println("In " + this.getClass().getSimpleName() + ":  Number of HelicalTrackHits=" + hitcol.size());
+        //  Sort the hits for this event
+        _hitmanager.OrganizeHits(hitcol);
+
+        //  Make the timing plots if requested
+        long start_time = System.currentTimeMillis();
+        double dtime = ((double) (start_time - last_time)) / 1000.;
+        last_time = start_time;
+        if (_timing)
+            aida.cloud1D("Organize Hits").fill(dtime);
+
+        //  Make sure that we have cleared the list of track seeds in the finder
+        _finder.clearTrackSeedList();
+
+        //  Loop over strategies and perform track finding
+        for (SeedStrategy strategy : _strategylist) {
+
+            //  Set the strategy for the diagnostics
+            if (_diag != null)
+                _diag.fireStrategyChanged(strategy);
+
+            //  Perform track finding under this strategy
+            _finder.FindTracks(strategy, _bfield);
+            if (_debug)
+                System.out.println("In " + this.getClass().getSimpleName() + ":  Number of Tracks Found=" + _finder.getTrackSeeds().size());
+            //  Make the timing plots if requested
+            long time = System.currentTimeMillis();
+            dtime = ((double) (time - last_time)) / 1000.;
+            last_time = time;
+            if (_timing)
+                aida.cloud1D("Tracking time for strategy " + strategy.getName()).fill(dtime);
+        }
+
+        //  Get the list of final list of SeedCandidates
+        List<SeedCandidate> trackseeds = _finder.getTrackSeeds();
+
+        if (_iterativeConfirmedFits > 0) {
+            // Iteratively re-fit tracks to take into account helix and hit position correlations
+            if (_debug)
+                System.out.printf("%s: Iteratively improve %d seeds\n", this.getClass().getSimpleName(), trackseeds.size());
+            List<SeedCandidate> seedsToRemove = new ArrayList<SeedCandidate>();
+            for (SeedCandidate seed : trackseeds) {
+                SeedStrategy strategy = seed.getSeedStrategy();
+                boolean success = false;
+                for (int iterFit = 0; iterFit < _iterativeConfirmedFits; ++iterFit)
+                    success = _helixfitter.FitCandidate(seed, strategy);
+                if (!success)
+                    seedsToRemove.add(seed);
+//                else if (_debug)
+//                    System.out.printf("%s: done iterating, this seed will be added to event:\n%s\n", this.getClass().getSimpleName(), seed.toString());
+            }
+            for (SeedCandidate badseed : seedsToRemove)
+                trackseeds.remove(badseed);
+        }
+
+        //  Make tracks from the final list of track seeds
+        _maketracks.Process(event, trackseeds, _bfield);
+
+        //  Save the MC Particles that have been seeded / confirmed if diagnostics are enabled
+        if (_diag != null) {
+            Set<MCParticle> seededmcpset = _finder.getSeededMCParticles();
+            List<MCParticle> seededmcp = new ArrayList<MCParticle>(seededmcpset);
+            event.put("SeededMCParticles", seededmcp, MCParticle.class, 0);
+            Set<MCParticle> confirmedmcpset = _finder.getConfirmedMCParticles();
+            List<MCParticle> confirmedmcp = new ArrayList<MCParticle>(confirmedmcpset);
+            event.put("ConfirmedMCParticles", confirmedmcp, MCParticle.class, 0);
+        }
+
+        //  Clear the list of track seeds accumulated in the track finder
+        _finder.clearTrackSeedList();
+
+        //  Make the total time plot if requested
+        long end_time = System.currentTimeMillis();
+        dtime = ((double) (end_time - start_time)) / 1000.;
+        if (_timing)
+            aida.cloud1D("Total tracking time").fill(dtime);
+
+        return;
+    }
+
+    @Override
+    protected void detectorChanged(Detector detector) {
+
+        //  Only build the model when the detector is changed
+        _materialmanager.buildModel(detector);
+
+        //  Find the bfield and pass it to the helix fitter and diagnostic package
+        if (!_forceBField)
+            _bfield = detector.getFieldMap().getField(_IP).z();
+
+        if (_diag != null)
+            _diag.setBField(_bfield);
+        _helixfitter.setBField(_bfield);
+
+        //  Get the tracking radius
+        _rtrk = _materialmanager.getRMax();
+
+        //  Set the sectoring parameters
+        if (_autosectoring)
+            _hitmanager.setSectorParams(_strategylist, _bfield, _rtrk);
+    }
+
+    /**
+     * Specifiy the strategies to be used by the SeedTracker algorithm. Invoking
+     * this
+     * method will override the default strategies defined by the
+     * DefaultStrategy
+     * class.
+     *
+     * @param strategylist List of strategies to be used
+     */
+    public void putStrategyList(List<SeedStrategy> strategylist) {
+
+        //  Save the strategy list
+        _strategylist = strategylist;
+
+        //  Set the sectoring parameters
+        if (_autosectoring)
+            _hitmanager.setSectorParams(strategylist, _bfield, _rtrk);
+
+        return;
+    }
+
+    public void setSectorParams(int nphi, double dz) {
+        _hitmanager.setSectorParams(nphi, dz);
+        _autosectoring = false;
+        return;
+    }
+
+    public void setDiagnostics(ISeedTrackerDiagnostics d) {
+
+        //  Set the diagnostic package
+        _diag = d;
+        _helixfitter.setDiagnostics(_diag);
+        _finder.setDiagnostic(_diag);
+
+        //  Pass the hit manager, material manager, and bfield to the diagnostic package
+        if (_diag != null) {
+            _diag.setMaterialManager(_materialmanager);
+            _diag.setHitManager(_hitmanager);
+            _diag.setBField(_bfield);
+        }
+    }
+
+    public void setTimingPlots(boolean timing) {
+        _timing = timing;
+    }
+
+    public void setTrkCollectionName(String name) {
+        _maketracks.setTrkCollectionName(name);
+    }
+
+    public void setInputCollectionName(String name) {
+        _inputCol = name;
+    }
+
+    public void setMaterialManagerTransform(ITransform3D _detToTrk) {
+        _materialmanager.setTransform(_detToTrk);
+    }
+
+    /**
+     * Set the maximum number of fits used to confirm or extend a seed.
+     *
+     * @param maxfit maximum number of fits
+     */
+    public void setMaxFit(int maxfit) {
+        _finder.setMaxFit(maxfit);
+    }
+
+    public void setBField(double bfield) {
+        _forceBField = true;
+        _bfield = bfield;
+    }
+
+    public void setReferencePoint(double xref, double yref) {
+        _helixfitter.setReferencePoint(xref, yref);
+    }
+
+    public void setSectorParams(boolean sector) {
+        _hitmanager.setDoSectoring(sector);
+    }
+
+    /**
+     * Set {@link TrackCheck} object to be used by the track finding algorithm.
+     * If this method is never called, no external checking of seeds and tracks
+     * is performed.
+     */
+    public void setTrackCheck(TrackCheck trackCheck) {
+        _finder._trackCheck = trackCheck;
+        _maketracks._trackCheck = trackCheck;
+    }
+
+    /**
+     * Set the maximum number of iterative fits on a confirmed/extended
+     * candidate.
+     *
+     * @param maxfits maximum number of fits
+     */
+    public void setIterativeConfirmed(int maxfits) {
+        this._iterativeConfirmedFits = maxfits;
+    }
+
+    public void setUseDefaultXPlane(boolean useDefault) {
+        _materialmanager.setDefaultXPlaneUsage(useDefault);
+
+    }
+
+}

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use