Commit in lcsim/src/org/lcsim/recon/pfa/identifier on MAIN
SmallPhotonMaker.java+133added 1.1
PFA utilities

lcsim/src/org/lcsim/recon/pfa/identifier
SmallPhotonMaker.java added at 1.1
diff -N SmallPhotonMaker.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SmallPhotonMaker.java	21 Mar 2007 00:51:24 -0000	1.1
@@ -0,0 +1,133 @@
+package org.lcsim.recon.pfa.identifier;
+
+import java.util.*;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.BasicHep3Vector;
+import org.lcsim.recon.cluster.structural.FragmentIdentifier;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.SimCalorimeterHit;
+
+/**
+ * Given a list of clusters, make ones that are consistent with
+ * fragments AND pass photon selection into small photon clusters.
+ *
+ * Photon selection: Innermost hit is in layer 0-3 of ECAL
+ *
+ * FIXME: I think this could be implemented as a combination of a
+ * filter and SimpleNeutralParticleMaker without the need for a 
+ * new class.
+ */
+
+public class SmallPhotonMaker extends SimpleNeutralParticleMaker
+{
+    protected FragmentIdentifier m_fragID = null;
+    public SmallPhotonMaker(FragmentIdentifier fragID) {
+	super(22); // make photons
+	m_fragID = fragID;
+    }
+
+    public void process(EventHeader event) 
+    {
+	m_event = event;
+
+	// Input, output:
+	List<Cluster> inputClusterList = event.get(Cluster.class, m_inputClusterListName);
+	List<Cluster> outputClusterList = new Vector<Cluster>();
+	outputClusterList.addAll(inputClusterList); // initially full
+	List<ReconstructedParticle> outputParticleList = new Vector<ReconstructedParticle>();
+
+	for (Cluster clus : inputClusterList) {
+	    if (m_fragID.isFragment(clus, event)) {
+		// Small cluster/fragment -- is it photon-like?
+		CalorimeterHit firstHitInECAL = findInnermostHitInECAL(clus);
+		boolean isPhoton = (firstHitInECAL!=null && getLayer(firstHitInECAL)<4);
+		if (isPhoton) {
+		    LocalReconstructedParticle part = new LocalReconstructedParticle();
+		    part.addCluster(clus);
+		    double clusterEnergy = estimateClusterEnergy(clus); // clumsy, not a real calibration...
+		    double particleEnergy = Math.sqrt(clusterEnergy*clusterEnergy + m_mass*m_mass);
+		    part.setEnergy(particleEnergy);
+		    // Set the other particle properties that are needed to render
+		    // properly in the event display.
+		    part.setMomentum(computeMomentum(particleEnergy, clus));
+		    part.setReferencePoint(new BasicHep3Vector(0,0,0));
+		    part.setCharge(0);
+		    // Add to the output list
+		    outputParticleList.add(part);
+		    outputClusterList.remove(clus);
+		}
+		if (m_debug) {
+		    String printme = new String();
+		    printme += "DEBUG: This fragment with ";
+		    printme += clus.getCalorimeterHits().size();
+		    printme += " hits has first ECAL layer ";
+		    if (firstHitInECAL==null) {
+			printme += "[null]";
+		    } else {
+			printme += getLayer(firstHitInECAL);
+		    }
+		    printme += " => isPhoton="+isPhoton;
+		    printme += ". True contributions: ";
+		    Map<MCParticle, List<CalorimeterHit>> tmpMap = new HashMap<MCParticle, List<CalorimeterHit>>();
+		    for (CalorimeterHit hit : clus.getCalorimeterHits()) {
+			SimCalorimeterHit simhit = (SimCalorimeterHit) (hit);
+			for (int i=0; i<simhit.getMCParticleCount(); i++) {
+			    MCParticle hitPart = simhit.getMCParticle(i);
+			    if ( ! (tmpMap.keySet().contains(hitPart)) ) {
+				tmpMap.put(hitPart, new Vector<CalorimeterHit>());
+			    }
+			    tmpMap.get(hitPart).add(hit);
+			}
+		    }
+		    for (MCParticle hitPart : tmpMap.keySet()) {
+			printme += " ";
+			printme += hitPart.getType().getName();
+			printme += " (E=";
+			printme += hitPart.getEnergy();
+			printme += ", hits=";
+			printme += tmpMap.get(hitPart).size();
+			printme += ")";
+		    }
+		    System.out.println(printme);
+		}
+	    }
+	}
+
+	event.put(m_outputParticleListName, outputParticleList);
+	event.put(m_outputClusterListName, outputClusterList);
+    }
+
+    protected String m_outputClusterListName;
+    public void setOutputClusterList(String name) { m_outputClusterListName = name; }
+
+
+    protected CalorimeterHit findInnermostHitInECAL(Cluster clus) {
+        CalorimeterHit innermostHit = null;
+        for (CalorimeterHit hit : clus.getCalorimeterHits()) {
+            int layer = getLayer(hit);
+            org.lcsim.geometry.Subdetector subdet = hit.getSubdetector();           
+            if ( ! subdet.isCalorimeter() ) { throw new AssertionError("Cluster hit outside calorimeter"); }
+            String name = subdet.getName();
+            if (name.compareTo("EMBarrel") == 0 || name.compareTo("EMEndcap") == 0) {
+                // EM -- OK
+                if (innermostHit==null || getLayer(innermostHit)>layer) {
+                    innermostHit = hit;
+                }
+            }
+        }
+        return innermostHit;
+    }
+    
+    protected int getLayer(CalorimeterHit hit) {
+        org.lcsim.geometry.IDDecoder id = hit.getIDDecoder();
+        id.setID(hit.getCellID());
+        int layer = id.getLayer();
+        return layer;
+    }
+}
CVSspam 0.2.8