9 added files
lcsim/sandbox/Partridge
diff -N DefaultStrategy.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DefaultStrategy.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,47 @@
+/*
+ * DefaultStrategy.java
+ *
+ * Created on March 29, 2006, 3:45 PM
+ *
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class DefaultStrategy
+{
+ private List<SeedStrategy> StrategyList;
+
+ /** Creates a new instance of DefaultStrategy */
+ public DefaultStrategy()
+ {
+ StrategyList = new ArrayList();
+
+ List<SeedLayer> TD012Layers = new ArrayList();
+ TD012Layers.add(new SeedLayer("TrackerEndcap", 0, SeedLayer.SeedType.SeedInner));
+ TD012Layers.add(new SeedLayer("TrackerEndcap", 1, SeedLayer.SeedType.SeedMiddle));
+ TD012Layers.add(new SeedLayer("TrackerEndcap", 2, SeedLayer.SeedType.SeedOuter));
+// StrategyList.add(new SeedStrategy("TD012",TD012Layers));
+
+ List<SeedLayer> VB012Layers = new ArrayList();
+ VB012Layers.add(new SeedLayer("VertexBarrel", 2, SeedLayer.SeedType.SeedInner));
+ VB012Layers.add(new SeedLayer("VertexBarrel", 3, SeedLayer.SeedType.SeedMiddle));
+ VB012Layers.add(new SeedLayer("VertexBarrel", 4, SeedLayer.SeedType.SeedOuter));
+ VB012Layers.add(new SeedLayer("TrackerBarrel", 0, SeedLayer.SeedType.Confirm3D));
+// VB012Layers.add(new SeedLayer("VertexBarrel", 0, SeedLayer.SeedType.Confirm3D));
+// VB012Layers.add(new SeedLayer("VertexBarrel", 1, SeedLayer.SeedType.Confirm3D));
+ StrategyList.add(new SeedStrategy("VB012",VB012Layers));
+
+ }
+ public List<SeedStrategy> getStrategyList()
+ {
+ return StrategyList;
+ }
+}
lcsim/sandbox/Partridge
diff -N HelicalTrackFitter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HelicalTrackFitter.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,180 @@
+/*
+ * HelicalTrackFitter.java
+ *
+ * Created on March 25, 2006, 6:11 PM
+ *
+ * $Id: HelicalTrackFitter.java,v 1.1 2007/08/06 23:59:57 partridge Exp $
+ */
+
+package org.lcsim.contrib.seedtracker;
+import hep.physics.matrix.SymmetricMatrix;
+import static java.lang.Math.atan2;
+import static java.lang.Math.abs;
+import static java.lang.Math.PI;
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+import org.lcsim.fit.circle.CircleFit;
+import org.lcsim.fit.circle.CircleFitter;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.line.SlopeInterceptLineFit;
+import org.lcsim.fit.line.SlopeInterceptLineFitter;
+/**
+ * Fit a helix to a set of space points. First, a circle is fit to the x-y coordinates.
+ * A straight-line fit is then performed on the s-z coordinates.
+ *
+ * The r-phi and z coordinate measurements are assumed to be uncorrelated. A block
+ * diagonal covariance matrix is formed from the results of the circle and s-z fits,
+ * ignoring any correlations between these fits.
+ *
+ * The resulting track parameters follow the "L3 Convention" adopted by org.lcsim.
+ *
+ * Modified August 2006 by Richard Partridge
+ * @author Norman Graf
+ */
+public class HelicalTrackFitter
+{
+ private CircleFitter _cfitter = new CircleFitter();
+ private SlopeInterceptLineFitter _lfitter = new SlopeInterceptLineFitter();
+
+ private HelicalTrackFit _fit;
+
+ private double[] _circleParameters = new double[3];
+
+ /**
+ * Creates a new instance of HelicalTrackFitter.
+ */
+ public HelicalTrackFitter()
+ {
+ }
+
+ /**
+ * Fit a helix to a set of space points. The space points should be ordered in
+ * increasing track length. The code will properly handle loopers provided
+ * that the change in direction between successive points is less than pi.
+ * @param x Array of x coordinates
+ * @param y Array of y coordinates
+ * @param z Array of z coordinates
+ * @param drphi Error in r-phi hit position
+ * @param dz Error in z coordinate. A negative value indicates that this point is to
+ * be excluded in the s-z fit.
+ * @param np Number of points
+ * @return True for successful fit
+ */
+ public boolean fit(double[] x, double[] y, double[] z, double[] drphi, double[] dz, int np)
+ {
+ // fit a circle in the x-y plane
+ double[] wrphi = new double[np];
+ for(int i=0; i<np; ++i)
+ {
+ wrphi[i] = 1/(drphi[i]*drphi[i]);
+ }
+ boolean success = _cfitter.fit(x, y, wrphi, np);
+ if(!success) return false;
+
+ CircleFit cfit = _cfitter.getfit();
+ double radius = 1./cfit.curvature();
+ double phi0 = cfit.phi();
+ double dca = -cfit.dca();
+ double xc = (radius-dca)*sin(phi0);
+ double yc = -(radius-dca)*cos(phi0);
+ _circleParameters[0] = xc;
+ _circleParameters[1] = yc;
+ _circleParameters[2] = radius;
+ // fit a line in the s-z plane
+ // assumes points are in increasing order
+ double[] s = new double[np];
+ double[] sfit = new double[np];
+ double[] zfit = new double[np];
+ double[] wz = new double[np];
+ int nz = 0;
+ for(int i=0; i<np; i++)
+ {
+ if (i==0) {
+ s[0] = s(radius, xc, yc, x[0], y[0], 0., 0.);
+ }
+ else {
+ s[i] = s(radius, xc, yc, x[i], y[i], x[i-1], y[i-1]) + s[i-1];
+ }
+ if (dz[i]>0) {
+ sfit[nz] = s[i];
+ zfit[nz] = z[i];
+ wz[nz] = 1/(dz[i]*dz[i]);
+ nz++;
+ }
+ }
+
+ success = _lfitter.fit(sfit, zfit, wz, nz);
+ if(!success) return false;
+ SlopeInterceptLineFit lfit = _lfitter.getFit();
+
+ double[] pars = new double[5];
+ SymmetricMatrix cov = new SymmetricMatrix(5);
+ double[] chisq = new double[2];
+ int[] ndf = new int[2];
+
+ chisq[0] = cfit.chisq();
+ chisq[1] = lfit.chisquared();
+
+ ndf[1] = lfit.ndf();
+ ndf[0] = np - 3;
+
+ // d0, xy impact parameter. Note: - sign due to opposite sign convention in CircleFitter
+ pars[0] = -cfit.dca();
+ // phi0
+ pars[1] = cfit.phi();
+ // omega signed curvature
+ pars[2] = cfit.curvature();
+ // z0
+ pars[3] = lfit.intercept();
+ // tan lambda
+ pars[4] = lfit.slope();
+
+ // fill in covariance matrix
+ cov.setElement(0,0, cfit.cov()[0]);
+ cov.setElement(0,1,-cfit.cov()[1]); // Need - sign due to sign convention in CircleFitter
+ cov.setElement(1,1, cfit.cov()[2]);
+ cov.setElement(0,2,-cfit.cov()[3]); // Need - sign due to sign convention in CircleFitter
+ cov.setElement(1,2, cfit.cov()[4]);
+ cov.setElement(2,2, cfit.cov()[5]);
+ //cov[0][3] = 0.;
+ //cov[1][3] = 0.;
+ //cov[2][3] = 0.;
+ cov.setElement(3,3, lfit.interceptUncertainty());
+ //cov[0][4] = 0.;
+ //cov[1][4] = 0.;
+ //cov[2][4] = 0.;
+ cov.setElement(3,4, lfit.covariance());
+ cov.setElement(4,4, lfit.slopeUncertainty());
+ _fit = new HelicalTrackFit(pars, cov, chisq, ndf);
+ _fit.setCircleParameters(_circleParameters);
+ return true;
+ }
+
+ /**
+ * Get the results of the most recent fit.
+ * @return HelicalTrackFit corresponding to most recent fit
+ */
+ public HelicalTrackFit getFit()
+ {
+ return _fit;
+ }
+
+ /**
+ * Get the circle paramaters (xc, yc, R) from the most recent fit.
+ * @return Circle parameters (xc, yc, R)
+ */
+ public double[] getCircleParameters()
+ {
+ return _circleParameters;
+ }
+
+ double s(double radius, double xcenter, double ycenter, double x1, double y1, double x2, double y2)
+ {
+ double phi1 = atan2( (y1-ycenter), (x1-xcenter) );
+ double phi2 = atan2( (y2-ycenter), (x2-xcenter) );
+ double dphi = abs(phi1-phi2);
+ if(dphi>PI) dphi = 2.*PI-dphi;
+ return abs(radius)*dphi;
+ }
+
+}
\ No newline at end of file
lcsim/sandbox/Partridge
diff -N HitManager.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HitManager.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,124 @@
+/*
+ * HitManager.java
+ *
+ * Created on August 4, 2007, 4:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.lcsim.event.base.BaseTrackerHitMC;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.TrackerHit;
+import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+
+/**
+ * Organize tracker hits into lists of hits sorted by detector name, layer number, and barrel-endcap flag
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class HitManager {
+ HashMap<String, List<TrackerHit>> map;
+ HashMap<String, double> _rmin;
+ HashMap<String, double> rmax;
+ HashMap<String, double> zmin;
+ HashMap<String, double> zmax;
+ private double _RMin = 99999;
+ private double _RMax = 0;
+ private double _ZMin = 99999;
+ private double _ZMax = -99999;
+
+ /** Creates a new instance of HitManager */
+ public HitManager() {
+
+ }
+
+ /**
+ * Sort the hits into distinct lists where each list has a unique detector name, layer number, and barrel endcap flag
+ * @param event EventHeader for the event to be organized
+ */
+ public void OrganizeHits(EventHeader event) {
+ map = new HashMap<String, List<TrackerHit>>();
+ List<List<TrackerHit>> hitcollections = event.get(TrackerHit.class);
+ for (List<TrackerHit> hitlist : hitcollections) {
+ for (TrackerHit hit : hitlist) {
+ String identifier = LyrIdentifier(hit);
+ if (!map.containsKey(identifier)) {
+ map.put(identifier, new ArrayList<TrackerHit>());
+ }
+ List<TrackerHit> lyrhits = map.get(identifier);
+ lyrhits.add(hit);
+ }
+ }
+ }
+
+ /**
+ * Return a list of TrackerHits for a particular detector name, layer number, and barrel-endcap flag
+ * @param detname Name of the detector as referenced by the getName method of the subDetector class
+ * @param layer Layer number
+ * @param beflag Barrel-endcap flag
+ * @return List of matching TrackerHits
+ */
+ public List<TrackerHit> getTrackerHits(String detname, int layer, BarrelEndcapFlag beflag) {
+ return map.get(Identifier(detname, layer, beflag));
+ }
+
+ public List<TrackerHit> getTrackerHits(SeedLayer seedlayer) {
+ return map.get(Identifier(seedlayer.getDetName(), seedlayer.getLayer(), seedlayer.getBEFlag()));
+ }
+
+ private String LyrIdentifier(TrackerHit hit) {
+ if (hit instanceof BaseTrackerHitMC) {
+ BaseTrackerHitMC newhit = (BaseTrackerHitMC) hit;
+ SimTrackerHit simhit = newhit.getSimHits().get(0);
+ String detname = simhit.getSubdetector().getName();
+ int layer = simhit.getLayer();
+ BarrelEndcapFlag beflag = simhit.getIDDecoder().getBarrelEndcapFlag();
+ return Identifier(detname, layer, beflag);
+ } else return new String("Unknown");
+ }
+
+ private String Identifier(String detname, int layer, BarrelEndcapFlag beflag) {
+ return new String(detname+layer+beflag.toString());
+ }
+
+ /**
+ * Return the smallest radius for a hit in this layer
+ * @return Smallest radius for a hit in this layer
+ */
+ public double getRMin() {
+ return _RMin;
+ }
+
+ /**
+ * Return largest radius for a hit in this layer
+ * @return Largest radius for a hit in this layer
+ */
+ public double getRMax() {
+ return _RMax;
+ }
+
+ /**
+ * Return minimum z for a hit in this layer
+ * @return Minimum z for a hit in this layer
+ */
+ public double getZMin() {
+ return _ZMin;
+ }
+
+ /**
+ * Return the maximum z coordinate for a hit in this layer
+ * @return Maximum z coordinate for a hit in this layer
+ */
+ public double getZMax() {
+ return _ZMax;
+ }
+
+}
lcsim/sandbox/Partridge
diff -N SeedCandidate.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SeedCandidate.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,97 @@
+/*
+ * SeedCandidate.java
+ *
+ * Created on August 3, 2007, 11:05 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.lcsim.event.TrackerHit;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+
+/**
+ * Candidate seed containing a list of hits that make up the SeedCandidate and the associated helix parameters
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class SeedCandidate {
+
+ private List<TrackerHit> _trackerhits = new ArrayList<TrackerHit>();
+ private HelicalTrackFit _helix;
+
+ /**
+ * Create a new SeedCandidate from a list of hits
+ * @param trackerhits List of tracker hits for the SeedCandidate
+ */
+ public SeedCandidate(List<TrackerHit> trackerhits) {
+ _trackerhits.addAll(trackerhits);
+ }
+
+ /**
+ * Create a new SeedCandidate from a list of hits and a helix
+ * @param trackerhits List of TrackerHits for the SeedCandidate
+ * @param helix HelicalTrackFit associated with the SeedCandidate
+ */
+ public SeedCandidate(List<TrackerHit> trackerhits, HelicalTrackFit helix) {
+ this(trackerhits);
+ _helix = helix;
+ }
+
+ /**
+ * Creates a clone of an existing instance of SeedCandidate
+ * @param seed Existing SeedCandidate to be cloned
+ */
+ public SeedCandidate(SeedCandidate seed) {
+ this(seed.getTrackerHits(), seed.getHelix());
+ }
+
+ /**
+ * Assign a list of TrackerHits to the SeedCandidate
+ * @param trackerhits List of TrackerHits for the SeedCandidate
+ */
+ public void setTrackerHits(List<TrackerHit> trackerhits) {
+ _trackerhits.clear();
+ _trackerhits.addAll(trackerhits);
+ return;
+ }
+
+ /**
+ * Assign helix parameters to the SeedCandidate
+ * @param helix HelicalTrackFit associated with the SeedCandidate
+ */
+ public void setHelix(HelicalTrackFit helix) {
+ _helix = helix;
+ return;
+ }
+
+ /**
+ * Add a hit to the SeedCandidate
+ * @param hit TrackerHit to be added to the SeedCandidate
+ */
+ public void addHit(TrackerHit hit) {
+ _trackerhits.add(hit);
+ return;
+ }
+
+ /**
+ * Return the list of TrackerHits for the SeedCandidate
+ * @return List of TrackerHits for the SeedCandidate
+ */
+ public List<TrackerHit> getTrackerHits() {
+ return _trackerhits;
+ }
+
+ /**
+ * Return the HelicalTrackFit associated with the SeedCandidate
+ * @return HelicalTrackFit associated with the SeedCandidate
+ */
+ public HelicalTrackFit getHelix() {
+ return _helix;
+ }
+}
lcsim/sandbox/Partridge
diff -N SeedLayer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SeedLayer.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,89 @@
+/*
+ * SeedLayer.java
+ *
+ * Created on March 29, 2006, 1:59 PM
+ *
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.lcsim.event.TrackerHit;
+import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+
+/**
+ * Encapsulates information about a tracker layer needed for the SeedTracker algorithm
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class SeedLayer {
+ /**
+ * Enumeration of possible layer types
+ */
+ public enum SeedType {
+ /**
+ * Seed layer
+ */
+ Seed,
+ /**
+ * Confirmation layer
+ */
+ Confirm,
+ /**
+ * Track extension layer
+ */
+ Extend}
+
+ private String _DetName;
+ private int _Layer;
+ private SeedType _Type;
+ private BarrelEndcapFlag _BEFlag;
+
+ /**
+ * Creates a new instance of SeedLayer
+ * @param DetName Decector name
+ * @param Layer Layer number
+ * @param BEFlag Barrel-Endcap flag
+ * @param Type Layer type
+ */
+ public SeedLayer(String DetName, int Layer, BarrelEndcapFlag BEFlag, SeedType Type) {
+ _DetName = DetName;
+ _Layer = Layer;
+ _BEFlag = BEFlag;
+ _Type = Type;
+ }
+
+ /**
+ * Return the detector name
+ * @return Detector name
+ */
+ public String getDetName() {
+ return _DetName;
+ }
+
+ /**
+ * Return the layer number
+ * @return Layer number
+ */
+ public int getLayer() {
+ return _Layer;
+ }
+
+ /**
+ * Return the barrel-endcap flag
+ * @return Barrel-endcap flag
+ */
+ public BarrelEndcapFlag getBEFlag() {
+ return _BEFlag;
+ }
+
+ /**
+ * Retrun the layer type
+ * @return Layer type
+ */
+ public SeedType getType() {
+ return _Type;
+ }
+}
lcsim/sandbox/Partridge
diff -N SeedStrategy.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SeedStrategy.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,136 @@
+/*
+ * SeedStrategy.java
+ *
+ * Created on March 29, 2006, 3:04 PM
+ *
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.lcsim.contrib.seedtracker.SeedLayer;
+
+/**
+ * Encapsulate the parameters and layers u
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class SeedStrategy {
+ private String _Name;
+ private List<SeedLayer> _LayerList = new ArrayList<SeedLayer>();
+ private double _MinPT = 0.5;
+ private double _MaxDCA = 10.0;
+ private double _MaxZ0 = 10.0;
+ private double _MaxChisq = 100.;
+ private int _MinConfirm = 1;
+ private int _MinHits = 4;
+
+ /** Creates a new instance of SeedStrategy */
+ public SeedStrategy(String Name, List<SeedLayer> LayerList, double MinPT,
+ double MaxDCA, double MaxZ0, double MaxChisq, int MinConfirm, int MinHits) {
+ this(Name, MinPT, MaxDCA, MaxZ0, MaxChisq, MinConfirm, MinHits);
+ _LayerList.addAll(LayerList);
+ }
+
+ public SeedStrategy(String Name, double MinPT, double MaxDCA,double MaxZ0,
+ double MaxChisq, int MinConfirm, int MinHits) {
+ _Name = Name;
+ _MinPT = MinPT;
+ _MaxDCA = MaxDCA;
+ _MaxZ0 = MaxZ0;
+ _MaxChisq = MaxChisq;
+ _MinConfirm = MinConfirm;
+ _MinHits = MinHits;
+ }
+
+ public SeedStrategy(String Name) {
+ _Name = Name;
+ }
+
+ public SeedStrategy(String Name, List<SeedLayer> LayerList) {
+ _Name = Name;
+ _LayerList.addAll(LayerList);
+ }
+
+ public String getName() {
+ return _Name;
+ }
+
+ public List<SeedLayer> getLayerList() {
+ return _LayerList;
+ }
+
+ public double getMinPT() {
+ return _MinPT;
+ }
+
+ public double getMaxDCA() {
+ return _MaxDCA;
+ }
+
+ public double getMaxZ0() {
+ return _MaxZ0;
+ }
+
+ public double getMaxChisq() {
+ return _MaxChisq;
+ }
+
+ public int getMinConfirm() {
+ return _MinConfirm;
+ }
+
+ public int getMinHits() {
+ return _MinHits;
+ }
+
+ public void putLayerList(List<SeedLayer> LayerList) {
+ _LayerList.addAll(LayerList);
+ return;
+ }
+
+ public void putMinPT(double MinPT) {
+ _MinPT = MinPT;
+ return;
+ }
+
+ public void putMaxDCA(double MaxDCA) {
+ _MaxDCA = MaxDCA;
+ return;
+ }
+
+ public void putMaxZ0(double MaxZ0) {
+ _MaxZ0 = MaxZ0;
+ return;
+ }
+
+ public void putMaxChisq(double MaxChisq) {
+ _MaxChisq = MaxChisq;
+ return;
+ }
+
+ public void putMinConfirm(int MinConfirm) {
+ _MinConfirm = MinConfirm;
+ return;
+ }
+
+ public void putMinHits(int MinHits) {
+ _MinHits = MinHits;
+ return;
+ }
+
+ public void addLayer(SeedLayer Layer) {
+ _LayerList.add(Layer);
+ return;
+ }
+
+ public List<SeedLayer> getLayers(SeedLayer.SeedType type) {
+ List<SeedLayer> layers = new ArrayList();
+ for (SeedLayer layer : _LayerList) {
+ if (layer.getType() == type) layers.add(layer);
+ }
+ return layers;
+ }
+}
\ No newline at end of file
lcsim/sandbox/Partridge
diff -N SeedTracker.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SeedTracker.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,309 @@
+/*
+ * SeedTracker.java
+ *
+ * Created on August 16, 2005, 8:54 AM
+ *
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.Track;
+import org.lcsim.event.TrackerHit;
+import org.lcsim.event.base.BaseTrack;
+import org.lcsim.event.base.BaseTrackerHitMC;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.subdetector.MultiLayerTracker;
+import org.lcsim.util.Driver;
+import org.lcsim.event.EventHeader;
+import org.lcsim.fit.helicaltrack.HelicalTrackFitter;
+import java.util.List;
+
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.BasicHep3Vector;
+
+/**
+ * Tracking algorithm based on forming track seeds from all 3-hit combinations
+ * and adding tracks to the helix defined by the three hits.
+ *
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class SeedTracker extends Driver {
+ private DefaultStrategy DS = new DefaultStrategy();
+ private List<SeedStrategy> StrategyList = DS.getStrategyList();
+ private HelicalTrackFitter hf = new HelicalTrackFitter();
+ private HelicalTrackFit helix;
+ private Hep3Vector IP = new BasicHep3Vector(0.,0.,0.);
+ private double BField;
+
+ /** Creates a new instance of SeedTracker */
+ public SeedTracker() {
+ }
+
+ protected void process(EventHeader event) {
+
+ // Find the magnetic field
+ Detector detector = event.getDetector();
+ BField = detector.getFieldMap().getField(IP).z();
+
+ // Associate hits with layers (ignore layers that aren't included in a strategy
+ AssociateHits(event);
+
+ // Create a list of tracks
+ List<BaseTrack> tracklist = new ArrayList();
+
+ // Loop over all strategies
+ for (SeedStrategy strategy : StrategyList) {
+ // Find the 3 hits seeds for this strategy
+ List<SeedCandidate> seedlist = FindSeeds(strategy);
+ // Loop over the seeds
+ for (SeedCandidate seed : seedlist) {
+ // See if we can create a helix that satisfies the cuts for this strategy
+ boolean status = hf.fit(seed.getTrackerHits());
+ if (!status) continue;
+ List<List<TrackerHit>> confirmlist = FindConfirms(strategy, seed);
+ int maxhits = 3 + strategy.getConfirmLayers().size();
+ int minhits = 3 + strategy.getMinConfirm();
+ // First try to find one or more tracks using all the confirm hits
+ // If this fails, work our way down to the minimum number
+ for (int nhit = maxhits; nhit >= minhits; nhit--) {
+ boolean foundtrack = false;
+ for (List<TrackerHit> candidate : confirmlist) {
+ if (candidate.size() == nhit) {
+ if (!isDuplicate(candidate, tracklist)) {
+ boolean status2 = FindHelix(strategy, candidate);
+ if (status2) {
+ // Create a new track
+ BaseTrack track = new BaseTrack();
+ track.setReferencePoint(IP.v());
+ track.setRefPointIsDCA(false);
+ track.setTrackParameters(helix.parameters(), BField);
+ track.setChisq(helix.chisq()[0]+helix.chisq()[1]);
+ track.setNDF(helix.ndf()[0]+helix.ndf()[1]);
+ track.setCovarianceMatrix(helix.covariance());
+ track.setTrackType(0);
+ List<TrackerHit> castcand = new ArrayList();
+ for (BaseTrackerHitMC hit : candidate) {
+ castcand.add((TrackerHit) hit);
+ }
+ track.addHits(castcand);
+ tracklist.add(track);
+ foundtrack = true;
+ }
+ }
+ }
+ }
+ if (foundtrack) break;
+ }
+ }
+ }
+ event.put("Tracks", tracklist, Track.class, 0);
+ }
+
+ private void AssociateHits(EventHeader event) {
+ List<BaseTrackerHitMC> hitcol = event.get(BaseTrackerHitMC.class,"BaseTrackerHitMC");
+
+ for (SeedStrategy strategy : StrategyList) {
+ for (SeedLayer slyr : strategy.getLayerList()) {
+ slyr.clearHitList();
+ for (BaseTrackerHitMC hit : hitcol) {
+ for (SimTrackerHit simhit : hit.getSimHits()) {
+ if (simhit.getLayer() == slyr.Layer) {
+ if (simhit.getSubdetector().getName().equals(slyr.getDetName())) {
+ slyr.addHit(hit);
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+ }
+ public List<SeedStrategy> getStrategyList() {
+ return StrategyList;
+ }
+
+ public void putStrategyList(List<SeedStrategy> StrategyList) {
+ this.StrategyList = StrategyList;
+ return;
+ }
+
+ private List<SeedCandidate> FindSeeds(SeedStrategy strategy) {
+
+ SeedLayer inner = strategy.getSeedInner();
+ SeedLayer middle = strategy.getSeedMiddle();
+ SeedLayer outer = strategy.getSeedOuter();
+
+ double RMin = strategy.getMinPT() / (0.0003 * BField);
+ double dMax = strategy.getMaxDCA();
+
+ // Todo: add code to limit seeds to those that satisfy cuts
+ List<SeedCandidate> seedlist = new ArrayList();
+
+ for (TrackerHit si : inner.getHitList()) {
+ double[] pos1 = si.getPosition();
+ double r1 = Math.sqrt(pos1[0]*pos1[0] + pos1[1]*pos1[1]);
+ double phi1 = Math.atan2(pos1[1],pos1[0]);
+ double dphi1 = Math.asin((2*RMin*dMax - dMax*dMax-r1*r1)/(2*r1*(RMin-dMax)));
+ for (TrackerHit sm : middle.getHitList()) {
+ double[] pos2 = sm.getPosition();
+ double r2 = Math.sqrt(pos2[0]*pos2[0] + pos2[1]*pos2[1]);
+ double phi2 = Math.atan2(pos2[1],pos2[0]);
+ double dphi2 = Math.asin((2*RMin*dMax - dMax*dMax-r2*r2)/(2*r2*(RMin-dMax)));
+ if (Math.abs(phi2-phi1) > Math.abs(dphi2-dphi1)) continue;
+
+ for (TrackerHit so : outer.getHitList()) {
+ double[] pos3 = so.getPosition();
+ double r3 = Math.sqrt(pos3[0]*pos3[0] + pos3[1]*pos3[1]);
+ double phi3 = Math.atan2(pos3[1],pos3[0]);
+ double dphi3 = Math.asin((2*RMin*dMax - dMax*dMax-r3*r3)/(2*r3*(RMin-dMax)));
+ if (Math.abs(phi3-phi2) > Math.abs(dphi3-dphi2)) continue;
+
+ List<TrackerHit> hitlist = new ArrayList();
+ hitlist.add(si);
+ hitlist.add(sm);
+ hitlist.add(so);
+ seedlist.add(new SeedCandidate(hitlist));
+ }
+ }
+ }
+ System.out.println(" Number of seeds: "+seedlist.size());
+
+ return seedlist;
+ }
+
+ private boolean FindHelix(SeedStrategy strategy, List<BaseTrackerHitMC> hitlist) {
+ boolean status = false;
+ int np = hitlist.size();
+ double[] xx = new double[np];
+ double[] yy = new double[np];
+ double[] zz = new double[np];
+ double[] drphi = new double[np];
+ double[] dz = new double[np];
+
+ for (int i=0; i<np; i++) {
+ BaseTrackerHitMC hit = hitlist.get(i);
+ double[] position = hit.getPosition();
+ xx[i] = position[0];
+ yy[i] = position[1];
+ zz[i] = position[2];
+ double[] covmat = hit.getCovMatrix();
+ drphi[i] = rphi_error(position, covmat);
+ dz[i] = Math.sqrt(covmat[5]);
+ }
+ boolean goodfit = hf.fit(xx, yy, zz, drphi, dz, np);
+ if (goodfit) {
+ helix = hf.getFit();
+ double[] params = helix.parameters();
+ double pT = 0.0003 * BField / Math.abs(params[2]);
+ if (helix.chisq()[0]+helix.chisq()[1] < strategy.getMaxChisq()) {
+ if (pT > strategy.getMinPT()) {
+ double d0 = params[0];
+ if (d0 < strategy.getMaxDCA()) {
+ double z0 = params[3];
+ if (z0 < strategy.getMaxZ0()) {
+ System.out.println(" d0 "+params[0]);
+ System.out.println(" phi0 "+params[1]);
+ System.out.println(" curvatures "+params[2]);
+ System.out.println(" z0 "+params[3]);
+ System.out.println(" slope "+params[4]);
+ System.out.println(" pT "+pT);
+ status = true;
+ }
+ }
+ }
+ }
+ }
+ return status;
+ }
+
+ private List<List<TrackerHit>> FindConfirms(SeedStrategy strategy, SeedCandidate seed) {
+ // Create a list of possible confirmation hits for each confirmation layer
+ List<List<TrackerHit>> confirmbylayer = new ArrayList();
+ // Loop over the various layers
+ for (SeedLayer layer : strategy.getConfirmLayers()) {
+ // Get the list of potential confirmation hits for this layer
+ // Todo - select only hits near tracks
+ List<TrackerHit> confirmhits = layer.getHitList();
+ // If we have some confirmation hits in this layer, add the list of hits for this layer
+ if (confirmhits.size()>0) confirmbylayer.add(confirmhits);
+ }
+ // Initialize a list of track candidates that include confirmation hits
+ List<List<TrackerHit>> candlist = new ArrayList();
+ // check that there are sufficient layers with confirmation hits
+ if (confirmbylayer.size() >= strategy.getMinConfirm()) {
+ // Start with our seed hits as a candidate
+ candlist.add(seed.getTrackerHits());
+ // Loop over all the confirming layers
+ for (List<TrackerHit> confirmhits : confirmbylayer) {
+ // Create a list of new candidates that have hits added from this layer
+ List<List<TrackerHit>> newcandlist = new ArrayList();
+ // Loop over all existing candidates
+ for (List<TrackerHit> oldcand : candlist) {
+ // Loop over all the hits in this confirming layer
+ for (TrackerHit hit : confirmhits) {
+ // Create a new track candidate that adds this hit
+ List<TrackerHit> newcand = new ArrayList();
+ boolean status = newcand.addAll(oldcand);
+ newcand.add(hit);
+ newcandlist.add(newcand);
+ }
+ }
+ boolean status = candlist.addAll(newcandlist);
+ }
+ }
+ // Remove candidates that have too few confirmation hits
+// ListIterator<List<BaseTrackerHitMC>> itr = candlist.listIterator();
+// while (itr.hasNext()) {
+// List<BaseTrackerHitMC> hitlist = itr.next();
+// if (hitlist.size() < strategy.getMinConfirm()+3) candlist.remove(hitlist);
+// }
+
+ return candlist;
+ }
+
+ private boolean isDuplicate(List<TrackerHit> hitlist, List<BaseTrack> tracklist) {
+ boolean isDuplicate = false;
+ for (BaseTrack track : tracklist) {
+ List<TrackerHit> hitlist2 = track.getTrackerHits();
+ boolean matchall = true;
+ if (hitlist.size() <= hitlist2.size()) {
+ for ( BaseTrackerHitMC hit1 : hitlist) {
+ boolean match = false;
+ for (TrackerHit hit2 : hitlist2) {
+ if (hit1 == (BaseTrackerHitMC) hit2) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ matchall = false;
+ break;
+ }
+ }
+ if (matchall) {
+ isDuplicate = true;
+ break;
+ }
+ }
+ }
+ return isDuplicate;
+ }
+
+ private double rphi_error(double[] position, double[] covmat) {
+ // Todo: include MS errors in weight
+ double x = position[0];
+ double y = position[1];
+ double r2 = x * x + y * y;
+ double varxx = covmat[0];
+ double varxy = covmat[1];
+ double varyy = covmat[2];
+ return Math.sqrt((y * y * varxx + x * x * varyy - 2 * x * y * varxy) / r2);
+ }
+
+}
\ No newline at end of file
lcsim/sandbox/Partridge
diff -N SeedTrackerDriver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SeedTrackerDriver.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,34 @@
+/*
+ * SeedTrackerDriver.java
+ *
+ * Created on March 29, 2006, 4:58 PM
+ *
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import org.lcsim.contrib.seedtracker.SeedTracker;
+import org.lcsim.contrib.seedtracker.SmearMCHits;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+
+/**
+ *
+ * @author Richard Partridge
+ * @version 1.0
+ */
+public class SeedTrackerDriver extends Driver
+{
+ /** Creates a new instance of SeedTrackerDriver */
+ public SeedTrackerDriver()
+ {
+ add(new SmearMCHits());
+ add(new SeedTracker());
+ }
+
+ public void process(EventHeader event)
+ {
+ super.process(event);
+ return;
+ }
+}
lcsim/sandbox/Partridge
diff -N SmearMCHits.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SmearMCHits.java 6 Aug 2007 23:59:57 -0000 1.1
@@ -0,0 +1,82 @@
+/*
+ * SmearMCHits.java
+ *
+ * Created on July 12, 2006, 10:25 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.seedtracker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import org.lcsim.util.Driver;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.base.BaseTrackerHitMC;
+
+/**
+ *
+ * @author partridge
+ */
+public class SmearMCHits extends Driver{
+
+ Random rn = new Random();
+ double drphi = 0.005;
+ double dz = 0.005;
+
+ /** Creates a new instance of SmearMCHits */
+ public SmearMCHits() {
+ }
+
+ public void process(EventHeader event) {
+
+ // Initialize the TrackerHit list
+ List<BaseTrackerHitMC> trkhits = new ArrayList<BaseTrackerHitMC>();
+ // Get the SimTrackerHit collections
+ List<List<SimTrackerHit>> allgenhits = event.get(SimTrackerHit.class);
+ // Loop over the various hit collections
+ for (List<SimTrackerHit> genhitcol : allgenhits) {
+ // Now loop over the hits in a particular collection
+ for (SimTrackerHit genhit : genhitcol) {
+ // Generate a new BaseTrackerHitMC for each SimTrackerHit
+ // Note: treat all layers the same for now, hard code the resolution
+ double x = genhit.getPoint()[0];
+ double y = genhit.getPoint()[1];
+ double z = genhit.getPoint()[2];
+ double r = Math.sqrt(x*x + y*y);
+ double phi = Math.atan2(y,x);
+ phi = phi + (drphi / r) * rn.nextGaussian();
+ z = z + dz * rn.nextGaussian();
+ // Fill in smeared position
+ double[] pos = new double[3];
+ pos[0] = r * Math.cos(phi);
+ pos[1] = r * Math.sin(phi);
+ pos[2] = z;
+ // covariance matrix in lower triangular form
+ double[] cov = new double[6];
+ cov[0] = Math.pow(Math.sin(phi)*drphi,2);
+ cov[1] = -Math.sin(phi)*Math.cos(phi)*drphi*drphi;
+ cov[2] = Math.pow(Math.cos(phi)*drphi,2);
+ cov[3] = 0.;
+ cov[4] = 0.;
+ cov[5] = dz*dz;
+
+ double time = genhit.getTime();
+
+ double dedx = genhit.getdEdx();
+
+ int type = 0;
+ // Create the list of SimTrackerHits for this TrackerHit and add our hit to the list
+ List<SimTrackerHit> hits = new ArrayList<SimTrackerHit>();
+ hits.add(genhit);
+ // Create a new TrackerHit and add it to our list of tracker hits
+ trkhits.add(new BaseTrackerHitMC(pos, cov, time, dedx, type, hits));
+ }
+ }
+ // Put the list of TrackerHits into the event
+ event.put("BaseTrackerHitMC",trkhits,BaseTrackerHitMC.class,0);
+ }
+}
CVSspam 0.2.8