Author: [log in to unmask]
Date: Wed Feb 10 14:26:49 2016
New Revision: 4196
Log:
Update dev branch with changes for run db, datacat and file crawling.
Added:
java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/MetadataWriter.java
java/branches/jeremy-dev/crawler/src/main/python/
java/branches/jeremy-dev/crawler/src/main/python/crawler/
java/branches/jeremy-dev/crawler/src/main/python/crawler/create_dataset_from_metadata.py (with props)
java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetCalculator.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/AbstractRunBuilder.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatabaseUpdater.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatBuilder.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatUtilities.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/LivetimeBuilder.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SpreadsheetBuilder.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigBuilder.java
java/branches/jeremy-dev/run-database/src/test/java/org/hps/run/database/RunBuilderTest.java
Modified:
java/branches/jeremy-dev/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java
java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatAddFile.java
java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatHelper.java
java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java
java/branches/jeremy-dev/distribution/pom.xml
java/branches/jeremy-dev/logging/src/main/resources/org/hps/logging/config/test_logging.properties
java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/TriggerConfigEvioProcessor.java
java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java
java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerConfigData.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseBuilder.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java
java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java
Modified: java/branches/jeremy-dev/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java
=============================================================================
--- java/branches/jeremy-dev/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java (original)
+++ java/branches/jeremy-dev/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java Wed Feb 10 14:26:49 2016
@@ -99,11 +99,14 @@
* @param file the CSV file
*/
public RunSpreadsheet(final File file) {
+ if (file == null) {
+ throw new IllegalArgumentException("The file argument is null.");
+ }
this.file = file;
try {
this.fromCsv(this.file);
} catch (final Exception e) {
- throw new RuntimeException();
+ throw new RuntimeException("Failed to parse run spreadsheet.", e);
}
}
Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatAddFile.java
=============================================================================
--- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatAddFile.java (original)
+++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatAddFile.java Wed Feb 10 14:26:49 2016
@@ -13,21 +13,18 @@
import org.srs.datacat.model.DatasetModel;
/**
- * Command line file crawler for populating the data catalog.
+ * Command line tool for adding files to the data catalog.
*
* @author Jeremy McCormick, SLAC
*/
public final class DatacatAddFile {
- /**
- * Setup the logger.
- */
private static final Logger LOGGER = Logger.getLogger(DatacatCrawler.class.getPackage().getName());
- private List<File> paths;
+ private List<File> paths = new ArrayList<File>();
/**
- * Command line options for the crawler.
+ * Command line options.
*/
private static final Options OPTIONS = new Options();
@@ -95,7 +92,6 @@
// List of paths.
if (!cl.getArgList().isEmpty()) {
- paths = new ArrayList<File>();
for (String arg : cl.getArgList()) {
paths.add(new File(arg));
}
@@ -129,7 +125,7 @@
}
/**
- * Print the usage statement for this tool to the console and then exit the program.
+ * Print the usage statement and then exit.
*/
private void printUsage() {
final HelpFormatter help = new HelpFormatter();
Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatHelper.java
=============================================================================
--- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatHelper.java (original)
+++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatHelper.java Wed Feb 10 14:26:49 2016
@@ -37,17 +37,17 @@
/*
* Static map of strings to file formats.
*/
- private static final Map<String, FileFormat> formatMap = new HashMap<String, FileFormat>();
+ private static final Map<String, FileFormat> FORMATS = new HashMap<String, FileFormat>();
static {
for (final FileFormat format : FileFormat.values()) {
- formatMap.put(format.extension(), format);
+ FORMATS.put(format.extension(), format);
}
}
/*
* System metadata fields.
*/
- private static final Set<String> SYSTEM_METADATA = new HashSet<String>();
+ static final Set<String> SYSTEM_METADATA = new HashSet<String>();
static {
SYSTEM_METADATA.add("eventCount");
SYSTEM_METADATA.add("size");
@@ -56,9 +56,13 @@
SYSTEM_METADATA.add("checksum");
SYSTEM_METADATA.add("scanStatus");
}
-
- /**
- * Create metadata for a file using its specific reader.
+
+ static final boolean isSystemMetadata(String name) {
+ return SYSTEM_METADATA.contains(name);
+ }
+
+ /**
+ * Create metadata for a file using its {@link FileMetadataReader}.
*
* @param file the file
* @return the metadata for the file
@@ -82,6 +86,7 @@
} catch (final IOException e) {
throw new RuntimeException(e);
}
+ metadata.put("scanStatus", "OK");
return metadata;
}
@@ -128,7 +133,7 @@
name = stripEvioFileNumber(name);
}
final String extension = name.substring(name.lastIndexOf(".") + 1);
- return formatMap.get(extension);
+ return FORMATS.get(extension);
}
/**
Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java
=============================================================================
--- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java (original)
+++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java Wed Feb 10 14:26:49 2016
@@ -11,11 +11,11 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.hps.record.evio.EventTagConstant;
import org.hps.record.evio.EvioEventUtilities;
import org.hps.record.evio.EvioFileUtilities;
import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition;
import org.hps.record.triggerbank.HeadBankData;
-import org.hps.record.triggerbank.TIData;
import org.hps.record.triggerbank.TiTimeOffsetEvioProcessor;
import org.hps.record.triggerbank.TriggerType;
import org.jlab.coda.jevio.BaseStructure;
@@ -24,13 +24,10 @@
import org.jlab.coda.jevio.EvioReader;
/**
- * Reads metadata from EVIO files, including the event count, run min and run max expected by the datacat, as well as
- * many custom field values applicable to HPS EVIO raw data.
+ * Creates detailed metadata for the datacat from an EVIO input file.
*
* @author Jeremy McCormick, SLAC
*/
-// TODO: add physics events count
-// TODO: remove trigger rate and TI time offset
final class EvioMetadataReader implements FileMetadataReader {
/**
@@ -42,11 +39,6 @@
* Head bank definition.
*/
private static IntBankDefinition HEAD_BANK = new IntBankDefinition(HeadBankData.class, new int[] {0x2e, 0xe10f});
-
- /**
- * TI data bank definition.
- */
- private static IntBankDefinition TI_BANK = new IntBankDefinition(TIData.class, new int[] {0x2e, 0xe10a});
/**
* Get the EVIO file metadata.
@@ -57,7 +49,7 @@
@Override
public Map<String, Object> getMetadata(final File file) throws IOException {
- long events = 0;
+ long totalEvents = 0;
int physicsEvents = 0;
int badEvents = 0;
int blinded = 0;
@@ -66,12 +58,12 @@
Integer lastHeadTimestamp = null;
Integer lastPhysicsEvent = null;
Integer firstPhysicsEvent = null;
+ Integer prestartTimestamp = null;
+ Integer endTimestamp = null;
+ Integer goTimestamp = null;
Double triggerRate = null;
- long lastTI = 0;
- long minTIDelta = 0;
- long maxTIDelta = 0;
- long firstTI = 0;
-
+
+ // Processor for calculating TI time offsets.
TiTimeOffsetEvioProcessor tiProcessor = new TiTimeOffsetEvioProcessor();
// Create map for counting trigger types.
@@ -83,7 +75,7 @@
// Get the file number from the name.
final int fileNumber = EvioFileUtilities.getSequenceFromName(file);
- // Files with a sequence number that is not divisible by 10 are blinded (Eng Run 2015 scheme).
+ // File numbers indivisible by 10 are blinded (Eng Run 2015 scheme).
if (!(fileNumber % 10 == 0)) {
blinded = 1;
}
@@ -106,22 +98,22 @@
EvioEvent evioEvent = null;
// Event read loop.
- fileLoop: while (true) {
+ eventLoop: while (true) {
try {
// Parse next event.
evioEvent = evioReader.parseNextEvent();
// End of file.
if (evioEvent == null) {
- LOGGER.fine("EOF after " + events + " events");
- break fileLoop;
+ LOGGER.fine("EOF after " + totalEvents + " events.");
+ break eventLoop;
}
// Increment event count (doesn't count events that can't be parsed).
- ++events;
+ ++totalEvents;
// Debug print event number and tag.
- LOGGER.finest("parsed event " + evioEvent.getEventNumber() + " with tag 0x"
+ LOGGER.finest("Parsed event " + evioEvent.getEventNumber() + " with tag 0x"
+ String.format("%08x", evioEvent.getHeader().getTag()));
// Get head bank.
@@ -139,7 +131,7 @@
// First header timestamp.
if (firstHeadTimestamp == null) {
firstHeadTimestamp = thisTimestamp;
- LOGGER.finer("first head timestamp " + firstHeadTimestamp + " from event "
+ LOGGER.finer("First head timestamp " + firstHeadTimestamp + " from event "
+ evioEvent.getEventNumber());
}
@@ -151,31 +143,12 @@
if (run == null) {
if (headBankData[1] != 0) {
run = (long) headBankData[1];
- LOGGER.finer("run " + run + " from event " + evioEvent.getEventNumber());
+ LOGGER.finer("Run number " + run + " from event " + evioEvent.getEventNumber());
}
}
}
}
-
- // Process trigger bank data for TI times (copied from Sho's BasicEvioFileReader class).
- BaseStructure tiBank = TI_BANK.findBank(evioEvent);
- if (tiBank != null) {
- TIData tiData = new TIData(tiBank.getIntData());
- if (lastTI == 0) {
- firstTI = tiData.getTime();
- }
- lastTI = tiData.getTime();
- if (thisTimestamp != 0) {
- long delta = thisTimestamp * 1000000000L - tiData.getTime();
- if (minTIDelta == 0 || minTIDelta > delta) {
- minTIDelta = delta;
- }
- if (maxTIDelta == 0 || maxTIDelta < delta) {
- maxTIDelta = delta;
- }
- }
- }
-
+
if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
final int[] eventIdData = EvioEventUtilities.getEventIdData(evioEvent);
@@ -188,11 +161,24 @@
// Set the first physics event.
if (firstPhysicsEvent == null) {
firstPhysicsEvent = eventIdData[0];
- LOGGER.finer("set first physics event " + firstPhysicsEvent);
+ LOGGER.finer("Set first physics event " + firstPhysicsEvent);
}
}
++physicsEvents;
+ } else if (EvioEventUtilities.isControlEvent(evioEvent)) {
+ int[] controlData = EvioEventUtilities.getControlEventData(evioEvent);
+ if (controlData[0] != 0) {
+ if (EventTagConstant.PRESTART.isEventTag(evioEvent)) {
+ prestartTimestamp = controlData[0];
+ }
+ if (EventTagConstant.GO.isEventTag(evioEvent)) {
+ goTimestamp = controlData[0];
+ }
+ if (EventTagConstant.END.isEventTag(evioEvent)) {
+ endTimestamp = controlData[0];
+ }
+ }
}
// Count trigger types for this event.
@@ -200,17 +186,16 @@
for (TriggerType mask : triggerTypes) {
int count = triggerCounts.get(mask) + 1;
triggerCounts.put(mask, count);
- LOGGER.finest("incremented " + mask.name() + " to " + count);
+ LOGGER.finest("Incremented " + mask.name() + " to " + count);
}
// Activate TI time offset processor.
tiProcessor.process(evioEvent);
- //} catch (IOException | NegativeArraySizeException | EvioException e) {
} catch (Exception e) {
- // Trap event processing errors.
+ // Trap all event processing errors.
badEvents++;
- LOGGER.warning("error processing EVIO event " + evioEvent.getEventNumber());
+ LOGGER.warning("Error processing EVIO event " + evioEvent.getEventNumber());
}
}
} catch (final EvioException e) {
@@ -222,22 +207,23 @@
try {
evioReader.close();
} catch (IOException e) {
- LOGGER.log(Level.WARNING, "error closing EVIO reader", e);
+ LOGGER.log(Level.WARNING, "Error closing EVIO reader", e);
}
}
}
- LOGGER.info("done reading " + events + " events from " + file.getPath());
+ LOGGER.info("Done reading " + totalEvents + " events from " + file.getPath());
// Rough trigger rate calculation.
try {
- if (firstHeadTimestamp != null && lastHeadTimestamp != null && events > 0) {
- triggerRate = calculateTriggerRate(firstHeadTimestamp, lastHeadTimestamp, events);
+ if (firstHeadTimestamp != null && lastHeadTimestamp != null && totalEvents > 0
+ && (firstHeadTimestamp - lastHeadTimestamp != 0)) {
+ triggerRate = calculateTriggerRate(firstHeadTimestamp, lastHeadTimestamp, totalEvents);
} else {
LOGGER.log(Level.WARNING, "Missing information for calculating trigger rate.");
}
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Error calculating trigger rate.", e);
+ LOGGER.log(Level.WARNING, "Error calculating the trigger rate.", e);
}
// Create and fill the metadata map.
@@ -248,15 +234,15 @@
run = new Long(EvioFileUtilities.getRunFromName(file));
}
} catch (Exception e) {
- throw new RuntimeException("Unable to determine run number from data or file name.", e);
- }
-
- // Set built-in system metadata.
+ throw new RuntimeException("Failed to get run number from event data or file name.", e);
+ }
+
+ // Set locationExtras metadata.
metadataMap.put("runMin", run);
metadataMap.put("runMax", run);
- metadataMap.put("eventCount", events);
+ metadataMap.put("eventCount", totalEvents);
metadataMap.put("size", size);
- metadataMap.put("checksum", checksum);
+ metadataMap.put("checksum", checksum);
// File sequence number.
metadataMap.put("FILE", fileNumber);
@@ -267,54 +253,52 @@
// First and last timestamps which may come from control or physics events.
if (firstHeadTimestamp != null) {
metadataMap.put("FIRST_HEAD_TIMESTAMP", firstHeadTimestamp);
- } else {
- metadataMap.put("FIRST_HEAD_TIMESTAMP", 0L);
- }
+ }
if (lastHeadTimestamp != null) {
metadataMap.put("LAST_HEAD_TIMESTAMP", lastHeadTimestamp);
- } else {
- metadataMap.put("LAST_HEAD_TIMESTAMP", 0L);
- }
+ }
// First and last physics event numbers.
if (firstPhysicsEvent != null) {
metadataMap.put("FIRST_PHYSICS_EVENT", firstPhysicsEvent);
- } else {
- metadataMap.put("FIRST_PHYSICS_EVENT", 0L);
- }
+ }
if (lastPhysicsEvent != null) {
metadataMap.put("LAST_PHYSICS_EVENT", lastPhysicsEvent);
- } else {
- metadataMap.put("LAST_PHYSICS_EVENT", 0L);
+ }
+
+ // Timestamps which are only set if the corresponding control events were found in the file.
+ if (prestartTimestamp != null) {
+ metadataMap.put("PRESTART_TIMESTAMP", prestartTimestamp);
+ }
+ if (endTimestamp != null) {
+ metadataMap.put("END_TIMESTAMP", endTimestamp);
+ }
+ if (goTimestamp != null) {
+ metadataMap.put("GO_TIMESTAMP", goTimestamp);
}
// TI times and offset.
- metadataMap.put("FIRST_TI_TIME", firstTI);
- metadataMap.put("LAST_TI_TIME", lastTI);
- metadataMap.put("TI_TIME_DELTA", maxTIDelta - minTIDelta);
-
- // TI time offset.
- //metadataMap.put("TI_TIME_OFFSET", tiProcessor.getTiTimeOffset());
-
+ metadataMap.put("TI_TIME_MIN_OFFSET", new Long(tiProcessor.getMinOffset()).toString());
+ metadataMap.put("TI_TIME_MAX_OFFSET", new Long(tiProcessor.getMaxOffset()).toString());
+ metadataMap.put("TI_TIME_N_OUTLIERS", tiProcessor.getNumOutliers());
+
// Event counts.
metadataMap.put("BAD_EVENTS", badEvents);
// Physics event count.
- metadataMap.put("PHYSICS_EVENTS", physicsEvents);
-
- // Trigger rate in Hz to 2 decimal places.
- /*
+ metadataMap.put("PHYSICS_EVENTS", physicsEvents);
+
+ // Rough trigger rate.
if (triggerRate != null && !Double.isInfinite(triggerRate) && !Double.isNaN(triggerRate)) {
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.CEILING);
- LOGGER.info("setting trigger rate " + triggerRate);
+ LOGGER.info("Setting trigger rate to " + triggerRate + " Hz.");
metadataMap.put("TRIGGER_RATE", Double.parseDouble(df.format(triggerRate)));
} else {
- metadataMap.put("TRIGGER_RATE", 0);
- }
- */
+ LOGGER.warning("Failed to calculate trigger rate.");
+ }
// Trigger type counts.
for (Entry<TriggerType, Integer> entry : triggerCounts.entrySet()) {
@@ -327,7 +311,7 @@
for (Entry<String, Object> entry : metadataMap.entrySet()) {
sb.append(" " + entry.getKey() + " = " + entry.getValue() + '\n');
}
- LOGGER.info("file metadata ..." + '\n' + sb.toString());
+ LOGGER.info("File metadata ..." + '\n' + sb.toString());
// Return the completed metadata map.
return metadataMap;
Added: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/MetadataWriter.java
=============================================================================
--- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/MetadataWriter.java (added)
+++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/MetadataWriter.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,137 @@
+package org.hps.crawler;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+/**
+ * Creates metadata for a file and writes the results to a Python snippet that can be used as input to the SRS datacat.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public final class MetadataWriter {
+
+ private static final Logger LOGGER = Logger.getLogger(MetadataWriter.class.getPackage().getName());
+ private static final Options OPTIONS = new Options();
+
+ private List<File> inputFiles;
+ private File outputDir = new File(".");
+
+ static {
+ OPTIONS.addOption("h", "help", false, "print help and exit (overrides all other arguments)");
+ OPTIONS.addOption("d", "dir", true, "directory where metadata files should be written");
+ }
+
+ public static void main(final String[] args) {
+ new MetadataWriter().parse(args).run();
+ }
+
+ private MetadataWriter parse(final String[] args) {
+
+ try {
+ final CommandLine cl = new DefaultParser().parse(OPTIONS, args);
+
+ // Print help.
+ if (cl.hasOption("h") || args.length == 0) {
+ this.printUsage();
+ }
+
+ // List of input files.
+ if (!cl.getArgList().isEmpty()) {
+ inputFiles = new ArrayList<File>();
+ for (String arg : cl.getArgList()) {
+ inputFiles.add(new File(arg));
+ }
+ } else {
+ printUsage();
+ }
+ if (this.inputFiles.isEmpty()) {
+ throw new RuntimeException("Missing at least one input file to process.");
+ }
+
+ // Output directory for metadata files.
+ if (cl.hasOption("d")) {
+ outputDir = new File(cl.getOptionValue("d"));
+ if (!outputDir.isDirectory()) {
+ throw new IllegalArgumentException("The file " + outputDir.getPath() + " is not a directory.");
+ }
+ }
+
+ } catch (final ParseException e) {
+ throw new RuntimeException("Error parsing command line options.", e);
+ }
+
+ LOGGER.info("Done parsing command line options.");
+
+ return this;
+ }
+
+ private void printUsage() {
+ final HelpFormatter help = new HelpFormatter();
+ help.printHelp(80, "MetadataWriter [options] file1 file2 [...]", "", OPTIONS, "");
+ System.exit(0);
+ }
+
+ private void run() {
+ for (File file : inputFiles) {
+ LOGGER.info("Creating metadata for " + file.getPath() + " ...");
+ Map<String, Object> metadata = DatacatHelper.createMetadata(file);
+ String metadataFileName = this.outputDir + File.separator + file.getName() + ".metadata";
+ writeString(toPyDict(metadata), new File(metadataFileName));
+ LOGGER.info("Wrote metadata for " + file.getPath() + " to " + metadataFileName);
+ }
+ }
+
+ private static String toPyDict(Map<String, Object> metadata) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("{");
+ for (String name : DatacatHelper.SYSTEM_METADATA) {
+ if (metadata.containsKey(name)) {
+ Object value = metadata.get(name);
+ if (value instanceof Number) {
+ sb.append("\"" + name + "\" : " + metadata.get(name) + ", ");
+ } else {
+ sb.append("\"" + name + "\" : \"" + metadata.get(name) + "\", ");
+ }
+ }
+ }
+ sb.setLength(sb.length() - 2);
+ sb.append(", \"versionMetadata\" : {");
+ for (Map.Entry<String, Object> entry : metadata.entrySet()) {
+ if (!DatacatHelper.isSystemMetadata(entry.getKey())) {
+ Object value = entry.getValue();
+ String name = entry.getKey();
+ if (value instanceof Number) {
+ sb.append("\"" + name + "\" : " + metadata.get(name) + ", ");
+ } else {
+ sb.append("\"" + name + "\" : \"" + metadata.get(name) + "\", ");
+ }
+ }
+ }
+ sb.setLength(sb.length() - 2);
+ sb.append("}");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ private static void writeString(String dictString, File file) {
+ try {
+ FileWriter fileWriter = new FileWriter(file);
+ fileWriter.write(dictString);
+ fileWriter.flush();
+ fileWriter.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
Added: java/branches/jeremy-dev/crawler/src/main/python/crawler/create_dataset_from_metadata.py
=============================================================================
--- java/branches/jeremy-dev/crawler/src/main/python/crawler/create_dataset_from_metadata.py (added)
+++ java/branches/jeremy-dev/crawler/src/main/python/crawler/create_dataset_from_metadata.py Wed Feb 10 14:26:49 2016
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+"""
+Insert files into datacat using previously written .metadata files or allow updating
+the metadata of an existing dataset if the "-u" option is specified.
+
+The dataset's resource directory and target folder in the datacat must be provided explicitly
+with command line arguments.
+
+author: Jeremy McCormick, SLAC
+"""
+
+import os, sys, glob, argparse
+
+from datacat import *
+from datacat.error import DcException
+from datacat.model import Dataset
+
+# assumes datacat config is in current working dir
+client = client_from_config_file(path=os.getcwd() + '/default.cfg')
+
+def get_data_format(name):
+ if name.endswith('.aida'):
+ return 'AIDA'
+ elif name.endswith('.slcio'):
+ return 'LCIO'
+ elif name.endswith('.root'):
+ return 'ROOT'
+ elif '.evio' in os.path.basename(name):
+ return 'EVIO'
+ raise Exception('Failed to get data format for %s' % name)
+
+def get_data_type(name, format):
+ if format == 'EVIO':
+ return 'RAW'
+ elif format == 'LCIO' and '_recon' in name:
+ return 'RECON'
+ elif format == 'ROOT' and '_dst' in name:
+ return 'DST'
+ elif format == 'ROOT' and '_dqm' in name:
+ return 'DQM'
+ elif format == 'AIDA' and '_dqm' in name:
+ return 'DQM'
+ raise Exception('Failed to get data type for %s' % name)
+
+# define CL options
+parser = argparse.ArgumentParser(description='insert or update datasets from metadata files')
+parser.add_argument('--basedir', '-b', dest='basedir', nargs=1, help='base dir containing metadata files to read', required = True)
+parser.add_argument('--folder', '-f', dest='folder', nargs=1, help='target folder in the datacat', required = True)
+parser.add_argument('--resource', '-r', dest='resource', nargs=1, help='actual directory of the files', required = True)
+parser.add_argument('--site', '-s', dest='site', nargs=1, help='datacat site (default JLAB)', default='JLAB') # TODO: default to dir of .metadata file
+parser.add_argument('--update', '-u', dest='update', help='allow updates to metadata of existing files', action='store_true')
+args = parser.parse_args()
+
+basedir = args.basedir[0]
+folder = args.folder[0]
+if args.resource[0] is not None:
+ resource = args.resource[0]
+else:
+ resource = basedir
+site = args.site[0]
+allow_update = args.update
+
+metadata_files = glob.glob(basedir + '/*.metadata')
+
+if len(metadata_files) == 0:
+ raise Exception("No metadata files found in %s dir." % basedir)
+
+for metadata_file in metadata_files:
+
+ metadata = eval(open(metadata_file).read())
+ if not isinstance(metadata, dict):
+ raise Exception("Input metadata from %s is not a dict." % metadata_file)
+
+ locationExtras = {}
+ for k, v in metadata.iteritems():
+ if k != 'versionMetadata':
+ locationExtras[k] = v
+ else:
+ versionMetadata = v
+
+ if versionMetadata is None:
+ versionmetadata = {}
+
+ # TODO: check for empty metadata here (should have some)
+
+ name = os.path.basename(metadata_file).replace('.metadata', '')
+ data_format = get_data_format(name)
+ data_type = get_data_type(name, data_format)
+
+ print "adding dataset ..."
+ print "folder = %s" % folder
+ print "name = %s" % name
+ print "data_format = %s" % data_format
+ print "data_type = %s" % data_type
+ print "site = %s" % site
+ print "resource = %s" % (resource + '/' + name)
+ print "versionMetadata = " + repr(versionMetadata)
+ print "locationExtras = " + repr(locationExtras)
+ print
+
+ dataset_exists = False
+ try:
+ p = client.path("%s/%s" % (folder, name))
+ if isinstance(p, Dataset):
+ dataset_exists = True
+ except DcException:
+ pass
+
+ if not dataset_exists:
+ print "Creating new dataset for %s ..." % name
+ try:
+ client.mkds(folder,
+ name,
+ data_type,
+ data_format,
+ site=site,
+ resource=resource + '/' + name,
+ versionMetadata=versionMetadata,
+ locationExtras=locationExtras)
+ print "%s was added successfully." % name
+ except DcException as e:
+ print 'Insert of %s failed!' % name
+ print repr(e)
+ else:
+ if allow_update:
+ print "Updating metadata on existing dataset %s ..." % name
+ try:
+ if metadata['checksum'] is not None:
+ del metadata['checksum']
+ client.patchds(folder + '/' + name, metadata)
+ except DcException as e:
+ print "Update of %s failed!" % name
+ print repr(e)
+ else:
+ raise Exception("Dataset already exists and updates are not allowed.")
Modified: java/branches/jeremy-dev/distribution/pom.xml
=============================================================================
--- java/branches/jeremy-dev/distribution/pom.xml (original)
+++ java/branches/jeremy-dev/distribution/pom.xml Wed Feb 10 14:26:49 2016
@@ -88,35 +88,31 @@
</program>
<program>
<mainClass>org.hps.job.JobManager</mainClass>
- <id>job</id>
+ <id>job-manager</id>
</program>
<program>
<mainClass>org.hps.conditions.cli.CommandLineTool</mainClass>
- <id>conddb</id>
- </program>
- <program>
- <mainClass>org.hps.crawler.DatacatCrawler</mainClass>
- <id>crawler</id>
+ <id>conditions-cli</id>
</program>
<program>
<mainClass>org.hps.run.database.RunDatabaseCommandLine</mainClass>
- <id>rundb</id>
+ <id>run-database-cli</id>
</program>
<program>
<mainClass>org.hps.monitoring.application.Main</mainClass>
- <id>monapp</id>
+ <id>monitoring-app</id>
</program>
<program>
<mainClass>org.lcsim.geometry.compact.converter.Main</mainClass>
- <id>detcnv</id>
+ <id>detector-converter</id>
</program>
<program>
<mainClass>org.hps.record.evio.EvioFileProducer</mainClass>
- <id>evio_file_producer</id>
+ <id>evio-file-producer</id>
</program>
<program>
<mainClass>org.jlab.coda.et.apps.StartEt</mainClass>
- <id>et_server</id>
+ <id>et-server</id>
<commandLineArguments>
<commandLineArgument>-f</commandLineArgument>
<commandLineArgument>ETBuffer</commandLineArgument>
@@ -124,6 +120,18 @@
<commandLineArgument>20000</commandLineArgument>
<commandLineArgument>-v</commandLineArgument>
</commandLineArguments>
+ </program>
+ <program>
+ <mainClass>org.hps.crawler.MetadataWriter</mainClass>
+ <id>dc-create-metadata</id>
+ </program>
+ <program>
+ <mainClass>org.hps.crawler.DatacatAddFile</mainClass>
+ <id>dc-add-file</id>
+ </program>
+ <program>
+ <mainClass>org.hps.crawler.DatacatCrawler</mainClass>
+ <id>dc-crawler</id>
</program>
</programs>
</configuration>
Modified: java/branches/jeremy-dev/logging/src/main/resources/org/hps/logging/config/test_logging.properties
=============================================================================
--- java/branches/jeremy-dev/logging/src/main/resources/org/hps/logging/config/test_logging.properties (original)
+++ java/branches/jeremy-dev/logging/src/main/resources/org/hps/logging/config/test_logging.properties Wed Feb 10 14:26:49 2016
@@ -66,7 +66,7 @@
org.hps.recon.tracking.gbl.level = WARNING
# run-database
-org.hps.run.database.level = WARNING
+org.hps.run.database.level = ALL
# monitoring-application
org.hps.monitoring.application.model.level = WARNING
Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/TriggerConfigEvioProcessor.java
=============================================================================
--- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/TriggerConfigEvioProcessor.java (original)
+++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/TriggerConfigEvioProcessor.java Wed Feb 10 14:26:49 2016
@@ -14,10 +14,11 @@
import org.jlab.coda.jevio.EvioEvent;
/**
- * Copied and modified from code in {@link org.hps.evio.TriggerConfigEvioReader} to extract DAQ config without
- * needing an output LCSim event.
+ * Extracts DAQ config strings from an EVIO event stream, saving a reference to the most recent
+ * {@link org.hps.record.triggerbank.TriggerConfigData} object.
* <p>
- * Only the last valid DAQ config object is available once the job is finished.
+ * When event processing is completed, the <code>triggerConfig</code> variable should reference
+ * the last valid DAQ config and can be accessed using the {@link #getTriggerConfigData()} method.
*
* @author Jeremy McCormick, SLAC
*/
@@ -25,8 +26,7 @@
private Logger LOGGER = Logger.getLogger(TriggerConfigEvioProcessor.class.getPackage().getName());
- private TriggerConfigData triggerConfig = null;
- private Integer run = null;
+ private TriggerConfigData triggerConfig = null;
private int timestamp = 0;
/**
@@ -35,32 +35,21 @@
@Override
public void process(EvioEvent evioEvent) {
try {
- // Initialize the run number if necessary.
- if (run == null) {
- try {
- run = EvioEventUtilities.getRunNumber(evioEvent);
- LOGGER.info("run " + run);
- } catch (NullPointerException e) {
+
+ // Set current timestamp from head bank.
+ BaseStructure headBank = EvioEventUtilities.getHeadBank(evioEvent);
+ if (headBank != null) {
+ if (headBank.getIntData()[3] != 0) {
+ timestamp = headBank.getIntData()[3];
+ LOGGER.finest("Set timestamp " + timestamp + " from head bank.");
}
}
-
- // Can only start parsing DAQ banks once the run is set.
- if (run != null) {
- // Set current timestamp from head bank.
- BaseStructure headBank = EvioEventUtilities.getHeadBank(evioEvent);
- if (headBank != null) {
- if (headBank.getIntData()[3] != 0) {
- timestamp = headBank.getIntData()[3];
- LOGGER.finest("set timestamp " + timestamp + " from head bank");
- }
- }
-
- // Parse config data from the EVIO banks.
- parseEvioData(evioEvent);
- }
+ // Parse config data from the EVIO banks.
+ parseEvioData(evioEvent);
+
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Error parsing DAQ config from EVIO.", e);
+ LOGGER.log(Level.SEVERE, "Error parsing DAQ config from EVIO.", e);
}
}
@@ -72,46 +61,68 @@
*/
private void parseEvioData(EvioEvent evioEvent) {
Map<Crate, String> stringData = null;
+ // Loop over top banks.
for (BaseStructure bank : evioEvent.getChildrenList()) {
if (bank.getChildCount() <= 0) {
continue;
}
- int crate = bank.getHeader().getTag();
+ int crateNumber = bank.getHeader().getTag();
+ // Loop over sub-banks.
for (BaseStructure subBank : bank.getChildrenList()) {
+ // In trigger config bank?
if (EvioBankTag.TRIGGER_CONFIG.equals(subBank)) {
- if (subBank.getStringData() == null) {
- LOGGER.warning("Trigger config bank is missing string data.");
- } else {
+ // Has a valid string array?
+ if (subBank.getStringData() != null) {
try {
+
+ // Make sure string data map is initialized for this event.
if (stringData == null) {
stringData = new HashMap<Crate, String>();
- }
- //LOGGER.fine("got raw trigger config string data ..." + '\n' + subBank.getStringData()[0]);
- stringData.put(TriggerConfigData.Crate.fromCrateNumber(crate), subBank.getStringData()[0]);
+ }
+
+ // Get the Crate enum from crate number (if this returns null then the crate is ignored).
+ Crate crate = Crate.fromCrateNumber(crateNumber);
+
+ // Is crate number valid?
+ if (crate != null) {
+
+ // Is there valid string data in the array?
+ if (subBank.getStringData().length > 0) {
+ // Add string data to map.
+ stringData.put(crate, subBank.getStringData()[0]);
+ LOGGER.info("Added crate " + crate.getCrateNumber() + " data ..." + '\n' + subBank.getStringData()[0]);
+ } /*else {
+ LOGGER.warning("The string bank has no data.");
+ }*/
+ }
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Failed to parse crate " + crate + " config.", e);
+ LOGGER.log(Level.SEVERE, "Error parsing DAQ config from crate " + crateNumber, e);
+ e.printStackTrace();
}
}
- }
+ } /*else {
+ LOGGER.warning("Trigger config bank is missing string data.");
+ }*/
}
}
if (stringData != null) {
+ LOGGER.info("Found " + stringData.size() + " config data strings in event " + evioEvent.getEventNumber());
TriggerConfigData currentConfig = new TriggerConfigData(stringData, timestamp);
if (currentConfig.isValid()) {
triggerConfig = currentConfig;
- LOGGER.warning("Found valid config in event num " + evioEvent.getEventNumber());
+ LOGGER.info("Found valid DAQ config data in event num " + evioEvent.getEventNumber());
} else {
- LOGGER.warning("Skipping invalid config from event num " + evioEvent.getEventNumber());
+ LOGGER.warning("Skipping invalid DAQ config data in event num " + evioEvent.getEventNumber());
}
}
}
/**
- * Get a map of bank number to string data for the current config.
+ * Get the last valid set of config data that was found in the event stream.
*
- * @return a map of bank to trigger config data
+ * @return a map of bank number to the corresponding trigger config string data
*/
public TriggerConfigData getTriggerConfigData() {
return this.triggerConfig;
}
-}
+}
Added: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetCalculator.java
=============================================================================
--- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetCalculator.java (added)
+++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetCalculator.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,56 @@
+package org.hps.record.triggerbank;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Calculate TI time offset given lists of min and max offsets and the number of outliers.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public class TiTimeOffsetCalculator {
+
+ /* Constants from TiTimeOffsetEvioProcessor. */
+ private final static int MAX_OUTLIERS = 10;
+ private final static double MIN_RANGE = 0.99e9;
+
+ private List<Long> minOffsets = new ArrayList<Long>();
+ private List<Long> maxOffsets = new ArrayList<Long>();
+ private int totalOutliers;
+
+ public void addMinOffset(long minOffset) {
+ minOffsets.add(minOffset);
+ }
+
+ public void addMaxOffset(long maxOffset) {
+ maxOffsets.add(maxOffset);
+ }
+
+ public void addNumOutliers(int nOutliers) {
+ totalOutliers += nOutliers;
+ }
+
+ public long calculateTimeOffset() {
+
+ if (minOffsets.size() == 0) {
+ throw new RuntimeException("The min offsets list has no data.");
+ }
+ if (maxOffsets.size() == 0) {
+ throw new RuntimeException("The max offsets list has no data.");
+ }
+
+ Collections.sort(minOffsets);
+ Collections.sort(maxOffsets);
+
+ long minOffset = minOffsets.get(0);
+ long maxOffset = maxOffsets.get(maxOffsets.size() - 1);
+
+ final long offsetRange = maxOffset - minOffset;
+ if (offsetRange > MIN_RANGE && totalOutliers < MAX_OUTLIERS) {
+ return minOffset;
+ } else {
+ return 0L;
+ }
+ }
+}
Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java
=============================================================================
--- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java (original)
+++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java Wed Feb 10 14:26:49 2016
@@ -56,6 +56,18 @@
}
}
+ public long getMinOffset() {
+ return this.minOffset;
+ }
+
+ public long getMaxOffset() {
+ return this.maxOffset;
+ }
+
+ public int getNumOutliers() {
+ return this.nOutliers;
+ }
+
public long getTiTimeOffset() {
final long offsetRange = maxOffset - minOffset;
if (offsetRange > minRange && nOutliers < maxOutliers) {
Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerConfigData.java
=============================================================================
--- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerConfigData.java (original)
+++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerConfigData.java Wed Feb 10 14:26:49 2016
@@ -26,20 +26,20 @@
this.crate = crate;
}
- public int crate() {
+ public int getCrateNumber() {
return crate;
}
public static Crate fromCrateNumber(int crateNumber) {
for (Crate crate : Crate.values()) {
- if (crate.crate() == crateNumber) {
+ if (crate.getCrateNumber() == crateNumber) {
return crate;
}
}
return null;
- }
+ }
}
-
+
private int timestamp;
private Map<Crate, String> data;
@@ -99,7 +99,7 @@
public DAQConfig loadDAQConfig(int run) {
EvioDAQParser parser = new EvioDAQParser();
for (Entry<Crate, String> entry : data.entrySet()) {
- parser.parse(entry.getKey().crate(), run, new String[] {entry.getValue()});
+ parser.parse(entry.getKey().getCrateNumber(), run, new String[] {entry.getValue()});
}
ConfigurationManager.updateConfiguration(parser);
return ConfigurationManager.getInstance();
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/AbstractRunBuilder.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/AbstractRunBuilder.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/AbstractRunBuilder.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,35 @@
+package org.hps.run.database;
+
+/**
+ * Class for incrementally building records for the run database.
+ * <p>
+ * Classes that add information to the run summary or create objects
+ * for insertion into the run database should implement this.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public abstract class AbstractRunBuilder {
+
+ private RunSummaryImpl runSummary;
+
+ void setRunSummary(RunSummaryImpl runSummary) {
+ this.runSummary = runSummary;
+ }
+
+ RunSummaryImpl getRunSummary() {
+ return runSummary;
+ }
+
+ int getRun() {
+ if (this.runSummary == null) {
+ throw new IllegalStateException("The run summary object was never set.");
+ }
+ return this.runSummary.getRun();
+ }
+
+ /**
+ * Abstract method that sub-classes should implement to update the run summary or
+ * create objects for insertion into the database.
+ */
+ abstract void build();
+}
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatabaseUpdater.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatabaseUpdater.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatabaseUpdater.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,61 @@
+package org.hps.run.database;
+
+import java.sql.Connection;
+
+import org.hps.record.triggerbank.TriggerConfigData;
+
+// TODO: add EPICs and scaler update
+
+public class DatabaseUpdater {
+
+ private Connection connection;
+ private TriggerConfigData triggerConfig;
+ private RunSummary runSummary;
+ private boolean updateExisting = false;
+
+ DatabaseUpdater(Connection connection) {
+ this.connection = connection;
+ }
+
+ void setTriggerConfigData(TriggerConfigData triggerConfig) {
+ this.triggerConfig = triggerConfig;
+ }
+
+ void setRunSummary(RunSummary runSummary) {
+ this.runSummary = runSummary;
+ }
+
+ void setUpdateExisting(boolean updateExisting) {
+ this.updateExisting = updateExisting;
+ }
+
+ void update() {
+
+ int run = runSummary.getRun();
+
+ final DaoProvider runFactory = new DaoProvider(connection);
+ final RunSummaryDao runSummaryDao = runFactory.getRunSummaryDao();
+
+ RunManager runManager = new RunManager();
+ runManager.setRun(runSummary.getRun());
+ if (runManager.runExists()) {
+ if (updateExisting) {
+ runSummaryDao.updateRunSummary(runSummary);
+ } else {
+ throw new RuntimeException("Run already exists and updates are not allowed.");
+ }
+ } else {
+ runSummaryDao.insertRunSummary(runSummary);
+ }
+
+ final TriggerConfigDao configDao = runFactory.getTriggerConfigDao();
+ if (configDao.getTriggerConfig(run) != null) {
+ if (updateExisting) {
+ configDao.deleteTriggerConfig(run);
+ } else {
+ throw new RuntimeException("Run already exists and updates are not allowed.");
+ }
+ }
+ configDao.insertTriggerConfig(this.triggerConfig, run);
+ }
+}
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatBuilder.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatBuilder.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatBuilder.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,191 @@
+package org.hps.run.database;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.hps.record.triggerbank.TiTimeOffsetCalculator;
+import org.srs.datacat.client.Client;
+import org.srs.datacat.client.exception.DcClientException;
+import org.srs.datacat.model.DatasetModel;
+import org.srs.datacat.model.DatasetResultSetModel;
+import org.srs.datacat.model.dataset.DatasetWithViewModel;
+import org.srs.datacat.shared.DatasetLocation;
+
+final class DatacatBuilder extends AbstractRunBuilder {
+
+ private static final Logger LOGGER = Logger.getLogger(DatacatBuilder.class.getPackage().getName());
+
+ private static final String[] METADATA_FIELDS = {
+ "TI_TIME_MIN_OFFSET",
+ "TI_TIME_MAX_OFFSET",
+ "TI_TIME_N_OUTLIERS",
+ "END_TIMESTAMP",
+ "GO_TIMESTAMP",
+ "PRESTART_TIMESTAMP"
+ };
+
+ private Client datacatClient;
+ private String site;
+ private String folder;
+ private List<File> files;
+
+ private static long calculateTiTimeOffset(DatasetResultSetModel results) {
+ TiTimeOffsetCalculator calc = new TiTimeOffsetCalculator();
+ for (DatasetModel ds : results) {
+ DatasetWithViewModel view = (DatasetWithViewModel) ds;
+ Map<String, Object> metadata = view.getMetadataMap();
+ if (metadata.containsKey("TI_TIME_MIN_OFFSET")) {
+ calc.addMinOffset(Long.parseLong((String) metadata.get("TI_TIME_MIN_OFFSET")));
+ }
+ if (metadata.containsKey("TI_TIME_MAX_OFFSET")) {
+ calc.addMaxOffset(Long.parseLong((String) metadata.get("TI_TIME_MAX_OFFSET")));
+ }
+ if (metadata.containsKey("TI_TIME_N_OUTLIERS")) {
+ calc.addNumOutliers((int) (long) metadata.get("TI_TIME_N_OUTLIERS"));
+ }
+ }
+ return calc.calculateTimeOffset();
+ }
+
+ private static long getTotalEvents(DatasetResultSetModel results) {
+ long totalEvents = 0;
+ for (DatasetModel ds : results) {
+ DatasetWithViewModel view = (DatasetWithViewModel) ds;
+ DatasetLocation loc = (DatasetLocation) view.getViewInfo().getLocations().iterator().next();
+ totalEvents += loc.getEventCount();
+ }
+ return totalEvents;
+ }
+
+ private static Integer getPrestartTimestamp(DatasetResultSetModel results) {
+ DatasetWithViewModel ds = (DatasetWithViewModel) results.getResults().get(0);
+ if (ds.getMetadataMap().containsKey("PRESTART_TIMESTAMP")) {
+ return (int) (long) ds.getMetadataMap().get("PRESTART_TIMESTAMP");
+ } else {
+ return null;
+ }
+ }
+
+ private static Integer getEndTimestamp(DatasetResultSetModel results) {
+ DatasetWithViewModel ds = (DatasetWithViewModel) results.getResults().get(results.getResults().size() - 1);
+ if (ds.getMetadataMap().containsKey("END_TIMESTAMP")) {
+ return (int) (long) ds.getMetadataMap().get("END_TIMESTAMP");
+ } else {
+ return null;
+ }
+ }
+
+
+ private static Integer getGoTimestamp(DatasetResultSetModel results) {
+ DatasetWithViewModel ds = (DatasetWithViewModel) results.getResults().get(0);
+ if (ds.getMetadataMap().containsKey("GO_TIMESTAMP")) {
+ return (int) (long) ds.getMetadataMap().get("GO_TIMESTAMP");
+ } else {
+ return null;
+ }
+ }
+
+ private static double calculateTriggerRate(Integer startTimestamp, Integer endTimestamp, long nEvents) {
+ if (startTimestamp == null) {
+ throw new IllegalArgumentException("The start timestamp is null.");
+ }
+ if (endTimestamp == null) {
+ throw new IllegalArgumentException("The end timestamp is null.");
+ }
+ if (endTimestamp - startTimestamp == 0) {
+ throw new IllegalArgumentException("The start and end timestamp are the same.");
+ }
+ if (nEvents == 0) {
+ throw new IllegalArgumentException("The number of events is zero.");
+ }
+ double triggerRate = (double) nEvents / ((double) endTimestamp - (double) startTimestamp);
+ return triggerRate;
+ }
+
+ void build() {
+
+ if (getRunSummary() == null) {
+ throw new RuntimeException("The run summary was not set.");
+ }
+ if (this.datacatClient == null) {
+ throw new RuntimeException("The datacat client was not set.");
+ }
+ if (this.folder == null) {
+ throw new RuntimeException("The target folder was not set.");
+ }
+ if (this.site == null) {
+ throw new RuntimeException("The site was not set.");
+ }
+
+ DatasetResultSetModel results = null;
+ try {
+ results = findDatasets();
+ } catch (DcClientException e) {
+ System.err.println("HTTP status: " + e.getStatusCode());
+ throw new RuntimeException(e);
+ }
+
+ files = DatacatUtilities.toFileList(results);
+
+ if (results.getResults().isEmpty()) {
+ throw new RuntimeException("No results found for datacat search.");
+ }
+
+ long tiTimeOffset = calculateTiTimeOffset(results);
+ getRunSummary().setTiTimeOffset(tiTimeOffset);
+
+ long totalEvents = getTotalEvents(results);
+ getRunSummary().setTotalEvents(totalEvents);
+
+ int nFiles = results.getResults().size();
+ getRunSummary().setTotalFiles(nFiles);
+
+ int prestartTimestamp = getPrestartTimestamp(results);
+ getRunSummary().setPrestartTimestamp(prestartTimestamp);
+
+ int goTimestamp = getGoTimestamp(results);
+ getRunSummary().setGoTimestamp(goTimestamp);
+
+ int endTimestamp = getEndTimestamp(results);
+ getRunSummary().setEndTimestamp(endTimestamp);
+
+ double triggerRate = calculateTriggerRate(prestartTimestamp, endTimestamp, totalEvents);
+ getRunSummary().setTriggerRate(triggerRate);
+ }
+
+ private DatasetResultSetModel findDatasets() {
+
+ LOGGER.info("finding EVIO datasets for run " + getRun() + " in " + this.folder + " at " + this.site + " ...");
+
+ DatasetResultSetModel results = datacatClient.searchForDatasets(
+ this.folder,
+ "current",
+ this.site,
+ "fileFormat eq 'EVIO' AND dataType eq 'RAW' AND runMin eq " + getRun(),
+ new String[] {"FILE"},
+ METADATA_FIELDS
+ );
+
+ LOGGER.info("found " + results.getResults().size() + " EVIO datasets for run " + getRun());
+
+ return results;
+ }
+
+ void setSite(String site) {
+ this.site = site;
+ }
+
+ void setDatacatClient(Client datacatClient) {
+ this.datacatClient = datacatClient;
+ }
+
+ void setFolder(String folder) {
+ this.folder = folder;
+ }
+
+ List<File> getFileList() {
+ return files;
+ }
+}
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatUtilities.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatUtilities.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/DatacatUtilities.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,29 @@
+package org.hps.run.database;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.srs.datacat.model.DatasetModel;
+import org.srs.datacat.model.DatasetResultSetModel;
+import org.srs.datacat.model.dataset.DatasetWithViewModel;
+
+final class DatacatUtilities {
+
+ private DatacatUtilities() {
+ throw new RuntimeException("Do not instantiate this class.");
+ }
+
+ static final List<File> toFileList(DatasetResultSetModel datasets) {
+ List<File> files = new ArrayList<File>();
+ for (DatasetModel dataset : datasets.getResults()) {
+ String resource =
+ ((DatasetWithViewModel) dataset).getViewInfo().getLocations().iterator().next().getResource();
+ if (resource.startsWith("/ss")) {
+ resource = "/cache" + resource;
+ }
+ files.add(new File(resource));
+ }
+ return files;
+ }
+}
Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java (original)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java Wed Feb 10 14:26:49 2016
@@ -16,7 +16,7 @@
*
* @param run the run number
*/
- public void deleteEpicsData(EpicsType epicsType, final int run);
+ public void deleteEpicsData(EpicsType epicsType, int run);
/**
* Get EPICS data by run.
@@ -34,5 +34,5 @@
*
* @param epicsDataList the list of EPICS data
*/
- void insertEpicsData(List<EpicsData> epicsDataList);
+ void insertEpicsData(List<EpicsData> epicsDataList, int run);
}
Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java (original)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java Wed Feb 10 14:26:49 2016
@@ -192,12 +192,14 @@
/**
* Insert a list of EPICS data into the database.
* <p>
- * The run number comes from the header information.
+ * By default, the run number from the header will be used, but it will be overridden
+ * if it does not match the <code>run</code> argument. (There are a few data files
+ * where the run in the EPICS header is occassionally wrong.)
*
* @param epicsDataList the list of EPICS data
*/
@Override
- public void insertEpicsData(final List<EpicsData> epicsDataList) {
+ public void insertEpicsData(final List<EpicsData> epicsDataList, int run) {
if (epicsDataList.isEmpty()) {
throw new IllegalArgumentException("The EPICS data list is empty.");
}
@@ -211,9 +213,11 @@
if (epicsHeader == null) {
throw new IllegalArgumentException("The EPICS data is missing a header.");
}
- insertHeaderStatement.setInt(1, epicsHeader.getRun());
+ insertHeaderStatement.setInt(1, run); /* Don't use run from bank as it is sometimes wrong! */
insertHeaderStatement.setInt(2, epicsHeader.getSequence());
insertHeaderStatement.setInt(3, epicsHeader.getTimestamp());
+ LOGGER.finer("creating EPICs record with run = " + run + " ; seq = "
+ + epicsHeader.getSequence() + "; ts = " + epicsHeader.getTimestamp());
final int rowsCreated = insertHeaderStatement.executeUpdate();
if (rowsCreated == 0) {
throw new SQLException("Creation of EPICS header record failed; no rows affected.");
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/LivetimeBuilder.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/LivetimeBuilder.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/LivetimeBuilder.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,58 @@
+package org.hps.run.database;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.hps.record.evio.EvioFileUtilities;
+import org.hps.record.scalers.ScalerData;
+import org.hps.record.scalers.ScalerUtilities;
+import org.hps.record.scalers.ScalersEvioProcessor;
+import org.hps.record.scalers.ScalerUtilities.LiveTimeIndex;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioException;
+import org.jlab.coda.jevio.EvioReader;
+
+public class LivetimeBuilder extends AbstractRunBuilder {
+
+ private List<File> files;
+ private ScalerData scalerData;
+
+ void setFiles(List<File> files) {
+ this.files = files;
+ }
+
+ void build() {
+ if (files == null) {
+ throw new RuntimeException("The list of files was never set.");
+ }
+ int fileIndex = files.size() - 1;
+ ScalersEvioProcessor processor = new ScalersEvioProcessor();
+ processor.setResetEveryEvent(false);
+ while (scalerData == null && fileIndex >= 0) {
+ File file = files.get(fileIndex);
+ try {
+ EvioReader reader = EvioFileUtilities.open(file, true);
+ EvioEvent evioEvent = reader.parseNextEvent();
+ while (evioEvent != null) {
+ processor.process(evioEvent);
+ evioEvent = reader.parseNextEvent();
+ }
+ if (processor.getCurrentScalerData() != null) {
+ scalerData = processor.getCurrentScalerData();
+ break;
+ }
+ fileIndex -= 1;
+ } catch (EvioException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ if (scalerData != null) {
+ double[] livetimes = ScalerUtilities.getLiveTimes(scalerData);
+ getRunSummary().setLivetimeClock(livetimes[LiveTimeIndex.CLOCK.ordinal()]);
+ getRunSummary().setLivetimeFcupTdc(livetimes[LiveTimeIndex.FCUP_TDC.ordinal()]);
+ getRunSummary().setLivetimeFcupTrg(livetimes[LiveTimeIndex.FCUP_TRG.ordinal()]);
+ }
+ }
+}
Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseBuilder.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseBuilder.java (original)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseBuilder.java Wed Feb 10 14:26:49 2016
@@ -6,6 +6,7 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -29,6 +30,7 @@
import org.hps.record.scalers.ScalersEvioProcessor;
import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition;
import org.hps.record.triggerbank.HeadBankData;
+import org.hps.record.triggerbank.TiTimeOffsetCalculator;
import org.hps.record.triggerbank.TiTimeOffsetEvioProcessor;
import org.hps.record.triggerbank.TriggerConfigData;
import org.hps.record.triggerbank.TriggerConfigData.Crate;
@@ -40,6 +42,7 @@
import org.srs.datacat.model.DatasetModel;
import org.srs.datacat.model.DatasetResultSetModel;
import org.srs.datacat.model.dataset.DatasetWithViewModel;
+import org.srs.datacat.shared.DatasetLocation;
/**
* Builds a complete {@link RunSummary} object from various data sources, including the data catalog and the run
@@ -143,7 +146,7 @@
* Default folder for file search.
*/
private String folder;
-
+
/**
* Reload state for the current run number for testing.
*/
@@ -208,15 +211,13 @@
private void findEvioDatasets() {
LOGGER.info("finding EVIO datasets for run " + getRun() + " in folder " + this.folder + " at site " + this.site);
-
+
DatasetResultSetModel results = datacatClient.searchForDatasets(
this.folder,
"current",
this.site,
"fileFormat eq 'EVIO' AND dataType eq 'RAW' AND runMin eq " + getRun(),
null,
- null,
- null,
null
);
@@ -262,7 +263,7 @@
// Insert the EPICS data.
if (epicsData != null && !epicsData.isEmpty()) {
LOGGER.info("inserting EPICS data");
- runFactory.getEpicsDataDao().insertEpicsData(epicsData);
+ runFactory.getEpicsDataDao().insertEpicsData(epicsData, getRun());
} else {
LOGGER.warning("no EPICS data to insert");
}
@@ -663,12 +664,21 @@
EvioReader reader = null;
Integer endTimestamp = null;
try {
- reader = EvioFileUtilities.open(lastEvioFile, true);
- EvioEvent evioEvent = reader.parseNextEvent();
- while (evioEvent != null) {
+ reader = EvioFileUtilities.open(lastEvioFile, true);
+ while (true) {
+ if (reader.getNumEventsRemaining() == 0) {
+ break;
+ }
+ EvioEvent evioEvent = null;
+ try {
+ evioEvent = reader.parseNextEvent();
+ } catch (Exception e) {
+ LOGGER.severe("Error parsing EVIO event; skipping to next event.");
+ continue;
+ }
if (EventTagConstant.END.matches(evioEvent)) {
endTimestamp = EvioEventUtilities.getControlEventData(evioEvent)[0];
- LOGGER.fine("found END timestamp " + endTimestamp);
+ LOGGER.fine("found END timestamp " + endTimestamp + " in event " + evioEvent.getEventNumber());
break;
}
BaseStructure headBank = headBankDefinition.findBank(evioEvent);
@@ -677,10 +687,9 @@
endTimestamp = headBank.getIntData()[0];
}
}
- evioEvent = reader.parseNextEvent();
- }
- } catch (IOException | EvioException e) {
- throw new RuntimeException("Error reading first EVIO file.", e);
+ }
+ } catch (IOException | EvioException e2) {
+ throw new RuntimeException("Error getting END timestamp.", e2);
} finally {
if (reader != null) {
try {
@@ -690,7 +699,9 @@
}
}
}
- runSummary.setEndTimestamp(endTimestamp);
+ if (endTimestamp != null) {
+ runSummary.setEndTimestamp(endTimestamp);
+ }
LOGGER.fine("end timestamp was set to " + endTimestamp);
}
@@ -816,16 +827,15 @@
startTimestamp = runSummary.getGoTimestamp();
} else if (runSummary.getPrestartTimestamp() != null) {
startTimestamp = runSummary.getPrestartTimestamp();
- } else {
- LOGGER.warning("Could not get starting timestamp for trigger rate calculation.");
- }
- if (runSummary.getEndTimestamp() != null && startTimestamp != null) {
+ }
+ Integer endTimestamp = runSummary.getEndTimestamp();
+ if (endTimestamp!= null && startTimestamp != null && runSummary.getTotalEvents() > 0) {
double triggerRate = ((double) runSummary.getTotalEvents() /
((double) runSummary.getEndTimestamp() - (double) runSummary.getGoTimestamp()));
runSummary.setTriggerRate(triggerRate);
LOGGER.info("trigger rate set to " + runSummary.getTriggerRate());
} else {
- LOGGER.warning("Skipped trigger rate calculation because a timestamp is missing.");
+ LOGGER.warning("Skipped trigger rate calculation due to missing data.");
}
}
}
Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java (original)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java Wed Feb 10 14:26:49 2016
@@ -45,4 +45,11 @@
* @return <code>true</code> if <code>run</code> exists in the database
*/
boolean runSummaryExists(int run);
+
+ /**
+ * Update a run summary that already exists.
+ *
+ * @param runSummary the run summary to update
+ */
+ void updateRunSummary(RunSummary runSummary);
}
Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java (original)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java Wed Feb 10 14:26:49 2016
@@ -27,6 +27,12 @@
+ " go_timestamp, end_timestamp, trigger_rate, trigger_config_name, ti_time_offset,"
+ " livetime_clock, livetime_fcup_tdc, livetime_fcup_trg, target, notes, created, updated)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
+
+ private static final String UPDATE = "UPDATE run_summaries SET nevents = ?, nfiles = ?, prestart_timestamp = ?,"
+ + " go_timestamp = ?, end_timestamp = ?, trigger_rate = ?, trigger_config_name = ?, ti_time_offset = ?,"
+ + " livetime_clock = ?, livetime_fcup_tdc = ?, livetime_fcup_trg = ?, target = ?, notes = ?, updated = NOW()"
+ + " WHERE run = ?";
+
/**
* Select record by run number.
@@ -196,6 +202,41 @@
}
}
}
+
+ @Override
+ public void updateRunSummary(RunSummary runSummary) {
+ PreparedStatement preparedStatement = null;
+ try {
+ preparedStatement = connection.prepareStatement(UPDATE);
+ preparedStatement.setLong(1, runSummary.getTotalEvents());
+ preparedStatement.setInt(2, runSummary.getTotalFiles());
+ preparedStatement.setObject(3, runSummary.getPrestartTimestamp());
+ preparedStatement.setObject(4, runSummary.getGoTimestamp());
+ preparedStatement.setObject(5, runSummary.getEndTimestamp());
+ preparedStatement.setObject(6, runSummary.getTriggerRate());
+ preparedStatement.setObject(7, runSummary.getTriggerConfigName());
+ preparedStatement.setObject(8, runSummary.getTiTimeOffset());
+ preparedStatement.setObject(9, runSummary.getLivetimeClock());
+ preparedStatement.setObject(10, runSummary.getLivetimeFcupTdc());
+ preparedStatement.setObject(11, runSummary.getLivetimeFcupTrg());
+ preparedStatement.setObject(12, runSummary.getTarget());
+ preparedStatement.setObject(13, runSummary.getNotes());
+ preparedStatement.setInt(14, runSummary.getRun());
+ LOGGER.fine(preparedStatement.toString());
+ preparedStatement.executeUpdate();
+ } catch (final SQLException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (preparedStatement != null) {
+ try {
+ preparedStatement.close();
+ } catch (final SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
/**
* Return <code>true</code> if a run summary exists in the database for the run number.
Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java (original)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java Wed Feb 10 14:26:49 2016
@@ -75,7 +75,7 @@
private Integer totalFiles;
/**
- * Get the name of the trigger config file.
+ * Name of the trigger config file.
*/
private String triggerConfigName;
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SpreadsheetBuilder.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SpreadsheetBuilder.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SpreadsheetBuilder.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,74 @@
+package org.hps.run.database;
+
+import java.io.File;
+import java.util.logging.Logger;
+
+import org.hps.conditions.run.RunSpreadsheet;
+import org.hps.conditions.run.RunSpreadsheet.RunData;
+
+/**
+ * Builds a complete {@link RunSummary} object from various data sources, including the data catalog and the run
+ * spreadsheet, so that it is ready to be inserted into the run database using the DAO interfaces. This class also
+ * extracts EPICS data, scaler data, trigger config and SVT config information from all of the EVIO files in a run.
+ * <p>
+ * The setters and some other methods follow the builder pattern and so can be chained by the caller.
+ *
+ * @author Jeremy McCormick, SLAC
+ * @see RunSummary
+ * @see RunSummaryImpl
+ */
+final class SpreadsheetBuilder extends AbstractRunBuilder {
+
+ private static final Logger LOGGER = Logger.getLogger(SpreadsheetBuilder.class.getPackage().getName());
+
+ private File spreadsheetFile;
+
+ void setSpreadsheetFile(File spreadsheetFile) {
+ this.spreadsheetFile = spreadsheetFile;
+ }
+
+ /**
+ * Update the current run summary from information in the run spreadsheet.
+ *
+ * @param spreadsheetFile file object pointing to the run spreadsheet (CSV format)
+ * @return this object
+ */
+ @Override
+ void build() {
+ if (this.spreadsheetFile == null) {
+ throw new IllegalStateException("The spreadsheet file was never set.");
+ }
+ if (getRunSummary() == null) {
+ throw new IllegalStateException("The run summary was never set.");
+ }
+ LOGGER.fine("updating from spreadsheet file " + spreadsheetFile.getPath());
+ RunSpreadsheet runSpreadsheet = new RunSpreadsheet(spreadsheetFile);
+ RunData data = runSpreadsheet.getRunMap().get(getRunSummary().getRun());
+ if (data != null) {
+ LOGGER.info("found run data ..." + '\n' + data.getRecord());
+
+ // Trigger config name.
+ String triggerConfigName = data.getRecord().get("trigger_config");
+ if (triggerConfigName != null) {
+ getRunSummary().setTriggerConfigName(triggerConfigName);
+ LOGGER.info("set trigger config name <" + getRunSummary().getTriggerConfigName() + "> from spreadsheet");
+ }
+
+ // Notes.
+ String notes = data.getRecord().get("notes");
+ if (notes != null) {
+ getRunSummary().setNotes(notes);
+ LOGGER.info("set notes <" + getRunSummary().getNotes() + "> from spreadsheet");
+ }
+
+ // Target.
+ String target = data.getRecord().get("target");
+ if (target != null) {
+ getRunSummary().setTarget(target);
+ LOGGER.info("set target <" + getRunSummary().getTarget() + "> from spreadsheet");
+ }
+ } else {
+ LOGGER.warning("No record for this run was found in spreadsheet.");
+ }
+ }
+}
Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigBuilder.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigBuilder.java (added)
+++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigBuilder.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,50 @@
+package org.hps.run.database;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.hps.record.daqconfig.TriggerConfigEvioProcessor;
+import org.hps.record.evio.EvioFileUtilities;
+import org.hps.record.triggerbank.TriggerConfigData;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioException;
+import org.jlab.coda.jevio.EvioReader;
+
+public class TriggerConfigBuilder extends AbstractRunBuilder {
+
+ private TriggerConfigData triggerConfig;
+ private List<File> files = null;
+
+ void setFiles(List<File> files) {
+ this.files = files;
+ }
+
+ void build() {
+ int fileIndex = files.size() - 1;
+ TriggerConfigEvioProcessor processor = new TriggerConfigEvioProcessor();
+ while (triggerConfig == null && fileIndex >= 0) {
+ File file = files.get(fileIndex);
+ try {
+ EvioReader reader = EvioFileUtilities.open(file, true);
+ EvioEvent evioEvent = reader.parseNextEvent();
+ while (evioEvent != null) {
+ processor.process(evioEvent);
+ if (processor.getTriggerConfigData() != null
+ && processor.getTriggerConfigData().isValid()) {
+ triggerConfig = processor.getTriggerConfigData();
+ break;
+ }
+ evioEvent = reader.parseNextEvent();
+ }
+ fileIndex -= 1;
+ } catch (EvioException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ TriggerConfigData getTriggerConfigData() {
+ return triggerConfig;
+ }
+}
Added: java/branches/jeremy-dev/run-database/src/test/java/org/hps/run/database/RunBuilderTest.java
=============================================================================
--- java/branches/jeremy-dev/run-database/src/test/java/org/hps/run/database/RunBuilderTest.java (added)
+++ java/branches/jeremy-dev/run-database/src/test/java/org/hps/run/database/RunBuilderTest.java Wed Feb 10 14:26:49 2016
@@ -0,0 +1,63 @@
+package org.hps.run.database;
+
+import java.io.File;
+import java.sql.Connection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.database.ConnectionParameters;
+import org.srs.datacat.client.ClientBuilder;
+
+public class RunBuilderTest extends TestCase {
+
+ private static final int RUN = 5403;
+ private static String DATACAT_URL = "http://localhost:8080/datacat-v0.5-SNAPSHOT/r";
+ private static String SPREADSHEET = "/work/hps/rundb/HPS_Runs_2015_Sheet1.csv";
+ private static String FOLDER = "/HPS/test";
+ private static String SITE = "SLAC";
+
+ private static final ConnectionParameters CONNECTION_PARAMETERS =
+ new ConnectionParameters("root", "derp", "hps_run_db", "localhost");
+
+ public void testRunBuilder() throws Exception {
+
+ RunSummaryImpl runSummary = new RunSummaryImpl(RUN);
+
+ // datacat
+ DatacatBuilder datacatBuilder = new DatacatBuilder();
+ datacatBuilder.setDatacatClient(new ClientBuilder().setUrl(DATACAT_URL).build());
+ datacatBuilder.setFolder(FOLDER);
+ datacatBuilder.setSite(SITE);
+ datacatBuilder.setRunSummary(runSummary);
+ datacatBuilder.build();
+
+ List<File> files = datacatBuilder.getFileList();
+
+ // livetime measurements
+ LivetimeBuilder livetimeBuilder = new LivetimeBuilder();
+ livetimeBuilder.setRunSummary(runSummary);
+ livetimeBuilder.setFiles(files);
+ livetimeBuilder.build();
+
+ // trigger config
+ TriggerConfigBuilder configBuilder = new TriggerConfigBuilder();
+ configBuilder.setFiles(files);
+ configBuilder.build();
+
+ // run spreadsheet
+ SpreadsheetBuilder spreadsheetBuilder = new SpreadsheetBuilder();
+ spreadsheetBuilder.setSpreadsheetFile(new File(SPREADSHEET));
+ spreadsheetBuilder.setRunSummary(datacatBuilder.getRunSummary());
+ spreadsheetBuilder.build();
+
+ // database updater
+ Connection connection = CONNECTION_PARAMETERS.createConnection();
+ DatabaseUpdater updater = new DatabaseUpdater(connection);
+ updater.setRunSummary(runSummary);
+ System.out.println("built run summary ...");
+ System.out.println(runSummary);
+ //updater.setTriggerConfigData(configBuilder.getTriggerConfigData());
+ //updater.update();
+ }
+}
|