Commit in lcsim/src/org/lcsim/contrib/uiowa on MAIN
FindSubClusters.java+238added 1.1
ReclusterDTreeDriver.java+41-1171.19 -> 1.20
+279-117
1 added + 1 modified, total 2 files
MJC: (contrib) Refactor code that looks for structure inside DTree clusters so that it runs in its own driver

lcsim/src/org/lcsim/contrib/uiowa
FindSubClusters.java added at 1.1
diff -N FindSubClusters.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ FindSubClusters.java	6 Jun 2008 00:07:59 -0000	1.1
@@ -0,0 +1,238 @@
+package org.lcsim.contrib.uiowa;
+
+import java.util.*; 
+
+import org.lcsim.util.*;
+import org.lcsim.util.hitmap.*;
+import org.lcsim.event.*;
+import org.lcsim.event.util.*;
+import org.lcsim.recon.cluster.mipfinder.*;
+import org.lcsim.recon.cluster.util.*;
+import org.lcsim.recon.cluster.clumpfinder.*;
+
+/**
+ * Find subclusters inside larger clusters (e.g. Directed Trees).
+ *
+ */
+
+public class FindSubClusters extends Driver
+{
+    public FindSubClusters(String inputLargeClusterList, 
+			   double newMipFinderRadius,
+			   int minHitsToBeTreatedAsCluster,
+			   boolean removePoorQualityMips,
+			   String outputOldMipList,
+			   String outputNewMipList,
+			   String outputClumpList,
+			   String outputBlockList,
+			   String outputLeftoverHitClusters,
+			   String outputMapTreeToTargets,
+			   String outputMapSharedToTree)
+    {
+	m_inputLargeClusterListName = inputLargeClusterList;
+	m_newMipFinderRadius = newMipFinderRadius;
+	m_minHitsToBeTreatedAsCluster = minHitsToBeTreatedAsCluster;
+	m_removePoorQualityMips = removePoorQualityMips;
+	m_doOldMipsOutsideTrees = false;
+	m_outputOldMipListName = outputOldMipList;
+	m_outputNewMipListName = outputNewMipList;
+	m_outputClumpListName = outputClumpList;
+	m_outputBlockListName = outputBlockList;
+	m_outputLeftoverHitClustersName = outputLeftoverHitClusters;
+	m_outputMapTreeToTargetsName = outputMapTreeToTargets;
+	m_outputMapSharedToTreeName = outputMapSharedToTree;
+    }
+    
+    Clusterer m_clustererForOldMips;
+    public void enableBarrelEndcapCrossing(String inputBarrelHitList, String inputBarrelHitListNearBoundary,
+					   String inputEndcapHitList, String inputEndcapHitListNearBoundary)
+    {
+	m_doOldMipsOutsideTrees = true;
+	m_inputBarrelHitListName = inputBarrelHitList;
+	m_inputBarrelHitListNearBoundaryName = inputBarrelHitListNearBoundary;
+	m_inputEndcapHitListName = inputEndcapHitList;
+	m_inputEndcapHitListNearBoundaryName = inputEndcapHitListNearBoundary;
+    }
+
+    public void process(EventHeader event) 
+    {
+	// Read in
+	m_event = event;
+	List<Cluster> dTreeClusters = event.get(Cluster.class, m_inputLargeClusterListName);
+
+	// Book-keeping
+	Map<Cluster, List<Cluster>> targetsInTree = new HashMap<Cluster, List<Cluster>>();
+	Map<Cluster, Cluster> treeOfSharedCluster = new HashMap<Cluster,Cluster>();
+	List<Cluster> mipsOld = new Vector<Cluster>();
+	List<Cluster> mipsNew = new Vector<Cluster>();
+	List<Cluster> clumps = new Vector<Cluster>();
+	List<Cluster> blocks = new Vector<Cluster>();
+	List<Cluster> leftoverHitClusters = new Vector<Cluster>();
+
+	if (m_doOldMipsOutsideTrees) {
+	    // We'll look for MIPs using all hits. Find all hits:
+	    List<CalorimeterHit> availableHits = new Vector<CalorimeterHit>();
+	    for (Cluster clus : dTreeClusters) {
+		availableHits.addAll(clus.getCalorimeterHits());
+	    }
+	    // Look up endcap/barrel split:
+	    List<CalorimeterHit> inputBarrelHitList = event.get(CalorimeterHit.class, m_inputBarrelHitListName);
+	    List<CalorimeterHit> inputBarrelHitListNearBoundary = event.get(CalorimeterHit.class, m_inputBarrelHitListNearBoundaryName);
+	    List<CalorimeterHit> inputEndcapHitList = event.get(CalorimeterHit.class, m_inputEndcapHitListName);
+	    List<CalorimeterHit> inputEndcapHitListNearBoundary = event.get(CalorimeterHit.class, m_inputEndcapHitListNearBoundaryName);	    
+	    // Run the clusterer:
+	    Clusterer oldMipFinder = new MipFinderCrossingBarrelEndcapBorder(inputBarrelHitList, inputBarrelHitListNearBoundary, inputEndcapHitList, inputEndcapHitListNearBoundary);
+	    List<Cluster> firstPassMipsOld = oldMipFinder.createClusters(availableHits);
+	    // Optionally, check quality and back out any bad MIPs:
+	    if (m_removePoorQualityMips) {
+		removePoorQualityMips(firstPassMipsOld);
+	    }
+	    mipsOld.addAll(firstPassMipsOld);
+	}
+
+	// Look for mips & clumps inside DTreeClusters
+	for (Cluster dTreeCluster : dTreeClusters) {
+	    // For book-keeping
+	    List<Cluster> targetList = new Vector<Cluster>();
+	    targetsInTree.put(dTreeCluster, targetList);
+	    HitMap hitsInTree = new HitMap(dTreeCluster.getCalorimeterHits());
+	    // Look for structure
+	    List<Cluster> mipsOldInThisTree = null;
+	    if (m_doOldMipsOutsideTrees) {
+		mipsOldInThisTree = findPreMadeMipsOld(hitsInTree, mipsOld);
+	    } else {
+		mipsOldInThisTree = findMipsOld(hitsInTree);
+		mipsOld.addAll(mipsOldInThisTree); // Inside if() to avoid double-counting when m_doOldMipsOutsideTrees=true
+	    } 
+	    List<Cluster> mipsNewInThisTree = findMipsNew(hitsInTree);
+	    List<Cluster> clumpsInThisTree = findClumps(hitsInTree);
+	    // Record what we found
+	    targetList.addAll(mipsOldInThisTree);
+	    targetList.addAll(mipsNewInThisTree);
+	    targetList.addAll(clumpsInThisTree);
+	    mipsNew.addAll(mipsNewInThisTree);
+ 	    clumps.addAll(clumpsInThisTree);
+	    // Check if tree has structure
+	    int numMipsInTree = mipsOldInThisTree.size() + mipsNewInThisTree.size();
+	    int numClumpsInTree = clumpsInThisTree.size();
+	    if (numMipsInTree==0 && numClumpsInTree==0 && hitsInTree.size()>=m_minHitsToBeTreatedAsCluster) {
+		// No structure found in tree. Treat it as a block.
+		blocks.add(dTreeCluster);
+		targetList.add(dTreeCluster);
+	    } else {
+		// Structure found in tree. Rest are leftover hits:
+		if (hitsInTree.size() > 0) {
+		    BasicCluster leftoverHitCluster = new BasicCluster();
+		    for (CalorimeterHit hit : hitsInTree.values()) {
+			if (hit == null) { throw new AssertionError("null hit in leftoverHits"); }
+			leftoverHitCluster.addHit(hit);
+		    }
+		    leftoverHitClusters.add(leftoverHitCluster);
+		    treeOfSharedCluster.put(leftoverHitCluster, dTreeCluster);
+		}
+	    }
+	}
+
+	// Write out:
+	event.put(m_outputOldMipListName, mipsOld);
+	event.put(m_outputNewMipListName, mipsNew);
+	event.put(m_outputClumpListName, clumps);
+	event.put(m_outputBlockListName, blocks);
+	event.put(m_outputLeftoverHitClustersName, leftoverHitClusters);
+	// These are a bit fiddly:
+	event.put(m_outputMapTreeToTargetsName, targetsInTree);
+	event.put(m_outputMapSharedToTreeName, treeOfSharedCluster);
+    }
+
+    protected List<Cluster> findPreMadeMipsOld(HitMap unusedHits, List<Cluster> mipsOld) {
+	List<Cluster> mipsOldInside = new Vector<Cluster>();
+	for (Cluster mip : mipsOld) {
+	    Set<CalorimeterHit> overlappingHitsThisMIP = new HashSet<CalorimeterHit>();
+	    for (CalorimeterHit mipHit : mip.getCalorimeterHits()) {
+		long id = mipHit.getCellID();
+		if (unusedHits.keySet().contains(id)) {
+		    overlappingHitsThisMIP.add(mipHit);
+		    unusedHits.remove(id);
+		}
+	    }
+	    if (overlappingHitsThisMIP.size()>0) {
+		mipsOldInside.add(mip);
+	    }		    
+	}
+	return mipsOldInside;
+    }
+
+    protected List<Cluster> findMipsOld(HitMap unusedHits) {
+	Clusterer oldMipfinder = new TrackClusterDriver();
+	List<Cluster> mipClustersOld = oldMipfinder.createClusters(unusedHits);
+	if (m_removePoorQualityMips) { 
+	    removePoorQualityMips(mipClustersOld);
+	}
+	for (Cluster mip : mipClustersOld) {
+	    for (CalorimeterHit hit : mip.getCalorimeterHits()) {
+		unusedHits.remove(hit.getCellID());
+	    }
+	}
+	return mipClustersOld;
+    }
+
+    protected List<Cluster> findMipsNew(HitMap unusedHits) {
+	Clusterer newMipFinder = new org.lcsim.recon.cluster.mipfinder.NonProjectiveMipFinder(m_newMipFinderRadius);
+	List<Cluster> mipClustersNew = newMipFinder.createClusters(unusedHits);
+	if (m_removePoorQualityMips) {
+	    removePoorQualityMips(mipClustersNew);
+	}
+	for (Cluster mip : mipClustersNew) {
+	    for (CalorimeterHit hit : mip.getCalorimeterHits()) {
+		unusedHits.remove(hit.getCellID());
+	    }
+	}
+	return mipClustersNew;
+    }
+
+    protected List<Cluster> findClumps(HitMap unusedHits) {
+	Clusterer clumpfinder = new ClumpFinder();
+	List<Cluster> clumpClusters = clumpfinder.createClusters(unusedHits);	    
+	for (Cluster clump : clumpClusters) {
+	    if (clump.getCalorimeterHits().size() == 0) { throw new AssertionError("clump has no hits"); }
+	    if (clump.getCalorimeterHits().contains(null)) { throw new AssertionError("null hit in clump"); }
+	    for (CalorimeterHit hit : clump.getCalorimeterHits()) {
+		unusedHits.remove(hit.getCellID());
+	    }
+	}
+	return clumpClusters;
+    }
+
+    protected void removePoorQualityMips(Collection<Cluster> mipList) {
+	MipQualityDecision check = new MipQualityDecision();
+	List<Cluster> mipsToRemove = new Vector<Cluster>();
+	for (Cluster mip : mipList) {
+	    boolean passesCheck = check.valid(mip);
+	    if (!passesCheck) {
+		mipsToRemove.add(mip);
+	    }
+	}
+	mipList.removeAll(mipsToRemove);
+    }
+
+    String m_inputBarrelHitListName;
+    String m_inputBarrelHitListNearBoundaryName;
+    String m_inputEndcapHitListName;
+    String m_inputEndcapHitListNearBoundaryName;
+
+    String m_inputLargeClusterListName;
+    String m_outputOldMipListName;
+    String m_outputNewMipListName;
+    String m_outputClumpListName;
+    String m_outputBlockListName;
+    String m_outputLeftoverHitClustersName;
+    String m_outputMapTreeToTargetsName;
+    String m_outputMapSharedToTreeName;
+
+    double m_newMipFinderRadius = 0.0;
+    int m_minHitsToBeTreatedAsCluster = 0;
+    boolean m_removePoorQualityMips = false;
+    boolean m_doOldMipsOutsideTrees = false;
+
+    EventHeader m_event;
+}

