Print

Print


Commit in lcsim/src/org/lcsim/recon/pfa/structural on MAIN
SetUpDTreeForReclustering.java+250-1821.6 -> 1.7
SetUpPFA.java+1-11.1 -> 1.2
+251-183
2 modified files
MJC: Propagate code changes to stable

lcsim/src/org/lcsim/recon/pfa/structural
SetUpDTreeForReclustering.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- SetUpDTreeForReclustering.java	31 Aug 2008 18:49:50 -0000	1.6
+++ SetUpDTreeForReclustering.java	22 Oct 2008 18:57:16 -0000	1.7
@@ -1,212 +1,280 @@
 package org.lcsim.recon.pfa.structural;
 
 import java.util.*;
+import hep.physics.vec.*;
 import org.lcsim.util.Driver;
 import org.lcsim.event.EventHeader;
 import org.lcsim.util.*;
 import org.lcsim.event.*;
 import org.lcsim.recon.cluster.directedtree.*;
 import org.lcsim.util.hitmap.*;
+import org.lcsim.util.decision.*;
+import org.lcsim.contrib.uiowa.MuonFinder.*;
+import org.lcsim.recon.pfa.identifier.*;
+import org.lcsim.recon.cluster.mipfinder.ShowerPointFinderDriver;
+import org.lcsim.recon.cluster.util.*;
 
 public class SetUpDTreeForReclustering extends Driver
 {
     boolean useOldRonPhotonFinder = false;
     boolean useForwardEcal = false;
 
-    public SetUpDTreeForReclustering() {
-	{
-	    // Convert DigiSim's lists to hitmaps:
-	    HitListToHitMapDriver converter1 = new HitListToHitMapDriver();
-	    HitListToHitMapDriver converter2 = new HitListToHitMapDriver();
-	    HitListToHitMapDriver converter3 = new HitListToHitMapDriver();
-	    HitListToHitMapDriver converter4 = new HitListToHitMapDriver();
-	    converter1.addInputList("EcalBarrDigiHits");
-	    converter2.addInputList("EcalEndcapDigiHits");
-	    converter3.addInputList("HcalBarrDigiHits");
-	    converter4.addInputList("HcalEndcapDigiHits");
-	    converter1.setOutput("EcalBarrDigiHitMap");
-	    converter2.setOutput("EcalEndcapDigiHitMap");
-	    converter3.setOutput("HcalBarrDigiHitMap");
-	    converter4.setOutput("HcalEndcapDigiHitMap");
-	    add(converter1);
-	    add(converter2);
-	    add(converter3);
-	    add(converter4);
-	    // Convert muon lists to hitmaps:
-	    HitListToHitMapDriver converter5 = new HitListToHitMapDriver();
-	    HitListToHitMapDriver converter6 = new HitListToHitMapDriver();
-	    converter5.addInputList("MuonBarrDigiHits");
-	    converter6.addInputList("MuonEndcapDigiHits");
-	    converter5.setOutput("MuonBarrDigiHitMap");
-	    converter6.setOutput("MuonEndcapDigiHitMap");
-	    add(converter5);
-	    add(converter6);
-
-	    
-	    // Convert forward EM endcap hits
-	    // NB, must have digisim configured to handle forward ECAL
-	    if (useForwardEcal) {
-		// Convert forward EM endcap hits:
-		HitListToHitMapDriver converter7 = new HitListToHitMapDriver();
-		converter7.addInputList("ForwardEcalEndcapDigiHits");
-		converter7.setOutput("ForwardEcalEndcapDigiHitMap");
-		add(converter7);
-	    }
+    public SetUpDTreeForReclustering(String inputTrackList, Collection<String> allHitLists, Collection<String> recoHitLists, Collection<String> hitsForMST, HelixExtrapolator findCluster) {
+	// Convert DigiSim's lists to hitmaps:
+	Map<String,String> mapListToHitMap = new HashMap<String,String>();
+	for (String inputName : allHitLists) {
+	    String outputName = (new String(inputName)).replace("DigiHits", "DigiHitMap");
+	    mapListToHitMap.put(inputName, outputName);
+	    HitListToHitMapDriver converter = new HitListToHitMapDriver();
+	    converter.addInputList(inputName);
+	    converter.setOutput(outputName);
+	    add(converter);
 	}
-
-	// Merge barrel & endcap hits
-	{
-	    HitMapAddDriver combineEcal = new HitMapAddDriver();
-	    HitMapAddDriver combineHcal = new HitMapAddDriver();
-	    combineEcal.addInputHitMap("EcalBarrDigiHitMap");
-	    combineHcal.addInputHitMap("HcalBarrDigiHitMap");
-	    combineEcal.addInputHitMap("EcalEndcapDigiHitMap");
-	    combineHcal.addInputHitMap("HcalEndcapDigiHitMap");
-	    if (useForwardEcal) {
-		combineEcal.addInputHitMap("ForwardEcalEndcapDigiHitMap"); // Include forward endcap
-	    }
-	    combineEcal.setOutputHitMap("EcalDigiHitMap");
-	    combineHcal.setOutputHitMap("HcalDigiHitMap");
-	    add(combineEcal);
-	    add(combineHcal);
+	// Convenience: Merge ECAL barrel & ECAL endcap
+	HitMapAddDriver combineEcal = new HitMapAddDriver();
+	combineEcal.addInputHitMap("EcalBarrDigiHitMap");
+	combineEcal.addInputHitMap("EcalEndcapDigiHitMap");
+	combineEcal.setOutputHitMap("EcalDigiHitMap");
+	add(combineEcal);
+	// Convenience: Merge HCAL barrel & HCAL endcap
+	HitMapAddDriver combineHcal = new HitMapAddDriver();
+	combineHcal.addInputHitMap("HcalBarrDigiHitMap");
+	combineHcal.addInputHitMap("HcalEndcapDigiHitMap");
+	combineHcal.setOutputHitMap("HcalDigiHitMap");
+	add(combineHcal);
+	// Make combined hitmap of all hits (for muon searches)
+	HitMapAddDriver combineAll = new HitMapAddDriver();
+	for (String inputName : allHitLists) {
+	    combineAll.addInputHitMap(mapListToHitMap.get(inputName));
+	    combineAll.setOutputHitMap("AllDigiHitMap");
+	}
+	add(combineAll);
+	// Make combined hitmap of all reconstructable hits
+	HitMapAddDriver combineReco = new HitMapAddDriver();
+	for (String inputName : recoHitLists) {
+	    combineReco.addInputHitMap(mapListToHitMap.get(inputName));
+	    combineReco.setOutputHitMap("RecoDigiHitMap");
 	}
+	add(combineReco);
 
 	// Find photons in ECAL
-	if (useOldRonPhotonFinder) {
-	    // Make photons in barrel & endcap separately
-	    org.lcsim.contrib.uiowa.RonPhotonFinder.RonPhotonFinderSid01 photonFinderEcalBarrel = new org.lcsim.contrib.uiowa.RonPhotonFinder.RonPhotonFinderSid01("EcalBarrDigiHitMap", "EcalBarrDigiHitMapWithoutPhotons", "EcalBarrPhotonClusters");
-	    org.lcsim.contrib.uiowa.RonPhotonFinder.RonPhotonFinderSid01 photonFinderEcalEndcap = new org.lcsim.contrib.uiowa.RonPhotonFinder.RonPhotonFinderSid01("EcalEndcapDigiHitMap", "EcalEndcapDigiHitMapWithoutPhotons", "EcalEndcapPhotonClusters");
-	    add(photonFinderEcalBarrel);
-	    add(photonFinderEcalEndcap);
-	    add(new TransientFlagDriver("EcalBarrPhotonClusters"));
-	    add(new TransientFlagDriver("EcalEndcapPhotonClusters"));
-	    // Merge to a single list of photons
-	    ListAddDriver<Cluster> mergePhotonClusters = new ListAddDriver<Cluster>(Cluster.class);
-	    mergePhotonClusters.addInputList("EcalBarrPhotonClusters");
-	    mergePhotonClusters.addInputList("EcalEndcapPhotonClusters");
-	    mergePhotonClusters.setOutputList("PhotonClustersForDTree");
-	    add(mergePhotonClusters);
-	    add(new TransientFlagDriver("PhotonClustersForDTree"));
-	} else {
-	    // Make photons in barrel & endcap together
-	    org.lcsim.contrib.Cassell.recon.DTPhotons.RonDTPhotonFinderSid01 photonFinder = new org.lcsim.contrib.Cassell.recon.DTPhotons.RonDTPhotonFinderSid01("EcalDigiHitMap", "EcalDigiHitMapWithoutPhotons", "PhotonClustersForDTree");
+	{
+	    // We have to use ALL hits for the photon-finder -- this is because it uses the
+            // presence of hits in early layers to veto on charged particles.
+	    org.lcsim.contrib.Cassell.recon.DTPhotons.RonDTPhotonFinderSid01 photonFinder = new org.lcsim.contrib.Cassell.recon.DTPhotons.RonDTPhotonFinderSid01("EcalDigiHitMap", "EcalDigiHitMapMinusPreliminaryPhotons", "PreliminaryPhotonClustersForDTree");
 	    add(photonFinder);
+	    add(new TransientFlagDriver("PreliminaryPhotonClustersForDTree"));
+
+	    // Check for electrons and set those to one side so we don't accidentally cluster them or use their tracks:
+	    add(new TrackToElectronMapMaker(findCluster, "PreliminaryPhotonClustersForDTree", inputTrackList, "MapElectronTracksToClusters", "TracksWithoutElectrons", "ElectronMapClusters"));
+	    add(new ListSubtractDriver("PreliminaryPhotonClustersForDTree", "ElectronMapClusters", "PreliminaryPhotonClustersForDTreeMinusElectrons"));
+	    add(new ClusterListToHitMapDriver("ElectronMapClusters", "ElectronHitMap"));
+	    add(new HitMapSubtractDriver("RecoDigiHitMap", "ElectronHitMap", "RecoDigiHitMapWithoutElectrons"));
+	    add(new HitMapSubtractDriver("AllDigiHitMap", "ElectronHitMap", "AllDigiHitMapWithoutElectrons"));
+	}
+
+
+	{
+	    // Find muons
+	    MuonFinderWrapper muonFinder = new MuonFinderWrapper("TracksWithoutElectrons", "AllDigiHitMapWithoutElectrons", "MuonTrackClusterMap", "AllDigiHitMapWithoutElectronsOrMuons", "TracksWithoutElectronsOrMuons");
+	    //muonFinder.skip(); // TEST
+	    add(muonFinder);
+	    // Identify the muon hits within useable hit block
+	    add(new HitMapSubtractDriver("RecoDigiHitMapWithoutElectrons", "AllDigiHitMapWithoutElectronsOrMuons", "RecoDigiHitMapMuons"));
+	    // Non-muon hits within useable hit block
+	    add(new HitMapSubtractDriver("RecoDigiHitMapWithoutElectrons", "RecoDigiHitMapMuons", "RecoDigiHitMapWithoutElectronsOrMuons"));
+	}
+
+	{
+	    // TJ's pre-shower MIP-finder
+	    ShowerPointFinderDriver showerFinder = new ShowerPointFinderDriver(findCluster, "RecoDigiHitMapWithoutElectronsOrMuons", "TracksWithoutElectronsOrMuons", "ShowerFinderMapTrackToMip", "RecoDigiHitMapWithoutElectronsOrMuonsOrMips", "ShowerFinderMips");
+	    add(showerFinder);
+	    add(new CheckDisjoint("RecoDigiHitMapWithoutElectronsOrMuonsOrMips", "ShowerFinderMips"));
+	    // Steve's pre-shower MIP-finder
+	    // disabled for now -- //add(new ReclusterDriver.SteveMipWrapper());
+
+	    // Match tracks -> pre-shower MIPs (best possible linkage)
+	    add(new TrackToPreShowerMipMapMaker("ShowerFinderMapTrackToMip", "TracksWithoutElectronsOrMuons", "MapPreShowerMipTracksToClusterSeeds", "UnmatchedTracksAfterPreShowerMipMap", "PreShowerMipMatchMipClusters", "PreShowerMipMatchSmallClusters", "PreShowerMipMatchBlockClusters"));
+	    // At this point, we COULD take the unlinked MIP hits back out and recycle them
+	    // into the DTree clustering. (The unlinked MIPs are the ones where two the MIP
+	    // clusters of 2+ tracks overlapped, or where there were too few hits, or both.)
+	    add(new ClusterListToHitMapDriver("PreShowerMipMatchSmallClusters", "PreShowerMipMatchSmallClusterHits"));
+	    add(new ClusterListToHitMapDriver("PreShowerMipMatchBlockClusters", "PreShowerMipMatchBlockClusterHits"));
+	    HitMapAddDriver remergeBadMips = new HitMapAddDriver();
+	    remergeBadMips.addInputHitMap("PreShowerMipMatchSmallClusterHits");
+	    remergeBadMips.addInputHitMap("PreShowerMipMatchBlockClusterHits");
+	    remergeBadMips.addInputHitMap("RecoDigiHitMapWithoutElectronsOrMuonsOrMips");
+	    remergeBadMips.setOutputHitMap("RecoDigiHitMapWithoutElectronsOrMuonsOrGoodMips");
+	    add(remergeBadMips); // TEST
+	}
+
+	{
+	    // Now go back and ensure that no photon uses hits from a charged particle's MIP.
+	    // We can either remove those individual hits or veto entire clusters.
+	    boolean remove = false;
+	    boolean findVetoedPhotons = true;
+	    if (remove) {
+		add(new RemoveHitsFromClusters("PreliminaryPhotonClustersForDTreeMinusElectrons", "MuonTrackClusterMap", "PhotonsMinusMuonHits"));
+		add(new RemoveHitsFromClusters("PhotonsMinusMuonHits", "ShowerFinderMapTrackToMip", "PhotonClustersForDTree"));
+	    } else {
+		add(new VetoHitsFromClusters("PreliminaryPhotonClustersForDTreeMinusElectrons", "MuonTrackClusterMap", "PhotonsMinusMuonHits"));
+		add(new VetoHitsFromClusters("PhotonsMinusMuonHits", "ShowerFinderMapTrackToMip", "PhotonClustersForDTree"));
+		if (findVetoedPhotons) {
+		    // Test: pick out vetoed clusters
+		    add(new ListSubtractDriver("PreliminaryPhotonClustersForDTree", "PhotonClustersForDTree", "VetoedPhotonClusters"));
+		    add(new CheckDisjoint("PhotonClustersForDTree", "VetoedPhotonClusters"));
+		    add(new RemoveHitsFromClusters("VetoedPhotonClusters", "MuonTrackClusterMap", "VetoedPhotonClustersMinusMuonHits"));
+		    add(new RemoveHitsFromClusters("VetoedPhotonClustersMinusMuonHits", "ShowerFinderMapTrackToMip", "VetoedPhotonClustersMinusMuonHitsAndMipHits"));
+		    add(new ClusterListToHitMapDriver("VetoedPhotonClustersMinusMuonHitsAndMipHits", "PhotonVetoHitMap"));
+		}
+	    }
+	    add(new TransientFlagDriver("PhotonsMinusMuonHits"));
 	    add(new TransientFlagDriver("PhotonClustersForDTree"));
-	    // Split back into barrel & endcap
-	    // This is a little fiddly -- need to do one subtraction to 
-	    // identify the photon hits, then a second to remove the photon
-	    // hits from the previous hitmaps.
-	    HitMapSubtractDriver separateEcal1 = new HitMapSubtractDriver("EcalBarrDigiHitMap", "EcalDigiHitMapWithoutPhotons", "EcalBarrel_photonHits");
-	    HitMapSubtractDriver separateEcal2 = new HitMapSubtractDriver("EcalEndcapDigiHitMap", "EcalDigiHitMapWithoutPhotons", "EcalEndcap_photonHits");
-	    HitMapSubtractDriver separateEcal3 = new HitMapSubtractDriver("EcalBarrDigiHitMap", "EcalBarrel_photonHits", "EcalBarrDigiHitMapWithoutPhotons");
-	    HitMapSubtractDriver separateEcal4 = new HitMapSubtractDriver("EcalEndcapDigiHitMap", "EcalEndcap_photonHits", "EcalEndcapDigiHitMapWithoutPhotons");
-	    add(separateEcal1);
-	    add(separateEcal2);
-	    add(separateEcal3);
-	    add(separateEcal4);
-	    if (useForwardEcal) {
-		HitMapSubtractDriver separateEcal5 = new HitMapSubtractDriver("ForwardEcalEndcapDigiHitMap", "EcalDigiHitMapWithoutPhotons", "ForwardEcalEndcap_photonHits");
-		HitMapSubtractDriver separateEcal6 = new HitMapSubtractDriver("ForwardEcalEndcapDigiHitMap", "ForwardEcalEndcap_photonHits", "ForwardEcalEndcapDigiHitMapWithoutPhotons");
-		add(separateEcal5);
-		add(separateEcal6);
+
+	    // Identify which hits were used for photons, electrons
+	    add(new ClusterListToHitMapDriver("PhotonClustersForDTree", "PhotonHitMap"));
+	    add(new CheckDisjoint("ShowerFinderMips", "PhotonHitMap"));
+
+	    // Identify remaining hits not used for photons or muons or mips
+	    if (!remove && findVetoedPhotons) {
+		add(new HitMapSubtractDriver("RecoDigiHitMapWithoutElectronsOrMuonsOrGoodMips", "PhotonHitMap", "TmpRecoDigiHitMapWithoutElectronsOrMuonsOrMipsOrPhotons"));
+		add(new HitMapSubtractDriver("TmpRecoDigiHitMapWithoutElectronsOrMuonsOrMipsOrPhotons", "PhotonVetoHitMap", "RecoDigiHitMapWithoutElectronsOrMuonsOrMipsOrPhotons"));
+	    } else {
+		add(new HitMapSubtractDriver("RecoDigiHitMapWithoutElectronsOrMuonsOrGoodMips", "PhotonHitMap", "RecoDigiHitMapWithoutElectronsOrMuonsOrMipsOrPhotons")); // Remove Muon/MIP hits
+		//add(new HitMapSubtractDriver("RecoDigiHitMap", "PhotonHitMap", "RecoDigiHitMapWithoutMuonsOrMipsOrPhotons")); // Keep all non-photon hits
 	    }
+	    add(new CheckDisjoint("RecoDigiHitMapWithoutElectronsOrMuonsOrMipsOrPhotons", "PhotonHitMap"));
 	}
 
-	// Run DTree
-	{
-	    DirectedTreeDriver treeDriverEcalBarr = new DirectedTreeDriver();
-	    treeDriverEcalBarr.setInputHitMap("EcalBarrDigiHitMapWithoutPhotons");
-	    treeDriverEcalBarr.setOutputClusterList("EcalBarrDTrees");
-	    treeDriverEcalBarr.setOutputHitMap("EcalBarrDigiHitMapAfterDTree");
-	    DirectedTreeDriver treeDriverEcalEndcap = new DirectedTreeDriver();
-	    treeDriverEcalEndcap.setInputHitMap("EcalEndcapDigiHitMapWithoutPhotons");
-	    treeDriverEcalEndcap.setOutputClusterList("EcalEndcapDTrees");
-	    treeDriverEcalEndcap.setOutputHitMap("EcalEndcapDigiHitMapAfterDTree");
-	    DirectedTreeDriver treeDriverHcalBarr = new DirectedTreeDriver();
-	    treeDriverHcalBarr.setInputHitMap("HcalBarrDigiHitMap");
-	    treeDriverHcalBarr.setOutputClusterList("HcalBarrDTrees");
-	    treeDriverHcalBarr.setOutputHitMap("HcalBarrDigiHitMapAfterDTree");
-	    DirectedTreeDriver treeDriverHcalEndcap = new DirectedTreeDriver();
-	    treeDriverHcalEndcap.setInputHitMap("HcalEndcapDigiHitMap");
-	    treeDriverHcalEndcap.setOutputClusterList("HcalEndcapDTrees");
-	    treeDriverHcalEndcap.setOutputHitMap("HcalEndcapDigiHitMapAfterDTree");
-	    add(treeDriverEcalBarr);
-	    add(treeDriverEcalEndcap);
-	    add(treeDriverHcalBarr);
-	    add(treeDriverHcalEndcap);
-	    add(new TransientFlagDriver("EcalBarrDTrees"));
-	    add(new TransientFlagDriver("EcalEndcapDTrees"));
-	    add(new TransientFlagDriver("HcalBarrDTrees"));
-	    add(new TransientFlagDriver("HcalEndcapDTrees"));
+	// Run DTree on each subdetector separately:
+	Map<String,String> mapInputListToDTreeClusterList = new HashMap<String,String>();
+	for (String rawInputName : recoHitLists) {
+	    String rawInputHitMapName = mapListToHitMap.get(rawInputName);
+	    String filteredInputHitMapName = (new String(rawInputName)).replace("DigiHits", "DigiHitMapForDTree");
+	    String outputHitMapName = new String(rawInputHitMapName+"AfterDTree");
+	    String outputClusterListName = new String(rawInputHitMapName+"Clusters");
+	    mapInputListToDTreeClusterList.put(rawInputName, outputClusterListName);
+	    // Filter hitmap to only contain hits from this subdet that are not muon/mip/photon hits
+	    add(new HitMapAndDriver(rawInputHitMapName, "RecoDigiHitMapWithoutElectronsOrMuonsOrMipsOrPhotons", filteredInputHitMapName));
+	    if (hitsForMST.contains(rawInputName)) {
+		// Run MST
+		org.lcsim.recon.cluster.mst.MSTClusterDriver mstDriver = new org.lcsim.recon.cluster.mst.MSTClusterDriver(outputHitMapName, outputClusterListName);
+		mstDriver.addInputHitMap(filteredInputHitMapName);
+		mstDriver.setThreshold(1500.0); // FIXME: This is not optimal
+		mstDriver.registerMetrics(new org.lcsim.recon.cluster.mst.MinimumHitToHitDistance());
+		add(mstDriver);
+	    } else {
+		// Run DTree
+		DirectedTreeDriver treeDriver = new DirectedTreeDriver();
+		treeDriver.setInputHitMap(filteredInputHitMapName);
+		treeDriver.setOutputClusterList(outputClusterListName);
+		treeDriver.setOutputHitMap(outputHitMapName);
+		add(treeDriver);
+	    }
+	    add(new TransientFlagDriver(outputClusterListName));
 	}
 	
-	// DTree doesn't handly anything except ECAL & HCAL right now, so use MST instead:
+	// Merge/categorize & write out
+	ListAddDriver<Cluster> mergeDTreeClustersECAL = new ListAddDriver<Cluster>(Cluster.class);
+	ListAddDriver<Cluster> mergeDTreeClustersHCAL = new ListAddDriver<Cluster>(Cluster.class);
+	ListAddDriver<Cluster> mergeDTreeClustersMCAL = new ListAddDriver<Cluster>(Cluster.class);
+	ListAddDriver<Cluster> mergeDTreeClustersAll  = new ListAddDriver<Cluster>(Cluster.class);
+	for (String inputName : recoHitLists) {
+	    String clusterListName = mapInputListToDTreeClusterList.get(inputName);
+	    mergeDTreeClustersAll.addInputList(clusterListName);
+	    if (inputName.contains("Ecal")) {
+		mergeDTreeClustersECAL.addInputList(clusterListName);
+	    }
+	    if (inputName.contains("Hcal")) {
+		mergeDTreeClustersHCAL.addInputList(clusterListName);
+	    }
+	    if (inputName.contains("MuonEndcap") || inputName.contains("MuonBarr")) {
+		mergeDTreeClustersMCAL.addInputList(clusterListName);
+	    }
+	}
+	mergeDTreeClustersECAL.setOutputList("DTreeClustersECAL");
+	mergeDTreeClustersHCAL.setOutputList("DTreeClustersHCAL");
+	mergeDTreeClustersMCAL.setOutputList("DTreeClustersMCAL");
+	mergeDTreeClustersAll .setOutputList("DTreeClusters");
+	add(mergeDTreeClustersECAL);
+	add(mergeDTreeClustersHCAL);
+	add(mergeDTreeClustersMCAL);
+	add(mergeDTreeClustersAll);
+	add(new TransientFlagDriver("DTreeClustersECAL"));
+	add(new TransientFlagDriver("DTreeClustersHCAL"));
+	add(new TransientFlagDriver("DTreeClustersMCAL"));
+	add(new TransientFlagDriver("DTreeClusters"));
+
+	// OK, now go back and look for hits near boundaries (for use when making MIPs
+	// with a layer-based algorithm so it can cross from endcap to barrel).
 	{
-	    org.lcsim.recon.cluster.mst.MSTClusterDriver mstMcalBarrel = new org.lcsim.recon.cluster.mst.MSTClusterDriver("MuonBarrDigiHitMapAfterDTree", "MuonBarrDTrees");
-	    org.lcsim.recon.cluster.mst.MSTClusterDriver mstMcalEndcap = new org.lcsim.recon.cluster.mst.MSTClusterDriver("MuonEndcapDigiHitMapAfterDTree", "MuonEndcapDTrees");
-	    mstMcalBarrel.addInputHitMap("MuonBarrDigiHitMap");
-	    mstMcalEndcap.addInputHitMap("MuonEndcapDigiHitMap");
-	    mstMcalBarrel.setThreshold(1500.0); // 3x3cm segmentation transversely, 6.5cm longitudinally
-	    mstMcalEndcap.setThreshold(1500.0); // 3x3cm segmentation transversely, 6.5cm longitudinally
-	    mstMcalBarrel.registerMetrics(new org.lcsim.recon.cluster.mst.MinimumHitToHitDistance());
-	    mstMcalEndcap.registerMetrics(new org.lcsim.recon.cluster.mst.MinimumHitToHitDistance());
-	    add(mstMcalBarrel);
-	    add(mstMcalEndcap);
-	    add(new TransientFlagDriver("MuonBarrDTrees"));
-	    add(new TransientFlagDriver("MuonEndcapDTrees"));
-	}
-
-	// Run DTree on FCAL -- this is currently rather tricky.
-	if (useForwardEcal) {
-	    org.lcsim.recon.cluster.mst.MSTClusterDriver mstFcalEndcap = new org.lcsim.recon.cluster.mst.MSTClusterDriver("ForwardEcalEndcapDigiHitMapAfterDTree", "ForwardEcalEndcapDTrees");
-	    mstFcalEndcap.addInputHitMap("ForwardEcalEndcapDigiHitMap");
-	    mstFcalEndcap.setThreshold(12.5); // 3.5x3.5cm segmentation transversely, 3.7mm longitudinally
-	    mstFcalEndcap.registerMetrics(new org.lcsim.recon.cluster.mst.MinimumHitToHitDistance());
-	    add(mstFcalEndcap);
-	    add(new TransientFlagDriver("ForwardEcalEndcapDTrees"));
-	}
-
-	// Merge & write out
-	{
-	    ListAddDriver<Cluster> mergeDTreeClustersECAL = new ListAddDriver<Cluster>(Cluster.class);
-	    mergeDTreeClustersECAL.addInputList("EcalBarrDTrees");
-	    mergeDTreeClustersECAL.addInputList("EcalEndcapDTrees");
-	    mergeDTreeClustersECAL.setOutputList("DTreeClustersECAL");
-	    add(mergeDTreeClustersECAL);
-	    add(new TransientFlagDriver("DTreeClustersECAL"));
-
-	    ListAddDriver<Cluster> mergeDTreeClustersHCAL = new ListAddDriver<Cluster>(Cluster.class);
-	    mergeDTreeClustersHCAL.addInputList("HcalBarrDTrees");
-	    mergeDTreeClustersHCAL.addInputList("HcalEndcapDTrees");
-	    mergeDTreeClustersHCAL.setOutputList("DTreeClustersHCAL");
-	    add(mergeDTreeClustersHCAL);
-	    add(new TransientFlagDriver("DTreeClustersHCAL"));
-
-	    ListAddDriver<Cluster> mergeDTreeClustersMCAL = new ListAddDriver<Cluster>(Cluster.class);
-	    //mergeDTreeClustersMCAL.addInputList("MuonBarrDTrees");
-	    mergeDTreeClustersMCAL.addInputList("MuonEndcapDTrees");
-	    mergeDTreeClustersMCAL.setOutputList("DTreeClustersMCAL");
-	    add(mergeDTreeClustersMCAL);
-	    add(new TransientFlagDriver("DTreeClustersMCAL"));
-
-	    if (useForwardEcal) {
-		ListAddDriver<Cluster> mergeDTreeClustersFCAL = new ListAddDriver<Cluster>(Cluster.class);
-		mergeDTreeClustersFCAL.addInputList("ForwardEcalEndcapDTrees");
-		mergeDTreeClustersFCAL.setOutputList("DTreeClustersFCAL");
-		add(mergeDTreeClustersFCAL);
-		add(new TransientFlagDriver("DTreeClustersFCAL"));
-	    }
-
-	    ListAddDriver<Cluster> mergeDTreeClusters = new ListAddDriver<Cluster>(Cluster.class);
-	    mergeDTreeClusters.addInputList("DTreeClustersECAL");
-	    mergeDTreeClusters.addInputList("DTreeClustersHCAL");
-	    mergeDTreeClusters.addInputList("DTreeClustersMCAL");
-	    if (useForwardEcal) {
-		mergeDTreeClusters.addInputList("DTreeClustersFCAL");
-	    }
-	    mergeDTreeClusters.setOutputList("DTreeClusters");
-	    add(mergeDTreeClusters);
-	    add(new TransientFlagDriver("DTreeClusters"));
+	    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));
+	    add(new TransientFlagDriver("EcalBarrDigiHitsNearBoundary"));
+	    add(new TransientFlagDriver("HcalBarrDigiHitsNearBoundary"));
+	    add(new TransientFlagDriver("EcalEndcapDigiHitsNearBoundary"));
+	    add(new TransientFlagDriver("HcalEndcapDigiHitsNearBoundary"));
 	}
+
+	// Look for substructure inside clusters:
+	{
+	    int m_minHitsToBeTreatedAsClusterECAL = 15;
+	    int m_minHitsToBeTreatedAsClusterHCAL = 20;
+	    int m_minHitsToBeTreatedAsClusterMCAL = 5;
+	    int m_minHitsToBeTreatedAsClusterFCAL = m_minHitsToBeTreatedAsClusterECAL;
+	    double m_newMipFinderRadiusECAL = 20.0;
+	    double m_newMipFinderRadiusHCAL = 50.0;
+	    double m_newMipFinderRadiusMCAL = 100.0;
+	    double m_newMipFinderRadiusFCAL = m_newMipFinderRadiusECAL;
+	    boolean m_removePoorQualityMips = false;
+
+	    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");
+	    clusDriverECAL.enableBarrelEndcapCrossing("EcalBarrDigiHits", "EcalBarrDigiHitsNearBoundary", "EcalEndcapDigiHits", "EcalEndcapDigiHitsNearBoundary");
+	    clusDriverHCAL.enableBarrelEndcapCrossing("HcalBarrDigiHits", "HcalBarrDigiHitsNearBoundary", "HcalEndcapDigiHits", "HcalEndcapDigiHitsNearBoundary");
+	    clusDriverECAL.setNNrange(1,1,1);
+	    clusDriverHCAL.setNNrange(2,2,1);
+	    clusDriverMCAL.setNNrange(2,2,1);
+	    //clusDriverFCAL.setNNrange(1,1,1);
+	    add(clusDriverECAL);
+	    add(clusDriverHCAL);
+	    add(clusDriverMCAL);
+	}
+
+	// Track-cluster matching in steps:
+	// Already done electrons, muons, and good pre-shower MIPs.
+	// Now take a go at the rest...
+
+	// Match tracks to MIP clusters in ECAL (ambiguities not allowed)
+	TrackToMipClusterMapMaker mipMapMaker = new TrackToMipClusterMapMaker(findCluster, "UnmatchedTracksAfterPreShowerMipMap", "MapMipClusterTracksToClusterSeeds", "UnmatchedTracksAfterMipClusterMap");
+	mipMapMaker.addInputList("OldMipsInsideTreesECAL", "MipMatchedOldMipsInsideTreesECAL", "UnmatchedOldMipsInsideTreesECALAfterMipMatch");
+	mipMapMaker.addInputList("NewMipsInsideTreesECAL", "MipMatchedNewMipsInsideTreesECAL", "UnmatchedNewMipsInsideTreesECALAfterMipMatch");
+	add(mipMapMaker);
+	// Match tracks to generic clusters in ECAL
+	TrackToGenericClusterMapMaker genMapMaker = new TrackToGenericClusterMapMaker(findCluster, "UnmatchedTracksAfterMipClusterMap", "MapGenClusterTracksToClusterSeeds", "UnmatchedTracksAfterGenClusterMap");
+	genMapMaker.addInputList("UnmatchedOldMipsInsideTreesECALAfterMipMatch", "GenMatchedOldMipsInsideTreesECAL", "UnmatchedOldMipsInsideTreesECALAfterGenMatch");
+	genMapMaker.addInputList("UnmatchedNewMipsInsideTreesECALAfterMipMatch", "GenMatchedNewMipsInsideTreesECAL", "UnmatchedNewMipsInsideTreesECALAfterGenMatch");
+	genMapMaker.addInputList("ClumpsInsideTreesECAL", "GenMatchedClumpsInsideTreesECAL", "UnmatchedClumpsInsideTreesECALAfterGenMatch");
+	genMapMaker.addInputList("BlocksInsideTreesECAL", "GenMatchedBlocksInsideTreesECAL", "UnmatchedBlocksInsideTreesECALAfterGenMatch");
+	genMapMaker.addInputList("LeftoverHitsInsideTreesECAL", "GenMatchedLeftoverHitsInsideTreesECAL", "UnmatchedLeftoverHitsInsideTreesECALAfterGenMatch");
+	genMapMaker.addInputList("PhotonClustersForDTree", "GenMatchedPhotonClustersForDTree", "UnmatchedPhotonClustersForDTreeAfterGenMatch");
+	add(genMapMaker);
+	// [here: can split photon seeds, large seeds, etc...]
+	// Remaining tracks have either NO match or an ambiguous one (i.e. >1 track to same cluster
+	AmbiguousTrackToClusterMapMaker ambiguousMapMaker = new AmbiguousTrackToClusterMapMaker(findCluster, "UnmatchedTracksAfterGenClusterMap", "MapAmbigClusterTracksToClusterSeeds", "UnmatchedTracksAfterAmbigClusterMap");
+	ambiguousMapMaker.addInputList("UnmatchedOldMipsInsideTreesECALAfterGenMatch", "AmbigMatchedOldMipsInsideTreesECAL", "UnmatchedOldMipsInsideTreesECALAfterAmbigMatch");
+	ambiguousMapMaker.addInputList("UnmatchedNewMipsInsideTreesECALAfterGenMatch", "AmbigMatchedNewMipsInsideTreesECAL", "UnmatchedNewMipsInsideTreesECALAfterAmbigMatch");
+	ambiguousMapMaker.addInputList("UnmatchedClumpsInsideTreesECALAfterGenMatch", "AmbigMatchedClumpsInsideTreesECAL", "UnmatchedClumpsInsideTreesECALAfterAmbigMatch");
+	ambiguousMapMaker.addInputList("UnmatchedBlocksInsideTreesECALAfterGenMatch", "AmbigMatchedBlocksInsideTreesECAL", "UnmatchedBlocksInsideTreesECALAfterAmbigMatch");
+	ambiguousMapMaker.addInputList("UnmatchedLeftoverHitsInsideTreesECALAfterGenMatch", "AmbigMatchedLeftoverHitsInsideTreesECAL", "UnmatchedLeftoverHitsInsideTreesECALAfterAmbigMatch");
+	ambiguousMapMaker.addInputList("UnmatchedPhotonClustersForDTreeAfterGenMatch", "AmbigMatchedPhotonClustersForDTree", "UnmatchedPhotonClustersForDTreeAfterAmbigMatch");
+	add(ambiguousMapMaker);
+	// [here: can try to split large seeds with >1 track]
     }
 }

lcsim/src/org/lcsim/recon/pfa/structural
SetUpPFA.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- SetUpPFA.java	22 Oct 2008 17:55:16 -0000	1.1
+++ SetUpPFA.java	22 Oct 2008 18:57:16 -0000	1.2
@@ -41,7 +41,7 @@
 	    allHitLists.addAll(recoHitLists);
 	    allHitLists.add("CorrMuonBarrDigiHits");
 	    mstHitLists.add("CorrMuonEndcapDigiHits");
-	    add(new org.lcsim.contrib.uiowa.SetUpDTreeForReclustering(trackList, allHitLists, recoHitLists, mstHitLists, findCluster));
+	    add(new SetUpDTreeForReclustering(trackList, allHitLists, recoHitLists, mstHitLists, findCluster));
 	}
 
 	// Set up and run PFA
CVSspam 0.2.8