LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  July 2015

HPS-SVN July 2015

Subject:

r3256 - /java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Fri, 10 Jul 2015 23:05:40 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1981 lines)

Author: [log in to unmask]
Date: Fri Jul 10 16:05:22 2015
New Revision: 3256

Log:
Add missing javadoc.  Simplify how physics event counting works.  Fix a few bug related to finding the run's end date.

Modified:
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/ScalerDataUpdater.java
    java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java	Fri Jul 10 16:05:22 2015
@@ -24,8 +24,8 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * Crawls EVIO files in a directory tree, groups the files that are found by run, and optionally performs various tasks based on the run summary
- * information that is accumulated, including printing a summary, caching the files from JLAB MSS, and updating a run database.
+ * Search for EVIO files in a directory tree, group the files that are found by run, extract meta data from these
+ * files, and optionally update a run database with the information that was found.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -51,12 +51,12 @@
      */
     static {
         OPTIONS.addOption("a", "runs", true, "list of run numbers to accept (others will be excluded)");
-        OPTIONS.addOption("b", "min-date", true, "min date for files (example 2015-03-26 11:28:59)");
-        OPTIONS.addOption("c", "cache", false, "automatically cache files from MSS (JLAB only)");
+        OPTIONS.addOption("b", "min-date", true, "min date for a file (example \"2015-03-26 11:28:59\")");
+        OPTIONS.addOption("c", "cache", false, "automatically cache files from MSS to cache disk (JLAB only)");
         OPTIONS.addOption("C", "connection-properties", true, "database connection properties file (required)");
         OPTIONS.addOption("d", "directory", true, "root directory to start crawling (default is current dir)");
-        OPTIONS.addOption("E", "evio-processor", true, "full class name of an EvioEventProcessor to execute (can be used multiple times)");
-        OPTIONS.addOption("h", "help", false, "print help and exit");
+        OPTIONS.addOption("E", "evio-processor", true, "class name of an EvioEventProcessor to execute");
+        OPTIONS.addOption("h", "help", false, "print help and exit (overrides all other arguments)");
         OPTIONS.addOption("m", "max-files", true, "max number of files to process per run (mostly for debugging)");
         OPTIONS.addOption("p", "print", true, "set event printing interval during EVIO processing");
         OPTIONS.addOption("r", "insert", false, "insert information into the run database (not done by default)");
@@ -67,7 +67,7 @@
     }
 
     /**
-     * Support running the crawler from the command line.
+     * Run the crawler from the command line.
      *
      * @param args the command line arguments
      */
@@ -88,24 +88,24 @@
      * The options parser.
      */
     private final PosixParser parser = new PosixParser();
-    
+
     /**
      * Configuration options from the command line.
      */
     private CrawlerConfig config;
-    
-    /**
-     * Parse command line options into internal configuration object.
+
+    /**
+     * Parse command line options and create a new {@link Crawler} object from the configuration.
      *
      * @param args the command line arguments
      * @return the configured crawler object
      */
     private Crawler parse(final String args[]) {
-        
+
         LOGGER.info("parsing command line options");
-        
+
         config = new CrawlerConfig();
-        
+
         try {
             final CommandLine cl = this.parser.parse(OPTIONS, args);
 
@@ -126,12 +126,15 @@
                 final String dbPropPath = cl.getOptionValue("C");
                 final File dbPropFile = new File(dbPropPath);
                 if (!dbPropFile.exists()) {
-                    throw new IllegalArgumentException("Connection properties file " + dbPropFile.getPath() + " does not exist.");
-                }                
-                config.setConnection(ConnectionParameters.fromProperties(dbPropFile));
+                    throw new IllegalArgumentException("Connection properties file " + dbPropFile.getPath()
+                            + " does not exist.");
+                }
+                ConnectionParameters connectionParameters = ConnectionParameters.fromProperties(dbPropFile);
+                config.setConnection(connectionParameters);
                 LOGGER.config("using " + dbPropPath + " for db connection properties");
             } else {
-                throw new RuntimeException("The -C switch providing the database connection properties file is a required argument.");
+                throw new RuntimeException(
+                        "The -C switch providing the database connection properties file is a required argument.");
             }
 
             // Root directory for file crawling.