lcsim/src/org/lcsim/contrib/uiowa
ReclusterDTreeDriver.java 1.19 -> 1.20
diff -u -r1.19 -r1.20
--- ReclusterDTreeDriver.java	5 Jun 2008 16:58:06 -0000	1.19
+++ ReclusterDTreeDriver.java	6 Jun 2008 00:07:59 -0000	1.20
@@ -34,7 +34,7 @@
   * in this package, which uses the implementation in
   * org.lcsim.recon.cluster.directedtree developed by NIU).
   *
-  * @version $Id: ReclusterDTreeDriver.java,v 1.19 2008/06/05 16:58:06 mcharles Exp $
+  * @version $Id: ReclusterDTreeDriver.java,v 1.20 2008/06/06 00:07:59 mcharles Exp $
   * @author Mat Charles <[log in to unmask]>
   */
 
@@ -94,13 +94,22 @@
 	m_eval = new LikelihoodEvaluatorWrapper();
 	m_outputParticleListName = "DTreeReclusteredParticles";
 
-	// Move this to a better place...
+	// Look for hits near boundaries:
 	HitNearBarrelEndcapBoundaryDecision dec = new HitNearBarrelEndcapBoundaryDecision(6.0, 15.0, 1);
 	add(dec);
 	add(new ListFilterDriver(dec, "EcalBarrDigiHits", "EcalBarrDigiHitsNearBoundary", CalorimeterHit.class));
 	add(new ListFilterDriver(dec, "HcalBarrDigiHits", "HcalBarrDigiHitsNearBoundary", CalorimeterHit.class));
 	add(new ListFilterDriver(dec, "EcalEndcapDigiHits", "EcalEndcapDigiHitsNearBoundary", CalorimeterHit.class));
 	add(new ListFilterDriver(dec, "HcalEndcapDigiHits", "HcalEndcapDigiHitsNearBoundary", CalorimeterHit.class));
