View Javadoc

1   package org.lcsim.recon.cheater;
2   
3   import java.util.HashMap;
4   import java.util.List;
5   import java.util.Map;
6   import java.util.Set;
7   
8   import org.lcsim.event.EventHeader;
9   import org.lcsim.util.Driver;
10  import org.lcsim.event.RelationalTable;
11  import org.lcsim.event.SimTrackerHit;
12  import org.lcsim.event.MCParticle;
13  import org.lcsim.event.EventHeader.LCMetaData;
14  import org.lcsim.event.base.BaseRelationalTable;
15  
16  /**
17   * A driver to remove additional tracker hits from the same particle in a tracking layer.
18   * This happens in regions where tracker modules are overlapping.</br>
19   * The SeedTracker takes only one hit per layer and will create additional tracks from the extra hits.
20   * Not removing those additional hits leads to fake tracks as well as a huge loss in performance.</br>
21   * This driver uses monte carlo truth to identify hits belonging to the same particle. It should be run <b>before</b> digitization.
22   * @author <a href="mailto:christian.grefe@cern.ch">Christian Grefe</a>
23   *
24   */
25  public class RemoveMultipleTrackHitsCheater extends Driver {
26  	
27  	public RemoveMultipleTrackHitsCheater() {
28  
29  	}
30  	
31  	@Override
32  	protected void process(EventHeader event) {
33  		List<List<SimTrackerHit>> trackerHitCollections = event.get(SimTrackerHit.class);
34  		List<MCParticle> mcParticles = event.getMCParticles();
35  		
36  		// need to relate each mc particle to its hits per collection
37  		Map<LCMetaData, RelationalTable<MCParticle, SimTrackerHit>> collectionToMcToHit = new HashMap<LCMetaData, RelationalTable<MCParticle,SimTrackerHit>>();
38  		
39  		int nHits = 0;
40  		
41  		// build map of hit to mc particle relation
42  		for (List<SimTrackerHit> trackerHitCollection : trackerHitCollections) {
43  			nHits += trackerHitCollection.size();
44  			LCMetaData meta = event.getMetaData(trackerHitCollection);
45  			if (!collectionToMcToHit.containsKey(meta)) {
46  				collectionToMcToHit.put(meta, new BaseRelationalTable<MCParticle, SimTrackerHit>(RelationalTable.Mode.ONE_TO_MANY, RelationalTable.Weighting.UNWEIGHTED));
47  			}
48  			RelationalTable<MCParticle, SimTrackerHit> mcpToHits = collectionToMcToHit.get(meta);
49  			
50  			for (SimTrackerHit hit : trackerHitCollection) {
51  				MCParticle mcParticle = hit.getMCParticle();
52  				if (mcParticles.contains(mcParticle)) {
53  					mcpToHits.add(mcParticle, hit);
54  				}
55  			}
56  		}
57  		
58  		int nHitsRemoved = 0;
59  		
60  		for (LCMetaData meta : collectionToMcToHit.keySet()) {
61  			RelationalTable<MCParticle, SimTrackerHit> mcpToHits = collectionToMcToHit.get(meta);
62  			
63  			for (MCParticle mcp : mcParticles) {
64  				Set<SimTrackerHit> hits = mcpToHits.allFrom(mcp);
65  				// store which layer has been hit by this mc particle
66  				Map<Integer, SimTrackerHit> layerToHits = new HashMap<Integer, SimTrackerHit>();
67  				
68  				for (SimTrackerHit hit : hits) {
69  					int layer = hit.getLayerNumber();
70  					if (layerToHits.containsKey(layer)) {
71  						SimTrackerHit hit2 = layerToHits.get(layer);
72  						// remove hit if in the same layer but not on same module
73  						// detector element is a Sensor and the module is one up in the hierarchy
74  						if (!hit.getDetectorElement().getParent().equals(hit2.getDetectorElement().getParent())) {
75  							event.get(SimTrackerHit.class, meta.getName()).remove(hit);
76  							nHitsRemoved++;
77  						}
78  					} else {
79  						// store that this layer had a hit by this mc particle
80  						layerToHits.put(layer, hit);
81  					}
82  				}
83  			}
84  		}
85  		
86  		if (this.getHistogramLevel() > HLEVEL_NORMAL) System.out.println("Removed "+nHitsRemoved+"/"+nHits+" tracker hits");
87  	}
88  }