Commit in java/sandbox/evio on MAIN
pom.xml+42added 356
src/main/java/org/hps/evio/BasicEvioFileReader.java+113added 356
                          /DummyEventBuilder.java+51added 356
                          /ECalEvioReader.java+229added 356
                          /ECalHitWriter.java+404added 356
                          /EventConstants.java+79added 356
                          /EvioFileProducer.java+269added 356
                          /EvioReader.java+30added 356
                          /HitWriter.java+25added 356
                          /LCSimEventBuilder.java+26added 356
                          /LCSimTestRunEventBuilder.java+174added 356
                          /SVTEvioReader.java+160added 356
                          /SVTHitWriter.java+158added 356
                          /TestRunEvioToLcio.java+302added 356
                          /TestRunReconToEvio.java+111added 356
                          /TestRunTriggeredReconToEvio.java+229added 356
                          /TestRunTriggeredReconToLcio.java+218added 356
                          /TriggerData.java+111added 356
                          /TriggerDataWriter.java+59added 356
+2790
19 added files
New HPS evio package (sandbox).

java/sandbox/evio
pom.xml added at 356
--- java/sandbox/evio/pom.xml	                        (rev 0)
+++ java/sandbox/evio/pom.xml	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>hps-evio</artifactId>
+    <name>hps-evio</name>
+    <description>HPS EVIO utilities package</description>
+    
+    <parent>
+        <groupId>org.hps</groupId>
+        <artifactId>hps-parent</artifactId>
+        <relativePath>../parent/pom.xml</relativePath>
+        <version>3.0.2-SNAPSHOT</version>
+    </parent>
+    
+    <scm>
+        <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/evio/</url>
+        <connection>scm:svn:svn://svn.freehep.org/hps/java/trunk/evio/</connection>
+        <developerConnection>scm:svn:svn://svn.freehep.org/hps/java/trunk/evio/</developerConnection>
+    </scm>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-jevio</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-et</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-tracking</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-math3</artifactId>
+            <version>3.2</version>
+        </dependency>
+    </dependencies>
+    
+</project>