+	// Set up driver to look for structure inside clusters:
+	FindSubClusters clusDriverECAL = new FindSubClusters("DTreeClustersECAL", m_newMipFinderRadiusECAL, m_minHitsToBeTreatedAsClusterECAL, m_removePoorQualityMips, "OldMipsInsideTreesECAL", "NewMipsInsideTreesECAL", "ClumpsInsideTreesECAL", "BlocksInsideTreesECAL", "LeftoverHitsInsideTreesECAL", "MapTreeToTargetsECAL", "MapSharedToTreeECAL");
+	FindSubClusters clusDriverHCAL = new FindSubClusters("DTreeClustersHCAL", m_newMipFinderRadiusHCAL, m_minHitsToBeTreatedAsClusterHCAL, m_removePoorQualityMips, "OldMipsInsideTreesHCAL", "NewMipsInsideTreesHCAL", "ClumpsInsideTreesHCAL", "BlocksInsideTreesHCAL", "LeftoverHitsInsideTreesHCAL", "MapTreeToTargetsHCAL", "MapSharedToTreeHCAL");
+	if (m_oldMipFinderCrossesTrees) {
+	    clusDriverECAL.enableBarrelEndcapCrossing("EcalBarrDigiHits", "EcalBarrDigiHitsNearBoundary", "EcalEndcapDigiHits", "EcalEndcapDigiHitsNearBoundary");
+	    clusDriverHCAL.enableBarrelEndcapCrossing("HcalBarrDigiHits", "HcalBarrDigiHitsNearBoundary", "HcalEndcapDigiHits", "HcalEndcapDigiHitsNearBoundary");
+	}
+	add(clusDriverECAL);
+	add(clusDriverHCAL);
     }
 
     public void process(EventHeader event) {
@@ -130,130 +139,29 @@
 	allHits.addAll(allHitsHcalBarrel);
 	allHits.addAll(allHitsHcalEndcap);
 
-	List<Cluster> dTreeClusters_EcalBarrel = event.get(Cluster.class, "EcalBarrDTrees");
-	List<Cluster> dTreeClusters_EcalEndcap = event.get(Cluster.class, "EcalEndcapDTrees");
-	List<Cluster> dTreeClusters_HcalBarrel = event.get(Cluster.class, "HcalBarrDTrees");
-	List<Cluster> dTreeClusters_HcalEndcap = event.get(Cluster.class, "HcalEndcapDTrees");
-	Set<Cluster> dTreeClusters_Ecal = new HashSet<Cluster>();
-	Set<Cluster> dTreeClusters_Hcal = new HashSet<Cluster>();
-	dTreeClusters_Ecal.addAll(dTreeClusters_EcalBarrel);
-	dTreeClusters_Ecal.addAll(dTreeClusters_EcalEndcap);
-	dTreeClusters_Hcal.addAll(dTreeClusters_HcalBarrel);
-	dTreeClusters_Hcal.addAll(dTreeClusters_HcalEndcap);
-	if (dTreeClusters_Ecal.size() + dTreeClusters_Hcal.size() != dTreeClusters.size()) { throw new AssertionError("Book-keeping error"); }
-
 	for (Cluster photon : photons) {
 	    if (photon.getCalorimeterHits().contains(null)) {
 		throw new AssertionError("photon contains null hit");
 	    }
 	}
 
-	// Lists of subclusters
-	// Make maps (from subclusters to tree)
-	Map<Cluster, Cluster> treeOfMip = new HashMap<Cluster, Cluster>();
-	Map<Cluster, Cluster> treeOfClump = new HashMap<Cluster,Cluster>();
-	Map<Cluster, Cluster> treeOfLeftoverHits = new HashMap<Cluster,Cluster>();
-
-	// First, look for MIPs in whole event (using only the "oldMipFinder" since the
-	// new one can't handle whole-event combinatorics.)
-	// Start by looking up what hits are we free to cluster (photon hits excluded)
-	List<CalorimeterHit> availableHitsECAL = new Vector<CalorimeterHit>();
-	List<CalorimeterHit> availableHitsHCAL = new Vector<CalorimeterHit>();
-	for (Cluster clus : dTreeClusters_Ecal) {
-	    availableHitsECAL.addAll(clus.getCalorimeterHits());
-	}
-	for (Cluster clus : dTreeClusters_Hcal) {
-	    availableHitsHCAL.addAll(clus.getCalorimeterHits());
-	}
-	// Run the clusterer
-	Clusterer oldMipFinder = new TrackClusterDriver();
-	List<Cluster> firstPassMipsOldEcal = oldMipFinder.createClusters(availableHitsECAL);
-	List<Cluster> firstPassMipsOldHcal = oldMipFinder.createClusters(availableHitsHCAL);
-	// Check quality & back out any bad MIPs:
-	if (m_removePoorQualityMips) {
-	    removePoorQualityMips(firstPassMipsOldEcal);
-	    removePoorQualityMips(firstPassMipsOldHcal);
-	}
-	List<Cluster> firstPassMipsOld = new Vector<Cluster>();
-	firstPassMipsOld.addAll(firstPassMipsOldEcal);
-	firstPassMipsOld.addAll(firstPassMipsOldHcal);
-	Set<CalorimeterHit> firstPassMipHits = new HashSet<CalorimeterHit>();
-	for (Cluster mip : firstPassMipsOld) {
-	    firstPassMipHits.addAll(mip.getCalorimeterHits());
-	}
-
-	// Book-keeping...
-	Map<Cluster, List<Cluster>> targetsInTree = new HashMap<Cluster, List<Cluster>>();
-	Map<Cluster, Cluster> treeOfSharedCluster = new HashMap<Cluster,Cluster>();
-
+	// Earlier, we made lists of DTree clusters & identified structure
+	// within/around them. Load them from the event:
 	List<Cluster> mipsOld = new Vector<Cluster>();
 	List<Cluster> mipsNew = new Vector<Cluster>();
 	List<Cluster> clumps = new Vector<Cluster>();
 	List<Cluster> leftoverHitClusters = new Vector<Cluster>();
 	List<Cluster> treesWithNoStructure = new Vector<Cluster>();
-	if (m_oldMipFinderCrossesTrees) {
-	    mipsOld.addAll(firstPassMipsOld);
-	}
-
-	// Now look for mips & clumps inside DTreeClusters
-	for (Cluster dTreeCluster : dTreeClusters) {
-	    // For book-keeping
-	    List<Cluster> targetList = new Vector<Cluster>();
-	    targetsInTree.put(dTreeCluster, targetList);
-	    // ECAL or HCAL?
-	    boolean treeInECAL = (dTreeClusters_Ecal.contains(dTreeCluster));
-	    boolean treeInHCAL = (dTreeClusters_Hcal.contains(dTreeCluster));
-	    if ( !(treeInECAL || treeInHCAL) || (treeInECAL && treeInHCAL) ) { throw new AssertionError("Book-keeping error"); }
-	    double minHitsToBeTreatedAsCluster;
-	    if (treeInECAL) { 
-		minHitsToBeTreatedAsCluster = m_minHitsToBeTreatedAsClusterECAL ; 
-	    } else {
-		minHitsToBeTreatedAsCluster = m_minHitsToBeTreatedAsClusterHCAL ; 
-	    }
-	    // Prepare hitmap, initially holdling all the hits in the cluster
-	    HitMap hitsInTree = new HitMap();
-	    // Look for structure
-	    List<Cluster> mipClustersOld = new Vector<Cluster>();
-	    List<Cluster> mipClustersNew = new Vector<Cluster>();
-	    List<Cluster> clumpClusters  = new Vector<Cluster>();
-	    if (m_oldMipFinderCrossesTrees) {
-		findStructureInsideClusterSupplyingOldMips(dTreeCluster, treeInECAL, mipClustersOld, mipClustersNew, clumpClusters, hitsInTree, firstPassMipsOld);
-	    } else {
-		findStructureInsideCluster(dTreeCluster, treeInECAL, mipClustersOld, mipClustersNew, clumpClusters, hitsInTree);
-	    }
-	    // Record what we found
-	    targetList.addAll(mipClustersOld);
-	    targetList.addAll(mipClustersNew);
-	    targetList.addAll(clumpClusters);
- 	    mipsNew.addAll(mipClustersNew);
- 	    clumps.addAll(clumpClusters);
-	    if (m_oldMipFinderCrossesTrees) {
-		// No need to record these MIPs again -- we already
-		// made a note of them when running on the whole event
-	    } else {
-		mipsOld.addAll(mipClustersOld);
-	    }
-
-	    int numMipsInTree = mipClustersNew.size() + mipClustersOld.size();
-	    int numClumpsInTree = clumpClusters.size();
-	    if (numMipsInTree==0 && numClumpsInTree==0 && hitsInTree.size()>=minHitsToBeTreatedAsCluster) {
-		// No structure found in tree. Treat it as a block.
-		treesWithNoStructure.add(dTreeCluster);
-		targetList.add(dTreeCluster);
-	    } else {
-		// Structure found in tree. Rest are leftover hits:
-		if (hitsInTree.size() > 0) {
-		    BasicCluster leftoverHitCluster = new BasicCluster();
-		    for (CalorimeterHit hit : hitsInTree.values()) {
-			if (hit == null) { throw new AssertionError("null hit in leftoverHits"); }
-			leftoverHitCluster.addHit(hit);
-		    }
-		    leftoverHitClusters.add(leftoverHitCluster);
-		    treeOfSharedCluster.put(leftoverHitCluster, dTreeCluster);
-		}
-	    }
-	}
-
+	mipsOld.addAll(event.get(Cluster.class, "OldMipsInsideTreesECAL"));
+	mipsOld.addAll(event.get(Cluster.class, "OldMipsInsideTreesHCAL"));
+	mipsNew.addAll(event.get(Cluster.class, "NewMipsInsideTreesECAL"));
+	mipsNew.addAll(event.get(Cluster.class, "NewMipsInsideTreesHCAL"));
+	clumps.addAll(event.get(Cluster.class, "ClumpsInsideTreesECAL"));
+	clumps.addAll(event.get(Cluster.class, "ClumpsInsideTreesHCAL"));
+	leftoverHitClusters.addAll(event.get(Cluster.class, "LeftoverHitsInsideTreesECAL"));
+	leftoverHitClusters.addAll(event.get(Cluster.class, "LeftoverHitsInsideTreesHCAL"));
+	treesWithNoStructure.addAll(event.get(Cluster.class, "BlocksInsideTreesECAL"));
+	treesWithNoStructure.addAll(event.get(Cluster.class, "BlocksInsideTreesHCAL"));
 	List<Cluster> mips = new Vector<Cluster>();
 	mips.addAll(mipsOld);
 	mips.addAll(mipsNew);
@@ -262,8 +170,22 @@
 	    System.out.println("Found "+mips.size()+" mips, "+clumps.size()+" clumps, "+photons.size()+" photons, "+leftoverHitClusters.size()+" leftover-hit-clusters, "+treesWithNoStructure.size()+" large DTrees with no structure, and "+trackList.size()+" tracks in event.");
 	}
 
