Commit in lcsim/src/org/lcsim/contrib/uiowa on MAIN
ReclusterDTreeDriver.java+130-801.39 -> 1.40
ReclusterDriver.java+25-51.32 -> 1.33
+155-85
2 modified files
MJC: (contrib) Use muon endcaps in PFA

lcsim/src/org/lcsim/contrib/uiowa
ReclusterDTreeDriver.java 1.39 -> 1.40
diff -u -r1.39 -r1.40
--- ReclusterDTreeDriver.java	12 Aug 2008 23:01:56 -0000	1.39
+++ ReclusterDTreeDriver.java	12 Aug 2008 23:42:52 -0000	1.40
@@ -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.39 2008/08/12 23:01:56 tjkim Exp $
+  * @version $Id: ReclusterDTreeDriver.java,v 1.40 2008/08/12 23:42:52 mcharles Exp $
   * @author Mat Charles <[log in to unmask]>
   */
 
@@ -71,8 +71,12 @@
 
     protected int m_minHitsToBeTreatedAsClusterECAL = 15;
     protected int m_minHitsToBeTreatedAsClusterHCAL = 20;
+    protected int m_minHitsToBeTreatedAsClusterMCAL = 5;
+    protected int m_minHitsToBeTreatedAsClusterFCAL = m_minHitsToBeTreatedAsClusterECAL;
     protected double m_newMipFinderRadiusECAL = 20.0;
     protected double m_newMipFinderRadiusHCAL = 50.0;
+    protected double m_newMipFinderRadiusMCAL = 100.0;
+    protected double m_newMipFinderRadiusFCAL = m_newMipFinderRadiusECAL;
     protected boolean m_allowSharingOfIsolatedHits = true;
 
     protected double m_jetScoreThreshold = 0.7; // don't hard-code
@@ -84,6 +88,9 @@
 
     protected boolean m_debugSeedSplitting = false;
 
+    protected boolean m_useMucal = true;
+    protected boolean m_useFcal = false;
+
     public void writeExtraEventOutput(boolean writeExtra) {
 	m_writeExtraEventOutput = writeExtra;
     }
@@ -113,6 +120,8 @@
 	// 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");