@@ -155,17 +158,19 @@
                     try {
                         // Create new time stamp file which will have its date updated at the end of the job.
                         LOGGER.config("creating new timestamp file " + timestampFile.getPath());
-                        timestampFile.createNewFile();                        
+                        timestampFile.createNewFile();
                     } catch (final IOException e) {
                         throw new IllegalArgumentException("Error creating timestamp file: " + timestampFile.getPath());
                     }
                 } else {
                     try {
                         // Get the date filter for files from an existing time stamp file provided by the user.
-                        Date timestamp = new Date(Files.readAttributes(config.timestampFile().toPath(), BasicFileAttributes.class).lastModifiedTime()
-                                .toMillis());
+                        Date timestamp = new Date(Files
+                                .readAttributes(config.timestampFile().toPath(), BasicFileAttributes.class)
+                                .lastModifiedTime().toMillis());
                         config.setTimestamp(timestamp);
-                        LOGGER.config("got timestamp " + timestamp + " from existing file " + config.timestampFile().getPath());
+                        LOGGER.config("got timestamp " + timestamp + " from existing file "
+                                + config.timestampFile().getPath());
                     } catch (final IOException e) {
                         throw new RuntimeException("Error getting attributes of timestamp file.", e);
                     }
@@ -226,7 +231,8 @@
             if (cl.hasOption("b")) {
                 try {
                     if (config.timestamp() != null) {
-                        LOGGER.warning("existing timestamp from file " + config.timestamp() + " will be overridden by date from -b argument");
+                        LOGGER.warning("existing timestamp from file " + config.timestamp()
+                                + " will be overridden by date from -b argument");
                     }
                     config.setTimestamp(cl.getOptionValue("b"));
                     LOGGER.config("set timestamp to " + config.timestamp() + " from -b argument");
@@ -250,30 +256,32 @@
         } catch (final ParseException e) {
             throw new RuntimeException("Error parsing options.", e);
         }
-        
+
         LOGGER.info("done parsing command line options");
 
         return this;
     }
 
     /**
-     * Print the usage statement for this tool to the console and exit.
+     * Print the usage statement for this tool to the console and then exit the program.
      */
     private void printUsage() {
         final HelpFormatter help = new HelpFormatter();
         help.printHelp("EvioFileCrawler", "", OPTIONS, "");
         System.exit(0);
     }
-   
-    /**
-     * Run the full crawler job, including all configured file-processing steps, which may take a very long time!
+
+    /**
+     * Run the full crawler job.
+     * <p>
+     * This might take quite a long time!
      *
      * @throws Exception if there is some error during the job
      */
     public void run() throws Exception {
 
         LOGGER.info("running Crawler job");
-        
+
         // Create the file visitor for crawling the root directory with the given date filter.
         final EvioFileVisitor visitor = new EvioFileVisitor(config.timestamp());
 
@@ -284,12 +292,12 @@
         final RunLog runs = visitor.getRunLog();
 
         // Print the run numbers that were found.
-        printRunNumbers(runs);
+        runs.printRunNumbers();
 
         // Sort the files on their sequence numbers.
-        runs.sortAllFiles();
-
-        // Process all the files, performing caching from MSS if necessary. 
+        runs.sortFiles();
+
+        // Process all the files, performing caching from the MSS if necessary.
         RunProcessor.processRuns(this.cacheManager, runs, config);
 
         // Print the summary information after the run processing is done.
@@ -320,15 +328,6 @@
             // Close the DB connection.
             connection.close();
         }
-    }
-
-    private void printRunNumbers(final RunLog runs) {
-        // Print the list of runs that were found.
-        final StringBuffer sb = new StringBuffer();
-        for (final Integer run : runs.getSortedRunNumbers()) {
-            sb.append(run + " ");
-        }
-        LOGGER.info("found EVIO files from runs: " + sb.toString());
     }
 
     private void walk(final EvioFileVisitor visitor) {

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java	Fri Jul 10 16:05:22 2015
@@ -12,15 +12,19 @@
 import org.hps.record.evio.EvioEventProcessor;
 
 /**
- * Crawls EVIO files in a directory tree, groups the files that are found by run, and optionally performs various tasks based on the run summary
- * information that is accumulated, including printing a summary, caching the files from JLAB MSS, and updating a run database.
+ * Full configuration information for the {@link Crawler class}.
+ * <p>
+ * The setter methods use the builder pattern so method chaining them is possible.
  *
  * @author Jeremy McCormick, SLAC
  */
 final class CrawlerConfig {
 
+    /**
+     * The format for input timestamps used for file filtering.
+     */
     private static final SimpleDateFormat TIMESTAMP_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-    
+
     /**
      * Default event print interval.
      */
@@ -30,14 +34,20 @@
      * Interval for printing out event number while running EVIO processors.
      */
     private int eventPrintInterval = DEFAULT_EVENT_PRINT_INTERVAL;
-   
+
     /**
      * A list of run numbers to accept in the job.
      */
     private Set<Integer> acceptRuns;
 
+    /**
+     * <code>true</code> if database updates are allowed meaning existing records can be deleted and replaced.
+     */
     private boolean allowUpdates = false;
 
+    /**
+     * The database connection parameters which must be provided by command line argument.
+     */
     private ConnectionParameters connectionParameters;
 
     /**
@@ -45,10 +55,13 @@
      */
     private int maxFiles = -1;
 
+    /**
+     * A list of extra {@link org.hps.record.evio.EvioEventProcessor}s to run with the job.
+     */
     private final List<EvioEventProcessor> processors = new ArrayList<EvioEventProcessor>();
 
     /**
-     * The root directory to crawl which defaults to the current directory.
+     * The root directory to search for files, which defaults to the current directory.
      */
     private File rootDir = new File(System.getProperty("user.dir"));
 
@@ -58,17 +71,17 @@
     private Date timestamp = null;
 
     /**
-     * A file to use for the timestamp date.
+     * A file to use for getting the timestamp date.
      */
     private File timestampFile = null;
 
     /**
-     * Flag indicating if the run database should be updated from results of the job.
+     * <code>true</code> if the run database should be updated from results of the job.
      */
     private boolean updateRunLog = false;
 
     /**
-     * Flag indicating if the file cache should be used (e.g. jcache automatically executed to move files to the cache disk from tape).
+     * <code>true</code> if file caching should be used to move files to the cache disk from tape at JLAB.
      */
     private boolean useFileCache = false;
 
@@ -77,11 +90,23 @@
      */
     private Long waitTime;
 
+    /**
+     * Add an {@link org.hps.record.evio.EvioEventProcessor} to the job.
+     * 
+     * @param processor
+     * @return this object
+     */
     CrawlerConfig addProcessor(final EvioEventProcessor processor) {
         this.processors.add(processor);
         return this;
     }
-    
+
+    /**
+     * Add an {@link org.hps.record.evio.EvioEventProcessor} to the job by its class name.
+     * 
+     * @param processor the <code>EvioEventProcessor</code> to instantiate
+     * @return this object
+     */
     CrawlerConfig addProcessor(final String className) {
         try {
             this.processors.add(EvioEventProcessor.class.cast(Class.forName(className).newInstance()));
@@ -91,111 +116,261 @@
         return this;
     }
 
+    /**
+     * Set the list of run numbers that should be accepted.
+     * 
+     * @param acceptRuns the list of acceptable run numbers
+     * @return this object
+     */
     CrawlerConfig setAcceptRuns(final Set<Integer> acceptRuns) {
         this.acceptRuns = acceptRuns;
         return this;
     }
 
+    /**
+     * Set whether database updates are allowed, i.e. replacement of existing records.
+     * 
+     * @param allowUpdates <code>true</code> to allow database record deletion/updates
+     * @return this object
+     */
     CrawlerConfig setAllowUpdates(final boolean allowUpdates) {
         this.allowUpdates = allowUpdates;
         return this;
     }
 
+    /**
+     * Set the database connection parameters.
+     * 
+     * @param connectionParameters the database connection parameters
+     * @return this object
+     */
     CrawlerConfig setConnection(final ConnectionParameters connectionParameters) {
         this.connectionParameters = connectionParameters;
         return this;
     }
 
+    /**
+     * Set the maximum number of files that will be processed by the job.
+     * <p>
+     * This should only be used for debugging purposes as it results in incorrect event counts for the run.
+     * 
+     * @param maxFiles the maximum number of files to process or -1 for unlimited
+     * @return this object
+     */
     CrawlerConfig setMaxFiles(final int maxFiles) {
         this.maxFiles = maxFiles;
         return this;
     }
-    
+
+    /**
+     * Set the root directory for the file search.
+     * 
+     * @param rootDir the root directory for the file search
+     * @return this object
+     */
     CrawlerConfig setRootDir(File rootDir) {
         this.rootDir = rootDir;
         return this;
     }
-    
+
+    /**
+     * Set a date for filtering input files.
+     * <p>
+     * Those files created before this date will not be processed.
+     * 
+     * @param timestamp the date for filtering files
+     * @return this object
+     */
     CrawlerConfig setTimestamp(Date timestamp) {
         this.timestamp = timestamp;
         return this;
     }
-    
+
+    /**
+     * Set a date for filtering input files using a string in the default format defined by
+     * <code>TIMESTAMP_DATE_FORMAT</code>.
+     * <p>
+     * Those files created before this date will not be processed.
+     * 
+     * @param timestamp the date string for filtering files
+     * @return this object
+     */
     CrawlerConfig setTimestamp(String timestampString) throws ParseException {
         TIMESTAMP_DATE_FORMAT.parse(timestampString);
         return this;
     }
-    
+
+    /**
+     * Set a date for filtering files based on the modification date of a timestamp file.
+     * 
+     * @param timestampFile the timestamp file for date filtering
+     * @return this object
+     */
     CrawlerConfig setTimestampFile(File timestampFile) {
         this.timestampFile = timestampFile;
         return this;
     }
-    
+
+    /**
+     * Set whether the run database should be updated in the job.
+     * <p>
+     * This will not allow replacement of existing run log records. The {@link #allowUpdates()} flag must be on for this
+     * be allowed.
+     * 
+     * @param updateRunLog <code>true</code> if the run database should be updated
+     * @return this object
+     */
     CrawlerConfig setUpdateRunLog(boolean updateRunLog) {
         this.updateRunLog = updateRunLog;
         return this;
     }
-    
+
+    /**
+     * Set whether file caching using the 'jcache' program should be enabled.
+     * <p>
+     * This is only relevant for jobs run at JLAB.
+     * 
+     * @param useFileCache <code>true</code> to allow file caching
+     * @return this object
+     */
     CrawlerConfig setUseFileCache(boolean useFileCache) {
         this.useFileCache = useFileCache;
         return this;
     }
-    
+
+    /**
+     * Set the max wait time in seconds for all file caching operations to complete.
+     * <p>
+     * If this time is exceeded then the job will fail with an error.
+     * 
+     * @param waitTime the max wait time in seconds allowed for file caching to complete
+     * @return this object
+     */
     CrawlerConfig setWaitTime(long waitTime) {
         this.waitTime = waitTime;
         return this;
     }
-    
+
+    /**
+     * Set the interval for printing the EVIO event numbers during processing.
+     * 
+     * @param eventPrintInterval the event print interval
+     * @return this object
+     */
     CrawlerConfig setEventPrintInterval(int eventPrintInterval) {
         this.eventPrintInterval = eventPrintInterval;
         return this;
     }
-    
+
+    /**
+     * Get the set of runs that will be accepted for the job.
+     * 
+     * @return the list of runs that will be accepted
+     */
     Set<Integer> acceptRuns() {
         return acceptRuns;
     }
-    
+
+    /**
+     * Return <code>true</code> if updates/deletions of existing records in the database is allowed.
+     * 
+     * @return <code>true</code> if updating/deleting records in the database is allowed
+     */
     boolean allowUpdates() {
         return allowUpdates;
     }
 
+    /**
+     * Get the database connection parameters.
+     * 
+     * @return the database connection parameters
+     */
     ConnectionParameters connectionParameters() {
         return connectionParameters;
     }
 
+    /**
+     * Get the maximum number of files that the job can process.
+     * 
+     * @return the maximum number of files
+     */
     int maxFiles() {
         return maxFiles;
     }
 
+    /**
+     * Get the list of extra event processors that will run with the job.
+     * <p>
+     * Required (default) processors for the job are not included here.
+     * 
+     * @return the list of extra event processors
+     */
     List<EvioEventProcessor> processors() {
         return processors;
     }
 
+    /**
+     * Get the root directory for the file search.
+     * 
+     * @return the root directory for the file search
+     */
     File rootDir() {
         return rootDir;
     }
 
+    /**
+     * Get the timestamp for file filtering.
+     * <p>
+     * Files older than this will not be included in the job.
+     * 
+     * @return the timestamp for file filtering
+     */
     Date timestamp() {
         return timestamp;
     }
-    
+
+    /**
+     * Get the timestamp file using for filtering EVIO files.
+     * 
+     * @return the timestamp file used for filtering EVIO files (can be null)
+     */
     File timestampFile() {
         return timestampFile;
     }
 
+    /**
+     * Return <code>true</code> if the run database should be updated.
+     * 
+     * @return <code>true</code> if the run database should be updated
+     */
     boolean updateRunLog() {
         return updateRunLog;
     }
 
+    /**
+     * Return <code>true</code> if file caching should be enabled.
+     * 
+     * @return <code>true</code> if file caching should be enabled
+     */
     boolean useFileCache() {
         return useFileCache;
     }
 
+    /**
+     * Get the max wait time in seconds to allow for file caching operations to complete.
+     * 
+     * @return the max wait time in seconds to allow for file caching operations to complete
+     */
     Long waitTime() {
         return waitTime;
-    }    
-    
+    }
+
+    /**
+     * Get the event print interval.
+     * 
+     * @return the event print interval
+     */
     int eventPrintInterval() {
         return this.eventPrintInterval;
-    }          
+    }
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java	Fri Jul 10 16:05:22 2015
@@ -17,7 +17,7 @@
 final class DateFileFilter implements FileFilter {
 
     /**
-     * The cut off time stamp.
+     * The cut off timestamp.
      */
     private final Date date;
 

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java	Fri Jul 10 16:05:22 2015
@@ -16,7 +16,8 @@
 final class EpicsLog extends EvioEventProcessor {
 
     /**
-     * A count of how many times a given EPICS variable is found in the input, e.g. for computing the mean value across the run.
+     * A count of how many times a given EPICS variable is found in the input, e.g. for computing the mean value across
+     * the entire run.
      */
     private final Map<String, Integer> counts = new HashMap<String, Integer>();
 
@@ -80,7 +81,7 @@
     /**
      * Update state from the current EPICS data.
      * <p>
-     * If the current data is null, this method does nothing.
+     * If the current data is <code>null</code>, this method does nothing.
      */
     private void update() {
         if (this.currentData != null) {
@@ -96,8 +97,9 @@
                 this.counts.put(name, count);
                 final double value = this.logData.getValue(name) + this.currentData.getValue(name);
                 this.logData.setValue(name, value);
-                //System.out.println(name + " => added " + this.currentData.getValue(name) + "; total = " + value + "; mean = " + value / count);
+                // System.out.println(name + " => added " + this.currentData.getValue(name) + "; total = " + value +
+                // "; mean = " + value / count);
             }
         }
-    }       
+    }
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java	Fri Jul 10 16:05:22 2015
@@ -6,6 +6,7 @@
 import org.hps.record.evio.EventTagBitMask;
 import org.hps.record.evio.EventTagConstant;
 import org.hps.record.evio.EvioEventProcessor;
+import org.hps.record.evio.EvioEventUtilities;
 import org.jlab.coda.jevio.EvioEvent;
 
 /**
@@ -24,6 +25,11 @@
      * The run summary to update.
      */
     private final RunSummary runSummary;
+
+    /**
+     * The total number of physics events processed.
+     */
+    private int physicsEventCount = 0;
 
     /**
      * Create the log pointing to a run summary.
@@ -58,23 +64,41 @@
     }
 
     /**
+     * Get the number of physics events counted.
+     * 
+     * @return the number of physics events counted
+     */
+    int getPhysicsEventCount() {
+        return physicsEventCount;
+    }
+
+    /**
      * Process an EVIO event and add its type to the map.
      *
      * @param event the EVIO event
      */
     @Override
     public void process(final EvioEvent event) {
+        
+        // Increment counts for exact event tag values.
         for (final EventTagConstant constant : EventTagConstant.values()) {
             if (constant.isEventTag(event)) {
                 final int count = this.eventTypeCounts.get(constant) + 1;
                 this.eventTypeCounts.put(constant, count);
             }
         }
+        
+        // Increment counts for bit masking of tags.
         for (final EventTagBitMask mask : EventTagBitMask.values()) {
             if (mask.isEventTag(event)) {
                 final int count = this.eventTypeCounts.get(mask) + 1;
                 this.eventTypeCounts.put(mask, count);
             }
         }
+
+        // Increment physics event count.
+        if (EvioEventUtilities.isPhysicsEvent(event)) {
+            ++this.physicsEventCount;
+        }
     }
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java	Fri Jul 10 16:05:22 2015
@@ -4,8 +4,8 @@
 import java.io.FileFilter;
 
 /**
- * This is a simple file filter that will accept EVIO files with a certain convention to their naming which looks like <i>FILENAME.evio.SEQUENCE</i>.
- * This matches the convention used by the CODA DAQ software.
+ * This is a simple file filter that will accept EVIO files with a certain convention to their naming which looks like
+ * <i>FILENAME.evio.SEQUENCE</i>. This matches the convention used by the CODA DAQ software.
  *
  * @author Jeremy McCormick, SLAC
  */

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java	Fri Jul 10 16:05:22 2015
@@ -3,30 +3,17 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.logging.Logger;
 
 import org.lcsim.util.log.LogUtil;
 
 /**
- * This is a list of <code>File</code> objects that are assumed to be EVIO files. There are some added utilities for getting the total number of
- * events in all the files.
+ * This is a list of <code>File</code> objects that are assumed to be EVIO files.
  *
  * @author Jeremy McCormick, SLAC
  */
 final class EvioFileList extends ArrayList<File> {
-
-    /**
-     * Setup logger.
-     */
-    private static final Logger LOGGER = LogUtil.create(EvioFileList.class);
-
-    /**
-     * Event count by file.
-     */
-    private final Map<File, Integer> eventCounts = new HashMap<File, Integer>();
 
     /**
      * Get the first file.
@@ -38,57 +25,12 @@
     }
 
     /**
-     * Get the event count for an EVIO file.
-     *
-     * @param file the EVIO file
-     * @return the event count for the file
-     * @throws RuntimeException if the count was never computed (file is not in map)
-     */
-    int getEventCount(final File file) {
-        if (this.eventCounts.get(file) == null) {
-            throw new RuntimeException("The event count for " + file.getPath() + " was never computed.");
-        }
-        return this.eventCounts.get(file);
-    }
-
-    /**
-     * Get the total number of events.
-     * <p>
-     * Files which do not have their event counts computed will be ignored.
-     *
-     * @return the total number of events
-     */
-    int getTotalEvents() {
-        int totalEvents = 0;
-        for (final File file : this) {
-            if (this.eventCounts.containsKey(file)) {
-                totalEvents += this.eventCounts.get(file);
-            } else {
-                // Warn about non-computed count.
-                // FIXME: Perhaps this should actually be a fatal error.
-                LOGGER.warning("event count for " + file.getPath() + " was not computed and will not be reflected in total");
-            }
-        }
-        return totalEvents;
-    }
-    
-    /**
      * Get the last file.
      *
      * @return the last file
      */
     File last() {
         return this.get(this.size() - 1);
-    }
-
-    /**
-     * Set the event count for a file.
-     *
-     * @param file the EVIO file
-     * @param eventCount the event count
-     */
-    void setEventCount(final File file, final Integer eventCount) {
-        this.eventCounts.put(file, eventCount);
     }
 
     /**

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java	Fri Jul 10 16:05:22 2015
@@ -14,7 +14,7 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * A miscellaneous collection of EVIO file utility methods used by classes in the crawler package.
+ * A miscellaneous collection of EVIO file utility methods used by the crawler package.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -108,23 +108,33 @@
     }
 
     /**
-     * Get the run end date which is taken either from the END event or the last physics event is the END event is not found.
+     * Get the run end date which is taken either from the END event or the last physics event if the END event is not
+     * found in the file.
      *
      * @param file the EVIO file
      * @return the run end date
      */
     static Date getRunEnd(final File file) {
-        Date date = getControlDate(file, EvioEventConstants.END_EVENT_TAG, -10);
-        if (date == null) {
+        
+        // Search for the END event in the last 10 events of the file.
+        Date endDate = getControlDate(file, EvioEventConstants.END_EVENT_TAG, -10);
+       
+        // Was the end date found from the END event?
+        if (endDate == null) {
+             
             EvioReader reader = null;
             try {
                 reader = open(file, true);
-                reader.gotoEventNumber(reader.getEventCount() - 11);
+                
+                // Search for the last physics event in the last 10 events of the file.
+                reader.gotoEventNumber(reader.getEventCount() - 10);
                 EvioEvent event = null;
                 while ((event = reader.parseNextEvent()) != null) {
                     if (EvioEventUtilities.isPhysicsEvent(event)) {
-                        if ((date = getHeadBankDate(event)) != null) {
-                            break;
+                        Date eventDate = getHeadBankDate(event);
+                        if (eventDate != null) {
+                            // This might be set multiple times but should result in the time of the last physics event.
+                            endDate = eventDate;
                         }
                     }
                 }
@@ -140,7 +150,7 @@
                 }
             }
         }
-        return date;
+        return endDate;
     }
 
     /**
@@ -158,16 +168,22 @@
     }
 
     /**
-     * Get the run start date from an EVIO file (should be the first in the run).
+     * Get the run start date from an EVIO file (should be the first file in the run).
      * <p>
-     * This is taken from the PRESTART event.
+     * This is taken from the PRESTART event if available or the first physics event.
      *
      * @param file the EVIO file
      * @return the run start date
      */
     static Date getRunStart(final File file) {
+        
+        // First try to find the start date in the special PRESTART event.
         Date date = getControlDate(file, EvioEventConstants.PRESTART_EVENT_TAG, 0);
+        
+        // Was start date not found from PRESTART?
         if (date == null) {
+            
+            // Read events until there is a physics event and use its time for the start date.
             EvioReader reader = null;
             try {
                 reader = open(file, true);
@@ -195,7 +211,7 @@
     }
 
     /**
-     * Get the EVIO file sequence number (the number at the end of the file name).
+     * Get the EVIO file sequence number, which is the number at the end of the file name.
      *
      * @param file the EVIO file
      * @return the file's sequence number
@@ -207,7 +223,7 @@
     }
 
     /**
-     * Return <code>true</code> if this is a cached file e.g. the path starts with "/cache".
+     * Return <code>true</code> if this is a file on the cache disk e.g. the path starts with "/cache".
      *
      * @param file the file
      * @return <code>true</code> if the file is a cached file
@@ -227,7 +243,7 @@
     }
 
     /**
-     * Open an EVIO file using a <code>EvioReader</code>.
+     * Open an EVIO file using an <code>EvioReader</code> in memory mapping mode.
      *
      * @param file the EVIO file
      * @return the new <code>EvioReader</code> for the file
@@ -260,14 +276,14 @@
     }
 
     /**
-     * Open an EVIO from a path.
-     *
-     * @param path the file path
+     * Open an EVIO file from a path string.
+     *
+     * @param path the path string
      * @return the new <code>EvioReader</code> for the file
      * @throws IOException if there is an IO problem
      * @throws EvioException if there is an error reading the EVIO data
      */
     static EvioReader open(final String path) throws IOException, EvioException {
-        return open(new File(path), true);
+        return open(new File(path), false);
     }
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java	Fri Jul 10 16:05:22 2015
@@ -16,9 +16,7 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * A file visitor that crawls directories for EVIO files.
- * <p>
- * It updates a run log to keep track of which files are associated with which run numbers.
+ * A file visitor that crawls directories for EVIO files and returns the information as a {@link RunLog}.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -62,7 +60,7 @@
         boolean accept = true;
         for (final FileFilter filter : this.filters) {
             accept = filter.accept(file);
-            if (accept == false) {
+            if (!accept) {
                 LOGGER.finer(filter.getClass().getSimpleName() + " rejected " + file.getPath());
                 break;
             }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java	Fri Jul 10 16:05:22 2015
@@ -5,6 +5,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
+import java.text.DecimalFormat;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -20,7 +21,7 @@
 import org.xml.sax.InputSource;
 
 /**
- * Utility class for using the <i>jcache</i> command at JLAB.
+ * Utility class for caching files from the MSS to cache disk at JLAB.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -50,7 +51,7 @@
          * The current status from executing the 'jcache request' command.
          */
         private String status;
-        
+
         /**
          * The xml node with request data.
          */
@@ -98,9 +99,7 @@
             } catch (final IOException e) {
                 throw new RuntimeException(e);
             }
-            // LOGGER.finer("raw XML: " + xmlString);
             xmlString = xmlString.substring(xmlString.trim().indexOf("<jcache>"));
-            // LOGGER.finer("cleaned XML: " + xmlString);
             return buildDocument(xmlString).getRootElement();
         }
 
@@ -152,14 +151,14 @@
         boolean isPending() {
             return "pending".equals(this.status);
         }
-        
+
         /**
          * Return <code>true</code> if status is "failed".
          */
         boolean isFailed() {
             return "failed".equals(this.status);
         }
-        
+
         /**
          * Get the error message from the XML request.
          * 
@@ -172,7 +171,7 @@
                 return "";
             }
         }
-      
+
         /**
          * Run the <i>jcache request</i> command for this request ID and return the XML output.
          * 
@@ -194,7 +193,7 @@
             if (status != 0) {
                 throw new RuntimeException("The jcache request returned an error status: " + status);
             }
-            return this.getRequestXml(process.getInputStream());            
+            return this.getRequestXml(process.getInputStream());
         }
 
         /**
@@ -203,10 +202,10 @@
         void update() {
             // Request status update and get the XML from that process.
             this.xml = request();
-            
+
             // Update the status from the XML.
             this.status = this.xml.getChild("request").getChild("file").getChildText("status");
-            
+
             // Is request done or file already in cache?
             if (this.isDone() || this.isHit()) {
                 // Flag file as cached.
@@ -231,9 +230,9 @@
     private static Logger LOGGER = LogUtil.create(JCacheManager.class, new DefaultLogFormatter(), Level.FINE);
 
     /**
-     * Time to wait between polling of all files (~10 seconds).
-     */
-    private static final long POLL_WAIT_TIME = 10000;
+     * Time to wait between re-polling all files (30 seconds).
+     */
+    private static final long POLL_WAIT_TIME = 30000;
 
     /**
      * Build an XML document from a string.
@@ -242,7 +241,7 @@
      * @return the XML document
      */
     private static Document buildDocument(final String xmlString) {
-        LOGGER.fine("building doc from string: " + xmlString);
+        LOGGER.fine(xmlString);
         final SAXBuilder builder = new SAXBuilder();
         Document document = null;
         try {
@@ -293,14 +292,14 @@
     private long maxWaitTime = DEFAULT_MAX_WAIT_TIME;
 
     /**
-     * The time when the caching operation starts.
+     * The time in milliseconds when the caching operation started.
      */
     long start = 0;
 
     /**
      * Cache a file by submitting a 'jcache submit' process.
      * <p>
-     * The resulting cache request will be registered with this manager until the {@link #clear()} method is called.
+     * The resulting cache request will be registered with this manager.
      *
      * @param file the file to cache which should be a path on the JLAB MSS (e.g. starts with '/mss')
      */
@@ -311,7 +310,7 @@
         }
 
         if (EvioFileUtilities.getCachedFile(file).exists()) {
-            // Assume (maybe unreasonably?!) that since the file already exists it will stay in the cache for the duration of the job.
+            // Assume that since the file already exists it will stay in the cache for the duration of the job.
             LOGGER.fine(file.getPath() + " is already on the cache disk so cache request is ignored");
         } else {
 
@@ -330,7 +329,7 @@
     }
 
     /**
-     * Submit cache request for every file in a list.
+     * Submit a cache request for every file in the list.
      *
      * @param files the list of files
      */
@@ -356,7 +355,8 @@
             // Get the cache status for a single file.
             final CacheStatus cacheStatus = entry.getValue();
 
-            LOGGER.info("checking status of " + cacheStatus.getFile().getPath() + " with req ID '" + cacheStatus.getRequestId() + "' ...");
+            LOGGER.info("checking status of " + cacheStatus.getFile().getPath() + " with req ID '"
+                    + cacheStatus.getRequestId() + "' ...");
 
             // Is this file flagged as not non-cached?
             if (!cacheStatus.isCached()) {
@@ -375,9 +375,10 @@
                     LOGGER.info(entry.getKey() + " is NOT cached with status " + cacheStatus.getStatus(false));
                 } else {
                     // Log that this file is now cached. It will not be checked next time.
-                    LOGGER.info(cacheStatus.getFile().getPath() + " is cached with status " + cacheStatus.getStatus(false));
+                    LOGGER.info(cacheStatus.getFile().getPath() + " is cached with status "
+                            + cacheStatus.getStatus(false));
                 }
-                
+
                 // Did the request fail?
                 if (cacheStatus.isFailed()) {
                     // Cache failure is a fatal error.
@@ -535,6 +536,11 @@
                 break;
             }
         }
+
+        double end = (double) (System.currentTimeMillis() - this.start);
+
+        LOGGER.info("caching took " + new DecimalFormat("#.##").format(end / 1000. / 60.) + " minutes");
+
         if (cached) {
             LOGGER.info("all files cached successfully!");
         } else {

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java	Fri Jul 10 16:05:22 2015
@@ -5,7 +5,7 @@
 import java.util.Set;
 
 /**
- * A filter which rejects files that have a run number not in the accept list.
+ * A filter which rejects files with run numbers not in a specified set.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -17,7 +17,7 @@
     private final Set<Integer> acceptRuns;
 
     /**
-     * Create a new <code>RunFilter</code> with a set of runs to accept.
+     * Create a new <code>RunFilter</code> with a set of run numbers to accept.
      *
      * @param acceptRuns the set of runs to accept
      */
@@ -29,7 +29,7 @@
     }
 
     /**
-     * Returns <code>true</code> if file is accepted (its run number is in the set).
+     * Returns <code>true</code> if file is accepted.
      *
      * @param file the EVIO file
      * @return <code>true</code> if file is accepted

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java	Fri Jul 10 16:05:22 2015
@@ -11,9 +11,7 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * This class contains summary information about a series of runs which are modeled with the {@link RunSummary} class.
- * <p> 
- * These can be looked up by their run number {@link #getRunSummary(int)}.
+ * This class contains information about a series of runs which each have a {@link RunSummary} object.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -30,9 +28,9 @@
     private final Map<Integer, RunSummary> runs = new LinkedHashMap<Integer, RunSummary>();
 
     /**
-     * Get a run summary by run number.
+     * Get a {@link RunSummary} by its run number.
      * <p>
-     * It will be created if it does not exist.
+     * It will be created if it does not exist already.
      *
      * @param run the run number
      * @return the <code>RunSummary</code> for the run number
@@ -44,15 +42,20 @@
         }
         return this.runs.get(run);
     }
-    
+
+    /**
+     * Get the collection of {@link RunSummary} objects.
+     * 
+     * @return the collection of {@link RunSummary} objects
+     */
     public Collection<RunSummary> getRunSummaries() {
         return this.runs.values();
     }
 
     /**
-     * Get a list of sorted run numbers in this run log.
+     * Get a list of sorted run numbers from this run log.
      * <p>
-     * This is a copy of the keys from the map so modifying it will have no effect on this class.
+     * This is a copy of the keys from the map, so modifying it will have no effect on the original.
      *
      * @return the list of sorted run numbers
      */
@@ -63,7 +66,7 @@
     }
 
     /**
-     * Print out the run summaries to <code>System.out</code>.
+     * Print out each {@link RunSummary} to <code>System.out</code>.
      */
     void printRunSummaries() {
         for (final int run : this.runs.keySet()) {
@@ -72,11 +75,24 @@
     }
 
     /**
-     * Sort all the file lists in place (by sequence number).
+     * Sort the file list for each run in place by EVIO sequence numbers.
      */
-    void sortAllFiles() {
+    void sortFiles() {
         for (final Integer run : this.runs.keySet()) {
             this.runs.get(run).sortFiles();
         }
     }
+
+    /**
+     * Print the run numbers to the log.
+     */
+    void printRunNumbers() {
+        // Print the list of runs that were found.
+        final StringBuffer sb = new StringBuffer();
+        for (final Integer run : getSortedRunNumbers()) {
+            sb.append(run + " ");
+        }
+        LOGGER.info("found EVIO files from runs: " + sb.toString());
+    }
+
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java	Fri Jul 10 16:05:22 2015
@@ -15,27 +15,27 @@
  * @author Jeremy McCormick, SLAC
  */
 public class RunLogUpdater {
-    
+
     /**
      * Setup logging.
      */
     private static final Logger LOGGER = LogUtil.create(RunLogUpdater.class);
-    
+
     /**
      * The run log with information for all runs.
      */
     private RunLog runLog;
-    
+
     /**
      * The database connection.
      */
     private final Connection connection;
-    
+
     /**
      * <code>true</code> if updates should be allowed in database or only inserts.
      */
     private boolean allowUpdates = false;
-    
+
     /**
      * Create a new updater.
      * 
@@ -43,54 +43,54 @@
      * @param allowUpdates <code>true</code> if updates should be allowed
      */
     RunLogUpdater(Connection connection, RunLog runLog, boolean allowUpdates) {
-        
+
         // Set the DB connection.
         this.connection = connection;
-        
+
         // Set the run log with the run info to update.
         this.runLog = runLog;
-        
+
         // Set whether db updates are allowed (replacement of existing records).
         this.allowUpdates = allowUpdates;
     }
-            
+
     /**
-     * Insert the run summary information into the database, including updating the <i>run_log_files</i>
-     * and <i>run_log_epics</i> tables.
+     * Insert the run summary information into the database, including updating the <i>run_log_files</i> and
+     * <i>run_log_epics</i> tables.
      *
      * @param connection the database connection
      * @throws SQLException if there is an error querying the database
      */
     void insert() throws SQLException {
-        
+
         LOGGER.info("inserting run data into database ...");
         try {
             connection.setAutoCommit(false);
-            
+
             // Loop over all runs found while crawling.
             for (final Integer run : runLog.getSortedRunNumbers()) {
-                
+
                 LOGGER.info("beginning transaction for run " + run);
-                
+
                 // Get the RunSummary data for the run.
                 RunSummary runSummary = runLog.getRunSummary(run);
-                                               
+
                 LOGGER.info("updating " + runSummary);
-                                
-                // Create the db updater for the RunSummary.
+
+                // Create the database updater for the RunSummary.
                 RunSummaryUpdater runUpdater = new RunSummaryUpdater(connection, runSummary);
-                                                
+
                 // Set whether existing records can be replaced.
                 runUpdater.setAllowDeleteExisting(allowUpdates);
-                
+
                 LOGGER.info("allow updates: " + allowUpdates);
-                
+
                 // Insert the run records.
                 runUpdater.insert();
-                
+
                 LOGGER.info("run " + runSummary.getRun() + " summary inserted successfully");
             }
-            
+
         } catch (final SQLException e) {
             LOGGER.log(Level.SEVERE, "rolling back transaction", e);
             try {
@@ -99,8 +99,8 @@
                 LOGGER.log(Level.SEVERE, "error rolling back transaction", e2);
                 throw new RuntimeException(e);
             }
-        } 
-        
+        }
+
         LOGGER.info("done inserting run data");
-    }             
+    }
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java	Fri Jul 10 16:05:22 2015
@@ -20,19 +20,34 @@
 /**
  * Processes EVIO files from a run in order to extract various meta data information including start and end dates.
  * <p>
- * This class is a wrapper for activating different sub-tasks, including optionally caching all files from the JLAB MSS to the cache disk.
+ * This class is a wrapper for activating different sub-tasks, including optionally caching all files from the JLAB MSS
+ * to the cache disk.
  * <p>
  * There is also a list of processors which is run on all events from the run.
  *
  * @author Jeremy McCormick, SLAC
  */
-// FIXME: Replace this class with Freehep loop implementation, EvioFileSource, etc.
 final class RunProcessor {
 
     /**
      * Setup logger.
      */
     private static final Logger LOGGER = LogUtil.create(RunProcessor.class, new DefaultLogFormatter(), Level.FINE);
+
+    /**
+     * Processor for extracting EPICS information.
+     */
+    private EpicsLog epicsLog;
+
+    /**
+     * Processor for extracting scaler data.
+     */
+    private ScalersEvioProcessor scalersProcessor;
+
+    /**
+     * Processor for extracting event type counts (sync, physics, trigger types, etc.).
+     */
+    private EventTypeLog eventTypeLog;
 
     /**
      * Create the processor for a single run.
@@ -40,34 +55,34 @@
      * @param runSummary the run summary for the run
      * @return the run processor
      */
-    static RunProcessor createRunProcessor(final JCacheManager cacheManager, final RunSummary runSummary, CrawlerConfig config) {
-
-        // Create new run processor.
-        final RunProcessor processor = new RunProcessor(runSummary, cacheManager);
+    RunProcessor(final JCacheManager cacheManager, final RunSummary runSummary, CrawlerConfig config) {
+
+        this.runSummary = runSummary;
+        this.cacheManager = cacheManager;
 
         // EPICS processor.
-        processor.addProcessor(new EpicsLog(runSummary));
+        epicsLog = new EpicsLog(runSummary);
+        addProcessor(epicsLog);
 
         // Scaler data processor.
-        final ScalersEvioProcessor scalersProcessor = new ScalersEvioProcessor();
+        scalersProcessor = new ScalersEvioProcessor();
         scalersProcessor.setResetEveryEvent(false);
-        processor.addProcessor(scalersProcessor);
+        addProcessor(scalersProcessor);
 
         // Event log processor.
-        processor.addProcessor(new EventTypeLog(runSummary));
+        eventTypeLog = new EventTypeLog(runSummary);
+        addProcessor(eventTypeLog);
 
         // Max files.
         if (config.maxFiles() != -1) {
-            processor.setMaxFiles(config.maxFiles());
+            setMaxFiles(config.maxFiles());
         }
 
         // Enable file caching.
-        processor.useFileCache(config.useFileCache());
+        useFileCache(config.useFileCache());
 
         // Set event printing interval.
-        processor.setEventPrintInterval(config.eventPrintInterval());
-
-        return processor;
+        setEventPrintInterval(config.eventPrintInterval());
     }
 
     /**
@@ -99,17 +114,6 @@
      * Set to <code>true</code> to use file caching.
      */
     private boolean useFileCache;
-
-    /**
-     * Create a new run processor.
-     *
-     * @param runSummary the run summary to update
-     * @param cacheManager the cache manager for executing 'jcache' commands
-     */
-    RunProcessor(final RunSummary runSummary, final JCacheManager cacheManager) {
-        this.runSummary = runSummary;
-        this.cacheManager = cacheManager;
-    }
 
     /**
      * Add a processor of EVIO events.
@@ -124,8 +128,8 @@
     /**
      * Cache all files and wait for the operation to complete.
      * <p>
-     * Potentially, this operation can take a very long time. This can be managed using the {@link JCacheManager#setWaitTime(long)} method to set a
-     * timeout.
+     * Potentially, this operation can take a very long time. This can be managed using the
+     * {@link JCacheManager#setWaitTime(long)} method to set a timeout.
      */
     private void cacheFiles() {
 
@@ -166,8 +170,8 @@
         if (this.maxFiles != -1) {
             int toIndex = this.maxFiles;
             if (toIndex > files.size()) {
-                toIndex = files.size();                
-            }            
+                toIndex = files.size();
+            }
             files = files.subList(0, toIndex);
         }
         return files;
@@ -182,17 +186,9 @@
         return this.processors;
     }
 
-    ScalersEvioProcessor getScalersProcessor() {
-        for (final EvioEventProcessor processor : this.processors) {
-            if (processor instanceof ScalersEvioProcessor) {
-                return ScalersEvioProcessor.class.cast(processor);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return <code>true</code> if a valid CODA <i>END</i> event can be located in the <code>EvioReader</code>'s current file.
+    /**
+     * Return <code>true</code> if a valid CODA <i>END</i> event can be located in the <code>EvioReader</code>'s current
+     * file.
      *
      * @param reader the EVIO reader
      * @return <code>true</code> if valid END event is located
@@ -218,8 +214,8 @@
     }
 
     /**
-     * Process the run by executing the registered {@link org.hps.record.evio.EvioEventProcessor}s and performing special tasks such as the extraction
-     * of start and end dates.
+     * Process the run by executing the registered {@link org.hps.record.evio.EvioEventProcessor}s and performing
+     * special tasks such as the extraction of start and end dates.
      * <p>
      * This method will also activate file caching, if enabled by the {@link #useFileCache} option.
      *
@@ -240,9 +236,9 @@
         }
 
         List<File> files = this.getFiles();
-        
+
         LOGGER.info("processing " + files.size() + " from run " + this.runSummary.getRun());
-        
+
         // Process all the files.
         for (final File file : files) {
             this.process(file);
@@ -281,12 +277,6 @@
                 LOGGER.fine("got run start " + runStart);
                 this.runSummary.setStartDate(runStart);
             }
-
-            // Compute the event count for the file and store the value in the run summary's file list.
-            LOGGER.info("getting event count for " + file.getPath() + "...");
-            final int eventCount = this.computeEventCount(reader);
-            this.runSummary.getEvioFileList().setEventCount(file, eventCount);
-            LOGGER.info("set event count " + eventCount + " for " + file.getPath());
 
             // Process the events using the EVIO processors.
             LOGGER.info("running EVIO processors ...");
@@ -319,10 +309,10 @@
             }
 
             // Pull scaler data from EVIO processor into run summary.
-            final ScalersEvioProcessor scalersProcessor = this.getScalersProcessor();
-            if (scalersProcessor != null) {
-                runSummary.setScalerData(scalersProcessor.getScalerData());
-            }
+            runSummary.setScalerData(this.scalersProcessor.getScalerData());
+
+            // Set total number of physics events.
+            runSummary.setTotalEvents(this.eventTypeLog.getPhysicsEventCount());
 
         } finally {
             if (reader != null) {
@@ -356,7 +346,8 @@
     /**
      * Set whether or not to use the file caching, which copies files from the JLAB MSS to the cache disk.
      * <p>
-     * Since EVIO data files at JLAB are primarily kept on the MSS, running without this option enabled there will likely cause the job to fail.
+     * Since EVIO data files at JLAB are primarily kept on the MSS, running without this option enabled there will
+     * likely cause the job to fail.
      *
      * @param cacheFiles <code>true</code> to enabled file caching
      */
@@ -364,7 +355,7 @@
         this.useFileCache = cacheFiles;
         LOGGER.config("file caching enabled");
     }
-    
+
     /**
      * Process all the runs that were found.
      *
@@ -372,27 +363,28 @@
      * @throws Exception if there is an error processing one of the runs
      */
     static void processRuns(JCacheManager cacheManager, final RunLog runs, CrawlerConfig config) throws Exception {
-        
+
         // Configure max wait time of jcache manager.
         if (config.waitTime() != null && config.waitTime() > 0L) {
             cacheManager.setWaitTime(config.waitTime());
             LOGGER.config("JCacheManager max wait time set to " + config.waitTime());
-        }                                
-        
+        }
+
         // Process all of the runs that were found.
         for (final int run : runs.getSortedRunNumbers()) {
-            
+
             // Get the run summary.
             RunSummary runSummary = runs.getRunSummary(run);
-            
+
             // Clear the cache manager.
             if (config.useFileCache()) {
                 cacheManager.clear();
             }
 
             // Create a processor to process all the EVIO events in the run.
-            final RunProcessor runProcessor = RunProcessor.createRunProcessor(cacheManager, runSummary, config);
-
+            final RunProcessor runProcessor = new RunProcessor(cacheManager, runSummary, config);
+
+            // Add extra processors.
             for (final EvioEventProcessor processor : config.processors()) {
                 runProcessor.addProcessor(processor);
                 LOGGER.config("added extra EVIO processor " + processor.getClass().getName());

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java	Fri Jul 10 16:05:22 2015
@@ -15,8 +15,8 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * This class models the run summary information which is persisted as a row in the <i>run_log</i>
- * table of the run database.
+ * This class models the run summary information which is persisted as a row in the <i>run_log</i> table of the run
+ * database.
  * <p>
  * This information includes:
  * <ul>
@@ -40,7 +40,7 @@
     static {
         DATE_DISPLAY.setCalendar(new GregorianCalendar(TimeZone.getTimeZone("America/New_York")));
     }
-    
+
     /**
      * Setup logger.
      */
@@ -151,7 +151,7 @@
     public EvioFileList getEvioFileList() {
         return this.files;
     }
-    
+
     /**
      * Get the run number.
      *
@@ -185,12 +185,13 @@
      * @return the total events in the run
      */
     public int getTotalEvents() {
-        if (this.totalEvents == -1) {
-            this.totalEvents = this.files.getTotalEvents();
-        }
         return this.totalEvents;
     }
-    
+
+    void setTotalEvents(int totalEvents) {
+        this.totalEvents = totalEvents;
+    }
+
     /**
      * Get the number of seconds in the run which is the difference between the start and end times.
      * 
@@ -205,10 +206,10 @@
         }
         return (getEndDate().getTime() - getStartDate().getTime()) / 1000;
     }
-    
-    /**
-     * Get the event rate (effectively the trigger rate) which is the total events divided by the number
-     * of seconds in the run.
+
+    /**
+     * Get the event rate (effectively the trigger rate) which is the total events divided by the number of seconds in
+     * the run.
      * 
      * @return the event rate
      */
@@ -289,6 +290,11 @@
         this.eventTypeCounts = eventTypeCounts;
     }
 
+    /**
+     * Set the scaler data of the run.
+     * 
+     * @param scalerData the scaler data
+     */
     void setScalerData(final ScalerData scalerData) {
         this.scalerData = scalerData;
     }
@@ -316,7 +322,7 @@
      */
     @Override
     public String toString() {
-        return "RunSummary { run: " + this.run + ", started: " + this.getStartDate() + ", ended: " + this.getEndDate() + ", events: "
-                + this.getTotalEvents() + ", endOkay: " + endOkay + " }";
+        return "RunSummary { run: " + this.run + ", started: " + this.getStartDate() + ", ended: " + this.getEndDate()
+                + ", events: " + this.getTotalEvents() + ", endOkay: " + endOkay + " }";
     }
 }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java	Fri Jul 10 16:05:22 2015
@@ -74,13 +74,13 @@
 
         // Delete scaler data.
         this.deleteScalerData();
-        
+
         // Delete file list.
         this.deleteFiles();
 
         // Delete run log.
         this.deleteRun();
-                
+
         LOGGER.info("deleted run " + runSummary.getRun() + " info successfully");
     }
 
@@ -94,7 +94,7 @@
         statement.setInt(1, this.run);
         statement.executeUpdate();
     }
-    
+
     /**
      * Delete existing EPICS data from the run_log_epics table.
      *
@@ -136,7 +136,7 @@
     }
 
     void insert() throws SQLException {
-        
+
         LOGGER.info("performing db insert for " + runSummary);
 
         // Turn auto-commit off as this whole method is a single transaction.
@@ -150,7 +150,8 @@
                 this.delete();
             } else {
                 // Rows exist but updating is disallowed which is a fatal error.
-                final RuntimeException x = new RuntimeException("Run " + runSummary.getRun() + " already exists and deleting is not allowed.");
+                final RuntimeException x = new RuntimeException("Run " + runSummary.getRun()
+                        + " already exists and deleting is not allowed.");
                 LOGGER.log(Level.SEVERE, x.getMessage(), x);
                 throw x;
             }
@@ -184,7 +185,8 @@
      * @throws SQLException if there is an error performing the db query
      */
     private void insertEpics() throws SQLException {
-        final PreparedStatement statement = connection.prepareStatement("INSERT INTO run_epics (run, variable_name, value) values (?, ?, ?)");
+        final PreparedStatement statement = connection
+                .prepareStatement("INSERT INTO run_epics (run, variable_name, value) values (?, ?, ?)");
         final EpicsData data = runSummary.getEpicsData();
         if (data != null) {
             for (final String variableName : data.getUsedNames()) {
@@ -254,6 +256,11 @@
         return rs.first();
     }
 
+    /**
+     * Set whether deletion and replacement of existing run information is allowed.
+     * 
+     * @param allowDeleteExisting <code>true</code> to allow deletion and replacement of existing information
+     */
     void setAllowDeleteExisting(final boolean allowDeleteExisting) {
         this.allowDeleteExisting = allowDeleteExisting;
     }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/ScalerDataUpdater.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/ScalerDataUpdater.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/ScalerDataUpdater.java	Fri Jul 10 16:05:22 2015
@@ -8,38 +8,77 @@
 import org.hps.record.scalers.ScalerData;
 
 /**
- * Database interface for inserting scaler data into the run log.
+ * Inserts scaler data into the run database.
  * 
  * @author Jeremy McCormick, SLAC
  */
 public class ScalerDataUpdater {
 
+    /**
+     * <code>true</code> if existing data can be replaced and deleted.
+     */
     private boolean allowDeleteExisting = false;
 
+    /**
+     * The database connection.
+     */
     private final Connection connection;
 
+    /**
+     * The scaler data to insert into the database.
+     */
     private final ScalerData data;
 
+    /**
+     * The run number for recording the scaler data.
+     */
     private final int run;
 
+    /**
+     * SQL delete query string.
+     */
     private final String SQL_DELETE = "DELETE FROM run_scalers WHERE run = ?";
 
+    /**
+     * SQL insert query string.
+     */
     private final String SQL_INSERT = "INSERT INTO run_scalers (run, idx, value) VALUES (?, ?, ?)";
 
+    /**
+     * SQL select query string.
+     */
     private final String SQL_SELECT = "SELECT run FROM run_scalers WHERE run = ?";
 
+    /**
+     * Create an updater for the given scaler data.
+     * 
+     * @param connection the database connection
+     * @param data the scaler data
+     * @param run the run number
+     */
     ScalerDataUpdater(final Connection connection, final ScalerData data, final int run) {
         this.connection = connection;
         this.data = data;
         this.run = run;
     }
 
+    /**
+     * Delete scaler data for the run.
+     * 
+     * @throws SQLException if there is a SQL query error
+     */
     private void delete() throws SQLException {
         final PreparedStatement s = connection.prepareStatement(SQL_DELETE);
         s.setInt(1, run);
         s.executeUpdate();
     }
 
+    /**
+     * Return <code>true</code> if scaler data exists for the run number.
+     * 
+     * @return <code>true</code> if scaler data exists
+     * @throws SQLException if there is a SQL query error
+     */
     private boolean exists() throws SQLException {
         final PreparedStatement s = connection.prepareStatement(SQL_SELECT);
         s.setInt(1, run);
@@ -47,6 +86,14 @@
         return rs.first();
     }
 
+    /**
+     * Insert scaler data for this run number into the database.
+     * <p>
+     * Includes check on whether data exists and can be replaced or not.
+     * 
+     * @throws SQLException if there is a SQL query error
+     * @throws RuntimeException if data exists and cannot be deleted
+     */
     void insert() throws SQLException {
         if (this.exists()) {
             if (allowDeleteExisting) {
@@ -62,6 +109,11 @@
         }
     }
 
+    /**
+     * Insert scaler data into the database.
+     *  
+     * @throws SQLException if there is a SQL query error
+     */
     private void insertScalerData() throws SQLException {
         final PreparedStatement statement;
         try {
@@ -77,6 +129,11 @@
         }
     }
 
+    /**
+     * Set whether existing data can be deleted and replaced.
+     * 
+     * @param allowDeleteExisting <code>true</code> if existing data can be replaced     
+     */
     void setAllowDeleteExisting(final boolean allowDeleteExisting) {
         this.allowDeleteExisting = allowDeleteExisting;
     }

Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java	Fri Jul 10 16:05:22 2015
@@ -1,8 +1,7 @@
 /**
- * Implements an EVIO file crawler to extract run and configuration information.
+ * Implements an EVIO file crawler to extract run meta data and update a run database with this information.
  * <p>
- * This information includes run start and end dates, event counts, EPICS data, scaler data, 
- * and the list of associated EVIO files.
+ * This includes run start and end dates, event counts, EPICS data, scaler data, and the list of associated EVIO files.
  *
  * @author Jeremy McCormick, SLAC
  */

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use