java/sandbox/evio/src/main/java/org/hps/evio
BasicEvioFileReader.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,113 @@
+package org.hps.evio;
+
+import java.io.File;
+import org.jlab.coda.jevio.*;
+
+public class BasicEvioFileReader {
+
+    static public void main(String[] args) {
+        if (args.length < 1) {
+            throw new RuntimeException("Missing EVIO file name.");
+        }
+        String evioFileName = args[0];
+        File evioFile = new File(evioFileName);
+        if (!evioFile.exists()) {
+            throw new RuntimeException("File " + evioFileName + " does not exist.");
+        }
+        try {
+            org.jlab.coda.jevio.EvioReader reader = new org.jlab.coda.jevio.EvioReader(evioFile);
+            int eventN = 1;
+            int badEvents = 0;
+            fileLoop:
+            while (true) {
+                System.out.println("Reading event " + eventN);
+                try {
+                    EvioEvent event = reader.nextEvent();
+                    if (event == null) {
+                        break fileLoop;
+                    }
+                    reader.parseEvent(event);
+                    //printBytes(event.getRawBytes()); // DEBUG
+                    System.out.println("Successfully read event " + eventN);// + " which contains " + event.getTotalBytes() + " bytes.");
+                    printBank(event, "");
+                } catch (Exception e) {
+                    System.out.println("Caught Exception processing event " + eventN + " which was...");
+                    e.printStackTrace();
+                    ++badEvents;
+                }
+                ++eventN;
+                System.out.println("-------");
+            }
+            System.out.println("There were " + badEvents + " bad events out of " + eventN + " total.");
+            reader.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void printBank(BaseStructure bank, String indent) throws EvioException {
+        System.out.println(indent + "Bank contains " + bank.getTotalBytes() + " bytes.");
+        System.out.println(indent + "Bank has " + bank.getChildCount() + " sub-banks.");
+        System.out.format(indent + "Bank tag: 0x%x length: %d type: %s num: %d\n", bank.getHeader().getTag(), bank.getHeader().getLength(), bank.getHeader().getDataType(), bank.getHeader().getNumber());
+        if (bank.getChildCount() > 0) {
+            for (BaseStructure child : bank.getChildren()) {
+                printBank(child, indent + "\t");
+            }
+        }
+        if (bank.getHeader().getDataType() == DataType.COMPOSITE) {
+//            for (CompositeData cdata : bank.getCompositeData()) {
+            CompositeData cdatalist[] = bank.getCompositeData();
+            for (CompositeData cdata:cdatalist)
+            switch (bank.getHeader().getTag()) {
+                case 0xe101:
+                    printWindow(cdata, indent + "\t");
+                    break;
+                case 0xe102:
+                    printComposite(cdata, indent + "\t");
+                    break;
+                case 0xe103:
+                    printComposite(cdata, indent + "\t");
+                    break;
+            }
+//            }
+        }
+        if (bank.getHeader().getDataType() == DataType.UINT32) {
+            int[] data = bank.getIntData();
+            if (data.length < 100) {
+                for (int i = 0; i < data.length; i++) {
+                    System.out.format(indent + "0x%x\n", data[i]);
+                }
+            }
+        }
+    }
+
+    private static void printComposite(CompositeData cdata, String indent) {
+        System.out.println(indent + "Raw byte count: " + cdata.getRawBytes().length);
+        System.out.println(cdata.toString(indent));
+    }
+
+    private static void printWindow(CompositeData cdata, String indent) {
+        while (cdata.index() < cdata.getItems().size()) {
+            System.out.println(indent + "Byte count: " + cdata.getRawBytes().length);
+            System.out.println(indent + "Slot: " + cdata.getByte());
+            System.out.println(indent + "Trigger: " + cdata.getInt());
+            System.out.println(indent + "Timestamp: " + cdata.getLong());
+            int nchannels = cdata.getNValue();
+            System.out.println(indent + "NChannels: " + nchannels);
+            for (int j = 0; j < nchannels; j++) {
+                System.out.println(indent + "Channel: " + cdata.getByte());
+                int nSamples = cdata.getNValue();
+                System.out.println(indent + "NSamples: " + nSamples);
+                for (int i = 0; i < nSamples; i++) {
+                    cdata.getShort();
+                }
+            }
+        }
+    }
+
+    /*
+     * private static void printBytes(final byte[] bytes) { for (int i=0;
+     * i<bytes.length; i++) { if (i%4==0) System.out.println();
+     * System.out.println(Byte.toString(bytes[i])); } }
+     */
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
DummyEventBuilder.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/DummyEventBuilder.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/DummyEventBuilder.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,51 @@
+package org.hps.evio;
+
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManagerImplementation;
+import org.lcsim.conditions.ConditionsReader;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.base.BaseLCSimEvent;
+import org.lcsim.util.loop.DummyConditionsConverter;
+import org.lcsim.util.loop.DummyDetector;
+
+/**
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: DummyEventBuilder.java,v 1.3 2012/09/01 00:15:15 meeg Exp $
+ */
+public class DummyEventBuilder implements LCSimEventBuilder {
+
+    String dummyName = "NONE";
+    
+    public DummyEventBuilder() {
+        setDummyDetector();
+    }
+
+    private void setDummyDetector() {
+        ConditionsManager cond = ConditionsManager.defaultInstance();
+        ConditionsReader dummyReader = ConditionsReader.createDummy();
+        ((ConditionsManagerImplementation)cond).setConditionsReader(dummyReader, dummyName);
+        DummyDetector detector = new DummyDetector(dummyName);
+        cond.registerConditionsConverter(new DummyConditionsConverter(detector));
+    }
+    
+    @Override
+    public EventHeader makeLCSimEvent(EvioEvent evioEvent) {
+        return new BaseLCSimEvent(0, evioEvent.getHeader().getNumber(), dummyName);
+    }
+
+    @Override
+    public void setDetectorName(String detectorName) {}
+
+    @Override
+    public void setDebug(boolean debug) {}
+
+	@Override
+	public boolean isPhysicsEvent(EvioEvent evioEvent) {
+		return true;
+	}
+
+    @Override
+    public void readEvioEvent(EvioEvent evioEvent) {
+    }
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
ECalEvioReader.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/ECalEvioReader.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/ECalEvioReader.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,229 @@
+package org.hps.evio;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hps.conditions.deprecated.EcalConditions;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.BaseStructureHeader;
+import org.jlab.coda.jevio.CompositeData;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.detector.identifier.Identifier;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.base.BaseRawCalorimeterHit;
+import org.lcsim.event.base.BaseRawTrackerHit;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: ECalEvioReader.java,v 1.23 2013/04/18 20:59:16 meeg Exp $
+ */
+public class ECalEvioReader extends EvioReader {
+    // Names of subdetectors.
+
+    private int bankTag = EventConstants.ECAL_PULSE_INTEGRAL_BANK_TAG;
+    private Class hitClass = BaseRawCalorimeterHit.class;
+
+    public ECalEvioReader() {
+        hitCollectionName = "EcalReadoutHits";
+    }
+
+    @Override
+    public boolean makeHits(EvioEvent event, EventHeader lcsimEvent) {
+        boolean foundHits = false;
+        List<Object> hits = new ArrayList<Object>();
+        hitClass = Object.class;
+        for (BaseStructure bank : event.getChildren()) {
+            BaseStructureHeader header = bank.getHeader();
+            int crateBankTag = header.getTag();
+            if (crateBankTag == EventConstants.ECAL_TOP_BANK_TAG || crateBankTag == EventConstants.ECAL_BOTTOM_BANK_TAG) {
+                foundHits = true;
+                if (bank.getChildCount() > 0) {
+                    if (debug) {
+                        System.out.println("ECal bank tag: " + header.getTag() + "; childCount: " + bank.getChildCount());
+                    }
+                    try {
+                        for (BaseStructure slotBank : bank.getChildren()) {
+                            if (slotBank.getHeader().getTag() == EventConstants.TRIGGER_BANK_TAG) {
+                                if (debug) {
+                                    int[] data = slotBank.getIntData();
+                                    for (int i = 0; i < data.length; i++) {
+                                        System.out.format("0x%x\n", data[i]);
+                                    }
+                                }
+                                continue;
+                            }
+                            for (CompositeData cdata : slotBank.getCompositeData()) {
+//                            CompositeData cdata = slotBank.getCompositeData();
+                                if (slotBank.getHeader().getTag() != bankTag) {
+                                    bankTag = slotBank.getHeader().getTag();
+                                    System.out.printf("ECal format tag: 0x%x\n", bankTag);
+                                }
+                                switch (slotBank.getHeader().getTag()) {
+                                    case EventConstants.ECAL_WINDOW_BANK_TAG:
+                                        hits.addAll(makeWindowHits(cdata, crateBankTag));
+                                        hitClass = RawTrackerHit.class;
+                                        break;
+                                    case EventConstants.ECAL_PULSE_BANK_TAG:
+                                        hits.addAll(makePulseHits(cdata, crateBankTag));
+                                        hitClass = RawTrackerHit.class;
+                                        break;
+                                    case EventConstants.ECAL_PULSE_INTEGRAL_BANK_TAG:
+                                        hits.addAll(makeIntegralHits(cdata, crateBankTag));
+                                        hitClass = BaseRawCalorimeterHit.class;
+                                        break;
+                                    default:
+                                        throw new RuntimeException("Unsupported ECal format - bank tag " + slotBank.getHeader().getTag());
+                                }
+                            }
+                        }
+                    } catch (EvioException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+        }
+        String readoutName = EcalConditions.getSubdetector().getReadout().getName();
+        lcsimEvent.put(hitCollectionName, hits, hitClass, 0, readoutName);
+//        for (Object hit : hits) {
+//            System.out.println(((RawTrackerHit) hit).getIDDecoder().getIDDescription().toString());
+//        }
+
+        return foundHits;
+    }
+
+    private List<BaseRawTrackerHit> makeWindowHits(CompositeData cdata, int crate) {
+        List<BaseRawTrackerHit> hits = new ArrayList<BaseRawTrackerHit>();
+        if (debug) {
+            int n = cdata.getNValues().size();
+            for (int i = 0; i < n; i++) {
+                System.out.println("cdata.N[" + i + "]=" + cdata.getNValues().get(i));
+            }
+            int ni = cdata.getItems().size();
+            for (int i = 0; i < ni; i++) {
+                System.out.println("cdata.type[" + i + "]=" + cdata.getTypes().get(i));
+            }
+        }
+        while (cdata.index() + 1 < cdata.getItems().size()) {
+            short slot = cdata.getByte();
+            int trigger = cdata.getInt();
+            long timestamp = cdata.getLong();
+            int nchannels = cdata.getNValue();
+            if (debug) {
+                System.out.println("slot#=" + slot + "; trigger=" + trigger + "; timestamp=" + timestamp + "; nchannels=" + nchannels);
+            }
+            for (int j = 0; j < nchannels; j++) {
+                short channel = cdata.getByte();
+                int nSamples = cdata.getNValue();
+                if (debug) {
+                    System.out.println("  channel=" + channel + "; nSamples=" + nSamples);
+                }
+                Long id = EcalConditions.daqToPhysicalID(crate, slot, channel);
+
+                short[] adcValues = new short[nSamples];
+                for (int i = 0; i < nSamples; i++) {
+                    adcValues[i] = cdata.getShort();
+                }
+                if (id == null) {
+                    System.out.printf("Crate %d, slot %d, channel %d not found in map\n", crate, slot, channel);
+                } else {
+                    hits.add(new BaseRawTrackerHit(0, id, adcValues, new ArrayList<SimTrackerHit>(), EcalConditions.getSubdetector().getDetectorElement().findDetectorElement(new Identifier(id)).get(0)));
+                }
+            }
+        }
+        return hits;
+    }
+
+    private List<BaseRawTrackerHit> makePulseHits(CompositeData cdata, int crate) {
+        List<BaseRawTrackerHit> hits = new ArrayList<BaseRawTrackerHit>();
+        if (debug) {
+            int n = cdata.getNValues().size();
+            for (int i = 0; i < n; i++) {
+                System.out.println("cdata.N[" + i + "]=" + cdata.getNValues().get(i));
+            }
+            int ni = cdata.getItems().size();
+            for (int i = 0; i < ni; i++) {
+                System.out.println("cdata.type[" + i + "]=" + cdata.getTypes().get(i));
+            }
+        }
+        while (cdata.index() < cdata.getItems().size()) {
+            short slot = cdata.getByte();
+            int trigger = cdata.getInt();
+            long timestamp = cdata.getLong();
+            int nchannels = cdata.getNValue();
+            if (debug) {
+                System.out.println("slot#=" + slot + "; trigger=" + trigger + "; timestamp=" + timestamp + "; nchannels=" + nchannels);
+            }
+            for (int j = 0; j < nchannels; j++) {
+                short channel = cdata.getByte();
+                int npulses = cdata.getNValue();
+                if (debug) {
+                    System.out.println("  channel=" + channel + "; npulses=" + npulses);
+                }
+                Long id = EcalConditions.daqToPhysicalID(crate, slot, channel);
+                for (int k = 0; k < npulses; k++) {
+                    short pulseNum = cdata.getByte();
+                    int sampleCount = cdata.getNValue();
+                    short[] adcValues = new short[sampleCount];
+                    for (int i = 0; i < sampleCount; i++) {
+                        adcValues[i] = cdata.getShort();
+                    }
+                    if (id == null) {
+                        System.out.printf("Crate %d, slot %d, channel %d not found in map\n", crate, slot, channel);
+                    } else {
+                        hits.add(new BaseRawTrackerHit(pulseNum, id, adcValues, new ArrayList<SimTrackerHit>(), EcalConditions.getSubdetector().getDetectorElement().findDetectorElement(new Identifier(id)).get(0)));
+                    }
+                }
+            }
+        }
+        return hits;
+    }
+
+    private List<BaseRawCalorimeterHit> makeIntegralHits(CompositeData cdata, int crate) {
+        List<BaseRawCalorimeterHit> hits = new ArrayList<BaseRawCalorimeterHit>();
+        if (debug) {
+            int n = cdata.getNValues().size();
+            for (int i = 0; i < n; i++) {
+                System.out.println("cdata.N[" + i + "]=" + cdata.getNValues().get(i));
+            }
+            int ni = cdata.getItems().size();
+            for (int i = 0; i < ni; i++) {
+                System.out.println("cdata.type[" + i + "]=" + cdata.getTypes().get(i));
+            }
+        }
+        while (cdata.index() + 1 < cdata.getItems().size()) { //the +1 is a hack because sometimes an extra byte gets read (padding)
+            short slot = cdata.getByte();
+            int trigger = cdata.getInt();
+            long timestamp = cdata.getLong();
+            int nchannels = cdata.getNValue();
+            if (debug) {
+                System.out.println("slot#=" + slot + "; trigger=" + trigger + "; timestamp=" + timestamp + "; nchannels=" + nchannels);
+            }
+            for (int j = 0; j < nchannels; j++) {
+                short channel = cdata.getByte();
+                int npulses = cdata.getNValue();
+                if (debug) {
+                    System.out.println("  channel=" + channel + "; npulses=" + npulses);
+                }
+                Long id = EcalConditions.daqToPhysicalID(crate, slot, channel);
+
+                for (int k = 0; k < npulses; k++) {
+                    short pulseTime = cdata.getShort();
+                    int pulseIntegral = cdata.getInt();
+                    if (debug) {
+                        System.out.println("    pulseTime=" + pulseTime + "; pulseIntegral=" + pulseIntegral);
+                    }
+                    if (id == null) {
+                        System.out.printf("Crate %d, slot %d, channel %d not found in map\n", crate, slot, channel);
+                    } else {
+                        hits.add(new BaseRawCalorimeterHit(id, pulseIntegral, pulseTime));
+                    }
+                }
+            }
+        }
+        return hits;
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
ECalHitWriter.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/ECalHitWriter.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/ECalHitWriter.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,404 @@
+package org.hps.evio;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.conditions.deprecated.EcalConditions;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.CompositeData;
+import org.jlab.coda.jevio.DataType;
+import org.jlab.coda.jevio.EventBuilder;
+import org.jlab.coda.jevio.EvioBank;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.lcio.LCIOConstants;
+
+import static org.hps.evio.EventConstants.*;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: ECalHitWriter.java,v 1.6 2013/04/18 20:59:16 meeg Exp $
+ */
+public class ECalHitWriter implements HitWriter {
+
+    private String hitCollectionName = "EcalReadoutHits";
+    private int mode = EventConstants.ECAL_PULSE_INTEGRAL_MODE;
+
+    public ECalHitWriter() {
+    }
+
+    public void setHitCollectionName(String hitCollectionName) {
+        this.hitCollectionName = hitCollectionName;
+    }
+
+    public void setMode(int mode) {
+        this.mode = mode;
+        if (mode != EventConstants.ECAL_WINDOW_MODE && mode != EventConstants.ECAL_PULSE_MODE && mode != EventConstants.ECAL_PULSE_INTEGRAL_MODE) {
+            throw new IllegalArgumentException("invalid mode " + mode);
+        }
+    }
+
+    @Override
+    public boolean hasData(EventHeader event) {
+        switch (mode) {
+            case EventConstants.ECAL_WINDOW_MODE:
+                return event.hasCollection(RawTrackerHit.class, hitCollectionName);
+            case EventConstants.ECAL_PULSE_MODE:
+                return event.hasCollection(RawTrackerHit.class, hitCollectionName);
+            case EventConstants.ECAL_PULSE_INTEGRAL_MODE:
+                return event.hasCollection(RawCalorimeterHit.class, hitCollectionName);
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public void writeData(EventHeader event, EventBuilder builder) {
+        List<Object> hits = new ArrayList<Object>();
+        switch (mode) {
+            case EventConstants.ECAL_WINDOW_MODE:
+                hits.addAll(event.get(RawTrackerHit.class, hitCollectionName));
+                writeHits(hits, builder, mode);
+                break;
+            case EventConstants.ECAL_PULSE_MODE:
+                hits.addAll(event.get(RawTrackerHit.class, hitCollectionName));
+                writeHits(hits, builder, mode);
+                break;
+            case EventConstants.ECAL_PULSE_INTEGRAL_MODE:
+                hits.addAll(event.get(RawCalorimeterHit.class, hitCollectionName));
+                writeHits(hits, builder, mode);
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void writeHits(List<Object> rawCalorimeterHits, EventBuilder builder, int mode) {
+        System.out.println("Writing " + rawCalorimeterHits.size() + " ECal hits in integral format");
+
+        // Make two lists containing the hits from top and bottom sections, which go into separate EVIO data banks.
+        List<Object> topHits = new ArrayList<Object>();
+        List<Object> bottomHits = new ArrayList<Object>();
+        for (Object hit : rawCalorimeterHits) {
+            Long daqID = EcalConditions.physicalToDaqID(getCellID(hit));
+            int crate = EcalConditions.getCrate(daqID);
+            if (crate == ECAL_BOTTOM_BANK_TAG) {
+                bottomHits.add(hit);
+            } else {
+                topHits.add(hit);
+            }
+        }
+
+        // Make a new bank for this crate.
+        BaseStructure topBank = null;
+        BaseStructure botBank = null;
+        // Do these banks already exist?
+        for (BaseStructure bank : builder.getEvent().getChildren()) {
+            switch (bank.getHeader().getTag()) {
+                case ECAL_TOP_BANK_TAG:
+                    topBank = bank;
+                    break;
+                case ECAL_BOTTOM_BANK_TAG:
+                    botBank = bank;
+                    break;
+            }
+        }
+        // If they don't exist, make them.
+        if (topBank == null) {
+            topBank = new EvioBank(ECAL_TOP_BANK_TAG, DataType.BANK, ECAL_BANK_NUMBER);
+            try {
+                builder.addChild(builder.getEvent(), topBank);
+            } catch (EvioException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        if (botBank == null) {
+            botBank = new EvioBank(ECAL_BOTTOM_BANK_TAG, DataType.BANK, ECAL_BANK_NUMBER);
+            try {
+                builder.addChild(builder.getEvent(), botBank);
+            } catch (EvioException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        switch (mode) {
+            case EventConstants.ECAL_WINDOW_MODE:
+                // Write the two collections for top and bottom hits to separate EVIO banks.
+                writeWindowHitCollection(topHits, topBank, builder);
+                writeWindowHitCollection(bottomHits, botBank, builder);
+                break;
+            case EventConstants.ECAL_PULSE_MODE:
+                // Write the two collections for top and bottom hits to separate EVIO banks.
+                writePulseHitCollection(topHits, topBank, builder);
+                writePulseHitCollection(bottomHits, botBank, builder);
+                break;
+            case EventConstants.ECAL_PULSE_INTEGRAL_MODE:
+                // Write the two collections for top and bottom hits to separate EVIO banks.
+                writeIntegralHitCollection(topHits, topBank, builder);
+                writeIntegralHitCollection(bottomHits, botBank, builder);
+                break;
+            default:
+                break;
+        }
+    }
+
+    private long getCellID(Object hit) {
+        if (RawCalorimeterHit.class.isInstance(hit)) {
+            return ((RawCalorimeterHit) hit).getCellID();
+        } else if (RawTrackerHit.class.isInstance(hit)) {
+            return ((RawTrackerHit) hit).getCellID();
+        }
+        return 0;
+    }
+
+    private void writeIntegralHitCollection(List<Object> hits, BaseStructure crateBank, EventBuilder builder) {
+        if (hits.isEmpty()) {
+            return;
+        }
+
+        // Get the ID decoder.
+        IDDecoder dec = EcalConditions.getSubdetector().getIDDecoder();
+
+        // Make a hit map; allow for multiple hits in a crystal.
+        Map<Long, List<RawCalorimeterHit>> hitMap = new HashMap<Long, List<RawCalorimeterHit>>();
+        for (Object thing : hits) {
+            RawCalorimeterHit hit = (RawCalorimeterHit) thing;
+            if (hitMap.get(hit.getCellID()) == null) {
+                hitMap.put(hit.getCellID(), new ArrayList<RawCalorimeterHit>());
+            }
+            List<RawCalorimeterHit> channelHits = hitMap.get(hit.getCellID());
+            channelHits.add(hit);
+        }
+
+        // Make map of slot number to hit IDs.
+        Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
+        for (Long id : hitMap.keySet()) {
+            dec.setID(id);
+//			System.out.println(dec.getIDDescription());
+//			System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
+            Long daqID = EcalConditions.physicalToDaqID(id);
+//			System.out.printf("physicalID %d, daqID %d\n", id, daqID);
+            int slot = EcalConditions.getSlot(daqID);
+            if (slotMap.get(slot) == null) {
+                slotMap.put(slot, new ArrayList<Long>());
+            }
+            List<Long> slots = slotMap.get(slot);
+            slots.add(id);
+        }
+
+        // Create composite data for this slot and its channels.
+        CompositeData.Data data = new CompositeData.Data();
+
+        // Loop over the slots in the map.
+        for (int slot : slotMap.keySet()) {
+            data.addUchar((byte) slot); // slot #
+            data.addUint(0); // trigger #
+            data.addUlong(0); // timestamp    		
+            List<Long> hitIDs = slotMap.get(slot);
+            int nhits = hitIDs.size();
+            data.addN(nhits); // number of channels
+            for (Long id : hitIDs) {
+                dec.setID(id);
+                int channel = EcalConditions.getChannel(EcalConditions.physicalToDaqID(id));
+                data.addUchar((byte) channel); // channel #
+                List<RawCalorimeterHit> channelHits = hitMap.get(id);
+                data.addN(channelHits.size()); // number of pulses
+                for (RawCalorimeterHit hit : channelHits) {
+                    data.addUshort((short) hit.getTimeStamp()); // pulse time
+                    data.addUint((int) hit.getAmplitude()); // pulse integral
+                }
+            }
+        }
+        // New bank for this slot.
+        EvioBank cdataBank = new EvioBank(EventConstants.ECAL_PULSE_BANK_TAG, DataType.COMPOSITE, 0);
+        List<CompositeData> cdataList = new ArrayList<CompositeData>();
+
+        // Add CompositeData to bank.
+        try {
+            CompositeData cdata = new CompositeData(ECAL_PULSE_INTEGRAL_FORMAT, 1, data, ECAL_PULSE_INTEGRAL_BANK_TAG, 0);
+            cdataList.add(cdata);
+            cdataBank.appendCompositeData(cdataList.toArray(new CompositeData[cdataList.size()]));
+            builder.addChild(crateBank, cdataBank);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void writePulseHitCollection(List<Object> hits, BaseStructure crateBank, EventBuilder builder) {
+        if (hits.isEmpty()) {
+            return;
+        }
+
+        // Get the ID decoder.
+        IDDecoder dec = EcalConditions.getSubdetector().getIDDecoder();
+
+        // Make a hit map; allow for multiple hits in a crystal.
+        Map<Long, List<RawTrackerHit>> hitMap = new HashMap<Long, List<RawTrackerHit>>();
+        for (Object thing : hits) {
+            RawTrackerHit hit = (RawTrackerHit) thing;
+            if (hitMap.get(hit.getCellID()) == null) {
+                hitMap.put(hit.getCellID(), new ArrayList<RawTrackerHit>());
+            }
+            List<RawTrackerHit> channelHits = hitMap.get(hit.getCellID());
+            channelHits.add(hit);
+        }
+
+        // Make map of slot number to hit IDs.
+        Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
+        for (Long id : hitMap.keySet()) {
+            dec.setID(id);
+//			System.out.println(dec.getIDDescription());
+//			System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
+            Long daqID = EcalConditions.physicalToDaqID(id);
+//			System.out.printf("physicalID %d, daqID %d\n", id, daqID);
+            int slot = EcalConditions.getSlot(daqID);
+            if (slotMap.get(slot) == null) {
+                slotMap.put(slot, new ArrayList<Long>());
+            }
+            List<Long> slots = slotMap.get(slot);
+            slots.add(id);
+        }
+
+        // Create composite data for this slot and its channels.
+        CompositeData.Data data = new CompositeData.Data();
+
+        // Loop over the slots in the map.
+        for (int slot : slotMap.keySet()) {
+            data.addUchar((byte) slot); // slot #
+            data.addUint(0); // trigger #
+            data.addUlong(0); // timestamp    		
+            List<Long> hitIDs = slotMap.get(slot);
+            int nhits = hitIDs.size();
+            data.addN(nhits); // number of channels
+            for (Long id : hitIDs) {
+                dec.setID(id);
+                int channel = EcalConditions.getChannel(EcalConditions.physicalToDaqID(id));
+                data.addUchar((byte) channel); // channel #
+                List<RawTrackerHit> channelHits = hitMap.get(id);
+                data.addN(channelHits.size()); // number of pulses
+                for (RawTrackerHit hit : channelHits) {
+                    data.addUchar((byte) channelHits.indexOf(hit)); // pulse number
+                    data.addN(hit.getADCValues().length); // number of samples
+                    for (short val : hit.getADCValues()) {
+                        data.addUshort(val); // sample
+                    }
+                }
+            }
+        }
+
+        // New bank for this slot.
+        EvioBank cdataBank = new EvioBank(EventConstants.ECAL_PULSE_BANK_TAG, DataType.COMPOSITE, 0);
+        List<CompositeData> cdataList = new ArrayList<CompositeData>();
+
+        // Add CompositeData to bank.
+        try {
+            CompositeData cdata = new CompositeData(EventConstants.ECAL_PULSE_FORMAT, 1, data, EventConstants.ECAL_PULSE_BANK_TAG, 0);
+            cdataList.add(cdata);
+            cdataBank.appendCompositeData(cdataList.toArray(new CompositeData[cdataList.size()]));
+            builder.addChild(crateBank, cdataBank);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void writeWindowHitCollection(List<Object> hits, BaseStructure crateBank, EventBuilder builder) {
+        if (hits.isEmpty()) {
+            return;
+        }
+
+        // Get the ID decoder.
+        IDDecoder dec = EcalConditions.getSubdetector().getIDDecoder();
+
+        // Make a hit map; allow for multiple hits in a crystal.
+        Map<Long, RawTrackerHit> hitMap = new HashMap<Long, RawTrackerHit>();
+        for (Object thing : hits) {
+            RawTrackerHit hit = (RawTrackerHit) thing;
+            hitMap.put(hit.getCellID(), hit);
+        }
+
+        // Make map of slot number to hit IDs.
+        Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
+        for (Long id : hitMap.keySet()) {
+            dec.setID(id);
+//			System.out.println(dec.getIDDescription());
+//			System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
+            Long daqID = EcalConditions.physicalToDaqID(id);
+//			System.out.printf("physicalID %d, daqID %d\n", id, daqID);
+            int slot = EcalConditions.getSlot(daqID);
+            if (slotMap.get(slot) == null) {
+                slotMap.put(slot, new ArrayList<Long>());
+            }
+            List<Long> slots = slotMap.get(slot);
+            slots.add(id);
+        }
+
+        // Create composite data for this slot and its channels.
+        CompositeData.Data data = new CompositeData.Data();
+
+        // Loop over the slots in the map.
+        for (int slot : slotMap.keySet()) {
+
+            // New bank for this slot.
+//            EvioBank slotBank = new EvioBank(EventConstants.ECAL_WINDOW_BANK_TAG, DataType.COMPOSITE, slot);
+
+            data.addUchar((byte) slot); // slot #
+            data.addUint(0); // trigger #
+            data.addUlong(0); // timestamp    		
+            List<Long> hitIDs = slotMap.get(slot);
+            int nhits = hitIDs.size();
+            data.addN(nhits); // number of channels
+            for (Long id : hitIDs) {
+                dec.setID(id);
+                int channel = EcalConditions.getChannel(EcalConditions.physicalToDaqID(id));
+                data.addUchar((byte) channel); // channel #
+                RawTrackerHit hit = hitMap.get(id);
+                data.addN(hit.getADCValues().length); // number of samples
+                for (short val : hit.getADCValues()) {
+                    data.addUshort(val); // sample
+                }
+            }
+        }
+
+        // New bank for this slot.
+        EvioBank cdataBank = new EvioBank(EventConstants.ECAL_WINDOW_BANK_TAG, DataType.COMPOSITE, 0);
+        List<CompositeData> cdataList = new ArrayList<CompositeData>();
+
+        // Add CompositeData to bank.
+        try {
+            CompositeData cdata = new CompositeData(EventConstants.ECAL_WINDOW_FORMAT, 1, data, EventConstants.ECAL_WINDOW_BANK_TAG, 0);
+            cdataList.add(cdata);
+            cdataBank.appendCompositeData(cdataList.toArray(new CompositeData[cdataList.size()]));
+            builder.addChild(crateBank, cdataBank);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void writeData(EventHeader event, EventHeader toEvent) {
+        String readoutName = EcalConditions.getSubdetector().getReadout().getName();
+        switch (mode) {
+            case EventConstants.ECAL_WINDOW_MODE:
+            case EventConstants.ECAL_PULSE_MODE:
+                List<RawTrackerHit> rawTrackerHits = event.get(RawTrackerHit.class, hitCollectionName);
+                System.out.println("Writing " + rawTrackerHits.size() + " ECal hits");
+                toEvent.put(hitCollectionName, rawTrackerHits, RawTrackerHit.class, 0, readoutName);
+                break;
+            case EventConstants.ECAL_PULSE_INTEGRAL_MODE:
+                List<RawCalorimeterHit> rawCalorimeterHits = event.get(RawCalorimeterHit.class, hitCollectionName);
+                System.out.println("Writing " + rawCalorimeterHits.size() + " ECal hits in integral format");
+                int flags = 0;
+                flags += 1 << LCIOConstants.RCHBIT_TIME; //store cell ID
+                toEvent.put(hitCollectionName, rawCalorimeterHits, RawCalorimeterHit.class, flags, readoutName);
+                break;
+            default:
+                break;
+        }
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
EventConstants.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/EventConstants.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/EventConstants.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,79 @@
+package org.hps.evio;
+
+import org.jlab.coda.jevio.EvioEvent;
+
+public final class EventConstants {
+
+    //event type tag
+    public static final int PHYSICS_EVENT_TAG = 1;
+    public static final int SYNC_EVENT_TAG = 16;
+    public static final int PRESTART_EVENT_TAG = 17;
+    public static final int GO_EVENT_TAG = 18;
+    public static final int PAUSE_EVENT_TAG = 19;
+    public static final int END_EVENT_TAG = 20;
+    //event type tag
+    public static final int EVENTID_BANK_TAG = 0xC000;
+    public static final int EVENT_BANK_NUM = 0xCC;
+    // These correspond to ROC (readout crate) IDs from the DAQ.
+    public static final int ECAL_TOP_BANK_TAG = 0x1;
+    public static final int ECAL_BOTTOM_BANK_TAG = 0x2;
+    public static final int SVT_BANK_TAG = 0x3;
+    // These values are put into the number field of the banks.
+    // FIXME Bank numbers should actually be sequentially numbered and not hard-coded.
+    public static final int SVT_BANK_NUMBER = 1;
+    public static final int ECAL_BANK_NUMBER = 1;
+    public static final int TRIGGER_BANK_NUMBER = 1;
+    public static final int ECAL_WINDOW_MODE = 1;
+    public static final int ECAL_PULSE_MODE = 2;
+    public static final int ECAL_PULSE_INTEGRAL_MODE = 3;
+    // The composite data format for window ecal data.
+    public static final String ECAL_WINDOW_FORMAT = "c,i,l,N(c,Ns)";
+    // The composite data format for pulse ecal data.
+    public static final String ECAL_PULSE_FORMAT = "c,i,l,N(c,N(c,Ns))";
+    // The composite data format for pulse integral ecal data.
+    public static final String ECAL_PULSE_INTEGRAL_FORMAT = "c,i,l,N(c,N(s,i))";
+    // The tag for ECal window data.
+    public static final int ECAL_WINDOW_BANK_TAG = 0xe101;
+    // The tag for ECal pulse data.
+    public static final int ECAL_PULSE_BANK_TAG = 0xe102;
+    // The tag for ECal pulse integral data.
+    public static final int ECAL_PULSE_INTEGRAL_BANK_TAG = 0xe103;
+    // The tag for trigger data.
+    public static final int TRIGGER_BANK_TAG = 0xe106;
+    public static final int SVT_TOTAL_NUMBER_FPGAS = 8;
+    public static final int MC_TIME = 2019686400; //Unix time (in seconds) used for Monte Carlo data - 1/1/2034
+
+    public static boolean isSyncEvent(EvioEvent event) {
+        return event.getHeader().getTag() == EventConstants.SYNC_EVENT_TAG;
+    }
+
+    // TODO: Move these methods into an EvioEventUtil class.
+    
+    /**
+     * Check if this event is a Pre Start Event.
+     *
+     * @param event
+     * @return
+     */
+    public static boolean isPreStartEvent(EvioEvent event) {
+        return event.getHeader().getTag() == EventConstants.PRESTART_EVENT_TAG;
+    }
+
+    public static boolean isGoEvent(EvioEvent event) {
+        return event.getHeader().getTag() == EventConstants.GO_EVENT_TAG;
+    }
+
+    public static boolean isPauseEvent(EvioEvent event) {
+        return event.getHeader().getTag() == EventConstants.PAUSE_EVENT_TAG;
+    }
+
+    /**
+     * Check if this event is an End Event.
+     *
+     * @param event
+     * @return True if this event is an End Event; false if not.
+     */
+    public static boolean isEndEvent(EvioEvent event) {
+        return event.getHeader().getTag() == EventConstants.END_EVENT_TAG;
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
EvioFileProducer.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/EvioFileProducer.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/EvioFileProducer.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,269 @@
+package org.hps.evio;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jlab.coda.et.EtAttachment;
+import org.jlab.coda.et.EtConstants;
+import org.jlab.coda.et.EtEvent;
+import org.jlab.coda.et.EtStation;
+import org.jlab.coda.et.EtSystem;
+import org.jlab.coda.et.EtSystemOpenConfig;
+import org.jlab.coda.et.enums.Mode;
+import org.jlab.coda.jevio.EventWriter;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioReader;
+
+/**
+ * 
+ * @author jeremym
+ *
+ */
+// This is copied and modified from Carl Timmer's EvioProducer class in et 12 org.jlab.coda.et.apps package.
+// TODO Add option to set number of events in put array.
+public class EvioFileProducer {
+
+    private List<File> evioFiles = new ArrayList<File>();
+    private EvioReader reader;
+    private ByteBuffer byteBuffer;
+    private String etName, host;
+    private int port = EtConstants.serverPort;
+    private int group = 1;
+    private int size = 10000; // Default event size.
+    private int delay = 0;
+    private static final boolean debug = false;
+
+    EvioFileProducer() {
+    }
+
+    private static void usage() {
+        System.out.println("\nUsage: java Producer -f <et name> -e <evio file> [-p <server port>] [-host <host>]"
+                + " [-d <delay in millisec>] [-g <group #>]\n\n"
+                + "       -f     ET system's name\n"
+                + "       -s     size in bytes for requested events\n"
+                + "       -p     port number for a udp broadcast\n"
+                + "       -g     group number of new events to get\n"
+                + "       -host  host the ET system resides on (defaults to anywhere)\n\n"
+                + "        This consumer works by making a connection to the\n"
+                + "        ET system's tcp server port.\n");
+        System.exit(1);
+    }
+
+    public void copyToEtEvent(EtEvent event) {
+        event.getDataBuffer().put(byteBuffer);
+    }
+
+    public static void main(String[] args) {
+        (new EvioFileProducer()).doMain(args); // call wrapper method
+    }
+
+    public void doMain(String[] args) {
+        try {
+            for (int i = 0; i < args.length; i++) {
+                if (args[i].equalsIgnoreCase("-e")) {
+                    //evioFileName = new String(args[++i]);
+                    evioFiles.add(new File(args[++i]));
+                } else if (args[i].equalsIgnoreCase("-f")) {
+                    etName = args[++i];
+                } else if (args[i].equalsIgnoreCase("-host")) {
+                    host = args[++i];
+                } else if (args[i].equalsIgnoreCase("-p")) {
+                    try {
+                        port = Integer.parseInt(args[++i]);
+                        if ((port < 1024) || (port > 65535)) {
+                            System.out.println("Port number must be between 1024 and 65535.");
+                            usage();
+                            return;
+                        }
+                    } catch (NumberFormatException ex) {
+                        System.out.println("Did not specify a proper port number.");
+                        usage();
+                        return;
+                    }
+                } else if (args[i].equalsIgnoreCase("-s")) {
+                    try {
+                        size = Integer.parseInt(args[++i]);
+                        if (size < 1) {
+                            System.out.println("Size needs to be positive int.");
+                            usage();
+                            return;
+                        }
+                    } catch (NumberFormatException ex) {
+                        System.out.println("Did not specify a proper size.");
+                        usage();
+                        return;
+                    }
+                } else if (args[i].equalsIgnoreCase("-g")) {
+                    try {
+                        group = Integer.parseInt(args[++i]);
+                        if ((group < 1) || (group > 10)) {
+                            System.out.println("Group number must be between 0 and 10.");
+                            usage();
+                            return;
+                        }
+                    } catch (NumberFormatException ex) {
+                        System.out.println("Did not specify a proper group number.");
+                        usage();
+                        return;
+                    }
+                } else if (args[i].equalsIgnoreCase("-d")) {
+                    try {
+                        delay = Integer.parseInt(args[++i]);
+                        if (delay < 1) {
+                            System.out.println("delay must be > 0.");
+                            usage();
+                            return;
+                        }
+                    } catch (NumberFormatException ex) {
+                        System.out.println("Did not specify a proper delay.");
+                        usage();
+                        return;
+                    }
+                } else {
+                    usage();
+                    return;
+                }
+            }
+
+            if (host == null) {
+                //host = EtConstants.hostAnywhere;
+                host = InetAddress.getLocalHost().getHostName();
+            }
+
+            // ET name is required.
+            if (etName == null) {
+                System.out.println("EVIO file name argument is required");
+                usage();
+                return;
+            }
+                        
+            if (this.evioFiles.size() == 0) {
+                System.out.println("At least one input EVIO file is required.");
+                usage();
+                return;
+            }
+
+            // Check existence of EVIO files.
+            System.out.println("EVIO input files ...");
+            for (File evioFile : evioFiles) {         
+                System.out.println(evioFile.getPath());
+                if (!evioFile.exists()) {
+                    System.err.println("EVIO file does not exist: " + evioFile.getPath());
+                    throw new RuntimeException("EVIO input file does not exist.");
+                }
+            }
+
+            // Setup ET system with the command line config.
+            EtSystemOpenConfig config = new EtSystemOpenConfig(etName, host, port);
+            EtSystem sys = new EtSystem(config, EtConstants.debugInfo);
+            sys.open();
+            EtStation gc = sys.stationNameToObject("GRAND_CENTRAL");
+            EtAttachment att = sys.attach(gc);
+
+            // array of events
+            EtEvent[] mevs;
+            
+            // Loop over input EVIO file list.
+            for (File evioFile : evioFiles) {
+                        
+                // Open EVIO reader.
+                System.out.println("Opening next EVIO file: " + evioFile.getPath());
+                reader = new EvioReader(evioFile.getPath());
+
+                // Print number of events.
+                if (debug) {
+                    System.out.println("EVIO file opened with " + reader.getEventCount() + " events.");
+                }
+
+                // Ref to current EVIO event.
+                EvioEvent event;
+
+                // Event sequence number; starts with 1.
+                int eventCount = 0;
+               
+                // Loop until event source is exhausted.
+                while (true) {
+
+                    // Get next event.
+                    event = reader.nextEvent();
+                    ++eventCount;
+                    if (eventCount % 1000 == 0) {
+                        System.out.println("EvioFileProducer - event <" + eventCount + ">");
+                    }
+                    if (event == null) {
+                        break;
+                    }
+                   
+                    // Try to parse the next event.  
+                    try {
+                        reader.parseEvent(event);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        System.out.println("Error making EVIO event with sequence number <" + eventCount + "> in file <" + evioFile.getPath() + ">.");
+                        // Attempt to recover from errors by skipping to next event if there are exceptions.
+                        continue;
+                    }
+
+                    if (debug) {
+                        System.out.println("new events - size=" + size + "; group=" + group);
+                    }
+
+                    // Create a new array of ET events.  This always has one event.
+                    mevs = sys.newEvents(
+                            att, // attachment
+                            Mode.SLEEP, // wait mode
+                            false, // create a buffer
+                            0, // delay 
+                            1, // number of events
+                            size, // size of event but overwritten later
+                            group); // group number; default value is arbitrary
+
+                    // Delay for X millis if applicable.
+                    if (delay > 0) {
+                        Thread.sleep(delay);
+                    }
+
+                    // Write the next EVIO event to the EtEvent's buffer.
+                    ByteBuffer buf = mevs[0].getDataBuffer();
+                    buf.order(ByteOrder.nativeOrder());
+                    EventWriter writer = new EventWriter(buf, 100000, 100, null, null);
+                    writer.writeEvent(event);
+                    try {
+                        writer.close();
+                    } catch (Exception e) {
+                        System.out.println("Caught exception while closing writer.");
+                        e.printStackTrace();
+                    }
+                    mevs[0].setLength(buf.position());
+                    mevs[0].setByteOrder(ByteOrder.nativeOrder());
+                    if (debug) {
+                        for (EtEvent mev : mevs) {
+                            System.out.println("event length = " + mev.getLength() + ", remaining bytes: " + mev.getDataBuffer().remaining());
+                        }
+                    }
+
+                    // Put events onto the ET ring.
+                    sys.putEvents(att, mevs);
+
+                    if (debug) {
+                        System.out.println("Wrote event #" + eventCount + " to ET");
+                        System.out.println("-------------------------------");
+                        ++eventCount;
+                    }
+                }
+
+                reader.close();
+            }
+
+            // Cleanup.
+            sys.close();            
+            
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
EvioReader.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/EvioReader.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/EvioReader.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,30 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.hps.evio;
+
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.event.EventHeader;
+
+/**
+ *
+ * @author meeg
+ */
+public abstract class EvioReader {
+
+	// Debug flag.
+	protected boolean debug = false;
+	protected String hitCollectionName = null;
+
+	//return true if appropriate EVIO bank found
+	abstract boolean makeHits(EvioEvent event, EventHeader lcsimEvent);
+
+	public void setHitCollectionName(String hitCollectionName) {
+		this.hitCollectionName = hitCollectionName;
+	}
+
+	public void setDebug(boolean debug) {
+		this.debug = debug;
+	}
+}

java/sandbox/evio/src/main/java/org/hps/evio
HitWriter.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/HitWriter.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/HitWriter.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,25 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.hps.evio;
+
+import org.jlab.coda.jevio.EventBuilder;
+import org.lcsim.event.EventHeader;
+
+/**
+ * Interface to be implemented by classes that convert LCSim data to recon data formats.
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: HitWriter.java,v 1.1 2012/07/30 23:31:45 meeg Exp $
+ */
+public interface HitWriter {
+
+	//checks whether the event contains data readable by this writer
+	public boolean hasData(EventHeader event);
+
+	//writes data from the event to the EVIO builder
+	public void writeData(EventHeader event, EventBuilder builder);
+
+	//writes data from the event to the EVIO builder
+	public void writeData(EventHeader event, EventHeader toEvent);
+}

java/sandbox/evio/src/main/java/org/hps/evio
LCSimEventBuilder.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/LCSimEventBuilder.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/LCSimEventBuilder.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,26 @@
+package org.hps.evio;
+
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.event.EventHeader;
+
+public interface LCSimEventBuilder {
+
+    /**
+     * Read any run information out of an EVIO event (not necessarily a physics event).
+     * @param evioEvent
+     */
+    void readEvioEvent(EvioEvent evioEvent);
+
+    /**
+     * Make the LCSim event.
+     * @param evioEvent - must be a physics event
+     * @return LCSim event
+     */
+    EventHeader makeLCSimEvent(EvioEvent evioEvent);
+
+    boolean isPhysicsEvent(EvioEvent evioEvent);
+
+    void setDetectorName(String detectorName);
+
+    void setDebug(boolean debug);
+}

java/sandbox/evio/src/main/java/org/hps/evio
LCSimTestRunEventBuilder.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,174 @@
+package org.hps.evio;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.hps.conditions.deprecated.EcalConditions;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.base.BaseLCSimEvent;
+import org.lcsim.geometry.Detector;
+
+/**
+ * Build LCSim events from EVIO data.
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: LCSimTestRunEventBuilder.java,v 1.24 2013/03/01 01:30:25 meeg
+ * Exp $
+ */
+public class LCSimTestRunEventBuilder implements LCSimEventBuilder {
+
+    // Names of subdetectors.
+//    private String trackerName;
+    // Detector conditions object.
+    private Detector detector;
+    // Debug flag.
+    private boolean debug = false;
+    ECalEvioReader ecalReader = null;
+    SVTEvioReader svtReader = null;
+    private int run = 0; //current run number, taken from prestart and end events
+    private long time = 0; //most recent event time (ns), taken from prestart and end events, and trigger banks (if any)
+
+    public LCSimTestRunEventBuilder() {
+        ecalReader = new ECalEvioReader();
+        svtReader = new SVTEvioReader();
+    }
+
+    @Override
+    public void setDetectorName(String detectorName) {
+        // Make a dummy event to setup the conditions system.
+        EventHeader dummyEvent = new BaseLCSimEvent(0, 0, detectorName);
+        detector = dummyEvent.getDetector();
+        EcalConditions.loadDaqMap(detector, "Ecal");
+    }
+
+    @Override
+    public void setDebug(boolean debug) {
+        this.debug = debug;
+        ecalReader.setDebug(debug);
+    }
+
+    public void setEcalHitCollectionName(String ecalHitCollectionName) {
+        ecalReader.setHitCollectionName(ecalHitCollectionName);
+    }
+
+    @Override
+    public void readEvioEvent(EvioEvent evioEvent) {
+        if (EventConstants.isSyncEvent(evioEvent)) {
+            int[] data = evioEvent.getIntData();
+            int seconds = data[0];
+            System.out.println("Sync event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count since last sync " + data[1] + ", event count so far " + data[2] + ", status " + data[3]);
+        } else if (EventConstants.isPreStartEvent(evioEvent)) {
+            int[] data = evioEvent.getIntData();
+            int seconds = data[0];
+            time = ((long) seconds) * 1000000000;
+            run = data[1];
+            System.out.println("Prestart event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", run " + run + ", run type " + data[2]);
+        } else if (EventConstants.isGoEvent(evioEvent)) {
+            int[] data = evioEvent.getIntData();
+            int seconds = data[0];
+            time = ((long) seconds) * 1000000000;
+            System.out.println("Go event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count so far " + data[2]);
+        } else if (EventConstants.isPauseEvent(evioEvent)) {
+            int[] data = evioEvent.getIntData();
+            int seconds = data[0];
+            time = ((long) seconds) * 1000000000;
+            System.out.println("Pause event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count so far " + data[2]);
+        } else if (EventConstants.isEndEvent(evioEvent)) {
+            int[] data = evioEvent.getIntData();
+            int seconds = data[0];
+            time = ((long) seconds) * 1000000000;
+            run = 0;
+            System.out.println("End event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count " + data[2]);
+        }
+    }
+
+    @Override
+    public EventHeader makeLCSimEvent(EvioEvent evioEvent) {
+        if (!isPhysicsEvent(evioEvent)) {
+            throw new RuntimeException("Not a physics event: event tag " + evioEvent.getHeader().getTag());
+        }
+
+        // Create a new LCSimEvent.
+        EventHeader lcsimEvent = getEventData(evioEvent);
+
+        // Make RawCalorimeterHit collection, combining top and bottom section of ECal into one list.
+        try {
+            ecalReader.makeHits(evioEvent, lcsimEvent);
+        } catch (Exception e) {
+            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making ECal hits", e);
+        }
+
+        // Make SVT RawTrackerHits
+        try {
+            svtReader.makeHits(evioEvent, lcsimEvent);
+        } catch (Exception e) {
+            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making SVT hits", e);
+        }
+
+        return lcsimEvent;
+    }
+
+    @Override
+    public boolean isPhysicsEvent(EvioEvent evioEvent) {
+        return (evioEvent.getHeader().getTag() == EventConstants.PHYSICS_EVENT_TAG);
+    }
+
+    private EventHeader getEventData(EvioEvent evioEvent) {
+        int[] eventID = null;
+        //array of length 3: {event number, trigger code, readout status}
+
+        List<TriggerData> triggerList = new ArrayList<TriggerData>();
+
+        if (evioEvent.getChildCount() > 0) {
+            for (BaseStructure bank : evioEvent.getChildren()) {
+                if (bank.getHeader().getTag() == EventConstants.EVENTID_BANK_TAG) {
+                    eventID = bank.getIntData();
+                }
+                if (bank.getHeader().getTag() == EventConstants.ECAL_TOP_BANK_TAG || bank.getHeader().getTag() == EventConstants.ECAL_BOTTOM_BANK_TAG) {
+                    if (bank.getChildCount() > 0) {
+                        for (BaseStructure slotBank : bank.getChildren()) {
+                            if (slotBank.getHeader().getTag() == EventConstants.TRIGGER_BANK_TAG) {
+                                TriggerData triggerData = new TriggerData(slotBank.getIntData());
+                                time = ((long) triggerData.getTime()) * 1000000000;
+                                triggerList.add(triggerData);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (eventID == null) {
+            System.out.println("No event ID bank found");
+            eventID = new int[3];
+        } else {
+            if (debug) {
+                System.out.println("Read EVIO event number " + eventID[0]);
+            }
+            if (eventID[1] != 1) {
+                System.out.println("Trigger code is usually 1; got " + eventID[1]);
+            }
+            if (eventID[2] != 0) {
+                System.out.println("Readout status is usually 0; got " + eventID[2]);
+            }
+        }
+
+        if (triggerList.isEmpty()) {
+            System.out.println("No trigger bank found");
+        } else if (triggerList.size() > 1) {
+            System.out.println("Found multiple trigger banks");
+        }
+
+        // Create a new LCSimEvent.
+        EventHeader lcsimEvent = new BaseLCSimEvent(run, eventID[0], detector.getDetectorName(), time);
+
+        lcsimEvent.put("TriggerBank", triggerList, TriggerData.class, 0);
+        return lcsimEvent;
+    }
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
SVTEvioReader.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/SVTEvioReader.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/SVTEvioReader.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,160 @@
+package org.hps.evio;
+
+//--- java ---//
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hps.conditions.deprecated.HPSSVTConstants;
+import org.hps.conditions.deprecated.SvtUtils;
+import org.hps.recon.tracking.FpgaData;
+import org.hps.recon.tracking.HPSSVTData;
+//--- Coda ---//
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.EvioEvent;
+//--- org.lcsim ---//
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+//--- hps-java ---//
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.base.BaseRawTrackerHit;
+import org.lcsim.hps.util.Pair;
+import org.lcsim.lcio.LCIOUtil;
+//--- Constants ---//
+import static org.hps.evio.EventConstants.SVT_BANK_TAG;
+
+/**
+ *
+ * @author Omar Moreno <[log in to unmask]>
+ * @version $Id: SVTEvioReader.java,v 1.10 2013/07/27 01:52:49 omoreno Exp $
+ */
+public class SVTEvioReader extends EvioReader {
+
+    String fpgaDataCollectionName = "FPGAData";
+    String readoutName = "TrackerHits";
+
+    /**
+     *
+     */
+    public SVTEvioReader() {
+        hitCollectionName = "SVTRawTrackerHits";
+        debug = false;
+    }
+
+    public void setReadoutName(String readoutName) {
+        this.readoutName = readoutName;
+    }
+
+    /**
+     *
+     */
+    @Override
+    public boolean makeHits(EvioEvent event, EventHeader lcsimEvent) {
+        // Create DAQ Maps
+        if (!SvtUtils.getInstance().isSetup()) {
+            SvtUtils.getInstance().setup(lcsimEvent.getDetector());
+        }
+
+        // Create a list to hold the temperatures 
+        List<FpgaData> fpgaDataCollection = new ArrayList<FpgaData>();
+
+        List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
+
+        boolean foundBank = false;
+        for (BaseStructure crateBank : event.getChildren()) {
+            int crateTag = crateBank.getHeader().getTag();
+
+            // Process only events inside the SVT Bank
+            if (crateTag == SVT_BANK_TAG) {
+                foundBank = true;
+                if (crateBank.getChildCount() == 0) {
+                    throw new RuntimeException("No children found in SVT bank!");
+                }
+
+                // Loop over all FPGA banks
+                for (BaseStructure fpgaBank : crateBank.getChildren()) {
+                    int fpgaID = fpgaBank.getHeader().getTag();
+                    if (fpgaID < 0 || fpgaID >= HPSSVTConstants.SVT_TOTAL_FPGAS) {
+                        System.out.println("Unexpected FPGA bank tag " + fpgaID);
+                    }
+
+                    // The data contained in FPGA 7 is currently not used
+                    if (fpgaBank.getHeader().getTag() == 7) {
+                        continue;
+                    }
+
+                    // Get data
+                    int[] data = fpgaBank.getIntData();
+
+                    if (debug) {
+                        System.out.println(this.getClass().getSimpleName() + ": The data size is " + data.length);
+                    }
+
+                    if (debug) {
+                        for (int index = 0; index < data.length; index++) {
+                            System.out.println("Data " + index + ": " + data[index]);
+                        }
+                    }
+
+                    // Get the hybrid temperature data associated with this FPGA
+                    int[] temperatureData = new int[6];
+                    System.arraycopy(data, 1, temperatureData, 0, 6);
+                    FpgaData fpgaData = new FpgaData(fpgaID, temperatureData, data[data.length - 1]);
+                    fpgaDataCollection.add(fpgaData);
+
+
+                    if (debug) {
+                        System.out.println(this.getClass().getSimpleName() + ": The temperatures are: ");
+                        double[] temps = HPSSVTData.getTemperature(temperatureData);
+                        for (int index = 0; index < temps.length; index++) {
+                            System.out.println("Temp " + index + ": " + temps[index]);
+                        }
+                    }
+
+                    // Get all of the samples
+                    int sampleLength = data.length - temperatureData.length - 2; // Tail length
+                    int[] allSamples = new int[sampleLength];
+                    System.arraycopy(data, 7, allSamples, 0, sampleLength);
+
+                    if (debug) {
+                        for (int index = 0; index < allSamples.length; index++) {
+                            System.out.println("Sample " + index + ": " + allSamples[index]);
+                        }
+                    }
+
+                    // Check whether a complete set of samples exist
+                    if (allSamples.length % 4 != 0) {
+                        throw new RuntimeException("Size of samples array is not divisible by 4!");
+                    }
+
+                    // Loop over all samples and create HPSSVTData
+                    for (int index = 0; index < allSamples.length; index += 4) {
+                        int[] samples = new int[4];
+                        System.arraycopy(allSamples, index, samples, 0, samples.length);
+                        hits.add(makeHit(samples));
+                    }
+                }
+            }
+        }
+        if (debug) {
+            System.out.println("Adding RawTrackerHit Collection of Size " + hits.size());
+        }
+
+        lcsimEvent.put(fpgaDataCollectionName, fpgaDataCollection, GenericObject.class, 0);
+        int flag = LCIOUtil.bitSet(0, 31, true); // Turn on 64-bit cell ID.
+        lcsimEvent.put(hitCollectionName, hits, RawTrackerHit.class, flag, readoutName);
+
+        return foundBank;
+    }
+
+    private static RawTrackerHit makeHit(int[] data) {
+        int hitTime = 0;
+        Pair<Integer, Integer> daqPair = new Pair<Integer, Integer>(HPSSVTData.getFPGAAddress(data), HPSSVTData.getHybridNumber(data));
+        SiSensor sensor = SvtUtils.getInstance().getSensor(daqPair);
+
+        int sensorChannel = HPSSVTData.getSensorChannel(data);
+        long cell_id = SvtUtils.makeCellID(sensor, sensorChannel);
+
+        return new BaseRawTrackerHit(hitTime, cell_id, HPSSVTData.getAllSamples(data), null, sensor);
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
SVTHitWriter.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/SVTHitWriter.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/SVTHitWriter.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,158 @@
+package org.hps.evio;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.conditions.deprecated.HPSSVTConstants;
+import org.hps.conditions.deprecated.SvtUtils;
+import org.hps.recon.tracking.FpgaData;
+import org.hps.recon.tracking.HPSSVTData;
+import org.jlab.coda.jevio.DataType;
+import org.jlab.coda.jevio.EventBuilder;
+import org.jlab.coda.jevio.EvioBank;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.lcio.LCIOConstants;
+
+import static org.hps.evio.EventConstants.SVT_BANK_NUMBER;
+import static org.hps.evio.EventConstants.SVT_BANK_TAG;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: SVTHitWriter.java,v 1.5 2013/05/22 18:45:33 jeremy Exp $
+ */
+public class SVTHitWriter implements HitWriter {
+
+    boolean debug = false;
+    private String hitCollectionName = "SVTRawTrackerHits";
+    private String fpgaDataCollectionName = "FPGAData";
+    private String relationCollectionName = "SVTTrueHitRelations";
+    String readoutName = "TrackerHits";
+
+    public SVTHitWriter() {
+    }
+
+    public void setHitCollectionName(String hitCollectionName) {
+        this.hitCollectionName = hitCollectionName;
+    }
+
+    @Override
+    public boolean hasData(EventHeader event) {
+        return event.hasCollection(RawTrackerHit.class, hitCollectionName);
+    }
+
+    //make some dummy FpgaData to use in case there isn't any real FpgaData
+    private static Map<Integer, FpgaData> makeFpgaData() {
+        double[] temps = new double[HPSSVTConstants.TOTAL_HYBRIDS_PER_FPGA * HPSSVTConstants.TOTAL_TEMPS_PER_HYBRID];
+        for (int i = 0; i < HPSSVTConstants.TOTAL_HYBRIDS_PER_FPGA * HPSSVTConstants.TOTAL_TEMPS_PER_HYBRID; i++) {
+            temps[i] = 23.0;
+        }
+        Map<Integer, FpgaData> fpgaData = new HashMap<Integer, FpgaData>();
+        for (Integer fpgaNumber : SvtUtils.getInstance().getFpgaNumbers()) {
+            fpgaData.put(fpgaNumber, new FpgaData(fpgaNumber, temps, 0));
+        }
+
+        return fpgaData;
+    }
+
+    @Override
+    public void writeData(EventHeader event, EventBuilder builder) {
+
+        List<RawTrackerHit> hits = event.get(RawTrackerHit.class, hitCollectionName);
+        Map<Integer, FpgaData> fpgaData = makeFpgaData();
+
+        System.out.println("Writing " + hits.size() + " SVT hits");
+        System.out.println("Writing " + fpgaData.size() + " FPGA data");
+
+        Map<Integer, List<int[]>> fpgaHits = new HashMap<Integer, List<int[]>>();
+
+        for (Integer fpgaNumber : SvtUtils.getInstance().getFpgaNumbers()) {
+            fpgaHits.put(fpgaNumber, new ArrayList<int[]>());
+        }
+
+        for (RawTrackerHit hit : hits) {
+            int fpgaAddress = SvtUtils.getInstance().getFPGA((SiSensor) hit.getDetectorElement());
+            int hybridNumber = SvtUtils.getInstance().getHybrid((SiSensor) hit.getDetectorElement());
+            int sensorChannel = hit.getIdentifierFieldValue("strip");
+            int apvNumber = HPSSVTData.getAPV(sensorChannel);
+            int channelNumber = HPSSVTData.getAPVChannel(sensorChannel);
+
+            int[] data = new int[4];
+            HPSSVTData.createSVTDataPacket(hybridNumber, apvNumber, channelNumber, fpgaAddress, hit.getADCValues(), data);
+            fpgaHits.get(fpgaAddress).add(data);
+        }
+
+        // SVT container bank.
+        EvioBank svtBank = new EvioBank(SVT_BANK_TAG, DataType.BANK, SVT_BANK_NUMBER);
+
+        // Iterate over FPGA's 0 - 6
+//        for (int fpgaNumber = 0; fpgaNumber < SVT_TOTAL_NUMBER_FPGAS; fpgaNumber++) {
+        for (Integer fpgaNumber : SvtUtils.getInstance().getFpgaNumbers()) {
+            FpgaData fpgaDatum = fpgaData.get(fpgaNumber);
+            int[] header = fpgaDatum.extractData();
+
+            // Get the raw int data buffer for this FPGA.
+            int[] dataBuffer = new int[header.length + 4 * fpgaHits.get(fpgaNumber).size() + 2];
+            int ptr = 0;
+
+            dataBuffer[ptr++] = 0;
+
+            System.arraycopy(header, 0, dataBuffer, ptr, header.length);
+            ptr += header.length;
+
+            for (int[] data : fpgaHits.get(fpgaNumber)) {
+                System.arraycopy(data, 0, dataBuffer, ptr, data.length);
+                ptr += data.length;
+            }
+
+            dataBuffer[ptr++] = fpgaDatum.getTail();
+
+            if (ptr != dataBuffer.length) {
+                throw new RuntimeException("tried to fill SVT buffer of length " + dataBuffer.length + " with " + ptr + " ints");
+            }
+
+            if (debug) {
+                System.out.println(this.getClass().getSimpleName() + ": FPGA " + fpgaNumber + " : Data size: " + dataBuffer.length);
+            }
+
+            // Bank for this FPGA's frame data.
+            EvioBank frameBank = new EvioBank(fpgaNumber, DataType.UINT32, fpgaNumber);
+            try {
+                // Add the FPGA bank to the SVT bank
+                builder.addChild(svtBank, frameBank);
+                // Add the SVT data to the FPGA bank
+                frameBank.appendIntData(dataBuffer);
+            } catch (EvioException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        // Add the SVT bank to the Main EVIO bank
+        try {
+            builder.addChild(builder.getEvent(), svtBank);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void writeData(EventHeader event, EventHeader toEvent) {
+        List<RawTrackerHit> rawTrackerHits = event.get(RawTrackerHit.class, hitCollectionName);
+        System.out.println("Writing " + rawTrackerHits.size() + " SVT hits");
+        int flags = 1 << LCIOConstants.TRAWBIT_ID1;
+        toEvent.put(hitCollectionName, rawTrackerHits, RawTrackerHit.class, flags, readoutName);
+
+        List<LCRelation> trueHitRelations = event.get(LCRelation.class, relationCollectionName);
+        toEvent.put(relationCollectionName, trueHitRelations, LCRelation.class, 0);
+
+        List<FpgaData> fpgaData = new ArrayList(makeFpgaData().values());
+        System.out.println("Writing " + fpgaData.size() + " FPGA data");
+
+        toEvent.put(fpgaDataCollectionName, fpgaData, FpgaData.class, 0);
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
TestRunEvioToLcio.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/TestRunEvioToLcio.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/TestRunEvioToLcio.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,302 @@
+package org.hps.evio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioReader;
+import org.lcsim.event.EventHeader;
+import org.lcsim.hps.util.RunControlDialog;
+import org.lcsim.job.JobControlManager;
+import org.lcsim.lcio.LCIOWriter;
+
+/**
+ * This class is for converting Test Run EVIO to LCIO events and performing an
+ * LCSim job in the same session. The processed events are then written to disk
+ * using an LCIOWriter.
+ *
+ * To run this class from command line:
+ *
+ * TestRunEvioToLcio [evioFile] -l [lcioFile] -d [detectorName] -x
+ * [lcsimXmlFile]
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class TestRunEvioToLcio {
+
+    private static final String defaultDetectorName = "";
+    private static final String defaultSteeringFile = "/org/lcsim/hps/steering/monitoring/DummyMonitoring.lcsim";
+
+    /**
+     * Defines command line options for this program.
+     *
+     * @return The command line options.
+     */
+    private static Options createCommandLineOptions() {
+        Options options = new Options();
+
+        options.addOption(new Option("l", true, "The name of the output LCIO file."));
+        options.addOption(new Option("d", true, "The name of the detector to use for LCSim conditions."));
+        options.addOption(new Option("x", true, "The LCSim XML file to process the LCIO events."));
+        options.addOption(new Option("s", true, "Sleep duration between events (in ms)"));
+        options.addOption(new Option("n", true, "Stop after N events"));
+        options.addOption(new Option("w", false, "Wait after end of data"));
+        options.addOption(new Option("c", false, "Show run control window"));
+        options.addOption(new Option("D", true, "Pass a variable to the steering file"));
+        options.addOption(new Option("r", false, "Interpret -x argument as a steering resource instead of a file path"));
+
+        return options;
+    }
+
+    /**
+     * This method will execute the EVIO to LCIO conversion and perform an
+     * intermediate LCSim job. Then the resultant LCIO events will be written to
+     * disk.
+     *
+     * @param args The command line arguments.
+     */
+    public static void main(String[] args) {
+        int maxEvents = 0;
+        int nEvents = 0;
+
+        // Set up command line parsing.
+        Options options = createCommandLineOptions();
+        if (args.length == 0) {
+            System.out.println("TestRunEvioToLcio [options] [evioFiles]");
+            HelpFormatter help = new HelpFormatter();
+            help.printHelp(" ", options);
+            System.exit(1);
+        }
+        CommandLineParser parser = new PosixParser();
+
+        // Parse command line arguments.
+        CommandLine cl = null;
+        try {
+            cl = parser.parse(options, args);
+        } catch (ParseException e) {
+            throw new RuntimeException("Problem parsing command line options.", e);
+        }
+
+        String lcioFileName = null;
+        LCIOWriter writer = null;
+        String detectorName = defaultDetectorName;
+        InputStream steeringStream = null;
+        int sleepTime = -1;
+
+        // Remind people not to use -e any more
+        //if (cl.hasOption("e")) {
+        //    System.out.println("Option -e is deprecated; EVIO file name is now a non-option argument");
+        //}
+
+        // LCIO output file.
+        if (cl.hasOption("l")) {
+            lcioFileName = cl.getOptionValue("l");
+        }
+
+        // Name of detector.
+        if (cl.hasOption("d")) {
+            detectorName = cl.getOptionValue("d");
+        }
+
+        if ("".equals(detectorName)) {
+            throw new RuntimeException("You need to specify a valid detector name as input, use the -d option");
+        }
+
+        // LCSim XML file to execute inline.
+        if (cl.hasOption("x")) {
+            String lcsimXmlName = cl.getOptionValue("x");
+            if (cl.hasOption("r")) {
+                steeringStream = TestRunEvioToLcio.class.getResourceAsStream(lcsimXmlName);
+            } else {
+                try {
+                    steeringStream = new FileInputStream(lcsimXmlName);
+                } catch (FileNotFoundException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        if (steeringStream == null) {
+            steeringStream = TestRunEvioToLcio.class.getResourceAsStream(defaultSteeringFile);
+        }
+
+        // Sleep time.
+        if (cl.hasOption("s")) {
+            sleepTime = Integer.valueOf(cl.getOptionValue("s"));
+        }
+
+        // Sleep time.
+        if (cl.hasOption("n")) {
+            maxEvents = Integer.valueOf(cl.getOptionValue("n"));
+        }
+
+        RunControlDialog runControl = null;
+
+        if (cl.hasOption("c")) {
+            runControl = new RunControlDialog();
+        }
+
+        // LCIO writer.
+        if (lcioFileName != null) {
+            try {
+                writer = new LCIOWriter(new File(lcioFileName));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        // LCSim job manager.
+        JobControlManager jobManager = new JobControlManager();
+
+        if (cl.hasOption("D")) {
+            String[] steeringOptions = cl.getOptionValues("D");
+            for (String def : steeringOptions) {
+                String[] s = def.split("=");
+                if (s.length != 2) {
+                    throw new RuntimeException("Bad variable format: " + def);
+                }
+                String key = s[0];
+                String value = s[1];
+                jobManager.addVariableDefinition(key, value);
+            }
+        }
+
+        jobManager.setup(steeringStream);
+        jobManager.configure();
+
+        // LCSim event builder.
+        LCSimEventBuilder eventBuilder = new LCSimTestRunEventBuilder();
+        eventBuilder.setDetectorName(detectorName);
+
+        for (String evioFileName : cl.getArgs()) {
+            // EVIO input file.
+            File evioFile = new File(evioFileName);
+            System.out.println("Opening file " + evioFileName);
+            // EVIO reader.
+            EvioReader reader = null;
+            try {
+                reader = new EvioReader(evioFile);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            boolean firstEvent = true;
+            long time = 0; //in ms
+
+            // Loop over EVIO events, build LCSim events, process them, and then
+            // write events to disk.
+            fileLoop:
+            while (maxEvents == 0 || nEvents < maxEvents) {
+                EvioEvent evioEvent = null;
+                try {
+                    eventLoop:
+                    while (evioEvent == null) {
+                        evioEvent = reader.nextEvent();
+                        if (evioEvent == null) {
+                            break fileLoop;
+                        }
+                        try {
+                            reader.parseEvent(evioEvent);
+                        } catch (Exception e) {
+                            Logger.getLogger(TestRunEvioToLcio.class.getName()).log(Level.SEVERE, "Error reading EVIO event", e);
+                            continue eventLoop;
+                        }
+                    }
+                    //let event builder check for run information
+                    eventBuilder.readEvioEvent(evioEvent);
+                    // Handlers for different event types.
+                    if (EventConstants.isPreStartEvent(evioEvent)) {
+                        int[] data = evioEvent.getIntData();
+                        int seconds = data[0];
+                        int runNumber = data[1];
+//                        calibListener.prestart(seconds, runNumber);
+                    } else if (EventConstants.isEndEvent(evioEvent)) {
+                        int[] data = evioEvent.getIntData();
+                        int seconds = data[0];
+                        int nevents = data[2];
+//                        calibListener.endRun(seconds, nevents);
+                    } else if (eventBuilder.isPhysicsEvent(evioEvent)) {
+                        EventHeader lcioEvent = eventBuilder.makeLCSimEvent(evioEvent);
+                        if (runControl == null || runControl.process(lcioEvent)) {
+                            time = (lcioEvent.getTimeStamp() / 1000000);
+
+                            if (firstEvent) {
+                                System.out.println("First physics event time: " + time / 1000 + " - " + new Date(time));
+                                firstEvent = false;
+                            }
+//                            if (lcioEvent.hasCollection(BaseRawCalorimeterHit.class, "EcalReadoutHits") && !lcioEvent.get(BaseRawCalorimeterHit.class, "EcalReadoutHits").isEmpty()) {
+//                                continue;
+//                            }
+//                            if (lcioEvent.hasCollection(TriggerData.class, "TriggerBank")) {
+//                                List<TriggerData> triggerList = lcioEvent.get(TriggerData.class, "TriggerBank");
+//                                if (!triggerList.isEmpty()) {
+//                                    TriggerData triggerData = triggerList.get(0);
+//
+//                                    int orTrig = triggerData.getOrTrig();
+//                                    int topTrig = triggerData.getTopTrig();
+//                                    int botTrig = triggerData.getBotTrig();
+//                                    int pairTrig = triggerData.getPairTrig();
+//                                    if (topTrig != 0 && botTrig != 0) {
+//                                        System.out.format("%x\t%x\t%x\t%x\n", orTrig, topTrig, botTrig, pairTrig);
+//                                    } else {
+//                                        continue;
+//                                    }
+//                                }
+//                            }
+                            jobManager.processEvent(lcioEvent);
+                            if (writer != null) {
+                                writer.write(lcioEvent);
+                                writer.flush();
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    // Catch all event processing errors and continue.
+                    Logger.getLogger(TestRunEvioToLcio.class.getName()).log(Level.SEVERE, "Error in event processing", e);
+                    continue;
+                } finally {
+                    if (sleepTime > 0) {
+                        try {
+                            Thread.sleep(sleepTime);
+                        } catch (InterruptedException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+                nEvents++;
+            }
+            System.out.println("Last physics event time: " + time / 1000 + " - " + new Date(time));
+            reader.close();
+        }
+        System.out.println("No more data");
+
+        if (!cl.hasOption("w")) {
+            System.out.println("Exiting");
+            jobManager.finish();
+            System.out.println("jobManager finished");
+        }
+
+        if (writer != null) {
+            System.out.println("close writer");
+            try {
+                writer.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+            System.out.println("closed writer");
+        }
+    }
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
TestRunReconToEvio.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/TestRunReconToEvio.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/TestRunReconToEvio.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,111 @@
+package org.hps.evio;
+
+import java.io.IOException;
+
+import org.jlab.coda.jevio.DataType;
+import org.jlab.coda.jevio.EventBuilder;
+import org.jlab.coda.jevio.EventWriter;
+import org.jlab.coda.jevio.EvioBank;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+
+/**
+ * This class takes raw data generated from MC and converts it to EVIO. The goal
+ * is to make this look like data which will come off the actual ET ring during
+ * the test run.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class TestRunReconToEvio extends Driver {
+
+	EventWriter writer;
+	String rawCalorimeterHitCollectionName = "EcalDigitizedHits";
+	String evioOutputFile = "TestRunData.evio";
+	EventBuilder builder = null;
+	private int eventsWritten = 0;
+	ECalHitWriter ecalWriter = null;
+	SVTHitWriter svtWriter = null;
+
+	public TestRunReconToEvio() {
+	}
+
+	public void setEvioOutputFile(String evioOutputFile) {
+		this.evioOutputFile = evioOutputFile;
+	}
+
+	public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
+		this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
+		if (ecalWriter != null) {
+			ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+		}
+	}
+
+	protected void startOfData() {
+		try {
+			writer = new EventWriter(evioOutputFile);
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		}
+
+		ecalWriter = new ECalHitWriter();
+		ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+
+		svtWriter = new SVTHitWriter();
+	}
+
+	protected void endOfData() {
+		System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " EVIO events in job.");
+		try {
+			writer.close();
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	protected void process(EventHeader event) {
+
+		if (!svtWriter.hasData(event)) {
+			return;
+		}
+
+		// Make a new EVIO event.
+		builder = new EventBuilder(0, DataType.BANK, event.getEventNumber());
+
+		// Write SVTData.
+		svtWriter.writeData(event, builder);
+
+		// Write RawCalorimeterHit collection.
+		ecalWriter.writeData(event, builder);
+//		writeRawCalorimeterHits(event);
+
+		// Write this EVIO event.
+		writeEvioEvent();
+	}
+
+	private void writeEvioEvent() {
+		EvioBank eventIDBank = new EvioBank(EventConstants.EVENTID_BANK_TAG, DataType.UINT32, 0);
+		int[] eventID = new int[3];
+		eventID[0] = eventsWritten;
+		eventID[1] = 0; //trigger type
+		eventID[2] = 0; //status
+
+		try {
+			eventIDBank.appendIntData(eventID);
+			builder.addChild(builder.getEvent(), eventIDBank);
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		}
+		builder.setAllHeaderLengths();
+		try {
+			writer.writeEvent(builder.getEvent());
+			++eventsWritten;
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
TestRunTriggeredReconToEvio.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToEvio.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToEvio.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,229 @@
+package org.hps.evio;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+import org.hps.conditions.deprecated.CalibrationDriver;
+import org.hps.conditions.deprecated.EcalConditions;
+import org.hps.readout.ecal.TriggerDriver;
+import org.jlab.coda.jevio.DataType;
+import org.jlab.coda.jevio.EventBuilder;
+import org.jlab.coda.jevio.EventWriter;
+import org.jlab.coda.jevio.EvioBank;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+
+/**
+ * This class takes raw data generated from MC and converts it to EVIO. The goal
+ * is to make this look like data which will come off the actual ET ring during
+ * the test run.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class TestRunTriggeredReconToEvio extends Driver {
+
+    EventWriter writer;
+    String rawCalorimeterHitCollectionName = "EcalReadoutHits";
+    String evioOutputFile = "TestRunData.evio";
+    Queue<QueuedEtEvent> builderQueue = null;
+    private int eventsWritten = 0;
+    private int eventNum = 0;
+    EcalConditions ecalIDConverter = null;
+    ECalHitWriter ecalWriter = null;
+    SVTHitWriter svtWriter = null;
+    TriggerDataWriter triggerWriter = null;
+    List<HitWriter> writers = null;
+    private int ecalMode = EventConstants.ECAL_PULSE_INTEGRAL_MODE;
+
+    public TestRunTriggeredReconToEvio() {
+    }
+
+    public void setEcalMode(int ecalMode) {
+        this.ecalMode = ecalMode;
+        if (ecalMode != EventConstants.ECAL_WINDOW_MODE && ecalMode != EventConstants.ECAL_PULSE_MODE && ecalMode != EventConstants.ECAL_PULSE_INTEGRAL_MODE) {
+            throw new IllegalArgumentException("invalid mode " + ecalMode);
+        }
+        if (ecalWriter != null) {
+            ecalWriter.setMode(ecalMode);
+        }
+    }
+
+    public void setEvioOutputFile(String evioOutputFile) {
+        this.evioOutputFile = evioOutputFile;
+    }
+
+    public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
+        this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
+        if (ecalWriter != null) {
+            ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+        }
+    }
+
+    @Override
+    protected void startOfData() {
+        try {
+            writer = new EventWriter(evioOutputFile);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+
+        writePrestartEvent();
+
+        writers = new ArrayList<HitWriter>();
+
+        ecalWriter = new ECalHitWriter();
+        ecalWriter.setMode(ecalMode);
+        ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+        writers.add(ecalWriter);
+
+        svtWriter = new SVTHitWriter();
+        writers.add(svtWriter);
+
+        triggerWriter = new TriggerDataWriter();
+        writers.add(triggerWriter);
+
+        builderQueue = new LinkedList<QueuedEtEvent>();
+    }
+
+    @Override
+    protected void endOfData() {
+        System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " EVIO events in job; " + builderQueue.size() + " incomplete events in queue.");
+        try {
+            writer.close();
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void process(EventHeader event) {
+        if (TriggerDriver.triggerBit()) {
+            // Make a new EVIO event.
+            EventBuilder builder = new EventBuilder(EventConstants.PHYSICS_EVENT_TAG, DataType.BANK, EventConstants.EVENT_BANK_NUM);
+            builderQueue.add(new QueuedEtEvent(builder, writers.size(), eventNum));
+            EvioBank eventIDBank = new EvioBank(EventConstants.EVENTID_BANK_TAG, DataType.UINT32, 0);
+            int[] eventID = new int[3];
+            eventID[0] = event.getEventNumber();
+            eventID[1] = 1; //trigger type
+            eventID[2] = 0; //status
+
+            eventNum++;
+            try {
+                eventIDBank.appendIntData(eventID);
+                builder.addChild(builder.getEvent(), eventIDBank);
+            } catch (EvioException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        for (int i = 0; i < writers.size(); i++) {
+            HitWriter evioWriter = writers.get(i);
+            if (evioWriter.hasData(event)) {
+                System.out.println(evioWriter.getClass().getSimpleName() + ": writing data, event " + event.getEventNumber());
+                EventBuilder builder = null;
+
+                for (QueuedEtEvent queuedEvent : builderQueue) {
+                    if (!queuedEvent.getRead(i)) {
+                        builder = queuedEvent.getBuilder();
+                        queuedEvent.setRead(i);
+                        break;
+                    }
+                }
+                if (builder == null) {
+                    throw new RuntimeException("no queued ET events waiting for an " + evioWriter.getClass().getSimpleName() + " bank");
+                }
+                // Write data.
+                evioWriter.writeData(event, builder);
+            }
+        }
+
+        while (!builderQueue.isEmpty() && builderQueue.peek().banksFilled()) {
+            System.out.println("writing filled ET event, event " + event.getEventNumber());
+            QueuedEtEvent queuedEvent = builderQueue.poll();
+            // Write this EVIO event.
+            writeEvioEvent(queuedEvent);
+        }
+    }
+
+    private void writeEvioEvent(QueuedEtEvent event) {
+        System.out.printf("Writing event %d with %d bytes\n", event.getEventNum(), event.getBuilder().getEvent().getTotalBytes());
+        try {
+            writer.writeEvent(event.getBuilder().getEvent());
+            ++eventsWritten;
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void writePrestartEvent() {
+        // Make a new EVIO event.
+        EventBuilder builder = new EventBuilder(EventConstants.PRESTART_EVENT_TAG, DataType.UINT32, EventConstants.EVENT_BANK_NUM);
+        int[] prestartData = new int[3];
+        prestartData[0] = EventConstants.MC_TIME; //Unix time in seconds - this value for MC data
+        prestartData[1] = CalibrationDriver.runNumber(); //run number
+        prestartData[2] = 0; //run type
+
+        try {
+            builder.appendIntData(builder.getEvent(), prestartData);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+        builder.setAllHeaderLengths();
+        try {
+            writer.writeEvent(builder.getEvent());
+            ++eventsWritten;
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private class QueuedEtEvent {
+
+        private EventBuilder builder;
+        public boolean readSVT = false;
+        public boolean readECal = false;
+        private boolean[] readData = null;
+        private int eventNum;
+
+        public QueuedEtEvent(EventBuilder builder, int numData, int eventNum) {
+            this.builder = builder;
+            readData = new boolean[numData];
+            this.eventNum = eventNum;
+        }
+
+        public int getEventNum() {
+            return eventNum;
+        }
+
+        public void setRead(int i) {
+            readData[i] = true;
+        }
+
+        public boolean getRead(int i) {
+            return readData[i];
+        }
+
+        public EventBuilder getBuilder() {
+            return builder;
+        }
+
+        public boolean banksFilled() {
+            for (boolean x : readData) {
+                if (!x) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
TestRunTriggeredReconToLcio.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToLcio.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToLcio.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,218 @@
+package org.hps.evio;
+
+import hep.physics.event.generator.MCEvent;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+import org.hps.conditions.deprecated.CalibrationDriver;
+import org.hps.conditions.deprecated.QuietBaseLCSimEvent;
+import org.hps.readout.ecal.ClockSingleton;
+import org.hps.readout.ecal.ReadoutTimestamp;
+import org.hps.readout.ecal.TriggerDriver;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.SimCalorimeterHit;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.lcio.LCIOWriter;
+import org.lcsim.util.Driver;
+
+/**
+ * This class takes raw data generated from MC and converts it to EVIO. The goal
+ * is to make this look like data which will come off the actual ET ring during
+ * the test run.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class TestRunTriggeredReconToLcio extends Driver {
+
+    String rawCalorimeterHitCollectionName = "EcalReadoutHits";
+    String outputFile = "TestRunData.slcio";
+    private int eventsWritten = 0;
+    private int eventNum = 0;
+    //interval for trigger candidates (tridents, A'), if used
+    private int triggerSpacing = 250;
+    private boolean rejectBackground = false;
+//    HPSEcalConditions ecalIDConverter = null;
+    ECalHitWriter ecalWriter = null;
+    SVTHitWriter svtWriter = null;
+    TriggerDataWriter triggerWriter = null;
+    List<HitWriter> writers = null;
+    LCIOWriter lcioWriter = null;
+    Queue<EventHeader> events = null;
+    private int ecalMode = EventConstants.ECAL_PULSE_INTEGRAL_MODE;
+    List<MCParticle> mcParticles = null;
+    List<SimTrackerHit> trackerHits = null;
+    List<SimCalorimeterHit> ecalHits = null;
+    //MC collections from the last 500n'th event (trident or preselected trigger event)
+    List<MCParticle> triggerMCParticles = null;
+    List<SimTrackerHit> triggerTrackerHits = null;
+    List<SimCalorimeterHit> triggerECalHits = null;
+    static final String ecalCollectionName = "EcalHits";
+    static final String trackerCollectionName = "TrackerHits";
+    private String relationCollectionName = "SVTTrueHitRelations";
+
+    public TestRunTriggeredReconToLcio() {
+    }
+
+    public void setEcalMode(int ecalMode) {
+        this.ecalMode = ecalMode;
+        if (ecalMode != EventConstants.ECAL_WINDOW_MODE && ecalMode != EventConstants.ECAL_PULSE_MODE && ecalMode != EventConstants.ECAL_PULSE_INTEGRAL_MODE) {
+            throw new IllegalArgumentException("invalid mode " + ecalMode);
+        }
+        if (ecalWriter != null) {
+            ecalWriter.setMode(ecalMode);
+        }
+    }
+
+    public void setOutputFile(String outputFile) {
+        this.outputFile = outputFile;
+    }
+
+    public void setTriggerSpacing(int triggerSpacing) {
+        this.triggerSpacing = triggerSpacing;
+    }
+
+    public void setRejectBackground(boolean rejectBackground) {
+        this.rejectBackground = rejectBackground;
+    }
+
+    public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
+        this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
+        if (ecalWriter != null) {
+            ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+        }
+    }
+
+    @Override
+    protected void startOfData() {
+        writers = new ArrayList<HitWriter>();
+
+        ecalWriter = new ECalHitWriter();
+        ecalWriter.setMode(ecalMode);
+        ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+        writers.add(ecalWriter);
+
+        svtWriter = new SVTHitWriter();
+        writers.add(svtWriter);
+
+        triggerWriter = new TriggerDataWriter();
+        writers.add(triggerWriter);
+
+        try {
+            lcioWriter = new LCIOWriter(new File(outputFile));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        events = new LinkedList<EventHeader>();
+    }
+
+    @Override
+    protected void endOfData() {
+        System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " events in job; " + events.size() + " incomplete events in queue.");
+        try {
+            lcioWriter.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void process(EventHeader event) {
+        if (event.hasCollection(SimCalorimeterHit.class, ecalCollectionName) && !event.getSimCalorimeterHits(ecalCollectionName).isEmpty()) {
+            mcParticles = event.getMCParticles();
+            ecalHits = event.getSimCalorimeterHits(ecalCollectionName);
+            trackerHits = event.getSimTrackerHits(trackerCollectionName);
+        }
+        if (ClockSingleton.getClock() % triggerSpacing == 0) {
+            if (event.hasCollection(MCParticle.class)) {
+                triggerMCParticles = event.getMCParticles();
+                triggerECalHits = event.getSimCalorimeterHits(ecalCollectionName);
+                triggerTrackerHits = event.getSimTrackerHits(trackerCollectionName);
+            } else {
+                triggerMCParticles = null;
+                triggerECalHits = null;
+                triggerTrackerHits = null;
+            }
+        }
+
+
+        if (TriggerDriver.triggerBit()) {
+            EventHeader lcsimEvent = new QuietBaseLCSimEvent(CalibrationDriver.runNumber(), event.getEventNumber(), event.getDetectorName());
+            events.add(lcsimEvent);
+            System.out.println("Creating LCIO event " + eventNum);
+            if (triggerMCParticles == null || triggerMCParticles.isEmpty()) {
+                lcsimEvent.put(MCEvent.MC_PARTICLES, mcParticles);
+                lcsimEvent.put(ecalCollectionName, ecalHits, SimCalorimeterHit.class, 0xe0000000);
+                lcsimEvent.put(trackerCollectionName, trackerHits, SimTrackerHit.class, 0xc0000000);
+                System.out.println("Adding " + mcParticles.size() + " MCParticles, " + ecalHits.size() + " SimCalorimeterHits, " + trackerHits.size() + " SimTrackerHits");
+            } else {
+                lcsimEvent.put(MCEvent.MC_PARTICLES, triggerMCParticles);
+                lcsimEvent.put(ecalCollectionName, triggerECalHits, SimCalorimeterHit.class, 0xe0000000);
+                lcsimEvent.put(trackerCollectionName, triggerTrackerHits, SimTrackerHit.class, 0xc0000000);
+                System.out.println("Adding " + triggerMCParticles.size() + " MCParticles, " + triggerECalHits.size() + " SimCalorimeterHits, " + triggerTrackerHits.size() + " SimTrackerHits");
+            }
+            lcsimEvent.put(ReadoutTimestamp.collectionName, event.get(ReadoutTimestamp.class, ReadoutTimestamp.collectionName));
+            ++eventNum;
+        }
+
+        writerLoop:
+        for (HitWriter hitWriter : writers) {
+            if (hitWriter.hasData(event)) {
+                System.out.println(hitWriter.getClass().getSimpleName() + ": writing data, event " + event.getEventNumber());
+
+                for (EventHeader queuedEvent : events) {
+                    if (!hitWriter.hasData(queuedEvent)) {
+                        // Write data.
+                        hitWriter.writeData(event, queuedEvent);
+                        continue writerLoop;
+                    }
+                }
+
+                throw new RuntimeException("no queued events waiting for an " + hitWriter.getClass().getSimpleName() + " bank");
+            }
+        }
+
+        eventLoop:
+        while (!events.isEmpty()) {
+            EventHeader queuedEvent = events.peek();
+            for (HitWriter hitWriter : writers) {
+                if (!hitWriter.hasData(queuedEvent)) {
+                    break eventLoop;
+                }
+            }
+            events.poll();
+
+            boolean writeThisEvent = true;
+            if (rejectBackground && queuedEvent.hasCollection(LCRelation.class, relationCollectionName)) {
+                writeThisEvent = false;
+                List<LCRelation> trueHitRelations = queuedEvent.get(LCRelation.class, relationCollectionName);
+                List<SimTrackerHit> trueHits = queuedEvent.getSimTrackerHits(trackerCollectionName);
+                for (LCRelation relation : trueHitRelations) {
+                    if (trueHits.contains((SimTrackerHit) relation.getTo())) {
+                        writeThisEvent = true;
+                        break;
+                    }
+                }
+            }
+
+            if (writeThisEvent) {
+                // Write this event.
+                System.out.println("writing filled LCIO event, event " + queuedEvent.getEventNumber());
+                try {
+                    lcioWriter.write(queuedEvent);
+                    ++eventsWritten;
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            } else {
+                System.out.println("rejecting filled LCIO event, event " + queuedEvent.getEventNumber() + " contains no SVT hits from truth particles");
+            }
+        }
+    }
+}
\ No newline at end of file

java/sandbox/evio/src/main/java/org/hps/evio
TriggerData.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/TriggerData.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/TriggerData.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,111 @@
+package org.hps.evio;
+
+import org.lcsim.event.GenericObject;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: TriggerData.java,v 1.3 2012/08/03 23:14:39 meeg Exp $
+ */
+public class TriggerData implements GenericObject {
+
+    public static final int OR_TRIG = 3;
+    public static final int TOP_TRIG = 4;
+    public static final int BOT_TRIG = 5;
+    public static final int AND_TRIG = 6;
+    public static final int TIME = 7;
+    public static final int TRIG_BANK_SIZE = 8;
+    public static final String TRIG_COLLECTION = "TriggerBank";
+    private int[] bank;
+
+    public TriggerData(int[] bank) {
+        this.bank = bank;
+    }
+
+    public int getTime() {
+        return getIntVal(TIME);
+    }
+
+    public int getOrTrig() {
+        return getIntVal(OR_TRIG);
+    }
+
+    public int getTopTrig() {
+        return getIntVal(TOP_TRIG);
+    }
+
+    public int getBotTrig() {
+        return getIntVal(BOT_TRIG);
+    }
+
+    public int getAndTrig() {
+        return getIntVal(AND_TRIG);
+    }
+
+    public int[] getBank() {
+        return bank;
+    }
+
+    public static int getTime(GenericObject object) {
+        return object.getIntVal(TIME);
+    }
+
+    public static int getOrTrig(GenericObject object) {
+        return object.getIntVal(OR_TRIG);
+    }
+
+    public static int getTopTrig(GenericObject object) {
+        return object.getIntVal(TOP_TRIG);
+    }
+
+    public static int getBotTrig(GenericObject object) {
+        return object.getIntVal(BOT_TRIG);
+    }
+
+    public static int getAndTrig(GenericObject object) {
+        return object.getIntVal(AND_TRIG);
+    }
+
+    public static int[] getBank(GenericObject object) {
+        int[] bank = new int[8];
+        for (int i = 0; i < 8; i++) {
+            bank[i] = object.getIntVal(i);
+        }
+        return bank;
+    }
+
+    @Override
+    public int getNInt() {
+        return TRIG_BANK_SIZE;
+    }
+
+    @Override
+    public int getNFloat() {
+        return 0;
+    }
+
+    @Override
+    public int getNDouble() {
+        return 0;
+    }
+
+    @Override
+    public int getIntVal(int index) {
+        return bank[index];
+    }
+
+    @Override
+    public float getFloatVal(int index) {
+        throw new UnsupportedOperationException("No float values in " + this.getClass().getSimpleName());
+    }
+
+    @Override
+    public double getDoubleVal(int index) {
+        throw new UnsupportedOperationException("No double values in " + this.getClass().getSimpleName());
+    }
+
+    @Override
+    public boolean isFixedSize() {
+        return true;
+    }
+}

java/sandbox/evio/src/main/java/org/hps/evio
TriggerDataWriter.java added at 356
--- java/sandbox/evio/src/main/java/org/hps/evio/TriggerDataWriter.java	                        (rev 0)
+++ java/sandbox/evio/src/main/java/org/hps/evio/TriggerDataWriter.java	2014-03-26 01:28:51 UTC (rev 356)
@@ -0,0 +1,59 @@
+package org.hps.evio;
+
+import java.util.List;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.DataType;
+import org.jlab.coda.jevio.EventBuilder;
+import org.jlab.coda.jevio.EvioBank;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.event.EventHeader;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: TriggerDataWriter.java,v 1.1 2012/08/03 23:14:39 meeg Exp $
+ */
+public class TriggerDataWriter implements HitWriter {
+
+    @Override
+    public boolean hasData(EventHeader event) {
+        return event.hasCollection(TriggerData.class, TriggerData.TRIG_COLLECTION);
+    }
+
+    @Override
+    public void writeData(EventHeader event, EventBuilder builder) {
+        // Make a new bank for this crate.
+        BaseStructure topBank = null;
+        // Does this bank already exist?
+        for (BaseStructure bank : builder.getEvent().getChildren()) {
+            if (bank.getHeader().getTag() == EventConstants.ECAL_TOP_BANK_TAG) {
+                topBank = bank;
+                break;
+            }
+        }
+        // If they don't exist, make them.
+        if (topBank == null) {
+            topBank = new EvioBank(EventConstants.ECAL_TOP_BANK_TAG, DataType.BANK, EventConstants.ECAL_BANK_NUMBER);
+            try {
+                builder.addChild(builder.getEvent(), topBank);
+            } catch (EvioException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+
+        List<TriggerData> triggerList = event.get(TriggerData.class, TriggerData.TRIG_COLLECTION);
+        EvioBank triggerBank = new EvioBank(EventConstants.TRIGGER_BANK_TAG, DataType.UINT32, EventConstants.TRIGGER_BANK_NUMBER);
+        try {
+            triggerBank.appendIntData(triggerList.get(0).getBank());
+            builder.addChild(topBank, triggerBank);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void writeData(EventHeader event, EventHeader toEvent) {
+        toEvent.put(TriggerData.TRIG_COLLECTION, event.get(TriggerData.class, TriggerData.TRIG_COLLECTION));
+    }
+}
SVNspam 0.1