+	FindSubClusters clusDriverMCAL = new FindSubClusters("DTreeClustersMCAL", m_newMipFinderRadiusMCAL, m_minHitsToBeTreatedAsClusterMCAL, m_removePoorQualityMips, "OldMipsInsideTreesMCAL", "NewMipsInsideTreesMCAL", "ClumpsInsideTreesMCAL", "BlocksInsideTreesMCAL", "LeftoverHitsInsideTreesMCAL", "MapTreeToTargetsMCAL", "MapSharedToTreeMCAL");
+	FindSubClusters clusDriverFCAL = new FindSubClusters("DTreeClustersFCAL", m_newMipFinderRadiusFCAL, m_minHitsToBeTreatedAsClusterFCAL, m_removePoorQualityMips, "OldMipsInsideTreesFCAL", "NewMipsInsideTreesFCAL", "ClumpsInsideTreesFCAL", "BlocksInsideTreesFCAL", "LeftoverHitsInsideTreesFCAL", "MapTreeToTargetsFCAL", "MapSharedToTreeFCAL");
 	if (m_oldMipFinderCrossesTrees) {
 	    clusDriverECAL.enableBarrelEndcapCrossing("EcalBarrDigiHits", "EcalBarrDigiHitsNearBoundary", "EcalEndcapDigiHits", "EcalEndcapDigiHitsNearBoundary");
 	    clusDriverHCAL.enableBarrelEndcapCrossing("HcalBarrDigiHits", "HcalBarrDigiHitsNearBoundary", "HcalEndcapDigiHits", "HcalEndcapDigiHitsNearBoundary");
@@ -120,9 +129,17 @@
 	if (m_findExtraNNClusters) {
 	    clusDriverECAL.setNNrange(1,1,1);
 	    clusDriverHCAL.setNNrange(2,2,1);
+	    clusDriverMCAL.setNNrange(2,2,1);
+	    clusDriverFCAL.setNNrange(1,1,1);
 	}
 	add(clusDriverECAL);
 	add(clusDriverHCAL);
+	if (m_useMucal) {
+	    add(clusDriverMCAL);
+	}
+	if (m_useFcal) {
+	    add(clusDriverFCAL);
+	}
     }
 
     public void process(EventHeader event) {
@@ -151,12 +168,29 @@
 	List<CalorimeterHit> allHitsEcalEndcap = m_event.get(CalorimeterHit.class, "EcalEndcapDigiHits");
 	List<CalorimeterHit> allHitsHcalBarrel = m_event.get(CalorimeterHit.class, "HcalBarrDigiHits");
 	List<CalorimeterHit> allHitsHcalEndcap = m_event.get(CalorimeterHit.class, "HcalEndcapDigiHits");
+	List<CalorimeterHit> allHitsMcalBarrel = null;
+	List<CalorimeterHit> allHitsMcalEndcap = null;
+	List<CalorimeterHit> allHitsFcalEndcap = null;
+	if (m_useMucal) {
+	    allHitsMcalBarrel = m_event.get(CalorimeterHit.class, "MuonBarrHits");
+	    allHitsMcalEndcap = m_event.get(CalorimeterHit.class, "MuonEndcapHits");
+	}
+	if (m_useFcal) {
+	    allHitsFcalEndcap = m_event.get(CalorimeterHit.class, "ForwardEcalEndcapDigiHits");
+	}
 
 	Set<CalorimeterHit> allHits = new HashSet<CalorimeterHit>();
 	allHits.addAll(allHitsEcalBarrel);
 	allHits.addAll(allHitsEcalEndcap);
 	allHits.addAll(allHitsHcalBarrel);
 	allHits.addAll(allHitsHcalEndcap);
+	if (m_useMucal) {
+	    allHits.addAll(allHitsMcalBarrel);
+	    allHits.addAll(allHitsMcalEndcap);
+	}
+	if (m_useFcal) {
+	    allHits.addAll(allHitsFcalEndcap);
+	}
 
 	for (Cluster photon : photons) {
 	    if (photon.getCalorimeterHits().contains(null)) {
@@ -181,6 +215,20 @@
 	leftoverHitClusters.addAll(event.get(Cluster.class, "LeftoverHitsInsideTreesHCAL"));
 	treesWithNoStructure.addAll(event.get(Cluster.class, "BlocksInsideTreesECAL"));
 	treesWithNoStructure.addAll(event.get(Cluster.class, "BlocksInsideTreesHCAL"));
+	if (m_useMucal) {
+	    mipsOld.addAll(event.get(Cluster.class, "OldMipsInsideTreesMCAL"));
+	    mipsNew.addAll(event.get(Cluster.class, "NewMipsInsideTreesMCAL"));
+	    clumps.addAll(event.get(Cluster.class, "ClumpsInsideTreesMCAL"));
+	    leftoverHitClusters.addAll(event.get(Cluster.class, "LeftoverHitsInsideTreesMCAL"));
+	    treesWithNoStructure.addAll(event.get(Cluster.class, "BlocksInsideTreesMCAL"));
+	}
+	if (m_useFcal) {
+	    mipsOld.addAll(event.get(Cluster.class, "OldMipsInsideTreesFCAL"));
+	    mipsNew.addAll(event.get(Cluster.class, "NewMipsInsideTreesFCAL"));
+	    clumps.addAll(event.get(Cluster.class, "ClumpsInsideTreesFCAL"));
+	    leftoverHitClusters.addAll(event.get(Cluster.class, "LeftoverHitsInsideTreesFCAL"));
+	    treesWithNoStructure.addAll(event.get(Cluster.class, "BlocksInsideTreesFCAL"));
+	}
 	List<Cluster> mips = new Vector<Cluster>();
 	mips.addAll(mipsOld);
 	mips.addAll(mipsNew);
@@ -195,12 +243,34 @@
 	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>> targetsInTreeMCAL = null;
+	Map<Cluster, Cluster> treeOfSharedClusterMCAL = null;
+	Map<Cluster, List<Cluster>> targetsInTreeFCAL = null;
+	Map<Cluster, Cluster> treeOfSharedClusterFCAL = null;
+	if (m_useMucal) {
+	    targetsInTreeMCAL = ((Map<Cluster, List<Cluster>>)(event.get("MapTreeToTargetsMCAL")));
+	    treeOfSharedClusterMCAL = ((Map<Cluster, Cluster>)(event.get("MapSharedToTreeMCAL")));
+	}
+	if (m_useFcal) {
+	    targetsInTreeFCAL = ((Map<Cluster, List<Cluster>>)(event.get("MapTreeToTargetsFCAL")));
+	    treeOfSharedClusterFCAL = ((Map<Cluster, Cluster>)(event.get("MapSharedToTreeFCAL")));
+	}
+
 	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);
+	if (m_useMucal) {
+	    targetsInTree.putAll(targetsInTreeMCAL);
+	    treeOfSharedCluster.putAll(treeOfSharedClusterMCAL);
+	}
+	if (m_useFcal) {
+	    targetsInTree.putAll(targetsInTreeFCAL);
+	    treeOfSharedCluster.putAll(treeOfSharedClusterFCAL);
+	}
+
 	// Legacy maps, no longer used.
 	Map<Cluster, Cluster> treeOfMip = new HashMap<Cluster, Cluster>();
 	Map<Cluster, Cluster> treeOfClump = new HashMap<Cluster,Cluster>();
@@ -607,6 +677,8 @@
 	List<Cluster> leftoverHitClustersToShare = new Vector<Cluster>();
 	List<Cluster> leftoverHitClustersToShareECAL = new Vector<Cluster>();
 	List<Cluster> leftoverHitClustersToShareHCAL = new Vector<Cluster>();
+	List<Cluster> leftoverHitClustersToShareMCAL = new Vector<Cluster>();
+	List<Cluster> leftoverHitClustersToShareFCAL = new Vector<Cluster>();
 	List<Cluster> leftoverHitClustersAllowedInShowers = new Vector<Cluster>();
 	linkableClustersExcludingPhotons.addAll(mips);
 	linkableClustersExcludingPhotons.addAll(clumps);
@@ -630,10 +702,19 @@
 			treeOfSharedCluster.put(tmpClus, tree);
 			leftoverHitClustersToShare.add(tmpClus);
 			boolean hitECAL = (allHitsEcalBarrel.contains(hit) || allHitsEcalEndcap.contains(hit));
+			boolean hitHCAL = (allHitsHcalBarrel.contains(hit) || allHitsHcalEndcap.contains(hit));
+			boolean hitMCAL = m_useMucal && (allHitsMcalBarrel.contains(hit) || allHitsMcalEndcap.contains(hit));
+			boolean hitFCAL = m_useFcal && (allHitsFcalEndcap.contains(hit));
 			if (hitECAL) {
 			    leftoverHitClustersToShareECAL.add(tmpClus);
-			} else {
+			} else if (hitHCAL) {
 			    leftoverHitClustersToShareHCAL.add(tmpClus);
+			} else if (hitMCAL && m_useMucal) {
+			    leftoverHitClustersToShareMCAL.add(tmpClus);
+			} else if (hitFCAL && m_useFcal) {
+			    leftoverHitClustersToShareFCAL.add(tmpClus);
+			} else {
+			    throw new AssertionError("Unknown subdetector");
 			}
 		    }
 		} else {
@@ -722,14 +803,22 @@
 	double maxDistanceForSmallClusters = 250.0; // 25cm isolation cut-off
 	double maxDistanceForDTreeClustersECAL = 150.0; // 15cm isolation (shorter since DTree sharing exists as backup)
 	double maxDistanceForDTreeClustersHCAL = 200.0; // 20cm isolation (shorter since DTree sharing exists as backup)
+	double maxDistanceForDTreeClustersMCAL = 300.0; // 30cm isolation (shorter since DTree sharing exists as backup)
+	double maxDistanceForDTreeClustersFCAL = maxDistanceForDTreeClustersECAL;
 	double maxDistanceForProximityClustersECAL = 100.0; // 10cm isolation (shorter since other sharing exists as backup)
 	double maxDistanceForProximityClustersHCAL = 150.0; // 10cm isolation (shorter since other sharing exists as backup)
+	double maxDistanceForProximityClustersMCAL = 200.0;
+	double maxDistanceForProximityClustersFCAL = maxDistanceForProximityClustersECAL;
 	if (m_allowSharingOfIsolatedHits) {
 	    maxDistanceForSmallClusters = 99999.9; // effectively no cut-off
 	    maxDistanceForDTreeClustersECAL = 99999.9; // effectively no cut-off
 	    maxDistanceForDTreeClustersHCAL = 99999.9; // effectively no cut-off
+	    maxDistanceForDTreeClustersFCAL = 99999.9; // effectively no cut-off
+	    maxDistanceForDTreeClustersMCAL = 99999.9; // effectively no cut-off
 	    maxDistanceForProximityClustersECAL = 99999.9; // effectively no cut-off
 	    maxDistanceForProximityClustersHCAL = 99999.9; // effectively no cut-off
+	    maxDistanceForProximityClustersFCAL = 99999.9; // effectively no cut-off
+	    maxDistanceForProximityClustersMCAL = 99999.9; // effectively no cut-off
 	}
 
 	boolean excludePhotonsFromCone = true;
@@ -885,7 +974,22 @@
 	} else {
 	    throw new AssertionError("Unhandled case!");
 	}
