Author: [log in to unmask] Date: Wed Dec 2 20:58:15 2015 New Revision: 4005 Log: More dev work on run database; trigger config moved to separate table. Added: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/util/ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/util/FileUtilities.java - copied, changed from r3998, java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfig.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDao.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDaoImpl.java Removed: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioReconMetadataReader.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/PathFilter.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigEvioProcessor.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/svt/SvtConfigEvioProcessor.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsType.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/RunDatabaseCommandLine.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseDaoFactory.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunManager.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummary.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 java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDao.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDaoImpl.java java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/package-info.java Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java Wed Dec 2 20:58:15 2015 @@ -4,6 +4,8 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; + +import org.hps.record.util.FileUtilities; /** * This is a metadata reader for ROOT DQM files. @@ -22,7 +24,7 @@ @Override public Map<String, Object> getMetadata(final File file) throws IOException { final Map<String, Object> metadata = new HashMap<String, Object>(); - final int run = CrawlerFileUtilities.getRunFromFileName(file); + final int run = FileUtilities.getRunFromFileName(file); metadata.put("runMin", run); metadata.put("runMax", run); return metadata; Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java Wed Dec 2 20:58:15 2015 @@ -24,6 +24,7 @@ import org.hps.datacat.client.DatacatClientFactory; import org.hps.datacat.client.DatasetFileFormat; import org.hps.datacat.client.DatasetSite; +import org.hps.record.util.FileUtilities; /** * Command line file crawler for populating the data catalog. @@ -266,7 +267,6 @@ for (String arg : cl.getArgList()) { config.addPath(arg); } - } } catch (final ParseException e) { @@ -360,8 +360,8 @@ // Use file on JLAB cache disk if necessary. File actualFile = file; - if (CrawlerFileUtilities.isMssFile(file)) { - actualFile = CrawlerFileUtilities.getCachedFile(file); + if (FileUtilities.isMssFile(file)) { + actualFile = FileUtilities.getCachedFile(file); LOGGER.info("using cached file " + actualFile.getPath()); } @@ -373,7 +373,7 @@ } else { // Assign run number even if metadata is not enabled. metadata = new HashMap<String, Object>(); - int run = CrawlerFileUtilities.getRunFromFileName(file); + int run = FileUtilities.getRunFromFileName(file); metadata.put("runMin", run); metadata.put("runMax", run); metadata.put("scanStatus", "UNSCANNED"); Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioReconMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioReconMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioReconMetadataReader.java Wed Dec 2 20:58:15 2015 @@ -90,7 +90,6 @@ metadata.put("DETECTOR", detectorName); metadata.put("COLLECTIONS", sb.toString()); - return metadata; } } Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/PathFilter.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/PathFilter.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/PathFilter.java Wed Dec 2 20:58:15 2015 @@ -32,8 +32,9 @@ @Override public boolean accept(File pathname) { for (String acceptPath : paths) { - if (pathname.getPath().equals(acceptPath)) { - LOGGER.info("accepted path " + pathname); + // FIXME: Use endsWith, equals or contains here???? + if (pathname.getPath().endsWith(acceptPath)) { + LOGGER.info("accepted path " + pathname); return true; } } Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java Wed Dec 2 20:58:15 2015 @@ -4,6 +4,8 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; + +import org.hps.record.util.FileUtilities; /** * This is a metadata reader for ROOT DQM files. @@ -22,7 +24,7 @@ @Override public Map<String, Object> getMetadata(final File file) throws IOException { final Map<String, Object> metadata = new HashMap<String, Object>(); - final int run = CrawlerFileUtilities.getRunFromFileName(file); + final int run = FileUtilities.getRunFromFileName(file); metadata.put("runMin", run); metadata.put("runMax", run); return metadata; Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java Wed Dec 2 20:58:15 2015 @@ -102,7 +102,7 @@ * @throws NoSuchRecordException if there are no records available from the queue */ @Override - public void next() throws IOException, NoSuchRecordException { + public synchronized void next() throws IOException, NoSuchRecordException { try { if (this.timeOutMillis > 0L) { // Poll the queue for the next record until timeout is exceeded. Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigEvioProcessor.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigEvioProcessor.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigEvioProcessor.java Wed Dec 2 20:58:15 2015 @@ -15,7 +15,7 @@ * Copied and modified from code in {@link org.hps.evio.TriggerConfigEvioReader} to extract DAQ config without * needing an output LCSim event. * <p> - * Only the last valid DAQ config object will be saved. + * Only the last valid DAQ config object is available once the job is finished. * * @author Jeremy McCormick, SLAC */ @@ -28,6 +28,10 @@ private Map<Integer, String> stringData = new HashMap<Integer, String>(); private Integer run = null; + + private int timestamp; + + private int currentTimestamp; /** * Process EVIO events to extract DAQ config data. @@ -43,10 +47,19 @@ } catch (NullPointerException e) { } } - + // 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) { + currentTimestamp = headBank.getIntData()[3]; + LOGGER.finest("set timestamp " + currentTimestamp + " from head bank"); + } + } + // Parse config data from the EVIO banks. EvioDAQParser evioParser = parseEvioData(evioEvent); @@ -55,7 +68,9 @@ // Set the current DAQ config object. ConfigurationManager.updateConfiguration(evioParser); daqConfig = ConfigurationManager.getInstance(); + timestamp = currentTimestamp; } + } } catch (Exception e) { LOGGER.log(Level.WARNING, "Error parsing DAQ config from EVIO.", e); @@ -119,11 +134,20 @@ } /** - * Get a map of bank number to its string data for the current config. + * Get a map of bank number to string data for the current config. * * @return a map of bank to trigger config data */ public Map<Integer, String> getTriggerConfigData() { return this.stringData; } + + /** + * Get the timestamp associated with the config. + * + * @return the timestamp + */ + public int getTimestamp() { + return timestamp; + } } Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/svt/SvtConfigEvioProcessor.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/svt/SvtConfigEvioProcessor.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/svt/SvtConfigEvioProcessor.java Wed Dec 2 20:58:15 2015 @@ -34,9 +34,9 @@ BaseStructure headBank = EvioEventUtilities.getHeadBank(evioEvent); int configBanks = 0; if (headBank != null) { - if (headBank.getIntData()[0] != 0) { - timestamp = headBank.getIntData()[0]; - LOGGER.info("set timestamp " + timestamp); + if (headBank.getIntData()[3] != 0) { + timestamp = headBank.getIntData()[3]; + //LOGGER.finest("set timestamp " + timestamp + " from head bank"); } } for (BaseStructure bank : evioEvent.getChildrenList()) { @@ -75,8 +75,8 @@ } } if (config != null) { - LOGGER.info("Adding SVT config " + evioEvent.getEventNumber() + " with " + configBanks - + " banks from event " + evioEvent.getEventNumber()); + LOGGER.info("Adding SVT config " + evioEvent.getEventNumber() + " with " + configBanks + + " banks and timestamp " + timestamp + " from event " + evioEvent.getEventNumber()); this.configs.add(config); } } Copied: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/util/FileUtilities.java (from r3998, java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java) ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/util/FileUtilities.java Wed Dec 2 20:58:15 2015 @@ -1,4 +1,4 @@ -package org.hps.crawler; +package org.hps.record.util; import java.io.File; @@ -7,15 +7,15 @@ * * @author Jeremy McCormick, SLAC */ -final class CrawlerFileUtilities { - +public final class FileUtilities { + /** * Get run number from file name assuming it looks like "hps_001234". * * @param file the file * @return the run number */ - static int getRunFromFileName(final File file) { + public static int getRunFromFileName(final File file) { final String name = file.getName(); return Integer.parseInt(name.substring(4, 10)); } @@ -60,4 +60,7 @@ public static boolean isMssFile(final File file) { return file.getPath().startsWith("/mss"); } + + private FileUtilities() { + } } Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsType.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsType.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/EpicsType.java Wed Dec 2 20:58:15 2015 @@ -13,11 +13,11 @@ /** * 20S EPICS data. */ - EPICS_20s(10), + EPICS_20s(20), /** * 2S EPICS data. */ - EPICS_2s(1); + EPICS_2s(2); /** * Get the type from an int. 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 Dec 2 20:58:15 2015 @@ -3,6 +3,7 @@ import java.io.File; import java.io.IOException; import java.sql.Connection; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; @@ -18,10 +19,9 @@ import org.hps.conditions.run.RunSpreadsheet; import org.hps.conditions.run.RunSpreadsheet.RunData; import org.hps.datacat.client.DatacatClient; -import org.hps.datacat.client.DatacatClientFactory; import org.hps.datacat.client.Dataset; -import org.hps.datacat.client.DatasetSite; import org.hps.record.AbstractRecordProcessor; +import org.hps.record.daqconfig.DAQConfig; import org.hps.record.daqconfig.DAQConfigEvioProcessor; import org.hps.record.epics.EpicsData; import org.hps.record.epics.EpicsRunProcessor; @@ -39,6 +39,7 @@ import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition; import org.hps.record.triggerbank.HeadBankData; import org.hps.record.triggerbank.TiTimeOffsetEvioProcessor; +import org.hps.record.util.FileUtilities; import org.jlab.coda.jevio.BaseStructure; import org.jlab.coda.jevio.EvioEvent; import org.jlab.coda.jevio.EvioException; @@ -48,7 +49,7 @@ /** * 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 and scaler records from the EVIO data for insertion into run database tables. + * extracts EPICS data, scaler data, trigger config and SVT config information. * <p> * The setters and some other methods follow the builder pattern and so can be chained by the caller. * @@ -97,6 +98,11 @@ * List of EVIO files. */ private List<File> evioFiles; + + /** + * List of EVIO files with cache path/ + */ + private List<File> cacheFiles; /** * Allow replacement of information in the database (off by default). @@ -127,7 +133,45 @@ * List of SVT configuration bank data. */ private List<SvtConfigData> svtConfigs; - + + /** + * The trigger config object. + */ + private TriggerConfig config; + + /** + * Reload run data after insert for debugging. + */ + private boolean reload; + + /** + * Reload state for the current run number (used for testing after a database insert). + */ + static void reload(Connection connection, int run) { + + RunManager runManager = new RunManager(connection); + runManager.setRun(run); + + RunSummary runSummary = runManager.getRunSummary(); + + LOGGER.info("loaded run summary ..." + '\n' + runSummary); + + LOGGER.info("loaded " + runManager.getEpicsData(EpicsType.EPICS_2s).size() + " EPICS 2S records"); + LOGGER.info("loaded " + runManager.getEpicsData(EpicsType.EPICS_20s).size() + " EPICS 20S records"); + + List<ScalerData> scalerData = runManager.getScalerData(); + LOGGER.info("loaded " + scalerData.size() + " scaler records"); + + List<SvtConfigData> svtConfigs = runManager.getSvtConfigData(); + LOGGER.info("loaded " + svtConfigs.size() + " SVT configurations"); + + LOGGER.info("printing DAQ config ..."); + DAQConfig daqConfig = runManager.getDAQConfig(); + daqConfig.printConfig(); + + runManager.closeConnection(); + } + /** * Create an empty run summary. * @@ -163,16 +207,26 @@ throw new IllegalStateException("No EVIO datasets for run " + getRun() + " were found in the data catalog."); } - // Map file to dataset. + // Map files to datasets. for (final Dataset dataset : datasets) { evioDatasets.put(new File(dataset.getLocations().get(0).getResource()), dataset); } - // Create the list of EVIO files. + // Create the list of sorted EVIO files. evioFiles = new ArrayList<File>(); evioFiles.addAll(evioDatasets.keySet()); EvioFileUtilities.sortBySequence(evioFiles); + // Create a list of files with cache paths in case running at JLAB. + cacheFiles = new ArrayList<File>(); + for (File file : evioFiles) { + if (FileUtilities.isMssFile(file)) { + cacheFiles.add(FileUtilities.getCachedFile(file)); + } else { + cacheFiles.add(file); + } + } + LOGGER.info("found " + evioFiles.size() + " EVIO file(s) for run " + runSummary.getRun()); } @@ -184,19 +238,7 @@ int getRun() { return runSummary.getRun(); } - - /** - * Initialize the datacat client. - */ - private void initializeDatacat() { - - LOGGER.info("initializing data catalog client"); - - // DEBUG: use dev datacat server; prod should use default JLAB connection - datacatClient = new DatacatClientFactory().createClient("http://localhost:8080/datacat-v0.4-SNAPSHOT/r", - DatasetSite.SLAC, "HPS"); - } - + /** * Insert the run data into the database using the current connection. */ @@ -235,49 +277,17 @@ LOGGER.warning("no SVT config to insert"); } - try { - connection.close(); - } catch (Exception e) { - LOGGER.log(Level.WARNING, e.getMessage(), e); - } - + // Insert trigger config data. + if (this.config != null) { + LOGGER.info("inserting trigger config"); + runFactory.createTriggerConfigDao().insertTriggerConfig(config, getRun()); + } else { + LOGGER.warning("no trigger config to inesrt"); + } + LOGGER.info("done inserting run " + getRun()); } - - /** - * Reload state for the current run number into this object (used for testing after a database insert). - * - * @param load <code>true</code> if this method should be executed (skipped if <code>false</code>) - * @return this object - */ - RunDatabaseBuilder load(boolean load) { - if (load) { - RunManager runManager = new RunManager(connectionParameters.createConnection()); - runManager.setRun(getRun()); - - this.runSummary = RunSummaryImpl.class.cast(runManager.getRunSummary()); - - LOGGER.info("loaded run summary ..." + '\n' + runSummary); - - epicsData = new ArrayList<EpicsData>(); - epicsData.addAll(runManager.getEpicsData(EpicsType.EPICS_2s)); - epicsData.addAll(runManager.getEpicsData(EpicsType.EPICS_20s)); - LOGGER.info("loaded " + epicsData.size() + " EPICS records"); - - scalerData = runManager.getScalerData(); - LOGGER.info("loaded " + scalerData.size() + " scaler records"); - - svtConfigs = runManager.getSvtConfigData(); - LOGGER.info("loaded " + svtConfigs.size() + " SVT configurations"); - - runManager.closeConnection(); - } else { - LOGGER.info("load is skipped"); - } - - return this; - } - + /** * Print summary information to the log. */ @@ -304,9 +314,9 @@ } else { LOGGER.info("no SVT config"); } - if (runSummary.getTriggerConfigData() != null) { - for (Entry<Integer, String> entry : runSummary.getTriggerConfigData().entrySet()) { - LOGGER.info("trigger config data " + entry.getKey() + " ..." + entry.getValue()); + if (config != null) { + for (Entry<Integer, String> entry : config.getData().entrySet()) { + LOGGER.info("trigger config data " + entry.getKey() + " with timestamp " + config.getTimestamp() + " ..." + entry.getValue()); } } else { LOGGER.info("no trigger config"); @@ -328,7 +338,7 @@ throw new IllegalStateException("The detector name was not set."); } - // Initialize the conditions system. + // Initialize the conditions system because the DAQ config processor needs it. try { DatabaseConditionsManager dbManager = DatabaseConditionsManager.getInstance(); DatabaseConditionsManager.getInstance().setDetector(detectorName, runSummary.getRun()); @@ -344,8 +354,12 @@ ScalersEvioProcessor scalersProcessor = new ScalersEvioProcessor(); scalersProcessor.setResetEveryEvent(false); processors.add(scalersProcessor); - - // Processor for calculating TI time offset. + + // Processor for getting EPICS data. + EpicsRunProcessor epicsProcessor = new EpicsRunProcessor(); + processors.add(epicsProcessor); + + // Processor for calculating the TI time offset. TiTimeOffsetEvioProcessor tiProcessor = new TiTimeOffsetEvioProcessor(); processors.add(tiProcessor); @@ -357,14 +371,10 @@ SvtConfigEvioProcessor svtProcessor = new SvtConfigEvioProcessor(); processors.add(svtProcessor); - // Processor for getting EPICS data. - EpicsRunProcessor epicsProcessor = new EpicsRunProcessor(); - processors.add(epicsProcessor); - // Run the job using the EVIO loop. EvioLoop loop = new EvioLoop(); loop.addProcessors(processors); - EvioFileSource source = new EvioFileSource(evioFiles); + EvioFileSource source = new EvioFileSource(cacheFiles); loop.setEvioFileSource(source); loop.loop(-1); @@ -374,13 +384,6 @@ // Set TI time offset. runSummary.setTiTimeOffset(tiProcessor.getTiTimeOffset()); - // Set DAQ config object. - runSummary.setDAQConfig(daqProcessor.getDAQConfig()); - - // Set map of crate number to string trigger config data. - runSummary.setTriggerConfigData(daqProcessor.getTriggerConfigData()); - LOGGER.info("found " + daqProcessor.getTriggerConfigData().size() + " valid SVT config events"); - // Set EPICS data list. epicsData = epicsProcessor.getEpicsData(); @@ -389,6 +392,11 @@ // Set SVT config data strings. svtConfigs = svtProcessor.getSvtConfigs(); + + // Set trigger config object. + if (!daqProcessor.getTriggerConfigData().isEmpty()) { + config = new TriggerConfig(daqProcessor.getTriggerConfigData(), daqProcessor.getTimestamp()); + } LOGGER.info("done processing EVIO files"); } @@ -406,9 +414,10 @@ throw new IllegalStateException("The run summary was never created."); } - // Setup datacat client. - initializeDatacat(); - + if (this.datacatClient == null) { + throw new IllegalStateException("The datacat client was not set."); + } + // Find EVIO datasets in the datacat. findEvioDatasets(); @@ -447,11 +456,17 @@ if (!dryRun) { // Update the database. updateDatabase(); + + if (reload) { + LOGGER.info("reloading data for run " + getRun() + " ..."); + reload(connectionParameters.createConnection(), getRun()); + } + } else { // Dry run so database is not updated. LOGGER.info("Dry run enabled so no updates were performed."); } - + return this; } @@ -463,6 +478,17 @@ */ RunDatabaseBuilder setConnectionParameters(ConnectionParameters connectionParameters) { this.connectionParameters = connectionParameters; + return this; + } + + /** + * Set the datacat client for querying the data catalog. + * + * @param datacatClient the datacat client + * @return this object + */ + RunDatabaseBuilder setDatacatClient(DatacatClient datacatClient) { + this.datacatClient = datacatClient; return this; } @@ -487,6 +513,17 @@ RunDatabaseBuilder setDryRun(boolean dryRun) { this.dryRun = dryRun; LOGGER.config("dryRun = " + this.dryRun); + return this; + } + + /** + * Set whether data should be reloaded at end (as debug check). + * + * @param reload <code>true</code> to reload data at end of job + * @return this object + */ + RunDatabaseBuilder setReload(boolean reload) { + this.reload = reload; return this; } @@ -539,27 +576,46 @@ LOGGER.fine("updating the run database"); // Initialize the run manager. - RunManager runManager = new RunManager(connectionParameters.createConnection()); + Connection connection = connectionParameters.createConnection(); + RunManager runManager = new RunManager(connection); runManager.setRun(runSummary.getRun()); - - // Does run exist? - if (runManager.runExists()) { + + // Turn off autocommit to start transaction. + try { + connection.setAutoCommit(false); + + // Does run exist? + if (runManager.runExists()) { - LOGGER.info("run already exists"); + LOGGER.info("run already exists"); - // If replacement is not enabled and run exists, then this is a fatal exception. - if (!replace) { - throw new RuntimeException("Run already exists (use -x option to enable replacement)."); - } - - // Delete the run so insert statements can be used to rebuild it. - LOGGER.info("deleting existing run"); - runManager.deleteRun(); - } - - // Insert the run data into the database. - LOGGER.info("inserting the run data"); - insertRun(runManager.getConnection()); + // If replacement is not enabled and run exists, then this is a fatal exception. + if (!replace) { + throw new RuntimeException("Run already exists (use -x option to enable replacement)."); + } + + // Delete the run so insert statements can be used to rebuild it. + LOGGER.info("deleting existing run"); + runManager.deleteRun(); + } + + // Insert the run data into the database. + LOGGER.info("inserting the run data"); + insertRun(connection); + + // Commit the transaction. + LOGGER.info("committing to run db ..."); + connection.commit(); + LOGGER.info("done committing"); + + } catch (Exception e1) { + try { + LOGGER.log(Level.SEVERE, "Error occurred updating database; rolling back transaction...", e1); + connection.rollback(); + } catch (SQLException e2) { + throw new RuntimeException(e2); + } + } // Close the database connection. runManager.closeConnection(); @@ -571,7 +627,7 @@ private void updateEndTimestamp() { LOGGER.info("updating end timestamp"); IntBankDefinition headBankDefinition = new IntBankDefinition(HeadBankData.class, new int[] {0x2e, 0xe10f}); - File lastEvioFile = evioFiles.get(evioFiles.size() - 1); + File lastEvioFile = cacheFiles.get(cacheFiles.size() - 1); EvioReader reader = null; Integer endTimestamp = null; try { @@ -618,16 +674,22 @@ RunData data = runSpreadsheet.getRunMap().get(runSummary.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) { runSummary.setTriggerConfigName(triggerConfigName); LOGGER.info("set trigger config name <" + runSummary.getTriggerConfigName() + "> from spreadsheet"); } + + // Notes. String notes = data.getRecord().get("notes"); if (notes != null) { runSummary.setNotes(notes); LOGGER.info("set notes <" + runSummary.getNotes() + "> from spreadsheet"); } + + // Target. String target = data.getRecord().get("target"); if (target != null) { runSummary.setTarget(target); @@ -653,9 +715,9 @@ runSummary.setLivetimeClock(livetimes[LiveTimeIndex.CLOCK.ordinal()]); runSummary.setLivetimeFcupTdc(livetimes[LiveTimeIndex.FCUP_TDC.ordinal()]); runSummary.setLivetimeFcupTrg(livetimes[LiveTimeIndex.FCUP_TRG.ordinal()]); - LOGGER.info("clock livetime set to " + runSummary.getLivetimeClock()); - LOGGER.info("fcup tdc livetime set to " + runSummary.getLivetimeFcupTdc()); - LOGGER.info("fcup trg livetime set to " + runSummary.getLivetimeFcupTrg()); + LOGGER.info("clock livetime = " + runSummary.getLivetimeClock()); + LOGGER.info("fcup tdc livetime = " + runSummary.getLivetimeFcupTdc()); + LOGGER.info("fcup trg livetime = " + runSummary.getLivetimeFcupTrg()); } /** @@ -663,7 +725,7 @@ */ private void updateStartTimestamps() { LOGGER.fine("updating start timestamps"); - File firstEvioFile = evioFiles.get(0); + File firstEvioFile = cacheFiles.get(0); int sequence = EvioFileUtilities.getSequenceFromName(firstEvioFile); if (sequence != 0) { LOGGER.warning("first file does not have sequence 0"); Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java Wed Dec 2 20:58:15 2015 @@ -8,6 +8,10 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.hps.conditions.database.ConnectionParameters; +import org.hps.datacat.client.DatacatClient; +import org.hps.datacat.client.DatacatClientFactory; +import org.hps.datacat.client.DatacatConstants; +import org.hps.datacat.client.DatasetSite; /** * Command line tool for inserting records into the run database. @@ -19,7 +23,7 @@ /** * Command line options for the crawler. */ - private static final Options OPTIONS = new Options(); + private static final Options OPTIONS = new Options(); /** * Statically define the command options. @@ -28,12 +32,15 @@ OPTIONS.addOption("h", "help", false, "print help and exit (overrides all other arguments)"); OPTIONS.addOption("r", "run", true, "run to update"); OPTIONS.addOption("p", "connection-properties", true, "database connection properties file (required)"); - OPTIONS.addOption("D", "dry-run", false, "dry run which will not update the database"); + OPTIONS.addOption("Y", "dry-run", false, "dry run which will not update the database"); OPTIONS.addOption("x", "replace", false, "allow deleting and replacing an existing run"); OPTIONS.addOption("s", "spreadsheet", true, "path to run database spreadsheet (CSV format)"); - OPTIONS.addOption("d", "detector", true, "conditions system detector name"); + OPTIONS.addOption("d", "detector", true, "conditions system detector name"); OPTIONS.addOption("N", "no-evio-processing", false, "skip processing of all EVIO files"); OPTIONS.addOption("L", "load", false, "load back run information after inserting (for debugging)"); + OPTIONS.addOption("u", "url", true, "datacat URL"); + OPTIONS.addOption("S", "site", true, "datacat site (e.g. SLAC or JLAB)"); + // TODO: add -D option for defining metadata values } /** @@ -79,12 +86,17 @@ /** * Load back run information after insert (for debugging). */ - private boolean load = false; + private boolean reload = false; /** * Database connection parameters. */ private ConnectionParameters connectionParameters = null; + + /** + * Datacat client to use for connecting to data catalog. + */ + private DatacatClient datacatClient = null; /** * Parse command line options and return reference to <code>this</code> object. @@ -125,7 +137,7 @@ } // Dry run. - if (cl.hasOption("D")) { + if (cl.hasOption("Y")) { this.dryRun = true; } @@ -154,8 +166,20 @@ // Load back run info at end of job. if (cl.hasOption("L")) { - this.load = true; - } + this.reload = true; + } + + // Setup datacat client. + DatasetSite site = DatasetSite.JLAB; + String url = DatacatConstants.BASE_URL; + String rootFolder = DatacatConstants.ROOT_FOLDER; + if (cl.hasOption("u")) { + url = cl.getOptionValue("u"); + } + if (cl.hasOption("S")) { + site = DatasetSite.valueOf(cl.getOptionValue("S")); + } + datacatClient = new DatacatClientFactory().createClient(url, site, rootFolder); } catch (final ParseException e) { throw new RuntimeException(e); @@ -172,12 +196,12 @@ .createRunSummary(run) .setDetectorName(detectorName) .setConnectionParameters(connectionParameters) + .setDatacatClient(datacatClient) .setDryRun(dryRun) .setReplace(replace) .skipEvioProcessing(skipEvioProcessing) .setSpreadsheetFile(spreadsheetFile) - .run() - .load(load); - } - + .setReload(reload) + .run(); + } } Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseDaoFactory.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseDaoFactory.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunDatabaseDaoFactory.java Wed Dec 2 20:58:15 2015 @@ -78,4 +78,13 @@ SvtConfigDao createSvtConfigDao() { return new SvtConfigDaoImpl(connection); } + + /** + * Get the trigger config DAO. + * + * @return the trigger config DAO + */ + TriggerConfigDao createTriggerConfigDao() { + return new TriggerConfigDaoImpl(connection); + } } Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunManager.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunManager.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunManager.java Wed Dec 2 20:58:15 2015 @@ -6,6 +6,7 @@ import java.util.logging.Logger; import org.hps.conditions.database.ConnectionParameters; +import org.hps.record.daqconfig.DAQConfig; import org.hps.record.epics.EpicsData; import org.hps.record.scalers.ScalerData; import org.hps.record.svt.SvtConfigData; @@ -28,6 +29,7 @@ List<EpicsData> epicsData = null; List<ScalerData> scalerData = null; List<SvtConfigData> svtConfigData = null; + DAQConfig daqConfig = null; } /** @@ -71,7 +73,7 @@ /** * The data cache of run information. */ - private DataCache dataCache; + private DataCache cache; /** * Factory for creating database API objects. @@ -140,15 +142,12 @@ * * @param run the run number */ - void deleteRun() { - + void deleteRun() { factory.createEpicsDataDao().deleteEpicsData(EpicsType.EPICS_2s, run); factory.createEpicsDataDao().deleteEpicsData(EpicsType.EPICS_20s, run); - - factory.createScalerDataDao().deleteScalerData(run); - + factory.createScalerDataDao().deleteScalerData(run); factory.createSvtConfigDao().deleteSvtConfigs(run); - + factory.createTriggerConfigDao().deleteTriggerConfig(run); factory.createRunSummaryDao().deleteRunSummary(run); } @@ -169,11 +168,11 @@ */ public List<EpicsData> getEpicsData(final EpicsType epicsType) { this.checkRunNumber(); - if (this.dataCache.epicsData == null) { + if (this.cache.epicsData == null) { LOGGER.info("loading EPICS data for run " + this.run); - this.dataCache.epicsData = factory.createEpicsDataDao().getEpicsData(epicsType, this.run); - } - return this.dataCache.epicsData; + this.cache.epicsData = factory.createEpicsDataDao().getEpicsData(epicsType, this.run); + } + return this.cache.epicsData; } /** @@ -211,10 +210,10 @@ */ public RunSummary getRunSummary() { this.checkRunNumber(); - if (this.dataCache.runSummary == null) { - this.dataCache.runSummary = factory.createRunSummaryDao().getRunSummary(this.run); - } - return this.dataCache.runSummary; + if (this.cache.runSummary == null) { + this.cache.runSummary = factory.createRunSummaryDao().getRunSummary(this.run); + } + return this.cache.runSummary; } /** @@ -224,11 +223,11 @@ */ public List<ScalerData> getScalerData() { this.checkRunNumber(); - if (this.dataCache.scalerData == null) { + if (this.cache.scalerData == null) { LOGGER.info("loading scaler data for run " + this.run); - this.dataCache.scalerData = factory.createScalerDataDao().getScalerData(run); - } - return this.dataCache.scalerData; + this.cache.scalerData = factory.createScalerDataDao().getScalerData(run); + } + return this.cache.scalerData; } /** @@ -238,11 +237,25 @@ */ public List<SvtConfigData> getSvtConfigData() { this.checkRunNumber(); - if (this.dataCache.svtConfigData == null) { + if (this.cache.svtConfigData == null) { LOGGER.info("loading SVT configuration data for run " + this.run); - this.dataCache.svtConfigData = factory.createSvtConfigDao().getSvtConfigs(run); - } - return this.dataCache.svtConfigData; + this.cache.svtConfigData = factory.createSvtConfigDao().getSvtConfigs(run); + } + return this.cache.svtConfigData; + } + + /** + * Get the DAQ configuration for the run. + * + * @return the DAQ configuration for the run + */ + public DAQConfig getDAQConfig() { + this.checkRunNumber(); + if (this.cache.daqConfig == null) { + TriggerConfig config = factory.createTriggerConfigDao().getTriggerConfig(run); + cache.daqConfig = config.loadDAQConfig(run); + } + return this.cache.daqConfig; } /** @@ -268,10 +281,10 @@ */ public boolean runExists() { this.checkRunNumber(); - if (this.dataCache.runExists == null) { - this.dataCache.runExists = factory.createRunSummaryDao().runExists(this.run); - } - return this.dataCache.runExists; + if (this.cache.runExists == null) { + this.cache.runExists = factory.createRunSummaryDao().runSummaryExists(this.run); + } + return this.cache.runExists; } /** @@ -281,7 +294,7 @@ * @return <code>true</code> if the run exists in the database */ boolean runExists(final int run) { - return factory.createRunSummaryDao().runExists(run); + return factory.createRunSummaryDao().runSummaryExists(run); } /** @@ -299,7 +312,7 @@ this.run = run; // Reset the data cache. - this.dataCache = new DataCache(); + this.cache = new DataCache(); } } } Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummary.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummary.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/RunSummary.java Wed Dec 2 20:58:15 2015 @@ -1,9 +1,6 @@ package org.hps.run.database; import java.util.Date; -import java.util.Map; - -import org.hps.record.daqconfig.DAQConfig; /** * This is an API for accessing run summary information which is persisted as a row in the <i>run_summaries</i> table. @@ -18,27 +15,12 @@ */ public interface RunSummary { - /* - * Mapping of trigger config fields to crate numbers. - */ - public static final int TRIGGER_CONFIG1 = 37; - public static final int TRIGGER_CONFIG2 = 39; - public static final int TRIGGER_CONFIG3 = 46; - public static final int TRIGGER_CONFIG4 = 58; - /** * Get the creation date of this record. * * @return the creation date of this record */ Date getCreated(); - - /** - * Get the trigger config. - * - * @return the trigger config - */ - DAQConfig getDAQConfig(); /** * Get the END event timestamp or the timestamp from the last head bank if END is not present. @@ -125,13 +107,6 @@ Integer getTotalFiles(); /** - * Get a map of crate number to trigger config data. - * - * @return the map of crate number to trigger config data - */ - Map<Integer, String> getTriggerConfigData(); - - /** * Get the trigger config name (from the run spreadsheet). * * @return the trigger config name 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 Dec 2 20:58:15 2015 @@ -15,13 +15,6 @@ * @param run the run number */ void deleteRunSummary(int run); - - /** - * Delete a run summary but not its objects. - * - * @param runSummary the run summary object - */ - void deleteRunSummary(RunSummary runSummary); /** * Get the list of run numbers. @@ -51,12 +44,5 @@ * @param run the run number * @return <code>true</code> if <code>run</code> exists in the database */ - boolean runExists(int run); - - /** - * Update a run summary. - * - * @param runSummary the run summary to update - */ - void updateRunSummary(RunSummary runSummary); + boolean runSummaryExists(int run); } 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 Dec 2 20:58:15 2015 @@ -1,14 +1,11 @@ package org.hps.run.database; -import java.sql.Clob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.logging.Logger; /** @@ -19,11 +16,6 @@ final class RunSummaryDaoImpl implements RunSummaryDao { /** - * Expected number of string banks in trigger config. - */ - private static final int TRIGGER_CONFIG_LEN = 4; - - /** * Delete by run number. */ private static final String DELETE = "DELETE FROM run_summaries WHERE run = ?"; @@ -32,23 +24,15 @@ * Insert a record for a run. */ private static final String INSERT = "INSERT INTO run_summaries (run, nevents, nfiles, prestart_timestamp," - + " go_timestamp, end_timestamp, trigger_rate, trigger_config_name, trigger_config1, trigger_config2," - + " trigger_config3, trigger_config4, ti_time_offset, livetime_clock, livetime_fcup_tdc, livetime_fcup_trg," - + " target, notes, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())"; + + " 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())"; /** * Select record by run number. */ private static final String SELECT = "SELECT * FROM run_summaries WHERE run = ?"; - - /** - * Update information for a run. - */ - private static final String UPDATE = "UPDATE run_summaries SET nevents = ?, nfiles = ?, prestart_timestamp = ?," - + " go_timestamp = ?, end_timestamp = ?, trigger_rate = ?, trigger_config_name = ?, trigger_config1 = ?," - + " trigger_config2 = ?, trigger_config3 = ?, trigger_config4 = ?, ti_time_offset = ?, livetime_clock = ?," - + " livetime_fcup_tdc = ?, livetime_fcup_trg = ?, target = ?, notes = ?, created WHERE run = ?"; - + /** * Initialize the logger. */ @@ -102,32 +86,7 @@ } } } - - /** - * Delete a run summary but not its objects. - * - * @param runSummary the run summary object - */ - @Override - public void deleteRunSummary(final RunSummary runSummary) { - PreparedStatement preparedStatement = null; - try { - preparedStatement = connection.prepareStatement(DELETE); - preparedStatement.setInt(1, runSummary.getRun()); - preparedStatement.executeUpdate(); - } catch (final SQLException e) { - throw new RuntimeException(e); - } finally { - if (preparedStatement != null) { - try { - preparedStatement.close(); - } catch (final SQLException e) { - e.printStackTrace(); - } - } - } - } - + /** * Get the list of run numbers. * @@ -183,10 +142,6 @@ runSummary.setEndTimestamp(resultSet.getInt("end_timestamp")); runSummary.setTriggerRate(resultSet.getDouble("trigger_rate")); runSummary.setTriggerConfigName(resultSet.getString("trigger_config_name")); - Map<Integer, String> triggerConfigData = createTriggerConfigData(resultSet); - if (!triggerConfigData.isEmpty()) { - runSummary.setTriggerConfigData(triggerConfigData); - } runSummary.setTiTimeOffset(resultSet.getLong("ti_time_offset")); runSummary.setLivetimeClock(resultSet.getDouble("livetime_clock")); runSummary.setLivetimeFcupTdc(resultSet.getDouble("livetime_fcup_tdc")); @@ -207,34 +162,6 @@ } } return runSummary; - } - - /** - * Create trigger config data from result set. - * - * @param resultSet the result set with the run summary record - * @return the trigger config data as a map of bank number to string data - * @throws SQLException if there is an error querying the database - */ - private Map<Integer, String> createTriggerConfigData(final ResultSet resultSet) throws SQLException { - Map<Integer, String> triggerConfigData = new LinkedHashMap<Integer, String>(); - Clob clob = resultSet.getClob("trigger_config1"); - if (clob != null) { - triggerConfigData.put(RunSummary.TRIGGER_CONFIG1, clob.getSubString(1, (int) clob.length())); - } - clob = resultSet.getClob("trigger_config2"); - if (clob != null) { - triggerConfigData.put(RunSummary.TRIGGER_CONFIG2, clob.getSubString(1, (int) clob.length())); - } - clob = resultSet.getClob("trigger_config3"); - if (clob != null) { - triggerConfigData.put(RunSummary.TRIGGER_CONFIG3, clob.getSubString(1, (int) clob.length())); - } - clob = resultSet.getClob("trigger_config4"); - if (clob != null) { - triggerConfigData.put(RunSummary.TRIGGER_CONFIG4, clob.getSubString(1, (int) clob.length())); - } - return triggerConfigData; } /** @@ -255,14 +182,12 @@ preparedStatement.setInt(6, runSummary.getEndTimestamp()); preparedStatement.setDouble(7, runSummary.getTriggerRate()); preparedStatement.setString(8, runSummary.getTriggerConfigName()); - Map<Integer, String> triggerData = runSummary.getTriggerConfigData(); - prepareTriggerData(preparedStatement, triggerData); - preparedStatement.setLong(13, runSummary.getTiTimeOffset()); - preparedStatement.setDouble(14, runSummary.getLivetimeClock()); - preparedStatement.setDouble(15, runSummary.getLivetimeFcupTdc()); - preparedStatement.setDouble(16, runSummary.getLivetimeFcupTrg()); - preparedStatement.setString(17, runSummary.getTarget()); - preparedStatement.setString(18, runSummary.getNotes()); + preparedStatement.setLong(9, runSummary.getTiTimeOffset()); + preparedStatement.setDouble(10, runSummary.getLivetimeClock()); + preparedStatement.setDouble(11, runSummary.getLivetimeFcupTdc()); + preparedStatement.setDouble(12, runSummary.getLivetimeFcupTrg()); + preparedStatement.setString(13, runSummary.getTarget()); + preparedStatement.setString(14, runSummary.getNotes()); LOGGER.fine(preparedStatement.toString()); preparedStatement.executeUpdate(); } catch (final SQLException e) { @@ -277,30 +202,6 @@ } } } - - /** - * Set trigger config data on prepared statement. - * @param preparedStatement the prepared statement - * @param triggerData the trigger config data - * @throws SQLException if there is an error querying the database - */ - private void prepareTriggerData(PreparedStatement preparedStatement, Map<Integer, String> triggerData) - throws SQLException { - if (triggerData != null && !triggerData.isEmpty()) { - if (triggerData.size() != TRIGGER_CONFIG_LEN) { - throw new IllegalArgumentException("The trigger config data has the wrong length."); - } - preparedStatement.setBytes(9, triggerData.get(RunSummary.TRIGGER_CONFIG1).getBytes()); - preparedStatement.setBytes(10, triggerData.get(RunSummary.TRIGGER_CONFIG2).getBytes()); - preparedStatement.setBytes(11, triggerData.get(RunSummary.TRIGGER_CONFIG3).getBytes()); - preparedStatement.setBytes(12, triggerData.get(RunSummary.TRIGGER_CONFIG4).getBytes()); - } else { - preparedStatement.setBytes(9, null); - preparedStatement.setBytes(10, null); - preparedStatement.setBytes(11, null); - preparedStatement.setBytes(12, null); - } - } /** * Return <code>true</code> if a run summary exists in the database for the run number. @@ -309,7 +210,7 @@ * @return <code>true</code> if run exists in the database */ @Override - public boolean runExists(final int run) { + public boolean runSummaryExists(final int run) { PreparedStatement preparedStatement = null; try { preparedStatement = connection.prepareStatement("SELECT run FROM run_summaries where run = ?"); @@ -328,58 +229,4 @@ } } } - - /** - * Update a run summary. - * - * @param runSummary the run summary to update - */ - @Override - public void updateRunSummary(final RunSummary runSummary) { - PreparedStatement preparedStatement = null; - try { - preparedStatement = connection.prepareStatement(UPDATE); - preparedStatement.setInt(1, runSummary.getTotalEvents()); - preparedStatement.setInt(2, runSummary.getTotalFiles()); - preparedStatement.setInt(3, runSummary.getPrestartTimestamp()); - preparedStatement.setInt(4, runSummary.getGoTimestamp()); - preparedStatement.setInt(5, runSummary.getEndTimestamp()); - preparedStatement.setDouble(6, runSummary.getTriggerRate()); - preparedStatement.setString(7, runSummary.getTriggerConfigName()); - Map<Integer, String> triggerData = runSummary.getTriggerConfigData(); - if (triggerData != null && !triggerData.isEmpty()) { - if (triggerData.size() != 4) { - throw new IllegalArgumentException("The trigger config data has the wrong length."); - } - preparedStatement.setBytes(8, triggerData.get(RunSummary.TRIGGER_CONFIG1).getBytes()); - preparedStatement.setBytes(9, triggerData.get(RunSummary.TRIGGER_CONFIG2).getBytes()); - preparedStatement.setBytes(10, triggerData.get(RunSummary.TRIGGER_CONFIG3).getBytes()); - preparedStatement.setBytes(11, triggerData.get(RunSummary.TRIGGER_CONFIG4).getBytes()); - } else { - preparedStatement.setBytes(8, null); - preparedStatement.setBytes(9, null); - preparedStatement.setBytes(10, null); - preparedStatement.setBytes(11, null); - } - preparedStatement.setLong(12, runSummary.getTiTimeOffset()); - preparedStatement.setDouble(13, runSummary.getLivetimeClock()); - preparedStatement.setDouble(14, runSummary.getLivetimeFcupTdc()); - preparedStatement.setDouble(15, runSummary.getLivetimeFcupTrg()); - preparedStatement.setString(16, runSummary.getTarget()); - preparedStatement.setString(17, runSummary.getNotes()); - preparedStatement.setInt(18, 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(); - } - } - } - } } 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 Dec 2 20:58:15 2015 @@ -1,12 +1,6 @@ package org.hps.run.database; import java.util.Date; -import java.util.Map; -import java.util.Map.Entry; - -import org.hps.record.daqconfig.ConfigurationManager; -import org.hps.record.daqconfig.DAQConfig; -import org.hps.record.daqconfig.EvioDAQParser; /** * Implementation of {@link RunSummary} for retrieving information from the run database. @@ -21,11 +15,6 @@ private Date created; /** - * DAQ config object built from string data. - */ - private DAQConfig daqConfig; - - /** * Timestamp of END event. */ private Integer endTimestamp; @@ -84,12 +73,7 @@ * The total number of files in the run. */ private Integer totalFiles; - - /** - * Map of crate number to trigger config string data. - */ - private Map<Integer, String> triggerConfigData; - + /** * Get the name of the trigger config file. */ @@ -120,11 +104,6 @@ } @Override - public DAQConfig getDAQConfig() { - return this.daqConfig; - } - - @Override public Integer getEndTimestamp() { return endTimestamp; } @@ -183,12 +162,7 @@ public Integer getTotalFiles() { return this.totalFiles; } - - @Override - public Map<Integer, String> getTriggerConfigData() { - return this.triggerConfigData; - } - + @Override public String getTriggerConfigName() { return this.triggerConfigName; @@ -205,55 +179,82 @@ } /** - * Load DAQ config object from trigger config string data. - */ - private void loadDAQConfig() { - if (this.triggerConfigData != null && !this.triggerConfigData.isEmpty()) { - EvioDAQParser parser = new EvioDAQParser(); - for (Entry<Integer, String> entry : this.triggerConfigData.entrySet()) { - parser.parse(entry.getKey(), this.getRun(), new String[] {entry.getValue()}); - } - ConfigurationManager.updateConfiguration(parser); - daqConfig = ConfigurationManager.getInstance(); - } - } - + * Set the creation date of the run summary. + * + * @param created the creation date + */ void setCreated(Date created) { this.created = created; } - void setDAQConfig(DAQConfig daqConfig) { - this.daqConfig = daqConfig; - } - + /** + * Set the end timestamp. + * + * @param endTimestamp the end timestamp + */ void setEndTimestamp(Integer endTimestamp) { this.endTimestamp = endTimestamp; } + /** + * Set the GO timestamp. + * + * @param goTimestamp the GO timestamp + */ void setGoTimestamp(Integer goTimestamp) { this.goTimestamp = goTimestamp; } + /** + * Set the clock livetime. + * + * @param livetimeClock the clock livetime + */ void setLivetimeClock(Double livetimeClock) { this.livetimeClock = livetimeClock; } + /** + * Set the FCUP TDC livetime. + * + * @param livetimeTdc the FCUP TDC livetime + */ void setLivetimeFcupTdc(Double livetimeTdc) { this.livetimeTdc = livetimeTdc; } + /** + * Set the FCUP TRG livetime. + * + * @param livetimeTrg the FCUP TRG livetime + */ void setLivetimeFcupTrg(Double livetimeTrg) { this.livetimeTrg = livetimeTrg; } + /** + * Set the notes. + * + * @param notes the notes + */ void setNotes(String notes) { this.notes = notes; } + /** + * Set the PRESTART timestamp. + * + * @param prestartTimestamp the PRESTART timestamp + */ void setPrestartTimestamp(Integer prestartTimestamp) { this.prestartTimestamp = prestartTimestamp; } + /** + * Set the target description. + * + * @param target the target description + */ void setTarget(String target) { this.target = target; } @@ -286,19 +287,6 @@ } /** - * Build the DAQ config from the trigger config string data. - * - * @param triggerConfigData a map of crate number to the trigger config string data from the bank - */ - void setTriggerConfigData(Map<Integer, String> triggerConfigData) { - this.triggerConfigData = triggerConfigData; - // Load DAQ config if not already set. - if (daqConfig == null) { - loadDAQConfig(); - } - } - - /** * Set the trigger config file. * * @param triggerConfigName the trigger config file @@ -316,6 +304,11 @@ this.triggerRate = triggerRate; } + /** + * Set the updated date of the summary. + * + * @param updated the updated date + */ void setUpdated(Date updated) { this.updated = updated; } @@ -337,7 +330,6 @@ + ", goTimestamp: " + this.getGoTimestamp() + ", endTimestamp: " + this.getEndTimestamp() + ", triggerConfigFile: " + this.getTriggerConfigName() - + ", DAQConfig: " + (this.getDAQConfig() != null ? true : false) + ", triggerRate: " + this.getTriggerRate() + ", livetimeClock: " + this.getLivetimeClock() + ", livetimeTdc: " + this.getLivetimeFcupTdc() Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java Wed Dec 2 20:58:15 2015 @@ -18,15 +18,9 @@ final class ScalerDataDaoImpl implements ScalerDataDao { /** - * SQL query strings. + * Insert a record. */ - private static final class ScalerDataQuery { - - /** - * Insert a record. - */ - private static final String INSERT = createInsertSql(); - } + private static final String INSERT = createInsertSql(); /** * Create insert SQL for scaler data. @@ -139,7 +133,7 @@ public void insertScalerData(final List<ScalerData> scalerDataList, final int run) { PreparedStatement insertScalers = null; try { - insertScalers = this.connection.prepareStatement(ScalerDataQuery.INSERT); + insertScalers = this.connection.prepareStatement(INSERT); for (final ScalerData scalerData : scalerDataList) { insertScalers.setInt(1, run); insertScalers.setInt(2, scalerData.getEventId()); Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDao.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDao.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDao.java Wed Dec 2 20:58:15 2015 @@ -9,7 +9,7 @@ * * @author Jeremy McCormick, SLAC */ -public interface SvtConfigDao { +interface SvtConfigDao { /** * Insert SVT configurations. Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDaoImpl.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDaoImpl.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/SvtConfigDaoImpl.java Wed Dec 2 20:58:15 2015 @@ -16,7 +16,7 @@ * * @author Jeremy McCormick, SLAC */ -public class SvtConfigDaoImpl implements SvtConfigDao { +final class SvtConfigDaoImpl implements SvtConfigDao { private Connection connection = null; Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfig.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfig.java (added) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfig.java Wed Dec 2 20:58:15 2015 @@ -0,0 +1,84 @@ +package org.hps.run.database; + +import java.util.Map; +import java.util.Map.Entry; + +import org.hps.record.daqconfig.ConfigurationManager; +import org.hps.record.daqconfig.DAQConfig; +import org.hps.record.daqconfig.EvioDAQParser; + +/** + * Raw trigger config string data with an associated timestamp. + * + * @author Jeremy McCormick, SLAC + */ +final class TriggerConfig { + + /** + * Expected number of string banks in trigger config. + */ + static final int DATA_LENGTH = 4; + + /* + * Mapping of trigger config database fields to their crate numbers. + */ + static final int CONFIG1 = 37; + static final int CONFIG2 = 39; + static final int CONFIG3 = 46; + static final int CONFIG4 = 58; + + private int timestamp; + private Map<Integer, String> data; + + TriggerConfig(Map<Integer, String> data, int timestamp) { + if (data == null) { + throw new RuntimeException("The data is null."); + } + this.data = data; + this.timestamp = timestamp; + } + + /** + * Get the config's timestamp. + * + * @return the config's timestamp + */ + int getTimestamp() { + return timestamp; + } + + /** + * Get the config data as a map from bank numbers to strings. + * + * @return the config data + */ + Map<Integer, String> getData() { + return data; + } + + /** + * Return <code>true</code> if the config is valid which means it has + * four, non-null string data banks. + * + * @return <code>true</code> if config is valid + */ + boolean isValid() { + return data.size() == DATA_LENGTH && data.get(CONFIG1) != null && data.get(CONFIG2) != null + && data.get(CONFIG3) != null && data.get(CONFIG4) != null; + } + + /** + * Load DAQ config object from trigger config string data. + * + * @param the run number (needed by configuration manager) + * @return the DAQ config object + */ + DAQConfig loadDAQConfig(int run) { + EvioDAQParser parser = new EvioDAQParser(); + for (Entry<Integer, String> entry : data.entrySet()) { + parser.parse(entry.getKey(), 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/TriggerConfigDao.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDao.java (added) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDao.java Wed Dec 2 20:58:15 2015 @@ -0,0 +1,32 @@ +package org.hps.run.database; + +/** + * Database interface for getting raw trigger config data. + * + * @author Jeremy McCormick, SLAC + */ +interface TriggerConfigDao { + + /** + * Get a trigger config by run number. + * + * @param run the run number + * @return the trigger config + */ + TriggerConfig getTriggerConfig(int run); + + /** + * Insert a trigger config. + * + * @param config the trigger config + * @param run the run number + */ + void insertTriggerConfig(TriggerConfig config, int run); + + /** + * Delete a trigger config by run. + * + * @param run the run number + */ + void deleteTriggerConfig(int run); +} Added: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDaoImpl.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDaoImpl.java (added) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/TriggerConfigDaoImpl.java Wed Dec 2 20:58:15 2015 @@ -0,0 +1,129 @@ +package org.hps.run.database; + +import java.sql.Clob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; + +final class TriggerConfigDaoImpl implements TriggerConfigDao { + + private static final String INSERT = + "INSERT INTO trigger_configs (run, timestamp, config1, config2, config3, config4)" + + " VALUES (?, ?, ?, ?, ?, ?)"; + + private static final String SELECT = "SELECT * FROM trigger_configs WHERE run = ?"; + + private static final String DELETE = "DELETE FROM trigger_configs WHERE run = ?"; + + /** + * The database connection. + */ + private final Connection connection; + + /** + * Create object for managing scaler data in the run database. + * + * @param connection the database connection + */ + TriggerConfigDaoImpl(final Connection connection) { + if (connection == null) { + throw new IllegalArgumentException("The connection is null."); + } + this.connection = connection; + } + + + @Override + public void insertTriggerConfig(TriggerConfig config, int run) { + if (!config.isValid()) { + throw new RuntimeException("The trigger config is not valid."); + } + PreparedStatement preparedStatement = null; + try { + preparedStatement = connection.prepareStatement(INSERT); + preparedStatement.setInt(1, run); + preparedStatement.setInt(2, config.getTimestamp()); + Map<Integer, String> data = config.getData(); + if (data.size() != TriggerConfig.DATA_LENGTH) { + throw new IllegalArgumentException("The trigger config data has the wrong length."); + } + preparedStatement.setBytes(3, data.get(TriggerConfig.CONFIG1).getBytes()); + preparedStatement.setBytes(4, data.get(TriggerConfig.CONFIG2).getBytes()); + preparedStatement.setBytes(5, data.get(TriggerConfig.CONFIG3).getBytes()); + preparedStatement.setBytes(6, data.get(TriggerConfig.CONFIG4).getBytes()); + preparedStatement.executeUpdate(); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + try { + preparedStatement.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Override + public void deleteTriggerConfig(int run) { + PreparedStatement preparedStatement = null; + try { + preparedStatement = connection.prepareStatement(DELETE); + preparedStatement.setInt(1, run); + preparedStatement.executeUpdate(); + } catch (final SQLException e) { + throw new RuntimeException(e); + } finally { + if (preparedStatement != null) { + try { + preparedStatement.close(); + } catch (final SQLException e) { + e.printStackTrace(); + } + } + } + } + + @Override + public TriggerConfig getTriggerConfig(int run) { + PreparedStatement preparedStatement = null; + TriggerConfig config = null; + try { + preparedStatement = connection.prepareStatement(SELECT); + preparedStatement.setInt(1, run); + ResultSet resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + Map<Integer, String> data = new LinkedHashMap<Integer, String>(); + int timestamp = resultSet.getInt("timestamp"); + Clob clob = resultSet.getClob("config1"); + if (clob != null) { + data.put(TriggerConfig.CONFIG1, clob.getSubString(1, (int) clob.length())); + } + clob = resultSet.getClob("config2"); + if (clob != null) { + data.put(TriggerConfig.CONFIG2, clob.getSubString(1, (int) clob.length())); + } + clob = resultSet.getClob("config3"); + if (clob != null) { + data.put(TriggerConfig.CONFIG3, clob.getSubString(1, (int) clob.length())); + } + clob = resultSet.getClob("config4"); + if (clob != null) { + data.put(TriggerConfig.CONFIG4, clob.getSubString(1, (int) clob.length())); + } + config = new TriggerConfig(data, timestamp); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + try { + preparedStatement.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return config; + } +} Modified: java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/package-info.java ============================================================================= --- java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/package-info.java (original) +++ java/branches/jeremy-dev/run-database/src/main/java/org/hps/run/database/package-info.java Wed Dec 2 20:58:15 2015 @@ -1,4 +1,4 @@ /** - * API for accessing the HPS run database. + * API for accessing and updating the HPS run database. */ package org.hps.run.database;