Author: [log in to unmask]
Date: Wed Aug 26 10:31:25 2015
New Revision: 3404
Log:
Add plots of the residual between an extrapolated track position at the Ecal and Ecal cluster position.
Modified:
java/trunk/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java
Modified: java/trunk/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java
=============================================================================
--- java/trunk/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java (original)
+++ java/trunk/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java Wed Aug 26 10:31:25 2015
@@ -1,4 +1,15 @@
package org.hps.recon.utils;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
+import hep.aida.IHistogramFactory;
+import hep.aida.ITree;
+import hep.aida.ref.rootwriter.RootFileStore;
import hep.physics.vec.BasicHep3Vector;
import hep.physics.vec.Hep3Vector;
@@ -15,118 +26,264 @@
*/
public class TrackClusterMatcher {
- /*
- * These cuts are set at +/- 3 sigma extracted from Gaussian fits to the
- * track-cluster residual distributions.
- */
- private double topClusterTrackMatchDeltaXLow = -7.61; // mm
- private double topClusterTrackMatchDeltaXHigh = 12.; // mm
- private double bottomClusterTrackMatchDeltaXLow = -13.75; // mm
- private double bottomClusterTrackMatchDeltaXHigh = 6.0; // mm
-
- private double topClusterTrackMatchDeltaYLow = -14; // mm
- private double topClusterTrackMatchDeltaYHigh = 14; // mm
- private double bottomClusterTrackMatchDeltaYLow = -14; // mm
- private double bottomClusterTrackMatchDeltaYHigh = 14; // mm
+ // Plotting
+ private ITree tree;
+ private IHistogramFactory histogramFactory;
+ private Map<String, IHistogram1D> plots1D;
+ private Map<String, IHistogram2D> plots2D;
+
+ /** Flag used to determine if plots are enabled/disabled */
+ boolean enablePlots = false;
+
+ /**
+ * These cuts are set at +/- 3 sigma extracted from Gaussian fits to the
+ * track-cluster residual distributions. The data used to determine these
+ * limits is run 5772, singles1 triggers.
+ */
+ private double topClusterTrackMatchDeltaXLow = -7.61; // mm
+ private double topClusterTrackMatchDeltaXHigh = 12.; // mm
+ private double bottomClusterTrackMatchDeltaXLow = -13.75; // mm
+ private double bottomClusterTrackMatchDeltaXHigh = 6.0; // mm
+
+ private double topClusterTrackMatchDeltaYLow = -14; // mm
+ private double topClusterTrackMatchDeltaYHigh = 14; // mm
+ private double bottomClusterTrackMatchDeltaYLow = -14; // mm
+ private double bottomClusterTrackMatchDeltaYHigh = 14; // mm
+
+ /** Constructor */
+ TrackClusterMatcher() {};
+
+ /**
+ * Enable/disable booking, filling of Ecal cluster and extrapolated track
+ * position plots.
+ *
+ * @param enablePlots : true to enable, false to disable
+ */
+ public void enablePlots(boolean enablePlots) {
+ this.enablePlots = enablePlots;
+ if (enablePlots == true) this.bookHistograms();
+ }
+
+ /**
+ * Set the window in which the x residual of the extrapolated bottom track
+ * position at the Ecal and the Ecal cluster position must be within to be
+ * considered a 'good match'
+ *
+ * @param xLow
+ * @param xHigh
+ */
+ public void setBottomClusterTrackDxCuts(double xLow, double xHigh) {
+ this.topClusterTrackMatchDeltaXLow = xLow;
+ this.topClusterTrackMatchDeltaXHigh = xHigh;
+ }
+
+ /**
+ * Set the window in which the y residual of the extrapolated bottom track
+ * position at the Ecal and the Ecal cluster position must be within to be
+ * considered a 'good match'
+ *
+ * @param yLow
+ * @param yHigh
+ */
+ public void setBottomClusterTrackDyCuts(double yLow, double yHigh) {
+ this.topClusterTrackMatchDeltaYLow = yLow;
+ this.topClusterTrackMatchDeltaYHigh = yHigh;
+ }
+
+ /**
+ * Set the window in which the x residual of the extrapolated top track position
+ * at the Ecal and the Ecal cluster position must be within to be considered
+ * a 'good match'
+ *
+ * @param xLow
+ * @param xHigh
+ */
+ public void setTopClusterTrackDxCuts(double xLow, double xHigh) {
+ this.topClusterTrackMatchDeltaXLow = xLow;
+ this.topClusterTrackMatchDeltaXHigh = xHigh;
+ }
+
+ /**
+ * Set the window in which the y residual of the extrapolated top track position
+ * at the Ecal and the Ecal cluster position must be within to be considered
+ * a 'good match'
+ *
+ * @param yLow
+ * @param yHigh
+ */
+ public void setTopClusterTrackDyCuts(double yLow, double yHigh) {
+ this.topClusterTrackMatchDeltaYLow = yLow;
+ this.topClusterTrackMatchDeltaYHigh = yHigh;
+ }
+
+ /**
+ * Determine if a track is matched to a cluster. Currently, this is
+ * determined by checking that the track and cluster are within the same
+ * detector volume of each other and that the extrapolated track position
+ * is within some defined distance of the cluster.
+ *
+ * @param cluster : The Ecal cluster to check
+ * @param track : The SVT track to check
+ * @return true if all cuts are pased, false otherwise.
+ */
+ public boolean isMatch(Cluster cluster, Track track) {
+
+ // Check that the track and cluster are in the same detector volume.
+ // If not, there is no way they can be a match.
+ if ((track.getTrackStates().get(0).getTanLambda() > 0 && cluster.getPosition()[1] < 0)
+ || (track.getTrackStates().get(0).getTanLambda() < 0 && cluster.getPosition()[1] > 0 )) return false;
+
+ // Get the cluster position
+ Hep3Vector clusterPosition = new BasicHep3Vector(cluster.getPosition());
+
+ // Extrapolate the track to the Ecal cluster position
+ // TODO: At some point, this needs to use the fringe field
+ Hep3Vector trackPosAtEcal = TrackUtils.extrapolateTrack(track, clusterPosition.z());
+
+ // Calculate the difference between the cluster position at the Ecal and
+ // the track in both the x and y directions
+ double deltaX = clusterPosition.x() - trackPosAtEcal.x();
+ double deltaY = clusterPosition.y() - trackPosAtEcal.y();
+
+ if (enablePlots) {
+ if (track.getTrackStates().get(0).getTanLambda() > 0) {
+
+ plots1D.get("Ecal cluster x - track x @ Ecal - top - all").fill(deltaX);
+ plots2D.get("Ecal cluster x v track x @ Ecal - top - all").fill(clusterPosition.x(),
+ trackPosAtEcal.x());
+ plots1D.get("Ecal cluster y - track y @ Ecal - top - all").fill(deltaY);
+ plots2D.get("Ecal cluster y v track y @ Ecal - top - all").fill(clusterPosition.y(),
+ trackPosAtEcal.y());
+
+ } else if (track.getTrackStates().get(0).getTanLambda() < 0) {
+
+ plots1D.get("Ecal cluster x - track x @ Ecal - bottom - all").fill(deltaX);
+ plots2D.get("Ecal cluster x v track x @ Ecal - bottom - all").fill(clusterPosition.x(),
+ trackPosAtEcal.x());
+ plots1D.get("Ecal cluster y - track y @ Ecal - bottom - all").fill(deltaY);
+ plots2D.get("Ecal cluster y v track y @ Ecal - bottom - all").fill(clusterPosition.y(),
+ trackPosAtEcal.y());
+ }
+ }
+
+ // Check that dx and dy between the extrapolated track and cluster
+ // positions is reasonable. Different requirements are imposed on
+ // top and bottom tracks in order to account for offsets.
+ if ((track.getTrackStates().get(0).getTanLambda() > 0 && (deltaX > topClusterTrackMatchDeltaXHigh ||
+ deltaX < topClusterTrackMatchDeltaXLow)) ||
+ (track.getTrackStates().get(0).getTanLambda() < 0 && (deltaX > bottomClusterTrackMatchDeltaXHigh ||
+ deltaX < bottomClusterTrackMatchDeltaXLow))) return false;
+
+ if ((track.getTrackStates().get(0).getTanLambda() > 0 && (deltaY > topClusterTrackMatchDeltaYHigh ||
+ deltaY < topClusterTrackMatchDeltaYLow)) ||
+ (track.getTrackStates().get(0).getTanLambda() < 0 && (deltaY > bottomClusterTrackMatchDeltaYHigh ||
+ deltaY < bottomClusterTrackMatchDeltaYLow))) return false;
+
+ if (enablePlots) {
+ if (track.getTrackStates().get(0).getTanLambda() > 0) {
+
+ plots1D.get("Ecal cluster x - track x @ Ecal - top - matched").fill(deltaX);
+ plots2D.get("Ecal cluster x v track x @ Ecal - top - matched").fill(clusterPosition.x(),
+ trackPosAtEcal.x());
+ plots1D.get("Ecal cluster y - track y @ Ecal - top - matched").fill(deltaY);
+ plots2D.get("Ecal cluster y v track y @ Ecal - top - matched").fill(clusterPosition.y(),
+ trackPosAtEcal.y());
+
+ } else if (track.getTrackStates().get(0).getTanLambda() < 0) {
+
+ plots1D.get("Ecal cluster x - track x @ Ecal - bottom - matched").fill(deltaX);
+ plots2D.get("Ecal cluster x v track x @ Ecal - bottom - matched").fill(clusterPosition.x(),
+ trackPosAtEcal.x());
+ plots1D.get("Ecal cluster y - track y @ Ecal - bottom - matched").fill(deltaY);
+ plots2D.get("Ecal cluster y v track y @ Ecal - bottom - matched").fill(clusterPosition.y(),
+ trackPosAtEcal.y());
+ }
+ }
+
+ // If all cuts are pased, return true.
+ return true;
+ }
- /** Constructor */
- TrackClusterMatcher() {};
-
- /**
- * Set the window in which the x residual of the extrapolated top track position
- * at the Ecal and the Ecal cluster position must be within to be considered
- * a 'good match'
- *
- * @param xLow
- * @param xHigh
- */
- public void setTopClusterTrackDxCuts(double xLow, double xHigh) {
- this.topClusterTrackMatchDeltaXLow = xLow;
- this.topClusterTrackMatchDeltaXHigh = xHigh;
- }
-
- /**
- * Set the window in which the y residual of the extrapolated top track position
- * at the Ecal and the Ecal cluster position must be within to be considered
- * a 'good match'
- *
- * @param yLow
- * @param yHigh
- */
- public void setTopClusterTrackDyCuts(double yLow, double yHigh) {
- this.topClusterTrackMatchDeltaYLow = yLow;
- this.topClusterTrackMatchDeltaYHigh = yHigh;
- }
-
- /**
- * Set the window in which the x residual of the extrapolated bottom track
- * position at the Ecal and the Ecal cluster position must be within to be
- * considered a 'good match'
- *
- * @param xLow
- * @param xHigh
- */
- public void setBottomClusterTrackDxCuts(double xLow, double xHigh) {
- this.topClusterTrackMatchDeltaXLow = xLow;
- this.topClusterTrackMatchDeltaXHigh = xHigh;
- }
-
- /**
- * Set the window in which the y residual of the extrapolated bottom track
- * position at the Ecal and the Ecal cluster position must be within to be
- * considered a 'good match'
- *
- * @param yLow
- * @param yHigh
- */
- public void setBottomClusterTrackDyCuts(double yLow, double yHigh) {
- this.topClusterTrackMatchDeltaYLow = yLow;
- this.topClusterTrackMatchDeltaYHigh = yHigh;
- }
+ /** Book histograms of Ecal cluster x/y vs extrapolated track x/y */
+ private void bookHistograms() {
+
+ plots1D = new HashMap<String, IHistogram1D>();
+ plots2D = new HashMap<String, IHistogram2D>();
+
+ tree = IAnalysisFactory.create().createTreeFactory().create();
+ histogramFactory = IAnalysisFactory.create().createHistogramFactory(tree);
+
+ //--- All tracks and clusters ---//
+ //-------------------------------//
+
+ //--- Top ---//
+ plots1D.put("Ecal cluster x - track x @ Ecal - top - all",
+ histogramFactory.createHistogram1D("Ecal cluster x - track x @ Ecal - top - all", 200, -200, 200));
+
+ plots2D.put("Ecal cluster x v track x @ Ecal - top - all",
+ histogramFactory.createHistogram2D("Ecal cluster x v track x @ Ecal - top - all", 200, -200, 200, 200, -200, 200));
+
+ plots1D.put("Ecal cluster y - track y @ Ecal - top - all",
+ histogramFactory.createHistogram1D("Ecal cluster y - track y @ Ecal - top - all", 100, -100, 100));
+
+ plots2D.put("Ecal cluster y v track y @ Ecal - top - all",
+ histogramFactory.createHistogram2D("Ecal cluster y v track @ Ecal - top - all", 100, -100, 100, 100, -100, 100));
- /**
- * Determine if a track is matched to a cluster. Currently, this is
- * determined by checking that the track and cluster are within the same
- * detector volume of each other and that the extrapolated track position
- * is within some defined distance of the cluster.
- *
- * @param cluster : The Ecal cluster to check
- * @param track : The SVT track to check
- * @return true if all cuts are pased, false otherwise.
- */
- private boolean isMatch(Cluster cluster, Track track) {
-
- // Check that the track and cluster are in the same detector volume.
- // If not, there is no way they can be a match.
- if ((track.getTrackStates().get(0).getTanLambda() > 0 && cluster.getPosition()[1] < 0)
- || (track.getTrackStates().get(0).getTanLambda() < 0 && cluster.getPosition()[1] > 0 )) return false;
-
- // Get the cluster position
- Hep3Vector clusterPosition = new BasicHep3Vector(cluster.getPosition());
-
- // Extrapolate the track to the Ecal cluster position
- // TODO: At some point, this needs to use the fringe field
- Hep3Vector trackPosAtEcal = TrackUtils.extrapolateTrack(track, clusterPosition.z());
-
- // Calculate the difference between the cluster position at the Ecal and
- // the track in both the x and y directions
- double deltaX = clusterPosition.x() - trackPosAtEcal.x();
- double deltaY = clusterPosition.y() - trackPosAtEcal.y();
-
- // Check that dx and dy between the extrapolated track and cluster
- // positions is reasonable. Different requirements are imposed on
- // top and bottom tracks in order to account for offsets.
- if ((track.getTrackStates().get(0).getTanLambda() > 0 && (deltaX > topClusterTrackMatchDeltaXHigh ||
- deltaX < topClusterTrackMatchDeltaXLow)) ||
- (track.getTrackStates().get(0).getTanLambda() < 0 && (deltaX > bottomClusterTrackMatchDeltaXHigh ||
- deltaX < bottomClusterTrackMatchDeltaXLow))) return false;
-
- if ((track.getTrackStates().get(0).getTanLambda() > 0 && (deltaY > topClusterTrackMatchDeltaYHigh ||
- deltaY < topClusterTrackMatchDeltaYLow)) ||
- (track.getTrackStates().get(0).getTanLambda() < 0 && (deltaY > bottomClusterTrackMatchDeltaYHigh ||
- deltaY < bottomClusterTrackMatchDeltaYLow))) return false;
-
- // If all cuts are pased, return true.
- return true;
- }
+ //--- Bottom ---//
+ plots1D.put("Ecal cluster x - track x @ Ecal - bottom - all",
+ histogramFactory.createHistogram1D("Ecal cluster x - track x @ Ecal - top - all", 200, -200, 200));
+
+ plots2D.put("Ecal cluster x v track x @ Ecal - bottom - all",
+ histogramFactory.createHistogram2D("Ecal cluster x v track x @ Ecal - top - all", 200, -200, 200, 200, -200, 200));
+
+ plots1D.put("Ecal cluster y - track y @ Ecal - bottom - all",
+ histogramFactory.createHistogram1D("Ecal cluster y - track y @ Ecal - top - all", 100, -100, 100));
+
+ plots2D.put("Ecal cluster y v track y @ Ecal - bottom - all",
+ histogramFactory.createHistogram2D("Ecal cluster y v track @ Ecal - top - all", 100, -100, 100, 100, -100, 100));
+
+ //--- Matched tracks ---//
+ //----------------------//
+
+ //--- Top ---//
+ plots1D.put("Ecal cluster x - track x @ Ecal - top - matched",
+ histogramFactory.createHistogram1D("Ecal cluster x - track x @ Ecal - top - matched", 200, -200, 200));
+
+ plots2D.put("Ecal cluster x v track x @ Ecal - top - matched",
+ histogramFactory.createHistogram2D("Ecal cluster x v track x @ Ecal - top - matched", 200, -200, 200, 200, -200, 200));
+
+ plots1D.put("Ecal cluster y - track y @ Ecal - top - matched",
+ histogramFactory.createHistogram1D("Ecal cluster y - track y @ Ecal - top - matched", 100, -100, 100));
+
+ plots2D.put("Ecal cluster y v track y @ Ecal - top - matched",
+ histogramFactory.createHistogram2D("Ecal cluster y v track @ Ecal - top - matched", 100, -100, 100, 100, -100, 100));
+
+ //--- Bottom ---//
+ plots1D.put("Ecal cluster x - track x @ Ecal - bottom - matched",
+ histogramFactory.createHistogram1D("Ecal cluster x - track x @ Ecal - top - matched", 200, -200, 200));
+
+ plots2D.put("Ecal cluster x v track x @ Ecal - bottom - matched",
+ histogramFactory.createHistogram2D("Ecal cluster x v track x @ Ecal - top - matched", 200, -200, 200, 200, -200, 200));
+
+ plots1D.put("Ecal cluster y - track y @ Ecal - bottom - matched",
+ histogramFactory.createHistogram1D("Ecal cluster y - track y @ Ecal - top - matched", 100, -100, 100));
+
+ plots2D.put("Ecal cluster y v track y @ Ecal - bottom - matched",
+ histogramFactory.createHistogram2D("Ecal cluster y v track @ Ecal - top - matched", 100, -100, 100, 100, -100, 100));
+
+ }
+
+ /** Save the histograms to a ROO file */
+ public void saveHistograms() {
+
+ String rootFile = "track_cluster_matching_plots.root";
+ RootFileStore store = new RootFileStore(rootFile);
+ try {
+ store.open();
+ store.add(tree);
+ store.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
|