-
+	// Muon hit sharing...
+	if (m_useMucal) {
+	    DTreeClusterSharingAlgorithm dTreeSharingAlgMCAL = new DTreeClusterSharingAlgorithm(treeOfSharedCluster, targetsInTree, 50.0, maxDistanceForDTreeClustersMCAL);
+	    SharedClusterGroup sharedLeftoverHitClustersMCAL = new SharedClusterGroup(leftoverHitClustersToShareMCAL, dTreeSharingAlgMCAL);
+	    sharedLeftoverHitClustersMCAL.createShares(linkableClusters);
+	    sharedLeftoverHitClustersMCAL.rebuildHints();
+	    allSharedClusters.add(sharedLeftoverHitClustersMCAL);
+	}
+	// Forward hit sharing...
+	if (m_useFcal) {
+	    DTreeClusterSharingAlgorithm dTreeSharingAlgFCAL = new DTreeClusterSharingAlgorithm(treeOfSharedCluster, targetsInTree, 50.0, maxDistanceForDTreeClustersFCAL);
+	    SharedClusterGroup sharedLeftoverHitClustersFCAL = new SharedClusterGroup(leftoverHitClustersToShareFCAL, dTreeSharingAlgFCAL);
+	    sharedLeftoverHitClustersFCAL.createShares(linkableClusters);
+	    sharedLeftoverHitClustersFCAL.rebuildHints();
+	    allSharedClusters.add(sharedLeftoverHitClustersFCAL);
+	}
 
 	if (m_debug) {
 	    for (Cluster clus : clustersMatchedToTweakedTracks.keySet()) {
@@ -1662,27 +1766,29 @@
 		debugTrackMatch.process(m_event);
 		for (int iLayer=minLayer; iLayer<maxLayer; iLayer++) {
 		    Set<CalorimeterHit> unusedHitsInLayer = unusedHitsByLayer.get(iLayer);
-		    List<Cluster> tmpClusterList = new Vector<Cluster>();
-		    for (CalorimeterHit hit : unusedHitsInLayer) {
-			if (!trackSeedHits.contains(hit)) {
-			    BasicCluster tmpClus = new BasicCluster();
-			    tmpClus.addHit(hit);
-			    tmpClusterList.add(tmpClus);
-			}
-		    }
-		    Cluster bestClusterMatchInLayer = debugTrackMatch.matchTrackToCluster(tr, tmpClusterList);
-		    Hep3Vector interceptPointInLayer = debugTrackMatch.getExtrapolator().extendToECALLayer(iLayer);
-		    if (bestClusterMatchInLayer != null) {
-			CalorimeterHit seedHit = bestClusterMatchInLayer.getCalorimeterHits().get(0);
-			Hep3Vector positionOfMatchedHit = new BasicHep3Vector(seedHit.getPosition());
-			double transverseDistance = VecOp.sub(positionOfMatchedHit, interceptPointInLayer).magnitude();
-			if (transverseDistance < cutTrackSeedDist) {
-			    // Within 1cm => OK
-			    trackSeedHits.add(seedHit);
-			    Hep3Vector tangent = debugTrackMatch.getExtrapolator().getTangent(interceptPointInLayer, tr);
-			    mapTrackSeedToTangent.put(seedHit, tangent);
-			    mapTrackToTrackSeed.put(tr, seedHit);
-			    break; // stop looping over layers
+		    if (unusedHitsInLayer != null) {
+			List<Cluster> tmpClusterList = new Vector<Cluster>();
+			for (CalorimeterHit hit : unusedHitsInLayer) {
+			    if (!trackSeedHits.contains(hit)) {
+				BasicCluster tmpClus = new BasicCluster();
+				tmpClus.addHit(hit);
+				tmpClusterList.add(tmpClus);
+			    }
+			}
+			Cluster bestClusterMatchInLayer = debugTrackMatch.matchTrackToCluster(tr, tmpClusterList);
+			Hep3Vector interceptPointInLayer = debugTrackMatch.getExtrapolator().extendToECALLayer(iLayer);
+			if (bestClusterMatchInLayer != null) {
+			    CalorimeterHit seedHit = bestClusterMatchInLayer.getCalorimeterHits().get(0);
+			    Hep3Vector positionOfMatchedHit = new BasicHep3Vector(seedHit.getPosition());
+			    double transverseDistance = VecOp.sub(positionOfMatchedHit, interceptPointInLayer).magnitude();
+			    if (transverseDistance < cutTrackSeedDist) {
+				// Within 1cm => OK
+				trackSeedHits.add(seedHit);
+				Hep3Vector tangent = debugTrackMatch.getExtrapolator().getTangent(interceptPointInLayer, tr);
+				mapTrackSeedToTangent.put(seedHit, tangent);
+				mapTrackToTrackSeed.put(tr, seedHit);
+				break; // stop looping over layers
+			    }
 			}
 		    }
 		}
@@ -1821,62 +1927,6 @@
 	return output;
     }
 
-    void findStructureInsideClusterSupplyingOldMips(Cluster largeCluster, boolean inECAL, List<Cluster> mipsOldInside, List<Cluster> mipsNewInside, List<Cluster> clumpsInside, HitMap unusedHits, List<Cluster> mipsOld) {
-	// Verify
-	if (mipsOldInside.size() != 0 || mipsNewInside.size() != 0 || clumpsInside.size() != 0 || unusedHits.size() != 0) {
-	    throw new AssertionError("Empty, non-null input lists required.");
-	}
-	// Book-keeping
-	for (CalorimeterHit hit : largeCluster.getCalorimeterHits()) {
-	    unusedHits.put(hit.getCellID(), hit);
-	}
-	// Look to see which old MIPs are found in this 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);
-	    }		    
-	}
-	// MIPs (new)
-	if (m_useNewMipFinder) {
-	    double radius = 0.0;
-	    if (inECAL) {
-		radius = m_newMipFinderRadiusECAL;
-	    } else {
-		radius = m_newMipFinderRadiusHCAL;
-	    }
-	    Clusterer newMipFinder = new org.lcsim.recon.cluster.mipfinder.NonProjectiveMipFinder(radius);
-	    List<Cluster> mipClustersNew = newMipFinder.createClusters(unusedHits);
-	    if (m_removePoorQualityMips) {
-		removePoorQualityMips(mipClustersNew);
-	    }
-	    for (Cluster mip : mipClustersNew) {
-		mipsNewInside.add(mip);
-		for (CalorimeterHit hit : mip.getCalorimeterHits()) {
-		    unusedHits.remove(hit.getCellID());
-		}
-	    }
-	}
-	// Clumps
-	Clusterer clumpfinder = new ClumpFinder();
-	List<Cluster> clumpClusters = clumpfinder.createClusters(unusedHits);	    
-	clumpsInside.addAll(clumpClusters);
-	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());
-	    }
-	}
-    }
-
     void findStructureInsideCluster(Cluster largeCluster, boolean inECAL, List<Cluster> mipsOldInside, List<Cluster> mipsNewInside, List<Cluster> clumpsInside, HitMap unusedHits) {
 	// Verify
 	if (mipsOldInside.size() != 0 || mipsNewInside.size() != 0 || clumpsInside.size() != 0 || unusedHits.size() != 0) {

lcsim/src/org/lcsim/contrib/uiowa
ReclusterDriver.java 1.32 -> 1.33
diff -u -r1.32 -r1.33
--- ReclusterDriver.java	12 Aug 2008 23:01:56 -0000	1.32
+++ ReclusterDriver.java	12 Aug 2008 23:42:52 -0000	1.33
@@ -38,7 +38,7 @@
   *
   * This version is PRELIMINARY.
   *
-  * @version $Id: ReclusterDriver.java,v 1.32 2008/08/12 23:01:56 tjkim Exp $
+  * @version $Id: ReclusterDriver.java,v 1.33 2008/08/12 23:42:52 mcharles Exp $
   * @author Mat Charles
   */
 
@@ -83,6 +83,7 @@
     protected int m_punchThroughLayers = 5;
     protected int m_punchThroughHitMinimum = 4;
     protected boolean m_checkSharedHitsForPunchThrough = true;
+    protected boolean m_allowLateralPunchThrough = false;
 
     protected boolean m_debugLinkPlots = false;
 
@@ -3283,13 +3284,32 @@
 	} else {
 	    clusterToCheckForPunchThrough = makeCombinedCluster(showerComponents);
 	}
+
+	if (!m_allowLateralPunchThrough) {
+	    // Ignore punch-through at the sides, since we can easily pick it up in the endcap muon system
+	    // So we'll remove endcap hits from consideration.
+	    BasicCluster newCluster = new BasicCluster();
+	    for (CalorimeterHit hit : clusterToCheckForPunchThrough.getCalorimeterHits()) {
+		org.lcsim.geometry.Subdetector det = hit.getSubdetector();
+		if (det.isBarrel()) {
+		    newCluster.addHit(hit);
+		}
+	    }
+	    clusterToCheckForPunchThrough = newCluster;
+	}
+
 	// Check for regular punch-through (shows up as hits in outermost layers of HCAL:
 	int hitCount = countHitsInLastLayersOfHcal(clusterToCheckForPunchThrough, m_punchThroughLayers);
 	boolean longitudinalPunchThrough = (hitCount >= m_punchThroughHitMinimum);
-	// Also check for tracks that punch through the sides of the barrel
-	int barrelEdgeHitCount = countHitsInSideEdgesOfHcal(clusterToCheckForPunchThrough, m_punchThroughLayers);
-	boolean transversePunchThrough = (barrelEdgeHitCount >= m_punchThroughHitMinimum);
-	return (longitudinalPunchThrough || transversePunchThrough);
+
+	// Optionally, also check for tracks that punch through the sides of the barrel
+	boolean lateralPunchThrough = false;
+	if (m_allowLateralPunchThrough) {
+	    int barrelEdgeHitCount = countHitsInSideEdgesOfHcal(clusterToCheckForPunchThrough, m_punchThroughLayers);
+	    lateralPunchThrough = (barrelEdgeHitCount >= m_punchThroughHitMinimum);
+	}
+
+	return (longitudinalPunchThrough || lateralPunchThrough);
     }
 
     protected int countHitsInLastLayersOfHcal(ReconstructedParticle part, int nLayersToCheck) {
CVSspam 0.2.8