Commit in lcsim/src/org/lcsim/recon/tracking/seedtracker on MAIN
SeedCandidate.java+16-11.2 -> 1.3
MergeSeedLists.java+46-321.4 -> 1.5
SeedTrackFinder.java+1-121.9 -> 1.10
ConfirmerExtender.java+121-1131.9 -> 1.10
+184-158
4 modified files
Reduce memory usage in seedtracker by restructuring algorithm

lcsim/src/org/lcsim/recon/tracking/seedtracker
SeedCandidate.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- SeedCandidate.java	13 Oct 2008 01:05:28 -0000	1.2
+++ SeedCandidate.java	24 Jul 2009 14:05:03 -0000	1.3
@@ -31,6 +31,7 @@
     private SeedStrategy _strategy;
     private Map<HelicalTrackHit, MultipleScatter> _msmap;
     private List<ScatterAngle> _scatters;
+    private LinkedList<SeedLayer> _unchecked;
     
     /**
      * Create an empty SeedCandidate.
@@ -70,6 +71,7 @@
         this(seed.getHits(), seed.getSeedStrategy(), seed.getHelix());
         _msmap.putAll(seed.getMSMap());
         _scatters = seed.getScatterAngles();
+        _unchecked = seed.getUncheckedLayers();
     }
     
     /**
@@ -163,7 +165,20 @@
     public List<ScatterAngle> getScatterAngles() {
         return _scatters;
     }
-    
+
+    public void setUncheckedLayers(List<SeedLayer> unchecked) {
+        _unchecked = new LinkedList<SeedLayer>(unchecked);
+        return;
+    }
+
+    public LinkedList<SeedLayer> getUncheckedLayers() {
+        return _unchecked;
+    }
+
+    public SeedLayer getNextLayer() {
+        return _unchecked.pollFirst();
+    }
+
     private void UpdateMSMap(HelicalTrackHit hit) {
         if (_helix == null) return;
         if (_scatters == null) return;

lcsim/src/org/lcsim/recon/tracking/seedtracker
MergeSeedLists.java 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- MergeSeedLists.java	30 Oct 2008 00:23:16 -0000	1.4
+++ MergeSeedLists.java	24 Jul 2009 14:05:03 -0000	1.5
@@ -4,7 +4,6 @@
  * Created on February 6, 2008, 9:54 AM
  *
  */
-
 package org.lcsim.recon.tracking.seedtracker;
 
 import java.util.List;
