Author: [log in to unmask]
Date: Wed Jan 18 11:57:10 2017
New Revision: 4668
Log:
Simple Analysis Driver to compare SimTrackerHit positions with strip cluster positions in the sensors.
Added:
java/trunk/analysis/src/main/java/org/hps/analysis/MC/
java/trunk/analysis/src/main/java/org/hps/analysis/MC/MCTrackerHitResidualAnalysisDriver.java
Added: java/trunk/analysis/src/main/java/org/hps/analysis/MC/MCTrackerHitResidualAnalysisDriver.java
=============================================================================
--- java/trunk/analysis/src/main/java/org/hps/analysis/MC/MCTrackerHitResidualAnalysisDriver.java (added)
+++ java/trunk/analysis/src/main/java/org/hps/analysis/MC/MCTrackerHitResidualAnalysisDriver.java Wed Jan 18 11:57:10 2017
@@ -0,0 +1,213 @@
+package org.hps.analysis.MC;
+
+import hep.physics.matrix.SymmetricMatrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import java.io.IOException;
+import static java.lang.Math.sqrt;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.hps.analysis.examples.DetailedAnalysisDriver;
+import org.hps.recon.tracking.TrackUtils;
+import org.lcsim.detector.DetectorElementStore;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.ITranslation3D;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.RelationalTable;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.Track;
+import org.lcsim.event.TrackerHit;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * Simple Driver to compare positions of the SimTrackerHits with the TrackerHits
+ * created by the full SVT simulation. This analyzes SimTrackerHits and
+ * TrackerHits separately, so should only be run on MC events with single
+ * tracks. TODO follow the link back from the TrackerHit to the SimTrackerHit to
+ * get a 1-to-1 correspondence between the hits.
+ *
+ * @author Norman A Graf
+ *
+ * @version $Id:
+ */
+public class MCTrackerHitResidualAnalysisDriver extends Driver
+{
+
+ private boolean debug = false;
+ AIDA aida = AIDA.defaultInstance();
+ String aidaFileName = "MCTrackerHitResidualAnalysisDriverPlots";
+ String aidaFileType = "aida";
+
+ @Override
+ protected void process(EventHeader event)
+ {
+ // a map of MC hit positions keyed on sensor name
+ Map<String, List<Double>> mcSensorHitPositionMap = new HashMap<String, List<Double>>();
+ // a map of Tracker hit positions keyed on sensor name
+ Map<String, List<Double>> trackSensorHitPositionMap = new HashMap<String, List<Double>>();
+
+ // First step is to get the SimTrackerHits and determine their location
+ // in local coordinates.
+ List<SimTrackerHit> simHits = event.get(SimTrackerHit.class, "TrackerHits");
+ System.out.println("found " + simHits.size() + " SimTrackerHits");
+ // loop over each hit
+ for (SimTrackerHit hit : simHits) {
+ // get the hit's position in global coordinates..
+ Hep3Vector globalPos = hit.getPositionVec();
+ // get the transformation from global to local
+ ITransform3D g2lXform = hit.getDetectorElement().getGeometry().getGlobalToLocal();
+ //System.out.println("transform matrix: " + g2lXform);
+ IRotation3D rotMat = g2lXform.getRotation();
+ //System.out.println("rotation matrix: " + rotMat);
+ ITranslation3D transMat = g2lXform.getTranslation();
+ //System.out.println("translation vector: " + transMat);
+ // check that we can reproduce the local origin
+ ITransform3D l2gXform = hit.getDetectorElement().getGeometry().getLocalToGlobal();
+ Hep3Vector o = new BasicHep3Vector();
+ //System.out.println("origin: " + o);
+ // tranform the local origin into global position
+ Hep3Vector localOriginInglobal = l2gXform.transformed(o);
+ //System.out.println("transformed local to global: " + localOriginInglobal);
+ // and now back...
+ //System.out.println("and back: " + g2lXform.transformed(localOriginInglobal));
+ // hmmm, so why is this not the same as the translation vector of the transform?
+ //Note:
+ // u is the measurement direction perpendicular to the strip
+ // v is along the strip
+ // w is normal to the wafer plane
+
+ Hep3Vector localPos = g2lXform.transformed(globalPos);
+// System.out.println("Layer: " + hit.getLayer() + " Layer Number: " + hit.getLayerNumber() + " ID: " + hit.getCellID() + " " + hit.getDetectorElement().getName());
+// System.out.println("global position " + globalPos);
+// System.out.println("local position " + localPos);
+ String sensorName = hit.getDetectorElement().getName();
+ double u = localPos.x();
+ System.out.println("MC " + hit.getDetectorElement().getName() + " u= " + localPos.x());
+ if (mcSensorHitPositionMap.containsKey(sensorName)) {
+ List<Double> vals = mcSensorHitPositionMap.get(sensorName);
+ vals.add(u);
+ } else {
+ List<Double> vals = new ArrayList<Double>();
+ vals.add(u);
+ mcSensorHitPositionMap.put(sensorName, vals);
+ }
+ } // end of loop over SimTrackerHits
+
+ // let's look at Tracker hits
+ setupSensors(event);
+ RelationalTable hitToStrips = TrackUtils.getHitToStripsTable(event);
+ RelationalTable hitToRotated = TrackUtils.getHitToRotatedTable(event);
+ List<Track> tracks = event.get(Track.class, "MatchedTracks");
+ System.out.println("found " + tracks.size() + " tracks");
+ for (Track t : tracks) {
+ List<TrackerHit> hits = t.getTrackerHits();
+ System.out.println("track has " + hits.size() + " hits");
+ if (hits.size() == 6) {
+ for (TrackerHit h : hits) {
+ Set<TrackerHit> stripList = hitToStrips.allFrom(hitToRotated.from(h));
+ for (TrackerHit strip : stripList) {
+ List rawHits = strip.getRawHits();
+ HpsSiSensor sensor = null;
+ for (Object o : rawHits) {
+ RawTrackerHit rth = (RawTrackerHit) o;
+ // TODO figure out why the following collection is always null
+ //List<SimTrackerHit> stipMCHits = rth.getSimTrackerHits();
+ sensor = (HpsSiSensor) rth.getDetectorElement();
+ }
+ int nHitsInCluster = rawHits.size();
+ String sensorName = sensor.getName();
+ Hep3Vector posG = new BasicHep3Vector(strip.getPosition());
+ Hep3Vector posL = sensor.getGeometry().getGlobalToLocal().transformed(posG);
+ double u = posL.x();
+ double mcU = mcSensorHitPositionMap.get(sensorName).get(0);
+
+ aida.cloud1D(sensorName + "_" + nHitsInCluster + "_hitCluster meas - MC u position").fill(u - mcU);
+ // now for the uncertainty in u
+ SymmetricMatrix covG = new SymmetricMatrix(3, strip.getCovMatrix(), true);
+ SymmetricMatrix covL = sensor.getGeometry().getGlobalToLocal().transformed(covG);
+ double sigmaU = sqrt(covL.e(0, 0));
+ aida.cloud1D(sensorName + "_" + nHitsInCluster + "_hitCluster meas - MC u position pull").fill((u - mcU) / sigmaU);
+ aida.cloud1D(sensorName + " number of hits in cluster").fill(nHitsInCluster);
+ System.out.println(" Track Hit: " + nHitsInCluster + " " + sensorName + " u " + u + " mcU " + mcU + " sigmaU " + sigmaU);
+ }
+ }
+ } // end of loop over six-hit tracks
+ } // end of loop over tracks
+ }
+
+ protected void endOfData()
+ {
+ try {
+ aida.saveAs(aidaFileName + "." + aidaFileType);
+ } catch (IOException ex) {
+ Logger.getLogger(DetailedAnalysisDriver.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public void setAidaFileName(String s)
+ {
+ aidaFileName = s;
+ }
+
+ public void setAidaFileType(String s)
+ {
+ aidaFileType = s;
+ }
+
+ private void setupSensors(EventHeader event)
+ {
+ List<RawTrackerHit> rawTrackerHits = null;
+ if (event.hasCollection(RawTrackerHit.class, "SVTRawTrackerHits")) {
+ rawTrackerHits = event.get(RawTrackerHit.class, "SVTRawTrackerHits");
+ }
+ if (event.hasCollection(RawTrackerHit.class, "RawTrackerHitMaker_RawTrackerHits")) {
+ rawTrackerHits = event.get(RawTrackerHit.class, "RawTrackerHitMaker_RawTrackerHits");
+ }
+ EventHeader.LCMetaData meta = event.getMetaData(rawTrackerHits);
+ // Get the ID dictionary and field information.
+ IIdentifierDictionary dict = meta.getIDDecoder().getSubdetector().getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
+ int fieldIdx = dict.getFieldIndex("side");
+ int sideIdx = dict.getFieldIndex("strip");
+ for (RawTrackerHit hit : rawTrackerHits) {
+ // The "side" and "strip" fields needs to be stripped from the ID for sensor lookup.
+ IExpandedIdentifier expId = dict.unpack(hit.getIdentifier());
+ expId.setValue(fieldIdx, 0);
+ expId.setValue(sideIdx, 0);
+ IIdentifier strippedId = dict.pack(expId);
+ // Find the sensor DetectorElement.
+ List<IDetectorElement> des = DetectorElementStore.getInstance().find(strippedId);
+ if (des == null || des.size() == 0) {
+ throw new RuntimeException("Failed to find any DetectorElements with stripped ID <0x" + Long.toHexString(strippedId.getValue()) + ">.");
+ } else if (des.size() == 1) {
+ hit.setDetectorElement((SiSensor) des.get(0));
+ } else {
+ // Use first sensor found, which should work unless there are sensors with duplicate IDs.
+ for (IDetectorElement de : des) {
+ if (de instanceof SiSensor) {
+ hit.setDetectorElement((SiSensor) de);
+ break;
+ }
+ }
+ }
+ // No sensor was found.
+ if (hit.getDetectorElement() == null) {
+ throw new RuntimeException("No sensor was found for hit with stripped ID <0x" + Long.toHexString(strippedId.getValue()) + ">.");
+ }
+ }
+ }
+
+}
|