Print

Print


Commit in lcsim/src/org/lcsim/recon/pfa/identifier on MAIN
MIPChargedParticleMaker.java+218added 1.1
MIP-specific charged particle maker

lcsim/src/org/lcsim/recon/pfa/identifier
MIPChargedParticleMaker.java added at 1.1
diff -N MIPChargedParticleMaker.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ MIPChargedParticleMaker.java	10 Aug 2006 22:57:56 -0000	1.1
@@ -0,0 +1,218 @@
+package org.lcsim.recon.pfa.identifier;
+
+import java.util.*;
+import hep.physics.vec.*;
+import hep.physics.particle.Particle;
+import org.lcsim.event.Track;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.event.Cluster;
+import org.lcsim.mc.fast.tracking.ReconTrack;
+import org.lcsim.event.base.BaseReconstructedParticle;
+
+/**
+ * Given a list of MIP clusters and a list of tracks,
+ * try to connect tracks to MIP segments and
+ * make a list of charged ReconstructedParticles.
+ *
+ * Each track is matched to exactly zero or one MIP,
+ * and appears in zero or one ReconstructedParticles.
+ * But a MIP/particle may be associated with more than
+ * one track.
+ *
+ * Optionally, the user may supply further list of clusters.
+ * If the MIP is part of one of these clusters (via Cluster.getClusters),
+ * then the entire cluster is added to the ReconstructedParticle instead.
+ * The parent must be unique.
+ *
+ * @version $Id: MIPChargedParticleMaker.java,v 1.1 2006/08/10 22:57:56 mcharles Exp $
+ */
+
+public class MIPChargedParticleMaker
+ extends Driver
+{
+    /** Simple constructor. */
+    public MIPChargedParticleMaker() {
+	m_clusterLists = new HashMap<String,String>();
+    }
+
+    public void setInputTrackList(String name) { m_inputTrackListName = name; }
+    public void setOutputTrackList(String name){ m_outputTrackListName = name; }
+    public void setInputMIPList(String name){ m_inputMIPListName = name; }
+    public void setOutputMIPList(String name){ m_outputMIPListName = name; }
+    public void setOutputParticleList(String name){ m_outputParticleListName = name; }
+    public void setTrackMatcher(TrackClusterMatcher matcher) { m_matcher = matcher; }
+   
+    public void addClusterList(String inputName, String outputName) {
+	m_clusterLists.put(inputName, outputName);
+    }
+
+    public void process(EventHeader event)
+    {
+	super.process(event);
+	
+	// Inputs:
+	List<Track> inputTrackList = event.get(Track.class, m_inputTrackListName);
+	List<Cluster> inputMIPList = event.get(Cluster.class, m_inputMIPListName);
+
+	// Outputs
+	// Initially, all tracks and MIPs are unmatched.
+	Map<Track,Cluster> matchedTracks = new HashMap<Track,Cluster>();
+	List<Track> unmatchedTracks = new Vector<Track>(inputTrackList);
+	List<Cluster> unmatchedMIPs = new Vector<Cluster>(inputMIPList);
+	List<ReconstructedParticle> outputParticleList = new Vector<ReconstructedParticle>();
+
+	// Optional inputs and outputs
+	// Output lists are initially identical to the input lists; we will
+	// remove clusters as they are matched.
+	Map<String,List<Cluster>> inputClusterLists = new HashMap<String,List<Cluster>>();
+	Map<String,List<Cluster>> outputClusterLists = new HashMap<String,List<Cluster>>();
+	for (String inputName : m_clusterLists.keySet()) {
+	    String outputName = m_clusterLists.get(inputName);
+	    List<Cluster> inputList = event.get(Cluster.class, inputName);
+	    List<Cluster> outputList = new Vector<Cluster>(inputList);
+	    inputClusterLists.put(inputName, inputList);
+	    outputClusterLists.put(outputName, outputList);
+	}
+
+	// Try to match each track to a MIP segment
+	Map<Cluster,List<Track>> matchedMIPs = new HashMap<Cluster,List<Track>>();
+	for (Track tr : inputTrackList) {
+	    Cluster matchedMIP = m_matcher.matchTrackToCluster(tr, inputMIPList);
+	    if (matchedMIP != null) {
+		// Verify that the returned MIP is a member of inputMIPList
+		if ( !(inputMIPList.contains(matchedMIP)) ) {
+		    throw new AssertionError("Book-keeping error: MIP Matcher must return a member of the input list or null");
+		}
+		if ( !(matchedMIPs.keySet().contains(matchedMIP)) ) {
+		    // First time we've seen this MIP => make its track list
+		    matchedMIPs.put(matchedMIP, new Vector<Track>());
+		}
+		matchedMIPs.get(matchedMIP).add(tr);
+		unmatchedMIPs.remove(matchedMIP);
+		unmatchedTracks.remove(tr);
+		matchedTracks.put(tr, matchedMIP);
+	    }
+	}
+
+	// Optional: Look for each MIP's parent cluster
+	for (Cluster matchedMIP : matchedMIPs.keySet()) {
+	    Cluster uniqueParent = null;
+	    for (String inputListName : m_clusterLists.keySet()) {
+		String outputListName = m_clusterLists.get(inputListName);
+		List<Cluster> inputList = inputClusterLists.get(inputListName);
+		List<Cluster> outputList = outputClusterLists.get(outputListName);
+		
+		for (Cluster clus : inputList) {
+		    List<Cluster> daughters = recursivelyFindSubClusters(clus);
+		    if (daughters.contains(matchedMIP)) {
+			// Found a parent containing this MIP.
+			if (uniqueParent != null) {
+			    throw new AssertionError("Book-keeping error: Non-unique parent of MIP");
+			}
+			uniqueParent = clus;
+		    }
+		}
+		
+		// If we found a unique parent in this list, do book-keeping:
+		//    1) Remove parent from output list of unmatched clusters
+		//    2) Make associated track(s) point to parent cluster
+		if (uniqueParent != null) {
+		    outputList.remove(uniqueParent);
+		    for (Track tr : matchedMIPs.get(matchedMIP)) {
+			matchedTracks.put(tr, uniqueParent); // over-write previous mapping
+		    }
+		}
+	    }
+	}
+
+	// Now that we have the track:cluster association, make output
+	// particles. We have to watch for the special case where >1 track
+	// is matched to a cluster.
+	Map<Cluster,LocalReconstructedParticle> matchedClusters = new HashMap<Cluster,LocalReconstructedParticle> ();
+	for (Track tr : matchedTracks.keySet()) {
+	    Cluster clus = matchedTracks.get(tr);
+	    if (matchedClusters.keySet().contains(clus)) {
+		// Already used this cluster in a particle => just add the track to that particle
+		LocalReconstructedParticle part = matchedClusters.get(clus);
+		part.addTrack(tr);
+		part.recomputeKinematics();
+	    } else {
+		// This cluster hasn't been used yet -- initialize its particle
+		LocalReconstructedParticle part = new LocalReconstructedParticle();
+		part.addTrack(tr);
+		part.addCluster(clus);
+		part.recomputeKinematics();
+		matchedClusters.put(clus, part);
+	    }
+	}
+	outputParticleList.addAll(matchedClusters.values());
+
+	// Write out
+	event.put(m_outputTrackListName, unmatchedTracks);
+	event.put(m_outputMIPListName, unmatchedMIPs);
+	event.put(m_outputParticleListName, outputParticleList);
+	for (String inputName : m_clusterLists.keySet()) {
+	    String outputName = m_clusterLists.get(inputName);
+	    List<Cluster> outputList = outputClusterLists.get(outputName);
+	    event.put(outputName, outputList);
+	}
+    }
+
+    /**
+     * Internal utility routine
+     */
+    protected List<Cluster> recursivelyFindSubClusters(Cluster clus) 
+    {
+	List<Cluster> output = new Vector<Cluster>();
+	for (Cluster dau : clus.getClusters()) {
+	    output.addAll(recursivelyFindSubClusters(dau));
+	}
+	output.add(clus);
+	return output;
+    }
+
+    protected TrackClusterMatcher m_matcher;
+    protected String m_inputTrackListName;
+    protected String m_outputTrackListName;
+    protected String m_inputMIPListName;
+    protected String m_outputMIPListName;
+    protected String m_outputParticleListName;
+    protected Map<String,String> m_clusterLists;
+
+    // Really, this belongs in a central implementation.
+    // It may change at any time (hence private).
+    private class LocalReconstructedParticle extends BaseReconstructedParticle
+    {
+	public void setEnergy(double e) {
+	    _fourVec.setT(e);
+	}
+	public void setMomentum(Hep3Vector p3) {
+	    _fourVec.setV3(_fourVec.t(), p3);
+	}
+	public void setReferencePoint(Hep3Vector p3) {
+	    _referencePoint = new BasicHep3Vector(p3.x(), p3.y(), p3.z());
+	}
+	public void setCharge(double q) {
+	    _charge = q;
+	}
+	public void recomputeKinematics() {
+	    double energy = 0.0;
+	    for (Track tr : this.getTracks()) {
+		double[] trackMomentum = tr.getMomentum();
+		double trackMomentumMagSq = (trackMomentum[0]*trackMomentum[0] + trackMomentum[1]*trackMomentum[1] + trackMomentum[2]*trackMomentum[2]);
+		double mass = 0.140;
+		if (tr instanceof ReconTrack) {
+		    Particle truthParticle = ((ReconTrack)(tr)).getMCParticle();
+		    if (truthParticle != null) {
+			mass = truthParticle.getMass();
+		    }
+		}
+		double trackEnergy = Math.sqrt(trackMomentumMagSq + mass*mass);
+		energy += trackEnergy;
+	    }
+	    this.setEnergy(energy);
+	}
+    }
+}
CVSspam 0.2.8