View Javadoc

1   /*
2    * SeedCandidate.java
3    *
4    * Created on August 3, 2007, 11:05 AM
5    *
6    * To change this template, choose Tools | Template Manager
7    * and open the template in the editor.
8    */
9   
10  package org.lcsim.recon.tracking.seedtracker;
11  
12  import java.util.ArrayList;
13  import java.util.HashMap;
14  import java.util.HashSet;
15  import java.util.Iterator;
16  import java.util.LinkedList;
17  import java.util.List;
18  import java.util.Map;
19  
20  import java.util.Set;
21  import org.lcsim.event.MCParticle;
22  import org.lcsim.fit.helicaltrack.HelicalTrackFit;
23  import org.lcsim.fit.helicaltrack.HelicalTrackHit;
24  import org.lcsim.fit.helicaltrack.HelixParamCalculator;
25  import org.lcsim.fit.helicaltrack.MultipleScatter;
26  
27  /**
28   * The SeedCandidate class encapsulates information about a track seed as it
29   * progresses throught the SeedTracker track finding algorithm.
30   * @author Richard Partridge
31   * @version 1.0
32   */
33  public class SeedCandidate {
34      
35      private List<HelicalTrackHit> _hits;
36      private HelicalTrackFit _helix;
37      private double _bfield;
38      private SeedStrategy _strategy;
39      private Map<HelicalTrackHit, MultipleScatter> _msmap;
40      private List<ScatterAngle> _scatters;
41      private LinkedList<SeedLayer> _unchecked;
42      private Set<MCParticle> _mcpset;
43      private Set<Integer> _pdgset;
44      private boolean _debug = false;
45      
46      /**
47       * Create an empty SeedCandidate.
48       */
49      public SeedCandidate(SeedStrategy strategy, double bfield) {
50          _strategy = strategy;
51          _bfield = bfield;
52          _hits = new LinkedList<HelicalTrackHit>();
53          _msmap = new HashMap<HelicalTrackHit, MultipleScatter>();
54          _mcpset = new HashSet<MCParticle>();
55          _pdgset = new HashSet<Integer>();
56       }
57      
58      /**
59       * Create a new SeedCandidate from a list of hits.
60       * @param hits list of hits for this SeedCandidate
61       * @param strategy strategy used for this SeedCandidate
62       */
63      public SeedCandidate(List<HelicalTrackHit> hits, SeedStrategy strategy, double bfield) {
64          this(strategy, bfield);
65          _hits.addAll(hits);
66          FindMCParticles();
67      }
68      
69      /**
70       * Create a new SeedCandidate from a list of hits and a helix.
71       * @param hits list of hits for this SeedCandidate
72       * @param strategy strategy used for this SeedCandidate
73       * @param helix HelicalTrackFit associated with the SeedCandidate
74       */
75      public SeedCandidate(List<HelicalTrackHit> hits, SeedStrategy strategy, HelicalTrackFit helix, double bfield) {
76          this(hits, strategy, bfield);
77          _helix = helix;
78      }
79  
80      public SeedCandidate(List<HelicalTrackHit> hits, SeedStrategy strategy) {
81          this(hits, strategy, 0.);
82      }
83  
84      /**
85       * Creates a clone of an existing instance of SeedCandidate.
86       * @param seed existing SeedCandidate to be cloned
87       */
88      public SeedCandidate(SeedCandidate seed) {
89          this(seed._strategy, seed._bfield);
90          _hits.addAll(seed.getHits());
91          _helix = seed.getHelix();
92          _msmap.putAll(seed.getMSMap());
93          List<ScatterAngle> oldscat = seed.getScatterAngles();
94          if (oldscat != null) _scatters = new ArrayList<ScatterAngle>(oldscat);
95          setUncheckedLayers(seed.getUncheckedLayers());
96          _mcpset.addAll(seed.getMCParticles());
97          _pdgset.addAll(seed.getTruePDG());
98      }
99      
100     /**
101      * Assign a list of TrackerHits to the SeedCandidate.
102      * @param hits list of hits for this SeedCandidate
103      */
104     public void setHits(List<HelicalTrackHit> hits) {
105         _hits.clear();
106         _hits.addAll(hits);
107         FindMCParticles();
108         return;
109     }
110     
111     /**
112      * Add a hit to the SeedCandidate.
113      * @param hit TrackerHit to be added to the SeedCandidate
114      */
115     public void addHit(HelicalTrackHit hit) {
116         //  If this is a new hit, add it to the list of hits and calculate the multiple scattering error
117         if (!_hits.contains(hit)) {
118             _hits.add(hit);
119             UpdateMSMap(hit);
120 
121             //  If this is the first hit, find the associated MC
122             if (_hits.size() == 1) {
123                 FindMCParticles();
124             } else {
125                 CheckHit(hit);
126             }
127         }
128 
129         return;
130     }
131     
132     /**
133      * Return a list of hits associated with this SeedCandidate.
134      * @return list of hits
135      */
136     public List<HelicalTrackHit> getHits() {
137         return _hits;
138     }
139     
140     /**
141      * Set the SeedStrategy used to construct this SeedCandidate.
142      * @param strategy strategy used to construct this SeedCandidate
143      */
144     
145     public void setStrategy(SeedStrategy strategy) {
146         _strategy = strategy;
147         return;
148     }
149     
150     /**
151      * Return the SeedStrategy used to construct this SeedCandidate.
152      * @return strategy used to construct this SeedCandidate
153      */
154     public SeedStrategy getSeedStrategy() {
155         return _strategy;
156     }
157     
158     /**
159      * Associate a HelicalTrackFit with this SeedCandidate.
160      * @param helix helix for this SeedCandidate
161      */
162     public void setHelix(HelicalTrackFit helix) {
163         _helix = helix;
164        return;
165     }
166     
167     /**
168      * Return the HelicalTrackFit associated with this SeedCandidate.
169      * @return HelicalTrackFit associated with the SeedCandidate
170      */
171     public HelicalTrackFit getHelix() {
172         return _helix;
173     }
174     
175     public void setMSMap(Map<HelicalTrackHit, MultipleScatter> msmap) {
176         _msmap = msmap;
177         return;
178     }
179 
180     public Map<HelicalTrackHit, MultipleScatter> getMSMap() {
181         return _msmap;
182     }
183         
184     public void setScatterAngles(List<ScatterAngle> scatters) {
185         
186         //  Save the list of MS scattering angles
187         _scatters = scatters;
188         
189         //  Calculate the multiple scattering error for each hit
190         for (HelicalTrackHit hit : _hits) {
191             UpdateMSMap(hit);
192         }
193         
194         return;
195     }
196     
197     public List<ScatterAngle> getScatterAngles() {
198         return _scatters;
199     }
200 
201     public void setUncheckedLayers(List<SeedLayer> unchecked) {
202         _unchecked = new LinkedList<SeedLayer>();
203         if (unchecked != null) _unchecked.addAll(unchecked);
204         return;
205     }
206 
207     public LinkedList<SeedLayer> getUncheckedLayers() {
208         return _unchecked;
209     }
210 
211     public SeedLayer getNextLayer() {
212         return _unchecked.poll();
213     }
214 
215     public Set<MCParticle> getMCParticles() {
216         return _mcpset;
217     }
218 
219     public void setTruePDG(int pdgid) {
220         _pdgset.add(pdgid);
221     }
222     
223     public Set<Integer> getTruePDG() {
224         return _pdgset;
225     }
226 
227     public boolean isTrueSeed() {
228         if (_mcpset.size() == 0) return false;
229         if (_pdgset.size() == 0) return true;
230         for (MCParticle mcp : _mcpset) {
231             for (int truepdg : _pdgset) {
232                 if (mcp.getPDGID() == truepdg) return true;
233             }
234         }
235         return false;
236     }
237 
238     public double getBField() {
239         return _bfield;
240     }
241     
242     /*
243      * Print information about this SeedCandidate
244      */
245     @Override
246     public String toString() {
247         String str = "SeedCandidate:\n";
248         str += String.format("%s",this.getHelix().toString());
249         List<HelicalTrackHit> hits = this.getHits();
250         str += String.format("chi2=%f, strategy=%s and %d hits:\n",this.getHelix().chisqtot(),this.getSeedStrategy().getName(),hits.size());
251         for (HelicalTrackHit hit : hits) {
252             double drphi_ms = this.getMSMap().get(hit).drphi();
253             double dz_ms = this.getMSMap().get(hit).dz();
254             double dz = Math.sqrt(hit.getCorrectedCovMatrix().diagonal(2));
255             str += String.format("Layer=%d c_pos=%s drphi=%f drphi_ms=%f dz=%f dz_ms=%f\n",hit.Layer(),hit.getCorrectedPosition().toString()
256                                                                                   ,hit.drphi(),drphi_ms,dz,dz_ms);
257         }
258         return str;
259     }
260     
261     private void UpdateMSMap(HelicalTrackHit hit) {
262         if (_helix == null) return;
263         if (_scatters == null) return;
264         _msmap.put(hit, MultipleScattering.CalculateScatter(hit, _helix, _scatters));
265         return;
266     }
267 
268     private void FindMCParticles() {
269 
270         if (_hits.size() == 0) return;
271         for (MCParticle mcp : _hits.get(0).getMCParticles()) {
272             boolean good = true;
273             for (HelicalTrackHit hit : _hits) {
274                 if (!hit.getMCParticles().contains(mcp)) {
275                     good = false;
276                     break;
277                 }
278             }
279             if (!good) continue;
280             if (CheckMCParticle(mcp)) _mcpset.add(mcp);
281         }
282 
283         return;
284     }
285 
286     private boolean CheckMCParticle(MCParticle mcp) {
287 
288         //  Check that we have a strategy defined
289         if (_strategy == null) return false;
290         if(mcp==null)return false;
291         //  Get the helix parameters for this MC Particle
292         HelixParamCalculator mchelix = new HelixParamCalculator(mcp, _bfield);
293 
294         //  Check that the momentum of the MC particle is above the cut
295         if (mchelix.getMCTransverseMomentum() < _strategy.getMinPT()) return false;
296 
297         //  Check the x-y impact parameter
298         if (Math.abs(mchelix.getDCA()) > _strategy.getMaxDCA()) return false;
299 
300         //  Check the s-z impact parameter
301         if (Math.abs(mchelix.getZ0()) > _strategy.getMaxZ0()) return false;
302 
303         return true;
304     }
305 
306     private void CheckHit(HelicalTrackHit hit) {
307         
308         //  First check if we have any true MCParticles
309         if (_mcpset.size() == 0) return;
310         
311         //  Get an iterator for the set so we can remove mcp's that don't match
312         Iterator<MCParticle> iter = _mcpset.iterator();
313         
314         //  Loop over the MCParticles that make this a "true seed"
315         while (iter.hasNext()) {
316             MCParticle mcp = iter.next();
317             
318             //  Remove MCParticles from the true seed list if they aren't associated with this hit
319             if (!hit.getMCParticles().contains(mcp)) iter.remove();
320             }
321 
322         return;
323     }
324 }