Author: [log in to unmask]
Date: Mon Jan 9 13:15:27 2017
New Revision: 4659
Log:
[HPSJAVA-708] Fix display of tracks and particles in Wired by installing custom heprep converters in the HPS plugin.
Added:
java/trunk/plugin/src/main/java/org/hps/plugin/HPSParticleConverter.java
java/trunk/plugin/src/main/java/org/hps/plugin/HPSTrackConverter.java
Modified:
java/trunk/plugin/src/main/java/org/hps/plugin/HPSPlugin.java
Added: java/trunk/plugin/src/main/java/org/hps/plugin/HPSParticleConverter.java
=============================================================================
--- java/trunk/plugin/src/main/java/org/hps/plugin/HPSParticleConverter.java (added)
+++ java/trunk/plugin/src/main/java/org/hps/plugin/HPSParticleConverter.java Mon Jan 9 13:15:27 2017
@@ -0,0 +1,199 @@
+package org.hps.plugin;
+
+import hep.graphics.heprep.HepRepFactory;
+import hep.graphics.heprep.HepRepInstance;
+import hep.graphics.heprep.HepRepInstanceTree;
+import hep.graphics.heprep.HepRepType;
+import hep.graphics.heprep.HepRepTypeTree;
+import hep.physics.vec.Hep3Vector;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.Track;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.heprep.HepRepCollectionConverter;
+import org.lcsim.util.heprep.LCSimHepRepConverter;
+import org.lcsim.util.heprep.RandomColorMap;
+import org.lcsim.util.swim.HelixSwimmer;
+import org.lcsim.util.swim.HelixSwimmerYField;
+
+/**
+ * This class converts an LCIO ReconstructedParticle to the HepRep format for
+ * display by Wired4. Clusters and tracks from a RP are given the same randomly
+ * generated color. Charged Tracks, Neutral Tracks, and Calorimeter Clusters are
+ * given their own sub-types, so that they can be easily switched on and off.
+ *
+ * @author jeremym
+ */
+class HPSParticleConverter implements HepRepCollectionConverter
+{
+
+ private static final double[] ORIGIN = {0, 0, 0.00001};
+ RandomColorMap rcolorMap;
+
+ private static final double[] zero = {0, 0, 0};
+
+ public HPSParticleConverter()
+ {
+ rcolorMap = new RandomColorMap(50);
+ }
+
+ public boolean canHandle(Class k)
+ {
+ return ReconstructedParticle.class.isAssignableFrom(k);
+ }
+
+ public void convert(EventHeader event, List collection, HepRepFactory factory, HepRepTypeTree typeTree, HepRepInstanceTree instanceTree)
+ {
+ rcolorMap.reset(collection.size());
+
+ String pfoName = event.getMetaData(collection).getName();
+
+ // RP top-level type.
+ HepRepType rpType = factory.createHepRepType(typeTree, pfoName);
+ rpType.addAttValue("layer", LCSimHepRepConverter.PARTICLES_LAYER);
+
+ // Neutral Tracks type.
+ HepRepType neutralTracksType = factory.createHepRepType(rpType, "NeutralTracks");
+ neutralTracksType.addAttValue("layer", LCSimHepRepConverter.PARTICLES_LAYER);
+ neutralTracksType.addAttValue("drawAs","Line");
+ /*neutralTracksType.addAttValue("LineStyle", "Dashed"); // Doesn't work.
+ neutralTracksType.addAttValue("color",Color.GREEN);*/
+
+ // Charged Tracks type.
+ HepRepType chargedTracksType = factory.createHepRepType(rpType, "ChargedTracks");
+ chargedTracksType.addAttValue("layer", LCSimHepRepConverter.PARTICLES_LAYER);
+ chargedTracksType.addAttValue("drawAs","Line");
+
+ // Clusters type.
+ HepRepType clustersType = factory.createHepRepType(rpType, "CalClusters");
+ clustersType.addAttValue("color",Color.RED);
+ clustersType.addAttValue("fill",true);
+ clustersType.addAttValue("fillColor",Color.RED);
+ clustersType.addAttValue("layer", LCSimHepRepConverter.HITS_LAYER);
+
+ /*
+ clustersType.addAttValue("layer", LCSimHepRepConverter.HITS_LAYER);
+ clustersType.addAttValue("drawAs", "Point");
+ clustersType.addAttValue("MarkName", "Box");
+ clustersType.addAttDef("energy", "Hit Energy", "physics", "");
+ clustersType.addAttDef("cluster", "Cluster Energy", "physics", "");
+ */
+
+ int rpCnt = 0;
+ for (ReconstructedParticle rp : (List<ReconstructedParticle>) collection)
+ {
+ // Get the color for this RP.
+ Color rpColor = rcolorMap.getColor(rpCnt % rcolorMap.size());
+
+ List<Cluster> clusters = rp.getClusters();
+ List<Track> tracks = rp.getTracks();
+
+ convertClusters(event, clusters, factory, typeTree, instanceTree, rpColor, clustersType);
+ convertTracks(event, tracks, factory, typeTree, instanceTree, rpColor, chargedTracksType);
+
+ if (rp.getCharge() == 0)
+ {
+ convertNeutralParticle(event.getDetector(), rp, instanceTree, factory, neutralTracksType, rpColor);
+ }
+
+ ++rpCnt;
+ }
+ }
+
+ private void convertClusters(EventHeader event, List<Cluster> collection, HepRepFactory factory, HepRepTypeTree typeTree, HepRepInstanceTree instanceTree, Color clusterColor, HepRepType type)
+ {
+ List<CalorimeterHit> hits = new ArrayList<CalorimeterHit>();
+
+ HepRepInstance instanceC = factory.createHepRepInstance(instanceTree, type);
+
+ for (Cluster cluster : collection)
+ {
+ if (cluster.getCalorimeterHits().size() != 0) {
+ hits.addAll(cluster.getCalorimeterHits());
+ }
+ }
+
+ if (hits != null)
+ {
+ for (CalorimeterHit hit : hits)
+ {
+ if (hit != null) {
+ double[] pos = hit.getPosition();
+ HepRepInstance instanceX = factory.createHepRepInstance(instanceC, type);
+ instanceX.addAttValue("MarkSize", 5);
+ instanceX.addAttValue("color", clusterColor);
+ instanceX.addAttValue("showparentattributes", true);
+ instanceX.addAttValue("pickparent", true);
+ //HepRepPoint pp =
+ factory.createHepRepPoint(instanceX, pos[0], pos[1], pos[2]);
+ }
+ }
+ }
+ }
+
+ private void convertTracks(EventHeader event, List<Track> collection, HepRepFactory factory, HepRepTypeTree typeTree, HepRepInstanceTree instanceTree, Color trackColor, HepRepType type)
+ {
+ if (collection.size() == 0)
+ return;
+
+ Detector detector = event.getDetector();
+
+ double trackingRMax = detector.getConstants().get("tracking_region_radius").getValue();
+ double trackingZMax = detector.getConstants().get("tracking_region_zmax").getValue();
+
+ double[] field = detector.getFieldMap().getField(ORIGIN);
+ HelixSwimmer helix = new HelixSwimmerYField(field[1]);
+
+ for (Track t : (List<Track>) collection)
+ {
+ helix.setTrack(t);
+ double distanceToCylinder = helix.getDistanceToCylinder(trackingRMax, trackingZMax);
+
+ HepRepInstance instanceX = factory.createHepRepInstance(instanceTree, type);
+ instanceX.addAttValue("color", trackColor);
+
+ double dAlpha = 10; // 1cm
+ for (int k = 0; k < 200; k++)
+ {
+ double d = k * dAlpha;
+ if (d > distanceToCylinder)
+ break;
+ Hep3Vector point = helix.getPointAtDistance(d);
+ factory.createHepRepPoint(instanceX, point.x(), point.y(), point.z());
+ }
+ }
+ }
+
+ // TODO: Connect to cluster center instead of swimming.
+ public void convertNeutralParticle(Detector detector, ReconstructedParticle p, HepRepInstanceTree tree, HepRepFactory factory, HepRepType type, Color rpColor)
+ {
+ HepRepInstance instanceX = factory.createHepRepInstance(tree, type);
+
+ double trackingRMax = detector.getConstants().get("tracking_region_radius").getValue();
+ double trackingZMax = detector.getConstants().get("tracking_region_zmax").getValue();
+
+ double[] field = detector.getFieldMap().getField(zero);
+ HelixSwimmer helix = new HelixSwimmer(field[2]);
+
+ double charge = p.getCharge();
+ Hep3Vector start = p.getReferencePoint();
+ Hep3Vector momentum = p.getMomentum();
+ helix.setTrack(momentum, start, (int) charge);
+ double distanceToCylinder = helix.getDistanceToCylinder(trackingRMax,trackingZMax);
+
+ Hep3Vector stop = helix.getPointAtDistance(distanceToCylinder);
+
+ factory.createHepRepPoint(instanceX,start.x(),start.y(),start.z());
+ factory.createHepRepPoint(instanceX,stop.x(),stop.y(),stop.z());
+ instanceX.addAttValue("color", rpColor);
+ instanceX.addAttValue("momentum",p.getEnergy());
+ instanceX.addAttValue("type",p.getType());
+ }
+}
Modified: java/trunk/plugin/src/main/java/org/hps/plugin/HPSPlugin.java
=============================================================================
--- java/trunk/plugin/src/main/java/org/hps/plugin/HPSPlugin.java (original)
+++ java/trunk/plugin/src/main/java/org/hps/plugin/HPSPlugin.java Mon Jan 9 13:15:27 2017
@@ -1,12 +1,65 @@
package org.hps.plugin;
import org.freehep.application.studio.Plugin;
+import org.freehep.application.studio.Studio;
+import org.freehep.util.FreeHEPLookup;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.Track;
+import org.lcsim.util.heprep.HepRepCollectionConverter;
+import org.lcsim.util.heprep.LCSimHepRepConverter;
/**
- * This is just a dummy plugin class to make JAS3 happy.
+ * JAS3 plugin for HPS.
+ * This install custom converter for the Track and ReconstructedParticle classes.
+ *
* @author Jeremy McCormick
* @version $Id: HPSPlugin.java,v 1.1 2013/06/03 16:23:47 jeremy Exp $
*/
-public class HPSPlugin extends Plugin
-{}
+public class HPSPlugin extends Plugin {
+
+ /**
+ * Install a custom converter for HPS Track and ReconstructedParticle objects
+ * so that they are swum correctly in the B-field.
+ */
+ protected void postInit() {
+
+ Studio app = getApplication();
+ FreeHEPLookup lookup = app.getLookup();
+
+ // Get the HepRep converter registered by lcsim.
+ Class<?> converterClass = null;
+ try {
+ converterClass = Class.forName("org.lcsim.util.heprep.LCSimHepRepConverter");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ LCSimHepRepConverter converter = (LCSimHepRepConverter) lookup.lookup(converterClass);
+ if (converter == null) {
+ throw new RuntimeException("LCSimHepRepConverter was not found.");
+ }
+
+ // Remove the existing track converter from the lcsim plugin.
+ HepRepCollectionConverter trackConverter = converter.findConverter(Track.class);
+ if (trackConverter != null) {
+ converter.deregister(trackConverter);
+ } else {
+ throw new RuntimeException("The TrackConverter was not found.");
+ }
+
+ // Register the HPS track converter in the heprep converter.
+ converter.register(new HPSTrackConverter());
+
+ // Remove the existing particle converter.
+ HepRepCollectionConverter particleConverter = converter.findConverter(ReconstructedParticle.class);
+ if (particleConverter != null) {
+ converter.deregister(particleConverter);
+ } else {
+ throw new RuntimeException("The ReconstructedParticleConverter was not found.");
+ }
+
+ // Register the HPS particle converter.
+ converter.register(new HPSParticleConverter());
+ }
+
+}
Added: java/trunk/plugin/src/main/java/org/hps/plugin/HPSTrackConverter.java
=============================================================================
--- java/trunk/plugin/src/main/java/org/hps/plugin/HPSTrackConverter.java (added)
+++ java/trunk/plugin/src/main/java/org/hps/plugin/HPSTrackConverter.java Mon Jan 9 13:15:27 2017
@@ -0,0 +1,121 @@
+package org.hps.plugin;
+
+import hep.graphics.heprep.HepRepFactory;
+import hep.graphics.heprep.HepRepInstance;
+import hep.graphics.heprep.HepRepInstanceTree;
+import hep.graphics.heprep.HepRepType;
+import hep.graphics.heprep.HepRepTypeTree;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.List;
+
+import org.lcsim.constants.Constants;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.EventHeader.LCMetaData;
+import org.lcsim.event.Track;
+import org.lcsim.event.TrackState;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.heprep.HepRepCollectionConverter;
+import org.lcsim.util.heprep.LCSimHepRepConverter;
+import org.lcsim.util.swim.HelixSwimmer;
+import org.lcsim.util.swim.HelixSwimmerYField;
+
+/**
+ * Convert an HPS track to heprep for Wired display.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class HPSTrackConverter implements HepRepCollectionConverter {
+
+ private static final double[] ORIGIN = {0, 0, 0.00001};
+
+ public boolean canHandle(Class k) {
+ return Track.class.isAssignableFrom(k);
+ }
+
+ public void convert(EventHeader event, List collection, HepRepFactory factory, HepRepTypeTree typeTree, HepRepInstanceTree instanceTree) {
+ try {
+ event.getDetector();
+ } catch (Exception x) {
+ return;
+ }
+
+ if (collection.size() == 0)
+ return;
+
+ List<Track> trackList = (List<Track>) collection;
+ Track firstTrack = trackList.get(0);
+
+ LCMetaData meta = event.getMetaData(collection);
+ String name = meta.getName();
+ Detector detector = event.getDetector();
+
+ double trackingRMax = detector.getConstants().get("tracking_region_radius").getValue();
+ double trackingZMax = detector.getConstants().get("tracking_region_zmax").getValue();
+
+ double[] field = detector.getFieldMap().getField(ORIGIN);
+ HelixSwimmer helix = new HelixSwimmerYField(field[1]);
+
+ HepRepType typeX = factory.createHepRepType(typeTree, name);
+ typeX.addAttValue("layer", LCSimHepRepConverter.PARTICLES_LAYER);
+ typeX.addAttValue("drawAs", "Line");
+
+ typeX.addAttDef("pT", "Transverse momentum", "physics", "");
+ typeX.addAttDef("dedX", "de/Dx", "physics", "GeV");
+ typeX.addAttDef("dedX error", "", "physics", "GeV");
+ typeX.addAttDef("Charge", "", "physics", "");
+ typeX.addAttDef("Chi2", "", "physics", "");
+ typeX.addAttDef("pX", "Momentum X", "physics", "GeV");
+ typeX.addAttDef("pY", "Momentum Y", "physics", "GeV");
+ typeX.addAttDef("pZ", "Momentum Z", "physics", "GeV");
+ typeX.addAttDef("NDF", "Number Degrees Freedom", "physics", "");
+ typeX.addAttDef("Reference Point X", "Reference Point X", "physics", "mm");
+ typeX.addAttDef("Reference Point Y", "Reference Point Y", "physics", "mm");
+ typeX.addAttDef("Reference Point Z", "Reference Point Z", "physics", "mm");
+ typeX.addAttDef("d0", "d0", "physics", "");
+ typeX.addAttDef("phi0", "phi0", "physics", "");
+ typeX.addAttDef("omega", "omega", "physics", "");
+ typeX.addAttDef("z0", "z0", "physics", "");
+ typeX.addAttDef("s", "s", "physics", "");
+
+ for (Track track : trackList) {
+
+ helix.setTrack(track);
+ double distanceToCylinder = helix.getDistanceToCylinder(trackingRMax, trackingZMax);
+
+ TrackState ts = track.getTrackStates().get(0);
+ double[] referencePoint = ts.getReferencePoint();
+ double[] momentum = ts.getMomentum();
+
+ HepRepInstance instanceX = factory.createHepRepInstance(instanceTree, typeX);
+ double pt = field[2] * Constants.fieldConversion / Math.abs(ts.getParameter(2));
+
+ instanceX.addAttValue("pT", pt);
+ instanceX.addAttValue("dedX", track.getdEdx());
+ instanceX.addAttValue("dedX error", track.getdEdxError());
+ instanceX.addAttValue("Charge", track.getCharge());
+ instanceX.addAttValue("Chi2", track.getChi2());
+ instanceX.addAttValue("pX", momentum[0]);
+ instanceX.addAttValue("pY", momentum[1]);
+ instanceX.addAttValue("pZ", momentum[2]);
+ instanceX.addAttValue("NDF", track.getNDF());
+ instanceX.addAttValue("Reference Point X", referencePoint[0]);
+ instanceX.addAttValue("Reference Point Y", referencePoint[1]);
+ instanceX.addAttValue("Reference Point Z", referencePoint[2]);
+ instanceX.addAttValue("d0", ts.getParameter(0));
+ instanceX.addAttValue("phi0", ts.getParameter(1));
+ instanceX.addAttValue("omega", ts.getParameter(2));
+ instanceX.addAttValue("z0", ts.getParameter(3));
+ instanceX.addAttValue("s", ts.getParameter(4));
+
+ double dAlpha = 10; // 1cm
+
+ for (int k = 0; k < 200; k++) {
+ double d = k * dAlpha;
+ if (d > distanceToCylinder)
+ break;
+ Hep3Vector point = helix.getPointAtDistance(d);
+ factory.createHepRepPoint(instanceX, point.x(), point.y(), point.z());
+ }
+ }
+ }
+}
|