Print

Print


Author: [log in to unmask]
Date: Tue Aug  4 15:09:59 2015
New Revision: 3331

Log:
Add processor to export EPICS data from EVIO data banks.  HPSJAVA-568

Added:
    java/trunk/record-util/src/main/java/org/hps/record/epics/EpicsCsvExporter.java

Added: java/trunk/record-util/src/main/java/org/hps/record/epics/EpicsCsvExporter.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/epics/EpicsCsvExporter.java	(added)
+++ java/trunk/record-util/src/main/java/org/hps/record/epics/EpicsCsvExporter.java	Tue Aug  4 15:09:59 2015
@@ -0,0 +1,144 @@
+package org.hps.record.epics;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.util.log.DefaultLogFormatter;
+import org.lcsim.util.log.LogUtil;
+
+/**
+ * Export EPICS data banks from EVIO to a CSV file.
+ * <p>
+ * The EPICS header information is appended to each row (run, sequence, timestamp).
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public class EpicsCsvExporter extends EpicsEvioProcessor {
+
+    private static final Logger LOGGER = LogUtil.create(EpicsCsvExporter.class, new DefaultLogFormatter(), Level.ALL);
+
+    private final File csvOutputFile;
+
+    private final Set<EpicsData> epicsDataSet = new LinkedHashSet<EpicsData>();
+
+    public EpicsCsvExporter() {
+        this(new File("epics.csv"), true);
+    }
+
+    public EpicsCsvExporter(final File csvOutputFile, final boolean append) {
+        if (csvOutputFile == null) {
+            throw new IllegalArgumentException("csvOutputFile is null.");
+        }
+        if (csvOutputFile.exists() && !append) {
+            throw new IllegalArgumentException("The file " + csvOutputFile.getPath()
+                    + " already exists and append = false.");
+        }
+        this.csvOutputFile = csvOutputFile;
+    }
+
+    @Override
+    public void endJob() {
+        try {
+            LOGGER.info("writing EPICS data to " + csvOutputFile.getPath() + " ...");
+            this.write(csvOutputFile);
+            LOGGER.info("wrote EPICS data to CSV");
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void process(final EvioEvent evioEvent) {
+        super.process(evioEvent);
+        epicsDataSet.add(this.getEpicsData());
+    }
+
+    /**
+     * Write the set of {@link EpicsData} from event processing to a CSV file.
+     *
+     * @param file the output CSV file
+     * @throws IOException if there is an IO problem with files operations
+     */
+    private void write(final File file) throws IOException {
+
+        FileWriter fileWriter = null;
+        CSVPrinter csvPrinter = null;
+
+        try {
+
+            boolean append = false;
+            if (file.exists()) {
+                LOGGER.info("appending EPICS data to existing file " + file.getPath());
+                append = true;
+            }
+
+            fileWriter = new FileWriter(file, append);
+            csvPrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT);
+
+            if (!append) {
+                // Add field names as first row if file is new.
+                final List<String> fieldNames = new ArrayList<String>();
+                fieldNames.add("run");
+                fieldNames.add("sequence");
+                fieldNames.add("timestamp");
+                fieldNames.addAll(EpicsData.getVariableNames());
+                csvPrinter.printRecord(fieldNames);
+            }
+
+            // Loop over all EPICS data that was processed and saved.
+            for (final EpicsData epicsData : epicsDataSet) {
+
+                // Data record for CSV output.
+                final List<Object> record = new ArrayList<Object>();
+
+                // The EPICs header data.
+                final EpicsHeader epicsHeader = epicsData.getEpicsHeader();
+
+                // Append header information first if it exists (defaults to all zeroes if not present).
+                int run = 0;
+                int sequence = 0;
+                int timestamp = 0;
+                if (epicsHeader != null) {
+                    run = epicsHeader.getRun();
+                    sequence = epicsHeader.getSequence();
+                    timestamp = epicsHeader.getTimeStamp();
+                }
+                record.add(run);
+                record.add(sequence);
+                record.add(timestamp);
+
+                // Append EPICS data variables to the record (non-existent variables have value of 0).
+                for (final String key : EpicsData.getVariableNames()) {
+                    final Object value = 0;
+                    if (epicsData.hasKey(key)) {
+                        record.add(epicsData.getValue(key));
+                    }
+                    record.add(value);
+                }
+
+                // Write the record to CSV.
+                csvPrinter.printRecord(record);
+            }
+
+        } finally {
+            try {
+                // Close the writers.
+                fileWriter.flush();
+                fileWriter.close();
+                csvPrinter.close();
+            } catch (final IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}