@@ -19,61 +18,76 @@
  * @version 1.0
  */
 public class MergeSeedLists {
-    
+
     private ISeedTrackerDiagnostics diag = null;
-    
+
     /** Creates a new instance of MergeSeedLists */
     public MergeSeedLists() {
     }
-    
-    public void setDiagnostic(ISeedTrackerDiagnostics diagnostic){
+
+    public void setDiagnostic(ISeedTrackerDiagnostics diagnostic) {
         diag = diagnostic;
     }
-    
-    public void Merge(List<SeedCandidate> seedlist, List<SeedCandidate> newseedlist, SeedStrategy strategy) {
-        if(diag!=null) diag.fireMergeStartDiagnostics(newseedlist);
-        for (SeedCandidate newseed : newseedlist ) {
-            ListIterator<SeedCandidate> itr = seedlist.listIterator();
-            boolean best = true;
-            while (itr.hasNext()) {
-                SeedCandidate seed = itr.next();
-                boolean dupe = isDuplicate(newseed, seed);
-                if(diag!=null) diag.fireMergeIsDuplicateDiagnostics(newseed, seed, dupe);
-                if (dupe) {
-                    boolean better = isBetter(newseed,seed,strategy);
-                    if(diag!=null) diag.fireMergeIsBetterDiagnostics(newseed, seed, better);
-                    if (better) {
-                        itr.remove();
-                    } else {
-                        best = false;
-                    }
+
+    public void Merge(List<SeedCandidate> seedlist, SeedCandidate newseed, SeedStrategy strategy) {
+//        if(diag!=null) diag.fireMergeStartDiagnostics(newseedlist);
+        ListIterator<SeedCandidate> itr = seedlist.listIterator();
+        boolean best = true;
+        while (itr.hasNext()) {
+            SeedCandidate seed = itr.next();
+            boolean dupe = isDuplicate(newseed, seed);
+            if (diag != null) {
+                diag.fireMergeIsDuplicateDiagnostics(newseed, seed, dupe);
+            }
+            if (dupe) {
+                boolean better = isBetter(newseed, seed, strategy);
+                if (diag != null) {
+                    diag.fireMergeIsBetterDiagnostics(newseed, seed, better);
+                }
+                if (better) {
+                    itr.remove();
+                } else {
+                    best = false;
                 }
             }
-            if (best) seedlist.add(newseed);
         }
+        if (best) {
+            seedlist.add(newseed);
+        }
+
         return;
     }
-    
+
     private boolean isDuplicate(SeedCandidate seed1, SeedCandidate seed2) {
         int nduplicate = 0;
         for (HelicalTrackHit hit1 : seed1.getHits()) {
             for (HelicalTrackHit hit2 : seed2.getHits()) {
                 if (hit1 == hit2) {
                     nduplicate++;
-                    if (nduplicate > 1) return true;
+                    if (nduplicate > 1) {
+                        return true;
+                    }
                 }
             }
         }
         return false;
     }
-    
+
     private boolean isBetter(SeedCandidate newseed, SeedCandidate oldseed, SeedStrategy strategy) {
         int hitdif = newseed.getHits().size() - oldseed.getHits().size();
         double chisqdif = newseed.getHelix().chisqtot() - oldseed.getHelix().chisqtot();
-        if (hitdif > 1) return true;
-        if (hitdif == 1) return chisqdif < strategy.getBadHitChisq();
-        if (hitdif == 0) return chisqdif < 0.;
-        if (hitdif == -1) return chisqdif < -strategy.getBadHitChisq();
+        if (hitdif > 1) {
+            return true;
+        }
+        if (hitdif == 1) {
+            return chisqdif < strategy.getBadHitChisq();
+        }
+        if (hitdif == 0) {
+            return chisqdif < 0.;
+        }
+        if (hitdif == -1) {
+            return chisqdif < -strategy.getBadHitChisq();
+        }
         return false;
     }
-}
\ No newline at end of file
+}

lcsim/src/org/lcsim/recon/tracking/seedtracker
SeedTrackFinder.java 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- SeedTrackFinder.java	7 Feb 2009 03:56:06 -0000	1.9
+++ SeedTrackFinder.java	24 Jul 2009 14:05:03 -0000	1.10
@@ -22,7 +22,6 @@
     private HitManager _hitmanager;
     private HelixFitter _helixfitter;
     private ConfirmerExtender _confirmer;
-    private MergeSeedLists _merger;
     private List<SeedCandidate> _trackseeds;
     private ISeedTrackerDiagnostics _diag = null;
 
@@ -37,7 +36,6 @@
 
         //  Instantiate the Confirmer/Extender and Seed Candidate merging classes
         _confirmer = new ConfirmerExtender(_hitmanager, _helixfitter);
-        _merger = new MergeSeedLists();
 
         //  Create a list of track seeds that have been found
         _trackseeds = new ArrayList<SeedCandidate>();
@@ -48,7 +46,6 @@
         //  Setup the diagnostics for this class and the classes used by this class
         _diag = d;
         _confirmer.setDiagnostics(_diag);
-        _merger.setDiagnostic(_diag);
     }
 
     public boolean FindTracks(SeedStrategy strategy, double bfield) {
@@ -128,15 +125,7 @@
                         for (SeedCandidate confirmedseed : confirmedlist) {
 
                             //  See if we can extend this seed candidate
-                            success = _confirmer.Extend(confirmedseed, strategy, bfield);
-                            if (!success) continue;
-                            nextend++;
-
-//                            System.out.println("Extended a seed candidate");
-                            //  Found a track candidate - merge it into the list of track candidates
-                            List<SeedCandidate> extendedlist = _confirmer.getResult();
-                            nextseeds += extendedlist.size();
-                            _merger.Merge(_trackseeds, extendedlist, strategy);
+                            _confirmer.Extend(confirmedseed, strategy, bfield, _trackseeds);
                         }
 //                        System.out.println("npair: " + npairs + " Good Pairs: " + ngdpairs +
 //                                " ntrip: " + ntrip + " nseed: " + nseed);

lcsim/src/org/lcsim/recon/tracking/seedtracker
ConfirmerExtender.java 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- ConfirmerExtender.java	19 Feb 2009 22:00:34 -0000	1.9
+++ ConfirmerExtender.java	24 Jul 2009 14:05:03 -0000	1.10
@@ -6,6 +6,7 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.lcsim.fit.helicaltrack.HelicalTrackFitter.FitStatus;
@@ -23,10 +24,11 @@
         CONFIRM,
         EXTEND;
     }
-    private HitManager hmanager;
-    private HelixFitter fitter;
-    private List<SeedCandidate> result;
-    private ISeedTrackerDiagnostics diag = null;
+    private HitManager _hmanager;
+    private HelixFitter _fitter;
+    private MergeSeedLists _merger;
+    private List<SeedCandidate> _result;
+    private ISeedTrackerDiagnostics _diag = null;
 
     /**
      * Constructs the Confirmer/Extender class..
@@ -39,8 +41,9 @@
      */
     public ConfirmerExtender(HitManager hitmanager, HelixFitter helixfitter) {
 
-        this.hmanager = hitmanager;
-        this.fitter = helixfitter;
+        _hmanager = hitmanager;
+        _fitter = helixfitter;
+        _merger = new MergeSeedLists();
     }
 
     /**
@@ -49,161 +52,166 @@
      */
     public List<SeedCandidate> getResult() {
 
-        return result;
+        return _result;
     }
 
     public void setDiagnostics(ISeedTrackerDiagnostics d) {
-        diag = d;
+        _diag = d;
+        _merger.setDiagnostic(_diag);
     }
 
     public boolean Confirm(SeedCandidate seed, SeedStrategy strategy, double bfield) {
-        return doTask(seed, Task.CONFIRM, strategy, bfield);
-    }
 
-    public boolean Extend(SeedCandidate seed, SeedStrategy strategy, double bfield) {
-        return doTask(seed, Task.EXTEND, strategy, bfield);
-    }
+        //  Create a list to hold the confirmed / extended seeds
+        _result = new ArrayList<SeedCandidate>();
 
-    private boolean doTask(SeedCandidate seed, Task task, SeedStrategy strategy, double bfield) {
+        //  Establish which layers are to be checked
+        seed.setUncheckedLayers(strategy.getLayers(SeedLayer.SeedType.Confirm));
 
-        //  Instantiate the fast hit checker
-        FastCheck checker = new FastCheck(strategy, bfield);
+        //  Process the seed
+        doTask(seed, Task.CONFIRM, strategy, bfield);
+        
+        //  Return true if we found at least one confirming seed candidate
+        return _result.size() > 0;
+    }
 
-        //  Create a list to hold the confirmed / extended seeds
-        this.result = new ArrayList<SeedCandidate>();
+    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;
 
-        //  Get the list of layers to use
-        List<SeedLayer> lyrs;
-        if (task == Task.EXTEND) {
-            lyrs = strategy.getLayers(SeedLayer.SeedType.Extend);
-        } else {
-            if (task == Task.CONFIRM) {
-                lyrs = strategy.getLayers(SeedLayer.SeedType.Confirm);
-            } else {
-                throw new RuntimeException("Unrecognized Task");
-            }
-        }
+        //  Establish which layers are to be checked
+        seed.setUncheckedLayers(strategy.getLayers(SeedLayer.SeedType.Extend));
 
-        int n = 0;
+        //  Extend the seed and return
+        doTask(seed, Task.EXTEND, strategy, bfield);
+        return;
+    }
 
-        //  Create a list of input seeds to be searched for a confirmation/extension hit
-        List<SeedCandidate> seedlist = new ArrayList<SeedCandidate>();
-        //  For the first confirm/extend layer, the input seed is the seed we are trying to check out
-        seedlist.add(seed);
+    private void doTask(SeedCandidate inputseed, Task task, SeedStrategy strategy, double bfield) {
 
-        //  Initialize the number of layers left to search
-        int nleft = lyrs.size();
+        //  Instantiate the fast hit checker
+        FastCheck checker = new FastCheck(strategy, bfield);
 
-        //  Calculate the minimum number of hits to suceed
+        //  Calculate the minimum number of hits to succeed
         int minhits = strategy.getMinHits();
         if (task == Task.CONFIRM) minhits = strategy.getMinConfirm() + 3;
 
-        //  Loop over the confirmation/extension layers
-        for (SeedLayer lyr : lyrs) {
+        //  Create a LIFO queue of seeds to be searched for a confirmation/extension hit
+        LinkedList<SeedCandidate> seedlist = new LinkedList<SeedCandidate>();
+
+        //  Start with the input seed
+        seedlist.add(inputseed);
+ 
+        //  Keep looping until we have fully processed all seed candidates
+        while (seedlist.size() > 0) {
+
+            //  Pull the last seed off the queue (use a LIFO queue to minimize queue length)
+            SeedCandidate seed = seedlist.pollLast();
+
+            //  See if there are any layers left for confirm/extend
+            int lyrsleft = seed.getUncheckedLayers().size();
+            if (lyrsleft == 0) {
+                if (task == Task.CONFIRM) {
+                    _result.add(seed);
+                } else if (task == Task.EXTEND) {
+                    if (seed.getHits().size() >= minhits) {
+                        _merger.Merge(_result, seed, strategy);
+                    }
+                }
+                continue;
+            }
+
+            //  Check if there are enough unchecked layers to meet the minimum number of hits
+            int possiblehits = lyrsleft + seed.getHits().size();
+            if (possiblehits < minhits) continue;
 
-            //  Create a list for seeds that are confirmed/extended using the current layer
-            List<SeedCandidate> newlist = new ArrayList<SeedCandidate>();
+            //  Pull the next layer off the queue
+            SeedLayer lyr = seed.getNextLayer();
 
             //  Get the list of sectors associated with this layer
-            List<Sector> sectorlist = hmanager.getSectors(lyr);
+            List<Sector> sectorlist = _hmanager.getSectors(lyr);
 
-            //  Loop over the input seeds for this layer search
-            for (SeedCandidate seedin : seedlist) {
+            //  Retrieve the chisq for the last fit and initialize the best fit chisq for this layer
+            double oldchisq = seed.getHelix().chisqtot();
+            double oldcirclechisq = seed.getHelix().chisq()[0];
+            double chisqbest = 1.e99;
 
-                //  Check if this seed is viable
-                if (seedin.getHits().size() + nleft < minhits) continue;
+            //  Create a list of hits to check for this layer / seed
+            List<HelicalTrackHit> hitlist = new ArrayList<HelicalTrackHit>();
 
-                //  Retrieve the chisq for the last fit and initialize the best fit chisq for this layer
-                double oldchisq = seedin.getHelix().chisqtot();
-                double oldcirclechisq = seedin.getHelix().chisq()[0];
-                double chisqbest = 1.e6;
+            //  Loop over the sectors with hits
+            for (Sector sector : sectorlist) {
 
-                //  Create a list of hits to check for this layer / seed
-                List<HelicalTrackHit> hitlist = new ArrayList<HelicalTrackHit>();
+                //  Check that this candidate is compatible with the sector
+                if (!checker.CheckSector(seed, sector)) continue;
 
-                //  Loop over the sectors with hits
-                for (Sector sector : sectorlist) {
+                //  Add the hits for this confirmation/extension sector to the hitlist
+                hitlist.addAll(sector.Hits());
+            }
 
-                    //  Check that this candidate is compatible with the sector
-                    if (!checker.CheckSector(seedin, sector)) continue;
+            SortHits comp = new SortHits(seed.getHelix());
+            Collections.sort(hitlist, comp);
 
-                    //  Add the hits for this confirmation/extension sector to the hitlist
-                    hitlist.addAll(sector.Hits());
-                }
+            if (_diag != null) {
+                _diag.fireConfirmerExtenderWorkingSeedInfo(task, seed, hitlist);
+            }
 
-                SortHits comp = new SortHits(seedin.getHelix());
-                Collections.sort(hitlist, comp);
+            //  Loop over the sorted hits in this layer
+            for (HelicalTrackHit hit : hitlist) {
 
-                if (diag != null) {
-                    diag.fireConfirmerExtenderWorkingSeedInfo(task, seedin, hitlist);
-                }
+                //  Check that this hit is potentially viable
+                if (!checker.CheckHitSeed(hit, seed)) continue;
 
-                //  For each hit in this confirmation/extension layer, make a test seed including the new hit
-                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, seedin)) continue;
+                //  See if we have a successful fit
+                boolean success = _fitter.FitCandidate(test, strategy);
 
-                    SeedCandidate test = new SeedCandidate(seedin);
-                    test.addHit(hit);
+                if (success) {
 
-                    //  See if we have a successful fit
-                    boolean success = fitter.FitCandidate(test, strategy);
+                    //  Attach the fit to the test seed
+                    test.setHelix(_fitter.getHelix());
 
-                    if (success) {
+                    if (_diag != null) {
+                        _diag.fireConfirmerExtenderFitSuccess(task, seed, hit, _fitter, chisqbest, true);
+                    }
 
-                        //  Attach the fit to the test seed and add it to the list
-                        test.setHelix(fitter.getHelix());
-                        if (diag != null) {
-                            diag.fireConfirmerExtenderFitSuccess(task, seedin, hit, fitter, chisqbest, true);
-                        }
-                        newlist.add(test);
-                        chisqbest = Math.min(chisqbest, fitter.getHelix().chisqtot());
+                    //  Add the seed to the LIFO queue of seed candidates
+                    seedlist.addLast(test);
+                    chisqbest = Math.min(chisqbest, _fitter.getHelix().chisqtot());
 
-                    } else {
+                } else {
 
-                        if (diag != null) {
-                            diag.fireConfirmerExtenderFitNoSuccess(task, seedin, hit, fitter, true);
-                        }
+                    if (_diag != null) {
+                        _diag.fireConfirmerExtenderFitNoSuccess(task, seed, hit, _fitter, true);
+                    }
 
-                        //  Stop checking hits in this layer if circle chisq increase is too big
-                        if (fitter.getFitStatus() != FitStatus.CircleFitFailed) {
-                            double circlechisq = fitter.getCircleFit().chisq();
-                            if (circlechisq > oldcirclechisq + strategy.getMaxChisq())
-                                break;
+                    //  Stop checking hits in this layer if circle chisq increase is too big
+                    if (_fitter.getFitStatus() != FitStatus.CircleFitFailed) {
+                        double circlechisq = _fitter.getCircleFit().chisq();
+                        if (circlechisq > oldcirclechisq + strategy.getMaxChisq()) {
+                            break;
                         }
                     }
                 }
+            }
+
+            //  Finished checking hits in the current layer
+            //  If all fit tries for this layer are potentially bad hits, include the starting seed in the list
+            if (chisqbest - oldchisq > strategy.getBadHitChisq()) {
+                seedlist.addLast(seed);
 
-                //  Finished checking hits to add to this seed candidate
-                //  If all fit tries for this layer are potentially bad hits, include the starting seed in the list
-                if (chisqbest - oldchisq > strategy.getBadHitChisq()) {
-                    newlist.add(seedin);
 //                    if (diag != null) {
 //                        diag.fireConfirmerExtenderAllHitsPotentiallyBad(task, seedin, hitlist, chisqbest, oldchisq);
 //                    }
-                } else {
-                    n++;
-                }
             }
 
-            //  Finished looping over the seeds we are trying to confirm/extend with this layer
-            //  Use the new list of seeds as the working listinput to the next layer search
-            seedlist = newlist;
-            if (diag != null) {
-                diag.fireConfirmerExtenderLayerDone(task, n, seedlist);
-            }
-
-            //  One less layer left
-            nleft--;
-        }
-
-        //  Finished looping over all confirm/extend layers
-        //  Check for seeds with sufficient numbers of confirmed/extended hits
-        for (SeedCandidate candidate : seedlist) {
-            int hits = candidate.getHits().size();
-            if (hits >= minhits) result.add(candidate);
         }
-        return result.size() > 0;
+        //  Finished looping over the seeds in the LIFO candidate queue
+        //if (_diag != null) _diag.fireConfirmerExtenderLayerDone(task, n, seedlist);
     }
 }
\ No newline at end of file
CVSspam 0.2.8