Commit in lcsim/src/org/lcsim/recon/cheater on MAIN | |||
RemoveMultipleHelicalTrackHitsCheater.java | +144 | added 1.1 |
New cone based algorithm to remove additional tracker hits in overlapping modules
diff -N RemoveMultipleHelicalTrackHitsCheater.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RemoveMultipleHelicalTrackHitsCheater.java 19 Jul 2012 11:51:39 -0000 1.1 @@ -0,0 +1,144 @@
+package org.lcsim.recon.cheater; + +import hep.physics.vec.Hep3Vector; +import hep.physics.vec.VecOp; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.lcsim.event.EventHeader; +import org.lcsim.event.EventHeader.LCMetaData; +import org.lcsim.event.MCParticle; +import org.lcsim.event.RelationalTable; +import org.lcsim.event.RelationalTable.Mode; +import org.lcsim.event.RelationalTable.Weighting; +import org.lcsim.event.base.BaseRelationalTable; +import org.lcsim.fit.helicaltrack.HelicalTrackHit; +import org.lcsim.util.Driver; + +/** + * A driver to remove additional tracker hits from the same particle in a tracking layer. + * This happens in regions where tracker modules are overlapping.</br> + * The SeedTracker takes only one hit per layer and will create additional tracks from the extra hits. + * Not removing those additional hits leads to fake tracks as well as a huge loss in performance.</br> + * This driver uses monte carlo truth to identify hits belonging to the same particle. In addition, + * the removed hits are required to lie within a cone of a given opening angle as seen from the first + * hit of that particle in that plane. This driver should be run <b>after</b> digitization. + * @author <a href="mailto:[log in to unmask]">Christian Grefe</a> + * + */ +public class RemoveMultipleHelicalTrackHitsCheater extends Driver { + + protected String trackHitCollection; + protected double coneAngle; + + public RemoveMultipleHelicalTrackHitsCheater() { + trackHitCollection = "HelicalTrackHits"; + coneAngle = Math.PI/18.; + } + + public void setTrackHitCollection(String trackHitCollection) { + this.trackHitCollection = trackHitCollection; + } + + /** + * Sets the minimum angle between a first hit and a secondary hit in layer. If inside the cone the secondary hit will be removed. + * @param coneAngle + */ + public void setConeAngle(double coneAngle) { + this.coneAngle = coneAngle; + } + + @Override + protected void process(EventHeader event) { + // get the collection of HelicalTrackHits + List<HelicalTrackHit> trackHits = event.get(HelicalTrackHit.class, trackHitCollection); + + // map to store a map of particle to hit relations for each layer. + Map<String, RelationalTable<HelicalTrackHit, MCParticle>> layerToHitsToParticleMap = new HashMap<String, RelationalTable<HelicalTrackHit,MCParticle>>(); + + // map to store the list of hits for each layer + Map<String, List<HelicalTrackHit>> layerToHitsMap = new HashMap<String, List<HelicalTrackHit>>(); + + // map to store all particles contributing to hits of a layer + Map<String, List<MCParticle>> layerToParticleMap = new HashMap<String, List<MCParticle>>(); + + // fill the maps + for (HelicalTrackHit hit : trackHits) { + List<MCParticle> particles = hit.getMCParticles(); + String identifier = hit.getLayerIdentifier(); + if (!layerToHitsMap.containsKey(identifier)) { + layerToHitsToParticleMap.put(identifier, new BaseRelationalTable<HelicalTrackHit, MCParticle>(Mode.MANY_TO_MANY, Weighting.WEIGHTED)); + layerToHitsMap.put(identifier, new ArrayList<HelicalTrackHit>()); + layerToParticleMap.put(identifier, new ArrayList<MCParticle>()); + } + layerToHitsMap.get(identifier).add(hit); + for (MCParticle particle : particles) { + layerToHitsToParticleMap.get(identifier).add(hit, particle); + if (!layerToParticleMap.get(identifier).contains(particle)) { + layerToParticleMap.get(identifier).add(particle); + } + } + + } + + // remove hits in each layer + for (String identifier : layerToHitsMap.keySet()) { + RelationalTable<HelicalTrackHit, MCParticle> layerTable = layerToHitsToParticleMap.get(identifier); + + // lists to store which hits to keep and which to remove + List<HelicalTrackHit> processedHits = new ArrayList<HelicalTrackHit>(); + List<HelicalTrackHit> removeHits = new ArrayList<HelicalTrackHit>(); + for (MCParticle particle : layerToParticleMap.get(identifier)) { + + // we just have a single hit from a particle: nothing to do + if (layerTable.allTo(particle).size() < 2) continue; + List<HelicalTrackHit> particleHits = new ArrayList<HelicalTrackHit>(layerTable.allTo(particle)); + + // sort the hits by distance from the IP + Collections.sort(particleHits, new CompareHelicalTrackHitsByDistanceFromIP()); + for (HelicalTrackHit hit : particleHits) { + Hep3Vector v1 = hit.getCorrectedPosition(); + processedHits.add(hit); + for (HelicalTrackHit otherHit : particleHits) { + if (removeHits.contains(otherHit) || processedHits.contains(otherHit)) continue; + Hep3Vector v12 = VecOp.sub(otherHit.getCorrectedPosition(), v1); + + // calculate angle of the direction of the second hit with respect to the line-of-sight from IP to the first hit + double deltaPhi = Math.acos(VecOp.dot(v1, v12)/(v1.magnitude()*v12.magnitude())); + if (Math.abs(deltaPhi) < coneAngle) { + removeHits.add(otherHit); + } + } + } + } + trackHits.removeAll(removeHits); + } + LCMetaData meta = event.getMetaData(trackHits); + + // replace the collection + event.put(trackHitCollection, trackHits, HelicalTrackHit.class, meta.getFlags()); + } + + /** + * Sort HelicalTrackHits by distance from the IP + */ + protected class CompareHelicalTrackHitsByDistanceFromIP implements Comparator<HelicalTrackHit> { + @Override + public int compare(HelicalTrackHit o1, HelicalTrackHit o2) { + double r1 = o1.getCorrectedPosition().magnitude(); + double r2 = o2.getCorrectedPosition().magnitude(); + if (r1 < r2) { + return -1; + } else if (r2 < r1) { + return 1; + } else { + return 0; + } + } + } +}
Use REPLY-ALL to reply to list
To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1