lcsim/src/org/lcsim/contrib/uiowa
diff -N ConeMIPReassignmentAlgorithm.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ConeMIPReassignmentAlgorithm.java 15 Aug 2008 17:40:01 -0000 1.1
@@ -0,0 +1,80 @@
+package org.lcsim.contrib.uiowa;
+
+import java.util.*;
+import org.lcsim.util.*;
+import org.lcsim.event.util.*;
+import org.lcsim.event.*;
+import hep.physics.vec.*;
+
+/**
+ * A class to calculate the cone angle for a track and a cluster.
+ * The apex of the cone is based on the showering point of the
+ * track, adjusted by an offset distance along the tangent of
+ * the track at its showering point. We then calculate the angle
+ * between the tangent and the vector from the apex to the cluster.
+ *
+ * @version $Id: ConeMIPReassignmentAlgorithm.java,v 1.1 2008/08/15 17:40:01 mcharles Exp $
+ */
+
+public class ConeMIPReassignmentAlgorithm implements ReassignClustersAlgorithm {
+
+ protected MIPGeometryHandler m_geom;
+ protected double m_distanceToGoBack = 0.0;
+ protected double m_limit = 0.0;
+
+ /**
+ * Constructor.
+ *
+ * @param geomHandler Helper class to calculate showering point and tangent of tracks.
+ * @param distanceToGoBack Offset distance from showering point to cone apex.
+ * @param limit If cone angle is bigger than this, the calculation will return null.
+ */
+ public ConeMIPReassignmentAlgorithm(MIPGeometryHandler geomHandler, double distanceToGoBack, double limit) {
+ m_geom = geomHandler;
+ m_distanceToGoBack = distanceToGoBack;
+ m_limit = limit;
+ }
+
+ /** Calculate cone angle. Returns null if angle is undefined or too large. */
+ public Double computeFigureOfMerit(Track tr, Cluster clus) {
+
+ // Check for case where track is a placeholder MultipleTrackTrack
+ if (tr.getTracks().size()!=0) {
+ Double bestAmongDaughters = null;
+ for (Track daughterTrack : tr.getTracks()) {
+ Double daughterFigureOfMerit = this.computeFigureOfMerit(daughterTrack, clus);
+ if (daughterFigureOfMerit != null) {
+ if (daughterFigureOfMerit < m_limit) {
+ if (bestAmongDaughters==null || daughterFigureOfMerit<bestAmongDaughters) {
+ bestAmongDaughters = daughterFigureOfMerit;
+ }
+ }
+ }
+ }
+ return bestAmongDaughters;
+ }
+
+ Hep3Vector showerPoint = m_geom.getShowerPoint(tr);
+ Hep3Vector tangentUnit = m_geom.getTangentUnit(tr);
+ Hep3Vector clusterPosition = new BasicHep3Vector(clus.getPosition());
+
+ if (showerPoint == null || tangentUnit == null) {
+ // Extrapolation failed
+ return null;
+ } else {
+ Hep3Vector coneOffset = VecOp.mult(m_distanceToGoBack, tangentUnit);
+ Hep3Vector coneStartPoint = VecOp.sub(showerPoint, coneOffset);
+ Hep3Vector displacement = VecOp.sub(clusterPosition, coneStartPoint);
+ Hep3Vector displacementUnit = VecOp.unit(displacement);
+ double cosTheta = VecOp.dot(tangentUnit, displacementUnit);
+ double angle = Math.acos(cosTheta);
+ if (angle < m_limit) {
+ return new Double(angle);
+ } else {
+ // Outside cone
+ return null;
+ }
+ }
+ }
+
+}