hps-java/src/main/java/org/lcsim/hps/evio
diff -u -r1.4 -r1.5
--- EvioConsumer.java 12 Mar 2012 21:30:36 -0000 1.4
+++ EvioConsumer.java 16 Mar 2012 19:10:47 -0000 1.5
@@ -2,12 +2,18 @@
import hep.aida.IAnalysisFactory;
import hep.aida.ICloud1D;
+import hep.aida.IHistogram1D;
import hep.aida.IPlotter;
+import hep.aida.IPlotterStyle;
+import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import org.freehep.record.loop.event.RecordSuppliedEvent;
import org.jlab.coda.et.EtAttachment;
import org.jlab.coda.et.EtConstants;
import org.jlab.coda.et.EtEvent;
@@ -21,8 +27,21 @@
import org.jlab.coda.jevio.CompositeData;
import org.jlab.coda.jevio.EvioEvent;
import org.jlab.coda.jevio.EvioReader;
+import org.lcsim.detector.DetectorElementStore;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.tracker.silicon.SiSensor;
import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.Track;
+import org.lcsim.event.TrackerHit;
+import org.lcsim.event.base.BaseLCSimEvent;
import org.lcsim.event.base.BaseRawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.job.JobControlManager;
+import org.lcsim.util.Driver;
+import org.lcsim.util.DriverAdapter;
import org.lcsim.util.aida.AIDA;
/**
@@ -34,6 +53,14 @@
*/
public class EvioConsumer {
+ private static final String detectorName = "HPS-Test-JLAB-v4pt0";
+ private static final String trackerName = "Tracker";
+ private static final String rawTrackerHitCollectionName = "RawTrackerHitMaker_RawTrackerHits";
+ private static final String readoutName = "TrackerHits";
+ private static final String trackCollectionName = "MatchedTracks";
+ private static final String trackerHitCollectionName = "StripClusterer_SiTrackerHitStrip1D";
+ private static final String lcsimXml = "/org/lcsim/hps/steering/EtTest.lcsim";
+
public EvioConsumer() {
}
@@ -201,124 +228,244 @@
// array of events
EtEvent[] mevs = null;
- // Test plots.
+ // Data plots.
AIDA aida = AIDA.defaultInstance();
- //ICloud1D idsPlot = aida.cloud1D("Cell IDs");
//ICloud1D timePlot = aida.cloud1D("Time");
- ICloud1D adcValuePlot = aida.cloud1D("ADC Value");
- ICloud1D eventRatePlot = aida.cloud1D("Event Rate [Hz]");
- ICloud1D hitCountPlot = aida.cloud1D("Number of RawTrackerHits in Event");
-
+ aida.tree().cd("/");
+ IHistogram1D adcValuePlot = aida.histogram1D("ADC Value", 500, 0, 1000);
+ ICloud1D eventRatePlot = aida.cloud1D("Event Rate [Hz]");
+ IHistogram1D rawHitCountPlot = aida.histogram1D("Number of RawTrackerHits in Event", 100, 0, 100);
+ IHistogram1D tkrHitCountPlot = aida.histogram1D("Number of TrackerHits in Event", 50, 0, 50);
+ IHistogram1D tkrCountPlot = aida.histogram1D("Number of Tracks in Event", 20, 0, 20);
+ ICloud1D hitsPerTrackPlot = aida.cloud1D("Number of Hits per Track");
+ IHistogram1D tkrMomXPlot = aida.histogram1D("Track Px", 200, 0, 2.0);
+ IHistogram1D tkrMomYPlot = aida.histogram1D("Track Py", 160, -0.2, 0.2);
+ IHistogram1D tkrMomZPlot = aida.histogram1D("Track Pz", 160, -0.2, 0.2);
+ IHistogram1D tkrMomPlot = aida.histogram1D("Track P", 200, 0, 10.0);
+
IAnalysisFactory fac = aida.analysisFactory();
- IPlotter plotter = fac.createPlotterFactory().create("Plot");
- plotter.createRegions(2,2);
+ IPlotter plotter = fac.createPlotterFactory().create("HPS SVT Plots");
+ plotter.style().dataStyle().errorBarStyle().setVisible(false);
+ plotter.createRegions(4,4);
plotter.region(0).plot(adcValuePlot);
plotter.region(1).plot(eventRatePlot);
- plotter.region(2).plot(hitCountPlot);
+ plotter.region(2).plot(rawHitCountPlot);
+ plotter.region(3).plot(tkrHitCountPlot);
+ plotter.region(4).plot(tkrCountPlot);
+ plotter.region(5).plot(hitsPerTrackPlot);
+ plotter.region(6).plot(tkrMomXPlot);
+ plotter.region(7).plot(tkrMomYPlot);
+ plotter.region(8).plot(tkrMomZPlot);
+ plotter.region(9).plot(tkrMomPlot);
plotter.show();
-
- // Number of current event from 0.
- int eventCount = 0;
+
+ // Job manager to run LCSim.
+ JobControlManager jobMgr = new JobControlManager();
+ jobMgr.checkInputFiles(false);
+ InputStream is = (new EvioConsumer()).getClass().getResourceAsStream(lcsimXml);
+ jobMgr.setup(is);
+
+ // Get list of Drivers.
+ List<Driver> drivers = jobMgr.getDriverExecList();
+
+ // Wrap Drivers with DriverAdapter.
+ Driver topDriver = new Driver();
+ for (Driver driver : drivers) {
+ topDriver.add(driver);
+ }
+ DriverAdapter driverAdapter = new DriverAdapter(topDriver);
+
+ // Call wrapper to startOfData() on DriverAdapter.
+ driverAdapter.configure(null);
+ // Create a dummy event in order to get Detector conditions.
+ BaseLCSimEvent dummyEvent = new BaseLCSimEvent(0, 0, detectorName);
+ Detector detector = dummyEvent.getDetector();
+
+ // Make a list of sensors in the SVT.
+ List<SiSensor> sensors = detector.getSubdetector("Tracker").getDetectorElement().findDescendants(SiSensor.class);
+
+ // Setup occupancy plots.
+ IPlotter plotter2 = fac.createPlotterFactory().create("HPS SVT Sensor Occupancy Plots");
+ IPlotterStyle style = plotter2.style();
+ style.dataStyle().fillStyle().setColor("yellow");
+ //style.dataStyle().lineStyle().setColor("yellow");
+ style.dataStyle().errorBarStyle().setVisible(false);
+ plotter2.createRegions(5, 4);
+ int ns = sensors.size();
+ for (int i=0; i<ns; i++) {
+ IHistogram1D occupancyPlot = aida.histogram1D(sensors.get(i).getName(), 640, 0, 639);
+ plotter2.region(i).plot(occupancyPlot);
+ }
+ plotter2.show();
+
+ // Data structure for occupancy calculations by sensor.
+ Map<SiSensor,int[]> occupancyMap = new HashMap<SiSensor,int[]>();
+ for (SiSensor sensor : sensors) {
+ occupancyMap.put(sensor, new int[640]);
+ }
+
+ // Setup normalized occupancy plots.
+ IPlotter plotter3 = fac.createPlotterFactory().create("HPS SVT Normalized Sensor Occupancy Plots");
+ IPlotterStyle style3 = plotter3.style();
+ style3.dataStyle().fillStyle().setColor("green");
+ style3.dataStyle().markerStyle().setColor("green");
+ style3.dataStyle().errorBarStyle().setVisible(false);
+ style3.statisticsBoxStyle().setVisible(false);
+ plotter3.createRegions(5, 4);
+ for (int i=0; i<ns; i++) {
+ IHistogram1D occupancyPlot = aida.histogram1D(sensors.get(i).getName() + " Normalized", 640, 0, 639);
+ plotter3.region(i).plot(occupancyPlot);
+ }
+ plotter3.show();
+
+ // Number of current event from 0.
+ int eventCount = 0;
while (true) {
-
+
long startTime = System.nanoTime();
// get events from ET system
- //mevs = sys.getEvents(att, Mode.SLEEP, null, 0, chunk);
+ //mevs = sys.getEvents(att, Mode.SLEEP, null, 0, chunk);
boolean timedOut = false;
try {
mevs = sys.getEvents(att, Mode.TIMED, Modify.NOTHING, 5000000, chunk);
} catch (EtTimeoutException e) {
- System.out.println("timed out!!!");
+ System.out.println("Timed out!!!");
timedOut = true;
- }
+ }
+ // Exit point here.
if (timedOut) {
+ // Driver cleanup.
+ // FIXME This requires that Driver.endOfData() be made public.
+ //for (Driver driver : drivers) {
+ // driver.endOfData();
+ //}
+
+ // Call wrapper to endOfData() on DriverAdapter.
+ driverAdapter.finish(null);
+
// Save AIDA plots.
- aida.saveAs("EtTestPlots.aida");
+ AIDA.defaultInstance().saveAs("EtTestPlots.aida");
// Exit after user pressed enter.
- System.out.println("press ENTER to exit");
+ System.out.println("Press ENTER to exit ...");
System.console().readLine();
System.exit(0);
- }
+ }
- if (debug)
- System.out.println("EvioConsumer read event #" + eventCount);
+ //if (debug)
+ // System.out.println("EvioConsumer read event #" + eventCount);
if (mevs.length > 1) {
- throw new RuntimeException("Did not expect more than 1 event in array!");
+ throw new RuntimeException("Did not expect to get more than one EtEvent!");
}
+ // This is the EtEvent corresponding to a single MC event with tracker data.
EtEvent mev = mevs[0];
- // example of reading & printing event data
- //for (EtEvent mev : mevs) {
-
- // This may be applicable when reading off the actual C-based ET server.
- if (mev.needToSwap()) {
- System.out.println("data needs swapping");
- }
-
- // Get CompositeData using event buffer.
+ // Get EvioEvent and make CompositeData from the EtEvent's data buffer.
ByteBuffer buf = mev.getDataBuffer();
EvioReader reader = new EvioReader(buf);
EvioEvent evioEvent = null;
try {
- evioEvent = reader.parseNextEvent();
+ evioEvent = reader.parseNextEvent();
} catch (java.nio.BufferUnderflowException e) {
- System.out.println("caught underflow");
+ System.out.println("Caught underflow!");
}
- // Something bad happened and event was not built. Skip it.
+ // Something bad happened and event was not built. Just skip it.
if (evioEvent == null) {
- System.out.println("failed to build EVIO event; skipping this EtEvent");
+ System.out.println("Failed to build EVIO event. Skipping this EtEvent!");
continue;
}
-
- // Build composite data.
CompositeData cdata = evioEvent.getCompositeData();
- // Make RawTrackerHits from composite data.
- List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
- List<Object> items = cdata.getItems();
- int n = items.size();
- for (int i=0; i<n; i+=3) {
- Long id = (Long)items.get(i);
- int time = (Integer)items.get(i+1);
- int adcValue = (Integer)items.get(i+2);
- if (debug)
- System.out.println("EvioConsumer --> id=0x"+Long.toHexString(id)+"; time="+time+"; adcValue="+adcValue);
- RawTrackerHit hit = new BaseRawTrackerHit(id, time, new short[] {(short)adcValue});
- hits.add(hit);
- }
- if (debug)
- System.out.println("made " + hits.size() + " RawTrackerHits from EtEvent");
-
- hitCountPlot.fill(hits.size());
+ // Make LCSim RawTrackerHits from CompositeData.
+ List<RawTrackerHit> hits = makeRawTrackerHits(detector, cdata);
+
+ // Create a new LCSimEvent and add the hits.
+ BaseLCSimEvent lcsimEvent = new BaseLCSimEvent(0, eventCount, detectorName);
+ lcsimEvent.put(rawTrackerHitCollectionName, hits, RawTrackerHit.class, 0, readoutName);
+
+ // Make a new event for DriverAdapter.
+ RecordSuppliedEvent loopEvent = new RecordSuppliedEvent(new Object(), lcsimEvent);
+
+ // Call process methods via Driver Adapter.
+ driverAdapter.recordSupplied(loopEvent);
+
+ // Fill RawTrackerHit count.
+ rawHitCountPlot.fill(hits.size());
- // Make some test plots from tracker data.
for (RawTrackerHit hit : hits) {
+
+ // Fill ADC value plot.
adcValuePlot.fill(hit.getADCValues()[0]);
- }
- //}
-
+
+ // Fill basic (non-normalized) occupancy plot.
+ aida.histogram1D(hit.getDetectorElement().getName()).fill(hit.getIdentifierFieldValue("strip"));
+
+ // Increment hit counts for occupancy calculations.
+ int[] strips = occupancyMap.get((SiSensor)hit.getDetectorElement());
+ strips[hit.getIdentifierFieldValue("strip")] += 1;
+ }
+
+ // Normalized occupancy plots.
+ plotter3.clearRegions();
+ int si = 0;
+ for (SiSensor sensor : occupancyMap.keySet()) {
+ int[] strips = occupancyMap.get(sensor);
+ aida.histogram1D(sensor.getName() + " Normalized").reset();
+ for (int i=0; i<strips.length; i++) {
+ double stripOccupancy = (double)strips[i] / (double)(eventCount + 1);
+ if (stripOccupancy != 0) {
+ aida.histogram1D(sensor.getName() + " Normalized").fill(i, stripOccupancy);
+ }
+ }
+ plotter3.region(si).plot(aida.histogram1D(sensor.getName() + " Normalized"));
+ ++si;
+ }
+ plotter3.show();
+
+ // Number of Tracks.
+ List<Track> tracks = lcsimEvent.get(Track.class, trackCollectionName);
+ tkrCountPlot.fill(tracks.size());
+
+ // Track plots.
+ for (Track track : tracks) {
+ hitsPerTrackPlot.fill(track.getTrackerHits().size());
+ tkrMomXPlot.fill(track.getPX());
+ tkrMomYPlot.fill(track.getPY());
+ tkrMomZPlot.fill(track.getPZ());
+ double[] p = track.getMomentum();
+ tkrMomPlot.fill(Math.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]));
+ }
+
+ // Number of TrackerHits.
+ List<TrackerHit> trackerHits = lcsimEvent.get(TrackerHit.class, trackerHitCollectionName);
+ tkrHitCountPlot.fill(trackerHits.size());
+
// put events back into ET system
+ // TODO Is this even necessary when running in read-only mode???
sys.putEvents(att, mevs);
// Compute event processing time.
long endTime = System.nanoTime();
long elapsed = endTime - startTime;
- System.out.println("processed event in " + elapsed + " ns");
+ //System.out.println("processed event in " + elapsed + " ns");
+ // Compute instantaneous event rate e.g. this event only.
double eventRate = 10e9 / elapsed;
- System.out.println("instantaneous event rate = " + eventRate + " hz");
-
+ //System.out.println("instantaneous event rate = " + eventRate + " hz");
+
+ // Fill event rate plot.
eventRatePlot.fill(eventRate);
-
+
+ // Increment event count.
++eventCount;
- System.out.println("----------------------");
+ //if (debug)
+ // System.out.println("----------------------");
}
}
catch (Exception ex) {
@@ -326,4 +473,65 @@
ex.printStackTrace();
}
}
+
+ private static boolean HIT_MAKING_DEBUG = false;
+ private static List<RawTrackerHit> makeRawTrackerHits(Detector detector, CompositeData cdata) {
+
+ // Get some ID info before looping in order to strip out irrelevant fields.
+ // TODO Next three can be removed from here and done only once at start of run.
+ IIdentifierDictionary dict = detector.getSubdetector(trackerName).getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
+ int fieldIdx = dict.getFieldIndex("side");
+ int sideIdx = dict.getFieldIndex("strip");
+
+ // List of hits to be returned.
+ List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
+
+ // Loop over the items in the CompositeData.
+ List<Object> items = cdata.getItems();
+ int n = items.size();
+ for (int i=0; i<n; i+=3) {
+
+ // Get values for hit.
+ Long id = (Long)items.get(i);
+ int time = (Integer)items.get(i+1);
+ int adcValue = (Integer)items.get(i+2);
+
+ // Make the new hit.
+ RawTrackerHit hit = new BaseRawTrackerHit(id, time, new short[] {(short)adcValue});
+
+ if (HIT_MAKING_DEBUG) {
+ System.out.println("id=0x"+Long.toHexString(id)+"; time="+time+"; adcValue="+adcValue);
+ }
+
+ // The "side" and "strip" fields needs to be taken out of the ID or the geometry lookup will fail.
+ IExpandedIdentifier expId = dict.unpack(hit.getIdentifier());
+ expId.setValue(fieldIdx, 0);
+ expId.setValue(sideIdx, 0);
+ IIdentifier strippedId = dict.pack(expId);
+
+ // Find the SiSensor of this hit. This is more complicated than it should be,
+ // because DetectorElements are not guaranteed to have unique IDs.
+ List<IDetectorElement> des = DetectorElementStore.getInstance().find(strippedId);
+ SiSensor sensor = null;
+ if (des == null || des.size() == 0) {
+ throw new RuntimeException("Failed to find DetectorElement for hit with id 0x"+Long.toHexString(strippedId.getValue()));
+ }
+ else if (des.size() == 1) {
+ sensor = (SiSensor)des.get(0);
+ }
+ else {
+ for (IDetectorElement de : des) {
+ if (de instanceof SiSensor) {
+ sensor = (SiSensor)de;
+ break;
+ }
+ }
+ }
+ hit.setDetectorElement(sensor);
+
+ // Add this hit to the list.
+ hits.add(hit);
+ }
+ return hits;
+ }
}
\ No newline at end of file