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);
+ }
+ }
+ }
+}
|