-	List<Cluster> electronClusters = new Vector<Cluster>();
-	List<Track>   electronTracks   = new Vector<Track>();
+	// Also load book-keeping maps that record what subclusters or hits
+	// belong to what tree:
+	Map<Cluster, List<Cluster>> targetsInTreeECAL = ((Map<Cluster, List<Cluster>>)(event.get("MapTreeToTargetsECAL")));
+	Map<Cluster, Cluster> treeOfSharedClusterECAL = ((Map<Cluster, Cluster>)(event.get("MapSharedToTreeECAL")));
+	Map<Cluster, List<Cluster>> targetsInTreeHCAL = ((Map<Cluster, List<Cluster>>)(event.get("MapTreeToTargetsHCAL")));
+	Map<Cluster, Cluster> treeOfSharedClusterHCAL = ((Map<Cluster, Cluster>)(event.get("MapSharedToTreeHCAL")));
+	Map<Cluster, List<Cluster>> targetsInTree = new HashMap<Cluster, List<Cluster>>();
+	Map<Cluster, Cluster> treeOfSharedCluster = new HashMap<Cluster,Cluster>();
+	targetsInTree.putAll(targetsInTreeECAL);
+	targetsInTree.putAll(targetsInTreeHCAL);
+	treeOfSharedCluster.putAll(treeOfSharedClusterECAL);
+	treeOfSharedCluster.putAll(treeOfSharedClusterHCAL);
+	// Legacy maps, no longer used.
+	Map<Cluster, Cluster> treeOfMip = new HashMap<Cluster, Cluster>();
+	Map<Cluster, Cluster> treeOfClump = new HashMap<Cluster,Cluster>();
+	Map<Cluster, Cluster> treeOfLeftoverHits = new HashMap<Cluster,Cluster>();
 
 	// Match tracks
 	// ------------
@@ -274,6 +196,8 @@
 	List<Cluster> chargedHadronLikePhotons = new Vector<Cluster>();
 	List<Cluster> modifiedPhotonClusters = new Vector<Cluster>();
 	List<Cluster> photonLikePhotons = new Vector<Cluster>();
+	List<Cluster> electronClusters = new Vector<Cluster>();
+	List<Track>   electronTracks   = new Vector<Track>();
 	photonHandling(photons, electronClusters, chargedHadronLikePhotons, modifiedPhotonClusters, photonLikePhotons, trackList, electronTracks, clustersMatchedToTracks, tracksMatchedToClusters);
 
 	// Resume track matching
CVSspam 0.2.8