Print

Print


Commit in java/trunk/monitoring-app on MAIN
pom.xml+1-1697 -> 698
src/main/java/org/hps/monitoring/DefaultEtEventProcessor.java-561697 removed
                                /EventPanel.java+24-43697 -> 698
                                /EventPanelUpdater.java+69added 698
                                /EvioFileProducer.java+3-3697 -> 698
                                /MonitoringApplication.java+255-468697 -> 698
                                /MonitoringApplicationMain.java+59added 698
                                /MonitoringCommands.java+16-23697 -> 698
                                /OldEtEventProcessor.java-152697 removed
src/main/java/org/hps/monitoring/record/EventProcessingChain.java+128-126697 -> 698
                                       /EventProcessingStep.java+12added 698
                                       /EventProcessingThread.java+15-14697 -> 698
                                       /EventProcessor.java+25-7697 -> 698
src/main/java/org/hps/monitoring/record/composite/CompositeRecord.java+41added 698
                                                 /CompositeRecordLoop.java+41added 698
                                                 /CompositeRecordLoopAdapter.java+39added 698
                                                 /CompositeRecordSource.java+82added 698
src/main/java/org/hps/monitoring/record/etevent/EtConnection.java+8697 -> 698
                                               /EtEventAdapter.java+2-2697 -> 698
                                               /EtEventProcessor.java+15-13697 -> 698
                                               /EtEventSource.java+2-2697 -> 698
src/main/java/org/hps/monitoring/record/evio/EvioAdapter.java+19-1697 -> 698
                                            /EvioEventLoop.java+3-1697 -> 698
                                            /EvioEventProcessor.java+12-2697 -> 698
                                            /EvioFileSource.java+2697 -> 698
src/main/java/org/hps/monitoring/subsys/et/EtSystemMonitor.java+2-2697 -> 698
src/main/scripts/start_monitoring_application.sh+4-4697 -> 698
src/test/java/org/hps/monitoring/record/EventProcessingChainTest.java+11-6697 -> 698
                                       /EvioEventProcessingTest.java+79added 698
src/test/java/org/hps/monitoring/subsys/et/EtSystemMonitorTest.java+2-1697 -> 698
+971-1432
8 added + 2 removed + 20 modified, total 30 files
Overhaul of the monitoring application record handling backend.  And a lot of other stuff too.

java/trunk/monitoring-app
pom.xml 697 -> 698
--- java/trunk/monitoring-app/pom.xml	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/pom.xml	2014-06-10 23:01:18 UTC (rev 698)
@@ -31,7 +31,7 @@
                             <transformers>
                                 <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                                 <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
-                                    <mainClass>org.hps.monitoring.MonitoringApplication</mainClass>
+                                    <mainClass>org.hps.monitoring.MonitoringApplicationMain</mainClass>
                                 </transformer>
                             </transformers>
                             <artifactSet>

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
DefaultEtEventProcessor.java removed after 697
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/DefaultEtEventProcessor.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/DefaultEtEventProcessor.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -1,561 +0,0 @@
-package org.hps.monitoring;
-
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.hps.evio.EventConstants;
-import org.hps.evio.LCSimEventBuilder;
-import org.hps.monitoring.record.etevent.EtConnection;
-import org.hps.monitoring.record.etevent.EtEventListener;
-import org.jlab.coda.et.EtEvent;
-import org.jlab.coda.et.exception.EtTimeoutException;
-import org.jlab.coda.jevio.EvioEvent;
-import org.jlab.coda.jevio.EvioException;
-import org.jlab.coda.jevio.EvioReader;
-import org.lcsim.event.EventHeader;
-import org.lcsim.job.JobControlManager;
-
-/**
- * This class executes the default event processing chain for HPS Test Run monitoring: ET -> EVIO -> LCIO.
- * {@link EtEventListener} objects can be registered with this class to receive notifications 
- * as processing occurs.  This is how the {@link MonitoringApplication} updates the GUI without the processor
- * having a direct reference to the actual application.
- * 
- * @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: DefaultEtEventProcessor.java,v 1.13 2013/10/25 23:13:53 jeremy Exp $
- */
-public class DefaultEtEventProcessor implements OldEtEventProcessor {
-
-    private int maxEvents;
-    private int eventsProcessed;
-    private int errorEvents;
-    private LCSimEventBuilder eventBuilder;
-    private JobControlManager jobManager;
-    private EtConnection et;
-    private List<EtEventListener> listeners = new ArrayList<EtEventListener>();
-    private int status;
-    private volatile boolean stopProcessing;
-    private volatile boolean nextEvents;
-    private volatile boolean stopOnError;
-    private volatile boolean pauseMode = false;
-    private volatile boolean done = false;
-    private volatile boolean blocked = false;
-    private static Logger logger;
-
-    /**
-     * Create an instance of the default EtEvent processor.
-     * @param et The ET connection.
-     * @param eventBuilder The builder for converting from EVIO to LCIO.
-     * @param jobManager The LCSim job manager.
-     * @param maxEvents Maximum number of events to process in the session.
-     * @param stopOnError True to stop on first error; false to continue processing.
-     * @param logHandler The log handler for redirecting log messages.
-     */
-    DefaultEtEventProcessor(
-            EtConnection et,
-            LCSimEventBuilder eventBuilder,
-            JobControlManager jobManager,
-            int maxEvents,
-            boolean stopOnError,
-            Handler logHandler) {
-
-        // Set class parameters.
-        this.et = et;
-        this.eventBuilder = eventBuilder;
-        this.jobManager = jobManager;
-        this.maxEvents = maxEvents;
-        this.stopOnError = stopOnError;
-
-        // Setup the logger if needed.  This will only happen once.
-        if (logger == null) {
-            logger = Logger.getLogger(this.getClass().getSimpleName());
-            logger.setUseParentHandlers(false);
-            logger.addHandler(logHandler);
-            logger.setLevel(Level.ALL);
-        }
-
-        // Log an initialization message.
-        logger.log(Level.CONFIG, "Event processor initialized successfully.");
-    }
-
-    /**
-     * Enable pause mode to pause between single events.
-     * @param p True to pause after each set of events; false to do real-time processing.
-     */
-    void setPauseMode(boolean p) {
-        this.pauseMode = p;
-    }
-
-    /**
-     * Add an <code>EtEventListener</code> that will receive a callback for each event.
-     * @param callme The EtEventListener to add.
-     */
-    public void addListener(EtEventListener callme) {
-        listeners.add(callme);
-    }
-
-    /**
-     * Set the maximum number of events before processing should stop.
-     * @param maxEvents The maximum number of events before processing should be stopped.
-     */
-    public void setMaxEvents(int maxEvents) {
-        this.maxEvents = maxEvents;
-        logger.log(Level.INFO, "Set maxEvents to <{0}>.", maxEvents);
-    }
-
-    /**
-     * Notify listeners of start of event processing. 
-     */
-    private void begin() {
-        for (EtEventListener listener : listeners) {
-            listener.begin();
-        }
-    }
-
-    /**
-     * Notify listeners of start of an event.
-     */
-    private void startOfEvent() {
-        for (EtEventListener listener : listeners) {
-            listener.startOfEvent();
-        }
-    }
-
-    /**
-     * Notify listeners of end of an event.
-     */
-    private void endOfEvent() {
-        for (EtEventListener listener : listeners) {
-            listener.endOfEvent();
-        }
-    }
-
-    /**
-     * Notify listeners that there was an error processing an event.
-     */
-    private void errorOnEvent() {
-        ++errorEvents;
-        for (EtEventListener listener : listeners) {
-            listener.errorOnEvent();
-        }
-    }
-
-    /**
-     * Notify listeners of end of job.
-     */
-    private void finish() {
-        logger.log(Level.FINER, "Calling finish() methods of listeners.");
-        for (EtEventListener listener : listeners) {
-            listener.finish();
-        }
-    }
-
-    /**
-     * Set the flag to stop processing events, which will cause the 
-     * event processing loop to stop the next time it checks this value.
-     */
-    public void stop() {
-        this.stopProcessing = true;
-        logger.log(Level.FINEST, "Received stop request.");
-    }
-
-    /**
-     * Get the total number of events processed thusfar.
-     * @return The number of events processed.
-     */
-    public int getNumberOfEventsProcessed() {
-        return eventsProcessed;
-    }
-
-    /**
-     * Get the total number of errors that have occurred.
-     * @return The number of errors that have happened.
-     */
-    public int getNumberOfErrors() {
-        return errorEvents;
-    }
-
-    /**
-     * Get the maximum number of events that should be processed before stopping.
-     * @return The maximum number of events to process.
-     */
-    public int getMaxEvents() {
-        return maxEvents;
-    }
-
-    /**
-     * Reset the event counter.
-     */
-    public void resetNumberOfEventsProcessed() {
-        eventsProcessed = 0;
-        errorEvents = 0;
-    }
-
-    /**
-     * Get the status of the processor.
-     * @return The status of the processor.
-     */
-    public int getStatus() {
-        return status;
-    }
-
-    /**
-     * Get EtEvents and process them.
-     * If in wait mode, continue after waitTime in microseconds if there are no events.
-     * If in async mode, expects non-empty event list immediately or an error occurs.
-     * If in sleep mode, the call to getEvents() will block, including requests to wake-up, until events arrive.
-     */
-    public void processEtEvents() throws EtTimeoutException, MaxEventsException, Exception {
-
-        /* 
-         * Get events from the ET system.  
-         * WARNING: This can potentially block forever until it receives events. 
-         */
-        blocked = true;
-        //EtEvent[] mevs = et.sys.getEvents(et.att, et.param.waitMode, Modify.NOTHING, et.param.waitTime, et.param.chunk);
-        EtEvent[] mevs = et.readEtEvents();
-        blocked = false;
-
-        // Loop over retrieved EtEvents.
-        for (EtEvent mev : mevs) {
-
-            // If running in pause mode, then hold here until the "Next Event" button is pressed.
-            if (pauseMode && this.status == ConnectionStatus.CONNECTED) {
-                logger.log(Level.FINEST, "Pausing until next events requested.");
-                while (true) {
-                    if (nextEvents) {
-                        logger.log(Level.FINEST, "User requested next set of events.");
-                        nextEvents = false;
-                        break;
-                    } else if (stopProcessing) {
-                        logger.log(Level.FINEST, "Stop was requested in inner event processing loop.");
-                        break;
-                    }
-                }
-            }
-
-            // Got an external request to stop processing.  Break out of loop.
-            if (stopProcessing) {
-                break;
-            }
-
-            // Process a single EtEvent using the default processing chain.
-            try {
-                processEtEvent(mev);
-            // Catch event processing errors, including ET -> EVIO, EVIO -> LCIO, and LCSim Driver execution.
-            } catch (EventProcessingException e) {       
-                /* Stack trace will show up log file. */
-                e.getCause().printStackTrace();
-                /* Print error message to log table. */
-                logger.log(Level.SEVERE, e.getMessage());
-                /* Print event number to log table. */
-                logger.log(Level.SEVERE, "Error processing event <" + this.eventsProcessed + ">.");
-                errorOnEvent();
-                if (stopOnError) {
-                    this.status = ConnectionStatus.ERROR;
-                    logger.log(Level.INFO, "Exiting on first error.");
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Process a single <code>EtEvent</code>.
-     * The exceptions throw by this method will be caught and handled from within {@link #processEtEvents()}.
-     * @param mev The EtEvent to process.
-     */
-    public void processEtEvent(EtEvent mev) throws EventProcessingException, MaxEventsException {
-                
-        /* Check if max events was reached or exceeded. */
-        if (maxEvents != -1 && eventsProcessed >= maxEvents) {
-            logger.log(Level.INFO, "Reached max events.");
-            throw new MaxEventsException();
-        }
-        
-        /* Check that the supplied EtEvent was not null. An exception is thrown if it is null. */
-    	if (mev == null) {
-    	    logger.log(Level.SEVERE, "Supplied EtEvent is null.");
-    	    throw new EventProcessingException("The supplied EtEvent is null");
-    	}
-
-        /* Notify listeners of start of event. */
-        startOfEvent();
-        
-        /* Increment the number of events processed. */
-        ++eventsProcessed;
-        
-        /* 
-         * Create the EVIO event. 
-         */
-        EvioEvent evioEvent = null;
-        boolean isPhysicsEvent = false;
-        try {
-            evioEvent = createEvioEvent(mev);
-        } catch (Exception e) {
-            throw new EventProcessingException("Failed to create EVIO event.", e);
-        } 
-        
-        /*
-         * Process the EVIO event if the EvioReader created a non-null object.
-         */
-        if (evioEvent != null) {
-            
-            /* Check for physics event. */
-            isPhysicsEvent = eventBuilder.isPhysicsEvent(evioEvent);
-            
-            /* 
-             * This is basically just redundantly printing information about the event to System.out, 
-             * but it also sets some internal state within the event builder so leave it for now.
-             */
-            eventBuilder.readEvioEvent(evioEvent);
-    
-            /* Log non-physics event information. */
-            logEvioEvent(evioEvent);
-            
-            /* 
-             * Notify listeners of non-physics events.
-             */
-            if (isPreStartEvent(evioEvent)) {
-                preStartEvent(evioEvent);
-            } else if (isEndEvent(evioEvent)) {
-                endRun(evioEvent);
-            }
-            
-            /* Check that the event has physics type. */
-            if (isPhysicsEvent) {
-                
-                /*
-                 * Use the event builder to create the lcsim event.
-                 */
-                EventHeader lcsimEvent = null;
-                try {
-                    lcsimEvent = eventBuilder.makeLCSimEvent(evioEvent);
-                } catch (Exception e) {
-                    throw new EventProcessingException("Failed to create LCSim event.", e);
-                }
-
-                /*
-                 * Process the event using the lcsim JobManager.
-                 */
-                if (lcsimEvent != null) {
-                    try {
-                        jobManager.processEvent(lcsimEvent);
-                    } catch (Exception e) {
-                        throw new EventProcessingException("Error processing the LCSim event.", e);
-                    }
-                } else {
-                    throw new EventProcessingException("The builder returned a null lcsim event.");
-                }
-            }
-        } else {
-            /*
-             * The EVIO event was null, so print an error message to the log.  This happens enough 
-             * that an exception is NOT thrown.  Ideally an error should be thrown but this
-             * means that the "disconnect on error" setting becomes completely useless, as this problem 
-             * basically happens at least a few times in every test run EVIO file.
-             */
-            logger.log(Level.SEVERE, "Error converting event <" + this.eventsProcessed + "> to EVIO.");
-            throw new EventProcessingException("The EVIO reader returned a null event.");
-        }
-
-        /* Notify listeners of end event. */
-        endOfEvent();
-    }
-
-    /**
-     * Static utility method for creating an EVIO event from an EtEvent
-     * @param etEvent The EtEvent.
-     * @return The EvioEvent.
-     * @throws IOException
-     * @throws EvioException
-     * @throws BufferUnderflowException
-     */
-    private static final EvioEvent createEvioEvent(EtEvent etEvent) throws IOException, EvioException, BufferUnderflowException {
-        return (new EvioReader(etEvent.getDataBuffer())).parseNextEvent();
-    }
-
-    /**
-     * Run the event processing from the ET connection until the job finishes.
-     */
-    public void process() {
-
-        // Set current status to connected.
-        this.status = ConnectionStatus.CONNECTED;
-
-        // Clear any leftover stop request before starting, just in case.
-        stopProcessing = false;
-
-        // A new job is starting so this flag gets reset.        
-        done = false;
-
-        // Notify listeners of job start.
-        begin();
-
-        // Loop until fatal error or stop flag is changed to true.
-        while (true) {
-
-            // Got a request to stop processing.
-            if (stopProcessing) {
-                logger.log(Level.FINEST, "Outer event processing loop got stop request.");
-                this.status = ConnectionStatus.DISCONNECT_REQUESTED;
-                break;
-            }
-
-            /* Try to process the next set of ET events. */
-            try {
-                processEtEvents();
-            /* The ET system timed out in the getEvents() method. */
-            } catch (EtTimeoutException e) {
-                logger.log(Level.WARNING, "ET connection timed out.");
-                this.status = ConnectionStatus.TIMED_OUT;
-            /* Event processing reached the maximum number of events. */
-            } catch (MaxEventsException e) {
-                logger.log(Level.INFO, "Reached max events <{0}>.", this.maxEvents);
-                this.status = ConnectionStatus.DISCONNECTING;
-            /* 
-             * Catch other types of errors.  These are most likely ET system exceptions
-             * or event processing errors.
-             */
-            } catch (Exception e) {
-                logger.log(Level.SEVERE, e.getMessage());
-                e.printStackTrace();
-                this.status = ConnectionStatus.ERROR;
-            /* Break out of processing loop if not still in connected state. */
-            } finally {
-                if (this.status != ConnectionStatus.CONNECTED) {
-                    break;
-                }
-            }
-            /* Force messages to show in the log table. */
-            logger.getHandlers()[0].flush();
-        }
-
-        logger.log(Level.FINEST, "End of processing loop.  About to cleanup.");
-        logger.getHandlers()[0].flush();
-
-        // Notify listeners of job end.
-        finish();
-
-        done = true;
-    }
-
-    /**
-     * Check if this is a Pre Start event.
-     * @param event
-     * @return True if event is of type Pre Start; false if not.
-     */
-    private static boolean isPreStartEvent(EvioEvent event) {
-        return event.getHeader().getTag() == EventConstants.PRESTART_EVENT_TAG;
-    }
-
-    /**
-     * Check if this is an End Event.
-     * @param event
-     * @return True if event is of type End Event; false if not.
-     */
-    private static boolean isEndEvent(EvioEvent event) {
-        return event.getHeader().getTag() == EventConstants.END_EVENT_TAG;
-    }
-
-    /**
-     * Notify listeners of Pre Start event being received by the ET system.
-     * @param event The EvioEvent for the Pre Start.
-     */
-    private void preStartEvent(EvioEvent event) {
-        int[] data = event.getIntData();
-        int seconds = data[0];
-        int runNumber = data[1];
-        for (EtEventListener listener : this.listeners) {
-            listener.prestart(seconds, runNumber);
-        }
-    }
-
-    /**
-     * Notify listeners of end of run being received by ET system.
-     * @param event The EvioEvent for the End Event record, which indicates end of run.
-     */
-    private void endRun(EvioEvent event) {
-        int[] data = event.getIntData();
-        int seconds = data[0];
-        int nevents = data[2];
-        for (EtEventListener listener : this.listeners) {
-            listener.endRun(seconds, nevents);
-        }
-    }
-
-    /**
-     * Set pause mode.
-     * @param p Set the pause mode; true to pause; false to unpause.
-     */
-    public void pauseMode(boolean p) {
-        pauseMode = p;
-    }
-
-    /**
-     * This is called externally to get the next event if running in pause mode.
-     */
-    public void nextEvents() {
-        nextEvents = true;
-    }
-
-    /**
-     * Set the application's log level.
-     * @param level The log level.
-     */
-    public void setLogLevel(Level level) {
-        logger.setLevel(level);
-    }
-
-    /**
-     * Get whether the event processing is blocked.
-     * @return True if blocked; false if not.
-     */
-    public boolean blocked() {
-        return blocked;
-    }
-
-    /**
-     * Get whether the event processing has been completed.
-     * @return True if event processing is complete; false if not.
-     */
-    public boolean done() {
-        return done;
-    }
- 
-    /**
-     * Print information from non-physics event.  
-     * Copied and modified from {@link org.lcsim.hps.evio.LCSimTestRunEventBuilder#readEvioEvent(EvioEvent)} 
-     * in order to route messages to the log table instead of <code>System.out</code>.
-     * @param evioEvent The EVIO event.
-     */
-    private void logEvioEvent(EvioEvent evioEvent) {
-        if (EventConstants.isSyncEvent(evioEvent)) {
-            int[] data = evioEvent.getIntData();
-            int seconds = data[0];
-            logger.log(Level.INFO, "Sync event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count since last sync " + data[1] + ", event count so far " + data[2] + ", status " + data[3]);
-        } else if (EventConstants.isPreStartEvent(evioEvent)) {
-            int[] data = evioEvent.getIntData();
-            int seconds = data[0];
-            logger.log(Level.INFO, "Prestart event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", run type " + data[2]);
-        } else if (EventConstants.isGoEvent(evioEvent)) {
-            int[] data = evioEvent.getIntData();
-            int seconds = data[0];
-            logger.log(Level.INFO, "Go event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count so far " + data[2]);
-        } else if (EventConstants.isPauseEvent(evioEvent)) {
-            int[] data = evioEvent.getIntData();
-            int seconds = data[0];
-            logger.log(Level.INFO, "Pause event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count so far " + data[2]);
-        } else if (EventConstants.isEndEvent(evioEvent)) {
-            int[] data = evioEvent.getIntData();
-            int seconds = data[0];
-            logger.log(Level.INFO, "End event: time " + seconds + " - " + new Date(((long) seconds) * 1000) + ", event count " + data[2]);
-        }
-    }
-}
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
EventPanel.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/EventPanel.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/EventPanel.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -12,19 +12,16 @@
 /**
  * This is the GUI component for displaying event information in real time.
  * @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: EventPanel.java,v 1.16 2013/11/05 17:15:04 jeremy Exp $
  */
-// FIXME: Clock seems to be running after disconnect!!!
 class EventPanel extends FieldsPanel { 
 
     private JTextField eventCounterField; // number of events in this job
     private JTextField elapsedTimeField; // elapsed time between job start
     private JTextField avgEventRateField; // average event rate in this job
     private JTextField refreshField; // number of events to wait before updating GUI
-    private JTextField badEventsField; // number of bad events where event event processing failed
     private JTextField sessionSuppliedField; // number of events supplied in this session; ignored by reset command
     private JTextField totalSuppliedField; // number of events supplied since the application started
-    private JTextField maxEventsField; // maximum number of events to process before disconenct
+    /*private JTextField maxEventsField;*/ // maximum number of events to process before disconenct
     private JTextField runNumberField; // Run number from CODA Pre Start event.
     private JTextField runStartField; // Start of run date from CODA Pre Start event.
     private JTextField runEventsField; // Number of events in run.
@@ -33,10 +30,10 @@
     private static final int defaultEventRefresh = 1;
     private int eventRefresh = defaultEventRefresh;
     private int eventCount;
-    private int badEventCount;
     private int sessionSupplied;
     private int totalSupplied;
     private boolean updateEvent = true;
+    private long jobStartTime;
     
     private final static DecimalFormat rateFormat = new DecimalFormat("#.##");
     
@@ -54,7 +51,6 @@
         elapsedTimeField = addField("Elapsed Time [seconds]", "0", 10);
         eventCounterField = addField("Events Processed", "0", 10);
         avgEventRateField = addField("Average Events Per Second", "0", 6);
-        badEventsField = addField("Event Errors", "0", 8); 
         runNumberField = addField("Run Number", "", 8);
         runStartField = addField("Run Started", "", 22);
         runStopField = addField("Run Stopped", "", 22);
@@ -62,7 +58,7 @@
         sessionSuppliedField = addField("Session Supplied Events", "0", 8);
         totalSuppliedField = addField("Total Supplied Events", "0", 8);
         refreshField = addField("Event Refresh", Integer.toString(eventRefresh), 8);
-        maxEventsField = addField("Max Events", "-1", 8);
+        //maxEventsField = addField("Max Events", "-1", 8);
     }
             
     /**
@@ -77,14 +73,17 @@
      * Get the max events setting from its GUI component.
      * @return The max events.
      */
+    /*
     int getMaxEvents() {
         return Integer.parseInt(maxEventsField.getText());
     }
+    */
     
     /**
      * Set the max events.
      * @param maxEvents The max events.
      */
+    /*
     void setMaxEvents(final int maxEvents) {
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
@@ -92,6 +91,7 @@
             }
         });
     }
+    */
     
     /**
      * Set the run number.
@@ -105,6 +105,10 @@
         });
     }
     
+    void setJobStartTime(long jobStartTime) {
+        this.jobStartTime = jobStartTime;
+    }
+    
     /**
      * Set the number of events in the run.
      * @param eventCount The number of events in the run.
@@ -184,34 +188,24 @@
         };
         SwingUtilities.invokeLater(r);
     }
-
+   
     /**
-     * Increment the number of bad events.
-     */
-    void updateBadEventCount() {
-    	++badEventCount;
-    	SwingUtilities.invokeLater(new Runnable() {
-    	    public void run() {
-    	        badEventsField.setText(Integer.toString(badEventCount));
-    	    }
-    	});
-    }
-    
-    /**
      * Update the average event rate.
      * @param jobStartTime The start time of the job in milliseconds.
      */
-    void updateAverageEventRate(long jobStartTime) {
+    void updateAverageEventRate() {
         if (updateEvent) {
-            final double jobTime = System.currentTimeMillis() - jobStartTime;
-            if (jobTime > 0) {
-                final double jobSeconds = jobTime / 1000;
-                final double eventsPerSecond = eventCount / jobSeconds;
-                SwingUtilities.invokeLater(new Runnable() {
-                    public void run() {
-                        avgEventRateField.setText(rateFormat.format(eventsPerSecond));
-                    }
-                });
+            if (eventCount > 0) {
+                final double elapsedTime = System.currentTimeMillis() - jobStartTime;
+                if (elapsedTime > 0) {
+                    final double jobSeconds = elapsedTime / 1000;
+                    final double eventsPerSecond = eventCount / jobSeconds;
+                    SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                            avgEventRateField.setText(rateFormat.format(eventsPerSecond));
+                        }
+                    });
+                }
             }
         }
     }
@@ -246,7 +240,6 @@
      */
     synchronized void reset() {
         resetEventCount();
-        resetBadEventCount();
         resetAverageEventRate();
         resetElapsedTime();
     }
@@ -286,18 +279,6 @@
     }
 
     /**
-     * Reset the bad event count.
-     */
-    private void resetBadEventCount() {
-        this.badEventCount = 0;
-        SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
-                badEventsField.setText("0");
-            }
-        });
-    }
-
-    /**
      * Reset the session supplied events.
      */
     void resetSessionSupplied() {

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
EventPanelUpdater.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/EventPanelUpdater.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/EventPanelUpdater.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,69 @@
+package org.hps.monitoring;
+
+import org.hps.monitoring.record.evio.EvioEventProcessor;
+import org.jlab.coda.jevio.EvioEvent;
+
+/**
+ * This class is an {@link org.hps.monitoring.record.evio.EvioEventProcessor}
+ * that updates the {@link EventPanel} as EVIO events are processed. 
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EventPanelUpdater extends EvioEventProcessor {
+    
+    EventPanel eventPanel;
+    
+    long jobStartTime;
+    
+    EventPanelUpdater(EventPanel eventPanel) {
+        this.eventPanel = eventPanel;
+    }
+    
+    public void startJob() {
+        
+        // Reset event GUI.
+        eventPanel.reset();
+
+        // This is only reset between different jobs.
+        eventPanel.resetSessionSupplied();
+        
+        eventPanel.setJobStartTime(System.currentTimeMillis());
+    }
+    
+    public void processEvent(EvioEvent evioEvent) {
+        eventPanel.updateEventCount();
+        eventPanel.updateAverageEventRate();
+    }
+
+    public void endJob() {
+        // Push final event counts to the GUI.
+        eventPanel.endJob();      
+    }
+
+    public void startRun(EvioEvent event) {
+        
+        // Get start of run data.
+        int[] data = event.getIntData();
+        int seconds = data[0];
+        int runNumber = data[1];        
+        final long millis = ((long) seconds) * 1000;
+        
+        // Update the GUI.
+        eventPanel.setRunNumber(runNumber);
+        eventPanel.setRunStartTime(millis);        
+    }
+
+    public void endRun(EvioEvent event) {
+        
+        // Get end run data.
+        int[] data = event.getIntData();
+        int seconds = data[0];
+        int eventCount = data[2];
+        final long millis = ((long) seconds) * 1000;
+        
+        // Update the GUI.
+        eventPanel.setRunEndTime(millis);
+        eventPanel.setRunEventCount(eventCount);
+    }
+    
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
EvioFileProducer.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/EvioFileProducer.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/EvioFileProducer.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -24,8 +24,8 @@
  * @author Jeremy McCormick <[log in to unmask]>
  *
  */
-// TODO: Add option to set number of events in put array.
-// TODO: Move to sub-package.
+// TODO: Add option to set number of events in the put array.
+// TODO: Move to a sub-package.
 public class EvioFileProducer {
 
     private List<File> evioFiles = new ArrayList<File>();
@@ -173,7 +173,7 @@
                         
                 // Open EVIO reader.
                 System.out.println("Opening next EVIO file: " + evioFile.getPath());
-                reader = new EvioReader(evioFile.getPath());
+                reader = new EvioReader(evioFile.getPath(), false);
 
                 // Print number of events.
                 if (debug) {

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
MonitoringApplication.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/MonitoringApplication.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/MonitoringApplication.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -13,8 +13,6 @@
 import static org.hps.monitoring.MonitoringCommands.NEXT;
 import static org.hps.monitoring.MonitoringCommands.PAUSE;
 import static org.hps.monitoring.MonitoringCommands.RESET_CONNECTION_SETTINGS;
-import static org.hps.monitoring.MonitoringCommands.RESET_DRIVERS;
-import static org.hps.monitoring.MonitoringCommands.RESET_EVENTS;
 import static org.hps.monitoring.MonitoringCommands.RESET_JOB_SETTINGS;
 import static org.hps.monitoring.MonitoringCommands.RESUME;
 import static org.hps.monitoring.MonitoringCommands.SAVE_CONNECTION;
@@ -24,10 +22,8 @@
 import static org.hps.monitoring.MonitoringCommands.SCREENSHOT;
 import static org.hps.monitoring.MonitoringCommands.SET_EVENT_BUILDER;
 import static org.hps.monitoring.MonitoringCommands.SET_LOG_LEVEL;
-import static org.hps.monitoring.MonitoringCommands.SET_MAX_EVENTS;
 import static org.hps.monitoring.MonitoringCommands.SET_STEERING_FILE;
 import static org.hps.monitoring.MonitoringCommands.SET_STEERING_RESOURCE;
-import static org.hps.monitoring.MonitoringCommands.UPDATE_TIME;
 
 import java.awt.AWTException;
 import java.awt.BorderLayout;
@@ -53,6 +49,8 @@
 import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.Vector;
 import java.util.logging.Handler;
 import java.util.logging.Level;
@@ -71,42 +69,30 @@
 import javax.swing.JTabbedPane;
 import javax.swing.JTable;
 import javax.swing.SwingUtilities;
-import javax.swing.Timer;
 import javax.swing.table.DefaultTableModel;
 
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.PosixParser;
 import org.hps.evio.LCSimEventBuilder;
+import org.hps.monitoring.record.EventProcessingChain;
+import org.hps.monitoring.record.EventProcessingThread;
 import org.hps.monitoring.record.etevent.EtConnection;
 import org.hps.monitoring.record.etevent.EtConnectionParameters;
-import org.hps.monitoring.record.etevent.EtEventListener;
-import org.hps.util.Resettable;
+import org.hps.monitoring.record.etevent.EtEventSource;
 import org.lcsim.job.JobControlManager;
-import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
 /**
- * Monitoring application for HPS Test Run, which can run LCSim steering files on data
- * converted from the ET ring. This class is accessible to users by calling its main()
- * method.
+ * Monitoring application for HPS Test Run, which can run LCSim steering files on data converted
+ * from the ET ring. This class is accessible to users by calling its main() method.
  * @author Jeremy McCormick <[log in to unmask]>
  * @version $Id: MonitoringApplication.java,v 1.61 2013/12/10 07:36:40 jeremy Exp $
  */
-// FIXME: Review minimum size settings to see which are actually being respected. Remove
-// where they are not needed.
-// FIXME: Since this class is almost 2k lines, might want to refactor it into multiple
-// classes.
+// FIXME: The tabs panel isn't filling the full available space even when fill is set to both.
+// TODO: Remove minimum GUI component size settings where they are redundant.
+// TODO: Refactor this class into multiple classes.
+// TODO: Log the messages from all Exceptions.
 // TODO: Capture std err and out and redirect to a text panel within the application.
-// TODO: Review use of Resettable and Redrawable to see if they can be removed and the
-//       standard Driver API used instead.  Resettable can maybe be replaced by startOfData().
-//       Not sure about Redrawable; maybe it isn't needed at all.
-// FIXME: Tracebacks from errors should be caught and written into the log table.
-// TODO: Replace DefaultEtEventProcessor with EventProcessingChain class.
+// TODO: Report state of event processing at the end of the job in a new GUI component.
+// TODO: Check if the complex logic used to disconnect/cleanup the ET system is necessary anymore.
 public class MonitoringApplication {
 
     // Top-level Swing components.
@@ -123,14 +109,12 @@
     private EventButtonsPanel buttonsPanel;
     private JFrame frame;
 
-    // References to menu items that will be enabled/disabled depending on application
-    // state.
+    // References to menu items that will be enabled/disabled depending on application state.
     private JMenuItem connectItem;
     private JMenuItem disconnectItem;
     private JMenuItem resetConnectionItem;
     private JMenuItem connectionLoadItem;
     private JMenuItem savePlotsItem;
-    private JMenuItem resetDriversItem;
     private JMenuItem logItem;
     private JMenuItem terminalItem;
     private JMenuItem steeringItem;
@@ -151,11 +135,11 @@
     // Event processing objects.
     private JobControlManager jobManager;
     private LCSimEventBuilder eventBuilder;
-    private OldEtEventProcessor eventProcessor;
-    private Thread eventProcessingThread;
+    private EventProcessingThread eventProcessingThread;
 
     // Job timing.
     private Timer timer;
+    private TimerTask updateTimeTask;
     private long jobStartTime;
 
     // ActionListener for GUI event dispatching.
@@ -176,9 +160,6 @@
     // Format for screenshots. Hard-coded to PNG.
     private static final String screenshotFormat = "png";
 
-    // Listener for processing EtEvents.
-    private EtEventListener etListener = new MonitoringApplicationEtListener();
-
     // Maximum time in millis to wait for the ET system to disconnect.
     // TODO: Make this an option in the JobPanel.
     private int maxCleanupTime = 5000;
@@ -196,9 +177,10 @@
     private static final int connectionStatusPanelHeight = 50;
     private static final int connectionStatusPanelWidth = 400;
 
+    EventProcessingChain eventProcessing;
+
     /**
-     * Constructor for the monitoring application. Users cannot access this. Call the main
-     * method instead.
+     * Constructor for the monitoring application. 
      */
     private MonitoringApplication() {
 
@@ -259,7 +241,7 @@
         GridBagConstraints c = new GridBagConstraints();
 
         // Event processing buttons.
-        c = new GridBagConstraints();
+        //c = new GridBagConstraints();
         c.gridx = 0;
         c.gridy = 0;
         c.anchor = GridBagConstraints.CENTER;
@@ -284,30 +266,30 @@
         eventPanel = new EventPanel();
         jobPanel = new JobPanel();
         jobPanel.addActionListener(actionListener);
-
-        // Tab panels.
+        
+        // Create the container for the tabbed pane.
+        JPanel tabsPanel = new JPanel();
         c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridy = 2;
         c.fill = GridBagConstraints.BOTH;
         c.weightx = c.weighty = 1.0;
-        JPanel tabsPanel = new JPanel();
+        c.insets = new Insets(0, 0, 0, 10);
+        leftPanel.add(tabsPanel, c);
+        
+        // Tab panels.
+        c = new GridBagConstraints();
+        c.fill = GridBagConstraints.BOTH;
+        c.weightx = c.weighty = 1.0;                       
         tabs = new JTabbedPane();
         tabs.addTab("Connection Settings", connectionPanel);
         tabs.addTab("Event Monitor", eventPanel);
         tabs.addTab("Job Settings", jobPanel);
         tabsPanel.add(tabs, c);
-
-        // Add tabs to main panel.
+                
+        // Layout attributes for the entire left panel.
         c = new GridBagConstraints();
         c.gridx = 0;
-        c.gridy = 2;
-        c.fill = GridBagConstraints.BOTH;
-        c.weightx = c.weighty = 1.0;
-        c.insets = new Insets(0, 0, 0, 10);
-        leftPanel.add(tabsPanel, c);
-
-        // Layout attributes for left panel.
-        c = new GridBagConstraints();
-        c.gridx = 0;
         c.gridy = 0;
         c.weightx = 1.0;
         c.weighty = 1.0;
@@ -365,11 +347,10 @@
         eventMenu.setMnemonic(KeyEvent.VK_E);
         menuBar.add(eventMenu);
 
-        addMenuItem("Reset Event Monitor", KeyEvent.VK_E, RESET_EVENTS, true, "Reset timer and counters in the event monitor tab.", eventMenu);
+        //addMenuItem("Reset Event Monitor", KeyEvent.VK_E, RESET_EVENTS, true, "Reset timer and counters in the event monitor tab.", eventMenu);
 
         /**
-         * FIXME: Rest of these should be converted to use the addMenuItem() helper
-         * method...
+         * FIXME: Rest of these should be converted to use the addMenuItem() helper method...
          */
 
         JMenuItem eventRefreshItem = new JMenuItem("Set Event Refresh...");
@@ -379,12 +360,14 @@
         eventRefreshItem.setToolTipText("Set the number of events between GUI updates.");
         eventMenu.add(eventRefreshItem);
 
+        /*
         JMenuItem maxEventsItem = new JMenuItem("Set Max Events...");
         maxEventsItem.setMnemonic(KeyEvent.VK_M);
         maxEventsItem.setActionCommand(SET_MAX_EVENTS);
         maxEventsItem.addActionListener(actionListener);
         maxEventsItem.setToolTipText("Set the maximum number of events to process in one session.");
         eventMenu.add(maxEventsItem);
+        */
 
         JMenu jobMenu = new JMenu("Job");
         jobMenu.setMnemonic(KeyEvent.VK_J);
@@ -433,14 +416,6 @@
         savePlotsItem.setToolTipText("Save plots from default AIDA tree to an output file.");
         jobMenu.add(savePlotsItem);
 
-        resetDriversItem = new JMenuItem("Reset LCSim Drivers");
-        resetDriversItem.setMnemonic(KeyEvent.VK_D);
-        resetDriversItem.setActionCommand(RESET_DRIVERS);
-        resetDriversItem.addActionListener(actionListener);
-        resetDriversItem.setEnabled(false);
-        resetDriversItem.setToolTipText("Reset Drivers that implement the Resettable interface.");
-        jobMenu.add(resetDriversItem);
-
         logItem = new JMenuItem("Redirect to File...");
         logItem.setMnemonic(KeyEvent.VK_F);
         logItem.setActionCommand(LOG_TO_FILE);
@@ -529,8 +504,8 @@
     }
 
     /**
-     * Creates the application's log table GUI component, which is a JTable containing
-     * messages from the logger.
+     * Creates the application's log table GUI component, which is a JTable containing messages
+     * from the logger.
      */
     private void createLogTable() {
 
@@ -566,9 +541,10 @@
      * Create the monitoring application frame and run it on a separate thread.
      * @return Reference to the created application.
      */
-    private static final MonitoringApplication createMonitoringApplication() {
+    static final MonitoringApplication createMonitoringApplication() {
         final MonitoringApplication app = new MonitoringApplication();
         SwingUtilities.invokeLater(new Runnable() {
+
             public void run() {
                 app.createApplicationFrame();
             }
@@ -577,53 +553,10 @@
     }
 
     /**
-     * Run the monitoring application from the command line.
-     * @param args The command line arguments.
-     */
-    public static void main(String[] args) {
-
-        // Set up command line parsing.
-        Options options = new Options();
-        options.addOption(new Option("h", false, "Print help."));
-        options.addOption(new Option("c", true, "Load properties file with connection settings."));
-        options.addOption(new Option("j", true, "Load properties file with job settings."));
-        CommandLineParser parser = new PosixParser();
-
-        // Parse command line arguments.
-        CommandLine cl = null;
-        try {
-            cl = parser.parse(options, args);
-        } catch (ParseException e) {
-            throw new RuntimeException("Problem parsing command line options.", e);
-        }
-
-        // Print help and exit.
-        if (cl.hasOption("h")) {
-            System.out.println("MonitoringApplication [options]");
-            HelpFormatter help = new HelpFormatter();
-            help.printHelp(" ", options);
-            System.exit(1);
-        }
-
-        // Create the application class.
-        MonitoringApplication app = MonitoringApplication.createMonitoringApplication();
-
-        // Load the connection settings.
-        if (cl.hasOption("c")) {
-            app.loadConnectionSettings(new File(cl.getOptionValue("c")));
-        }
-
-        // Load the job settings.
-        if (cl.hasOption("j")) {
-            app.loadJobSettings(new File(cl.getOptionValue("j")));
-        }
-    }
-
-    /**
      * Load connection settings from a file.
      * @param file The properties file.
      */
-    private void loadConnectionSettings(File file) {
+    void loadConnectionSettings(File file) {
         connectionPanel.loadPropertiesFile(file);
     }
 
@@ -631,7 +564,7 @@
      * Load job settings from a file.
      * @param file The properties file.
      */
-    private void loadJobSettings(File file) {
+    void loadJobSettings(File file) {
         try {
             jobPanel.setJobSettings(new JobSettings(file));
             // Need to check here if System.out and err have been redirected.
@@ -653,26 +586,17 @@
          * @param e The event to handle.
          */
         public void actionPerformed(ActionEvent e) {
-            String cmd = e.getActionCommand();
-            if (cmd != MonitoringCommands.UPDATE_TIME) {
-                // Log actions performed. Catch errors in case logging is not initialized
-                // yet.
-                try {
-                    log(Level.FINEST, "Action performed <" + cmd + ">.");
-                } catch (Exception xx) {
-                    xx.printStackTrace();
-                }
-            }
+            String cmd = e.getActionCommand();            
             if (CONNECT.equals(cmd)) {
-                startSessionThread();
+                //startSessionThread();
+                startSession();
             } else if (DISCONNECT.equals(cmd)) {
-                startDisconnectThread();
+                //startDisconnectThread();
+                stopSession();
             } else if (EDIT_EVENT_REFRESH.equals(cmd)) {
                 setEventRefresh();
             } else if (SAVE_PLOTS.equals(cmd)) {
                 savePlots();
-            } else if (RESET_DRIVERS.equals(cmd)) {
-                resetDrivers();
             } else if (LOG_TO_FILE.equals(cmd)) {
                 logToFile();
             } else if (LOG_TO_TERMINAL.equals(cmd)) {
@@ -681,30 +605,26 @@
                 chooseScreenshot();
             } else if (EXIT.equals(cmd)) {
                 exit();
-            } else if (UPDATE_TIME.equals(cmd)) {
-                updateTime();
-            } else if (RESET_EVENTS.equals(cmd)) {
-                resetJob();
             } else if (SAVE_CONNECTION.equals(cmd)) {
                 connectionPanel.save();
             } else if (LOAD_CONNECTION.equals(cmd)) {
                 connectionPanel.load();
             } else if (RESET_CONNECTION_SETTINGS.equals(cmd)) {
                 connectionPanel.reset();
-            } else if (SET_MAX_EVENTS.equals(cmd)) {
+            } /*else if (SET_MAX_EVENTS.equals(cmd)) {
                 setMaxEvents();
-            } else if (SAVE_LOG_TABLE.equals(cmd)) {
+            }*/ else if (SAVE_LOG_TABLE.equals(cmd)) {
                 saveLogToFile();
             } else if (CLEAR_LOG_TABLE.equals(cmd)) {
                 clearLog();
             } else if (SET_EVENT_BUILDER.equals(cmd)) {
                 jobPanel.editEventBuilder();
             } else if (PAUSE.equals(cmd)) {
-                pause();
+                pauseEventProcessing();
             } else if (NEXT.equals(cmd)) {
-                next();
+                nextEvent();
             } else if (RESUME.equals(cmd)) {
-                resume();
+                resumeEventProcessing();
             } else if (SET_LOG_LEVEL.equals(cmd)) {
                 setLogLevel();
             } else if (AIDA_AUTO_SAVE.equals(cmd)) {
@@ -724,8 +644,8 @@
     }
 
     /**
-     * This fires when a steering resource file is selected from the combo box. The Job
-     * Settings are changed to use a resource type.
+     * This fires when a steering resource file is selected from the combo box. The Job Settings
+     * are changed to use a resource type.
      */
     private void steeringResourceSelected() {
         jobPanel.setSteeringType(JobPanel.RESOURCE);
@@ -780,152 +700,21 @@
         // Redirect System.out and err back to the terminal.
         logToTerminal();
     }
-
+   
     /**
-     * This is the primary entry point for starting a monitoring session. The session is
-     * started on a new thread so it doesn't block.
-     */
-    private void startSessionThread() {
-        if (getConnectionStatus() != ConnectionStatus.CONNECTED) {
-            Runnable r = new Runnable() {
-                public void run() {
-                    session();
-                }
-            };
-            Thread t = new Thread(r, "Session Thread");
-            t.start();
-        } else {
-            log(Level.SEVERE, "Ignoring connection request.  Already connected!");
-        }
-    }
-
-    /**
      * Set a new log level for the application and also forward to the event processor.
      */
     private void setLogLevel() {
         Level newLevel = jobPanel.getLogLevel();
         logger.setLevel(newLevel);
-        if (eventProcessor != null) {
-            eventProcessor.setLogLevel(newLevel);
-        }
+        //if (eventProcessor != null) {
+        //    eventProcessor.setLogLevel(newLevel);
+        //}
 
         log(Level.INFO, "Log Level was changed to <" + jobPanel.getLogLevel().toString() + ">.");
     }
 
     /**
-     * The listener for hooking into the event processor.
-     */
-    private class MonitoringApplicationEtListener implements EtEventListener {
-
-        /**
-         * Beginning of job.
-         */
-        public void begin() {
-
-            // Reset event GUI.
-            eventPanel.reset();
-
-            // This is only reset between different jobs.
-            eventPanel.resetSessionSupplied();
-
-            // Start the job timer.
-            startTimer();
-        }
-
-        /**
-         * Start of next event.
-         */
-        public void startOfEvent() {
-            eventPanel.updateEventCount();
-        }
-
-        /**
-         * End of single event.
-         */
-        public void endOfEvent() {
-            eventPanel.updateAverageEventRate(jobStartTime);
-        }
-
-        /**
-         * Error on this event.
-         */
-        public void errorOnEvent() {
-            eventPanel.updateBadEventCount();
-        }
-
-        /**
-         * End of job actions. This cleans up the Monitoring Application to put it into
-         * the proper state for subsequent disconnection from the ET ring.
-         */
-        public void finish() {
-
-            // Show a warning dialog box before disconnecting, if this option is selected.
-            // This needs to go here rather than in disconnect() so that the LCSim plots
-            // stay up.
-            if (warnOnDisconnect()) {
-                log(Level.FINEST, "Waiting for user to verify disconnect request.");
-                showDialog("You are about to be disconnected.");
-                // DisconnectDialog d = new DisconnectDialog();
-                // d.waitForConfirm();
-            }
-
-            try {
-
-                // Save final AIDA file if option is selected.
-                if (jobPanel.isAidaAutoSaveEnabled()) {
-                    log(Level.INFO, "Auto saving AIDA file <" + jobPanel.getAidaAutoSaveFileName() + ">.");
-                    AIDA.defaultInstance().saveAs(jobPanel.getAidaAutoSaveFileName());
-                }
-
-                // Call cleanup methods of Drivers.
-                try {
-                    log(Level.INFO, "Cleaning up LCSim.");
-                    if (jobManager != null) {
-                        jobManager.finish();
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    logger.log(Level.WARNING, "Error cleaning up LCSim job.");
-                }
-
-                // Stop the job timer.
-                log(Level.INFO, "Stopping the job timer.");
-                timer.stop();
-                timer = null;
-
-                // Push final event counts to GUI.
-                eventPanel.endJob();
-                
-            } catch (Exception e) {
-                e.printStackTrace();
-                log(Level.WARNING, "Error cleaning up job <" + e.getMessage() + ">.");
-            }
-        }
-
-        /**
-         * Prestart event received.
-         */
-        public void prestart(int seconds, int runNumber) {
-            final long millis = ((long) seconds) * 1000;
-            eventPanel.setRunNumber(runNumber);
-            eventPanel.setRunStartTime(millis);
-            log(Level.INFO, "Set run number <" + runNumber + "> from Pre Start.");
-            log(Level.INFO, "Run start time <" + EventPanel.dateFormat.format(new Date(millis)) + "> from Pre Start.");
-        }
-
-        /**
-         * End run event received.
-         */
-        public void endRun(int seconds, int events) {
-            final long millis = ((long) seconds) * 1000;
-            eventPanel.setRunEndTime(millis);
-            eventPanel.setRunEventCount(events);
-            log(Level.INFO, "Set number of events in run to <" + events + ">.");
-            log(Level.INFO, "End run time <" + EventPanel.dateFormat.format(new Date(millis)) + ">.");
-        }
-    }
-
-    /**
      * Set the connection status.
      * @param status The connection status.
      */
@@ -963,19 +752,7 @@
         frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
         // frame.setMinimumSize(new Dimension(600, 850));
         frame.setResizable(true);
-        frame.pack();
-
-        // Maximize frame size.
-        // final GraphicsConfiguration config = frame.getGraphicsConfiguration();
-        // final int left = Toolkit.getDefaultToolkit().getScreenInsets(config).left;
-        // final int right = Toolkit.getDefaultToolkit().getScreenInsets(config).right;
-        // final int top = Toolkit.getDefaultToolkit().getScreenInsets(config).top;
-        // final int bottom = Toolkit.getDefaultToolkit().getScreenInsets(config).bottom;
-        // final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-        // final int width = screenSize.width - left - right;
-        // final int height = screenSize.height - top - bottom;
-        // frame.setSize(width,height);
-
+        frame.pack();    
         frame.setVisible(true);
     }
 
@@ -997,7 +774,7 @@
     }
 
     /**
-     * Select an LCSim steering file from disk.
+     * Select an LCSim steering file.
      */
     private void selectSteeringFile() {
         JFileChooser fc = new JFileChooser();
@@ -1050,9 +827,10 @@
     }
 
     /**
-     * Call the reset() method on Drivers which implement {@link Resettable}. They must
-     * implement the {@link Resettable} interface for this to work.
+     * Call the reset() method on Drivers which implement {@link Resettable}. They must implement
+     * the {@link Resettable} interface for this to work.
      */
+    /*
     private synchronized void resetDrivers() {
         if (jobManager != null) {
             for (Driver driver : jobManager.getDriverExecList()) {
@@ -1067,11 +845,11 @@
         }
         log(Level.INFO, "LCSim drivers were reset.");
     }
+    */
 
     /**
-     * Redirect System.out and System.err to a file. This is primarily used to capture
-     * lengthy debug output from event processing. Messages sent to the Logger are
-     * unaffected.
+     * Redirect System.out and System.err to a file. This is primarily used to capture lengthy
+     * debug output from event processing. Messages sent to the Logger are unaffected.
      */
     private void logToFile() {
         JFileChooser fc = new JFileChooser();
@@ -1090,6 +868,7 @@
                     redirectStdOutAndErrToFile(logFile);
 
                     SwingUtilities.invokeLater(new Runnable() {
+
                         public void run() {
                             jobPanel.setLogToFile(true);
                             jobPanel.setLogFile(logFile.getPath());
@@ -1121,14 +900,15 @@
     }
 
     /**
-     * Redirect <code>System.out</code> and <code>System.err</code> back to the terminal, 
-     * e.g. if they were previously sent to a file. This is independent of messages that 
-     * are sent to the application's log table.
+     * Redirect <code>System.out</code> and <code>System.err</code> back to the terminal, e.g. if
+     * they were previously sent to a file. This is independent of messages that are sent to the
+     * application's log table.
      */
     private void logToTerminal() {
         System.setOut(sysOut);
         System.setErr(sysErr);
         SwingUtilities.invokeLater(new Runnable() {
+
             public void run() {
                 jobPanel.setLogFile("");
                 jobPanel.setLogToFile(false);
@@ -1159,9 +939,10 @@
     }
 
     /**
-     * Using a modal dialog, set the maximum number of events to process before an
-     * automatic disconnect.
+     * Using a modal dialog, set the maximum number of events to process before an automatic
+     * disconnect.
      */
+    /*
     private void setMaxEvents() {
         String inputValue = JOptionPane.showInputDialog("Max Events:", eventPanel.getMaxEvents());
         try {
@@ -1173,9 +954,9 @@
             // Set max events in panel.
             eventPanel.setMaxEvents(newMaxEvents);
             // Set max events in event processor.
-            if (eventProcessor != null) {
-                eventProcessor.setMaxEvents(newMaxEvents);
-            }
+            //if (eventProcessor != null) {
+            //    eventProcessor.setMaxEvents(newMaxEvents);
+            //}
             log("Max events set to <" + newMaxEvents + ">.");
         } catch (Exception e) {
             e.printStackTrace();
@@ -1183,10 +964,11 @@
             showDialog("The value " + inputValue + " is not valid for Max Events.");
         }
     }
+    */
 
     /**
-     * Set the GUI state to disconnected, which will enable/disable applicable GUI
-     * components and menu items.
+     * Set the GUI state to disconnected, which will enable/disable applicable GUI components and
+     * menu items.
      */
     private void setDisconnectedGuiState() {
 
@@ -1196,7 +978,7 @@
         resetConnectionItem.setEnabled(true);
         connectionLoadItem.setEnabled(true);
         savePlotsItem.setEnabled(false);
-        resetDriversItem.setEnabled(false);
+        //resetDriversItem.setEnabled(false);
         logItem.setEnabled(true);
         terminalItem.setEnabled(true);
         steeringItem.setEnabled(true);
@@ -1216,8 +998,8 @@
     }
 
     /**
-     * Set the GUI to connected state, which will enable/disable appropriate components
-     * and menu items.
+     * Set the GUI to connected state, which will enable/disable appropriate components and menu
+     * items.
      */
     private void setConnectedGuiState() {
 
@@ -1233,7 +1015,7 @@
         resetConnectionItem.setEnabled(false);
         connectionLoadItem.setEnabled(false);
         savePlotsItem.setEnabled(true);
-        resetDriversItem.setEnabled(true);
+        //resetDriversItem.setEnabled(true);
         logItem.setEnabled(false);
         terminalItem.setEnabled(false);
         steeringItem.setEnabled(false);
@@ -1251,7 +1033,7 @@
      */
     private void exit() {
         if (connection != null) {
-            cleanupConnection();
+            cleanupEtConnection();
         }
         System.exit(0);
     }
@@ -1295,8 +1077,8 @@
     }
 
     /**
-     * Get the fully qualified class name of the current event builder for converting from
-     * EVIO to LCIO. 
+     * Get the fully qualified class name of the current event builder for converting from EVIO to
+     * LCIO.
      * @return The class name of the event builder.
      */
     private String getEventBuilderClassName() {
@@ -1315,91 +1097,53 @@
      * Get the current max events setting.
      * @return The maximum number of events to process before disconnect.
      */
+    /*
     private int getMaxEvents() {
         return eventPanel.getMaxEvents();
     }
+    */
 
     /**
-     * Execute a monitoring session. This is executed in a separate thread so as not to
-     * block the GUI or other threads during a monitoring session.
+     * Execute a monitoring session. This should be executed in a separate thread so as not to block the
+     * GUI or other threads during a monitoring session.
      */
-    private void session() {
+    private void startSession() {
 
         log(Level.INFO, "Starting a new monitoring session.");
 
-        int endStatus = ConnectionStatus.DISCONNECTING;
-
         try {
 
-            // Setup LCSim.
+            // Reset the plot panel and global AIDA state.
+            resetPlots();
+
+            // Setup the LCSim JobControlManager and event builder.
             setupLCSim();
 
-            // Connect to the ET system.
+            // Connect to the ET system, which will setup a valid EtConnection object.
             connect();
+            
+            // Setup the EventProcessingChain object using the EtConnection.
+            setupEventProcessingChain();
 
-            // TODO: Add EtEventCounter thread here for counting all ET events.
-
-            // Create the event processing thread.
-            createEventProcessingThread();
-
-            // Wait for the event processing thread to finish.
-            try {
-                eventProcessingThread.join();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-            log("Event processor finished with status <" + ConnectionStatus.toString(eventProcessor.getStatus()) + ">.");
-            endStatus = eventProcessor.getStatus();
+            // Start the event processing thread.
+            eventProcessingThread.start();
+            
+            // Start the session timer.
+            startSessionTimer();
+           
+            log(Level.INFO, "Successfully started the monitoring session.");
+                                                      
         } catch (Exception e) {
             e.printStackTrace();
-            log(Level.SEVERE, "Fatal error in monitoring session.");
-            endStatus = ConnectionStatus.ERROR;
-        } finally {
-            logHandler.flush();
-            // Disconnect if needed.
-            if (getConnectionStatus() != ConnectionStatus.DISCONNECTED) {
-                disconnect(endStatus);
-            }
-        }
-
-        log("Finished monitoring session.");
+            log(Level.SEVERE, e.getMessage());
+            disconnect(ConnectionStatus.ERROR);
+        }         
     }
 
     /**
-     * Create the thread that will execute the EtEvent processing chain.
-     * @return The thread on which event processing will occur.
-     */
-    private void createEventProcessingThread() {
-
-        // Create a new event processor.
-        eventProcessor = new DefaultEtEventProcessor(this.connection, this.eventBuilder, this.jobManager, getMaxEvents(), disconnectOnError(), this.logHandler);
-
-        // Add the application's listener for callbacks to the GUI components.
-        eventProcessor.addListener(this.etListener);
-
-        // Set pause mode from JobPanel, after which it can be toggled using the event
-        // buttons.
-        eventProcessor.pauseMode(this.jobPanel.pauseMode());
-
-        // Create a new thread for event processing.
-        Runnable run = new Runnable() {
-            public void run() {
-                eventProcessor.process();
-            }
-        };
-        eventProcessingThread = new Thread(run, "Event Processing Thread");
-
-        // Start the event processing thread.
-        eventProcessingThread.start();
-
-        log(Level.FINEST, "Started event processing thread.");
-        logHandler.flush();
-    }
-
-    /**
      * Connect to the ET system specified in the GUI's connection panel settings.
      */
-    private void connect() {
+    private void connect() throws IOException {
 
         log("Connecting to ET system.");
 
@@ -1409,9 +1153,13 @@
         setConnectedGuiState();
 
         // Create a connection to the ET server.
-        createEtConnection();
-
-        log("Successfully connected to ET system.");
+        try {
+            createEtConnection();          
+            log("Successfully connected to ET system.");
+        } catch (Exception e) {
+            log(e.getMessage());
+            throw new IOException(e);
+        }       
     }
 
     /**
@@ -1464,45 +1212,28 @@
      */
     synchronized private void disconnect(int status) {
 
-        log("Disconnecting from ET system with status <" + ConnectionStatus.toString(status) + ">.");
+        log("Disconnecting from the ET system.");
+     
+        // Cleanup the ET connection.
+        cleanupEtConnection();
 
-        // Check if disconnected already.
-        if (getConnectionStatus() == ConnectionStatus.DISCONNECTED) {
-            log(Level.WARNING, "ET system is already disconnected.");
-            return;
-        }
-
-        // Check if in the process of disconnecting.
-        if (getConnectionStatus() == ConnectionStatus.DISCONNECTING) {
-            log(Level.WARNING, "ET system is already disconnecting.");
-            return;
-        }
-
-        // Stop event processing if currently connected.
-        if (eventProcessor != null) {
-            log(Level.FINE, "Stopping the event processor.");
-            eventProcessor.stop();
-        }
-
-        // Set the application status from the caller.
-        setConnectionStatus(status);
-
-        // Cleanup the ET session.
-        cleanupConnection();
-
         // Update state of GUI to disconnected.
         setDisconnectedGuiState();
 
         // Finally, change application state to fully disconnected.
         setConnectionStatus(ConnectionStatus.DISCONNECTED);
+        
+        // Set the application status from the caller if an error had occurred.
+        if (status == ConnectionStatus.ERROR)
+            setConnectionStatus(status);
 
-        log("Disconnected from ET system.");
+        log("Successfully disconnected from ET system.");
     }
 
     /**
-     * This is a thread for cleaning up the ET connection. This is executed under a
-     * separate thread, because it could potentially block forever. So we need to be able
-     * to kill it after waiting for X amount of time.
+     * This is a thread for cleaning up the ET connection. 
+     * It is executed under a separate thread, because it could potentially block forever. 
+     * So we need to be able to kill it after waiting for X amount of time.
      */
     private class EtCleanupThread extends Thread {
 
@@ -1530,10 +1261,10 @@
     /**
      * Cleanup the ET connection.
      */
-    private void cleanupConnection() {
+    private void cleanupEtConnection() {
 
         if (connection != null) {
-
+           
             // Execute the connection cleanup thread.
             EtCleanupThread cleanupThread = new EtCleanupThread();
             log(Level.FINE, "Starting EtCleanupThread to disconnect from ET system.");
@@ -1549,18 +1280,17 @@
             if (cleanupThread.succeeded()) {
                 log(Level.FINE, "EtCleanupThread succeeded in disconnecting from ET system.");
             } else {
-                log(Level.SEVERE, "EtCleanupThread failed to disconnect.  Your station <" + this.connection.getEtStation().getName() + "> is zombified.");
+                log(Level.SEVERE, "EtCleanupThread failed to disconnect.  Your station <" + this.connection.getEtStation().getName() + "> is zombified!");
                 // Make the cleanup thread yield.
                 cleanupThread.stopCleanup();
                 // Stop the cleanup thread.
                 // FIXME: Should call yield() instead?
                 cleanupThread.stop();
-                // Join to cleanup thread until it dies.
-                log(Level.FINEST, "Waiting for EtCleanupThread to die");
+                // Join to cleanup thread until it dies.                
                 log(Level.FINEST, "EtCleanupThread was killed.");
                 // The ET connection is now unusable so set it to null.
                 this.connection = null;
-            }
+            }            
         }
     }
 
@@ -1571,13 +1301,6 @@
 
         log(Level.INFO, "Setting up LCSim.");
 
-        // Clear the static AIDA tree in case plots are hanging around from previous sessions.
-        resetAidaTree();
-
-        // Reset the top plots panel so that it is empty.
-        plotPane.removeAll();
-        //((MonitoringAnalysisFactory)MonitoringAnalysisFactory.create()).clearPlotterFactories();
-
         // Get steering resource or file as a String parameter.
         String steering = getSteering();
         int steeringType = jobPanel.getSteeringType();
@@ -1590,8 +1313,7 @@
         }
 
         try {
-            // Create job manager and configure based on steering type of resource or
-            // file.
+            // Create job manager and configure.
             jobManager = new JobControlManager();
             jobManager.setPerformDryRun(true);
             if (steeringType == JobPanel.RESOURCE) {
@@ -1604,12 +1326,10 @@
                 jobManager.setup(new File(steering));
             }
 
-            // Call configure to trigger conditions setup and other initialization.
-            jobManager.configure();
-
             // Setup the event builder to translate from EVIO to LCIO.
             createEventBuilder();
-        // Catch all other setup exceptions and re-throw them as RuntimeExceptions.
+
+            // Catch all other setup exceptions and re-throw them as RuntimeExceptions.
         } catch (Exception e) {
             e.printStackTrace();
             log(Level.SEVERE, e.getMessage());
@@ -1641,24 +1361,11 @@
[truncated at 1000 lines; 219 more skipped]

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
MonitoringApplicationMain.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/MonitoringApplicationMain.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/MonitoringApplicationMain.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,59 @@
+package org.hps.monitoring;
+
+import java.io.File;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+
+
+public class MonitoringApplicationMain {
+
+    /**
+     * Run the monitoring application from the command line.
+     * @param args The command line arguments.
+     */
+    public static void main(String[] args) {
+
+        // Set up command line parsing.
+        Options options = new Options();
+        options.addOption(new Option("h", false, "Print help."));
+        options.addOption(new Option("c", true, "Load properties file with connection settings."));
+        options.addOption(new Option("j", true, "Load properties file with job settings."));
+        CommandLineParser parser = new PosixParser();
+
+        // Parse command line arguments.
+        CommandLine cl = null;
+        try {
+            cl = parser.parse(options, args);
+        } catch (ParseException e) {
+            throw new RuntimeException("Problem parsing command line options.", e);
+        }
+
+        // Print help and exit.
+        if (cl.hasOption("h")) {
+            System.out.println("MonitoringApplication [options]");
+            HelpFormatter help = new HelpFormatter();
+            help.printHelp(" ", options);
+            System.exit(1);
+        }
+
+        // Create the application class.
+        MonitoringApplication app = MonitoringApplication.createMonitoringApplication();
+
+        // Load the connection settings.
+        if (cl.hasOption("c")) {
+            app.loadConnectionSettings(new File(cl.getOptionValue("c")));
+        }
+
+        // Load the job settings.
+        if (cl.hasOption("j")) {
+            app.loadJobSettings(new File(cl.getOptionValue("j")));
+        }
+    }
+    
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
MonitoringCommands.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/MonitoringCommands.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/MonitoringCommands.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -6,36 +6,29 @@
  * @author Jeremy McCormick <[log in to unmask]>
  */
 final class MonitoringCommands {
-
-    private MonitoringCommands() {}
-
+    static final String AIDA_AUTO_SAVE = "aidaAutoSave";
+    static final String CLEAR_LOG_TABLE = "clearLogTable";
     static final String CONNECT = "connect";
     static final String DISCONNECT = "disconnect";
-    static final String SAVE_CONNECTION = "saveConnection";
+    static final String EDIT_EVENT_REFRESH = "editEventRefresh";
+    static final String EXIT = "exit";    
     static final String LOAD_CONNECTION = "loadConnection";
-    static final String RESET_CONNECTION_SETTINGS = "resetConnectionSettings";
-    static final String RESET_EVENTS = "resetEvents";
-    static final String SAVE_PLOTS = "savePlots";
-    static final String RESET_DRIVERS = "resetDrivers";
-    static final String SET_EVENT_BUILDER = "setEventBuilder";
-    static final String SET_EVENT_REFRESH = "setEventRefresh";
-    static final String EXIT = "exit";
+    static final String LOAD_JOB_SETTINGS = "loadJobSettings";
     static final String LOG_TO_FILE = "logToFile";
     static final String LOG_TO_TERMINAL = "logToTerminal";
-    static final String SCREENSHOT = "screenshot";
-    static final String EDIT_EVENT_REFRESH = "editEventRefresh";
-    static final String UPDATE_TIME = "updateTime";    
-    static final String SET_MAX_EVENTS = "setMaxEvents";
-    static final String SAVE_LOG_TABLE = "saveLogTable";
-    static final String CLEAR_LOG_TABLE = "clearLogTable";    
+    static final String NEXT = "next";
     static final String PAUSE = "pause";
     static final String RESUME = "resume";
-    static final String NEXT = "next";
-    static final String SET_LOG_LEVEL = "setLogLevel";
-    static final String AIDA_AUTO_SAVE = "aidaAutoSave";
-    static final String SAVE_JOB_SETTINGS = "saveJobSettings";
-    static final String LOAD_JOB_SETTINGS = "loadJobSettings";
+    static final String RESET_CONNECTION_SETTINGS = "resetConnectionSettings";
     static final String RESET_JOB_SETTINGS = "resetJobSettings";
-    static final String SET_STEERING_RESOURCE = "setSteeringResource";
+    static final String SAVE_CONNECTION = "saveConnection";
+    static final String SAVE_JOB_SETTINGS = "saveJobSettings";
+    static final String SAVE_LOG_TABLE = "saveLogTable";
+    static final String SAVE_PLOTS = "savePlots";
+    static final String SCREENSHOT = "screenshot";
+    static final String SET_EVENT_BUILDER = "setEventBuilder";
+    static final String SET_EVENT_REFRESH = "setEventRefresh";
+    static final String SET_LOG_LEVEL = "setLogLevel";
     static final String SET_STEERING_FILE = "setSteeringFile";
+    static final String SET_STEERING_RESOURCE = "setSteeringResource";
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring
OldEtEventProcessor.java removed after 697
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/OldEtEventProcessor.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/OldEtEventProcessor.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -1,152 +0,0 @@
-package org.hps.monitoring;
-
-import java.util.logging.Level;
-
-import org.hps.monitoring.record.etevent.EtEventListener;
-import org.jlab.coda.et.EtEvent;
-import org.jlab.coda.et.exception.EtTimeoutException;
-
-/**
- * This is an interface for processing EtEvent objects and receiving callbacks
- * via an {@link EtEventListener}.
- * @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: EtEventProcessor.java,v 1.4 2013/11/05 17:15:04 jeremy Exp $
- */
-interface OldEtEventProcessor
-{
-    /** 
-     * Process a single EtEvent.
-     * @param event The ET event.
-     * @throws EventProcessingException if there was an error processing the event.
-     * @throws MaxEventsException if the maximum number of events was reached or exceeded.
-     */
-    void processEtEvent(EtEvent event) throws EventProcessingException, MaxEventsException;
-    
-    /**
-     * Process the next array of EtEvents.  This method may block for a long time or forever.
-     * The default implementation calls processEtEvent() on each event, but this is not required.
-     * @throws EtTimeoutException if the connection times out.
-     * @throws MaxEventsException if the maximum number of events was reached or exceeded.
-     * @throws EventProcessingException if there was an error processing events.
-     * @throws Exception if some other exception occurs.
-     */
-    void processEtEvents() throws EtTimeoutException, MaxEventsException, EventProcessingException, Exception;
-    
-    /** 
-     * Process all incoming EtEvents until ET system goes down or stop is requested.
-     */
-    void process();
-    
-    /**
-     * Get the current status as a {@link ConnectionStatus} code.
-     */
-    int getStatus();
-    
-    /** 
-     * Get the total number of events processing thusfar, including those with errors.
-     * @return The number of events processed.
-     */
-    int getNumberOfEventsProcessed();
-    
-    /**
-     * Get the maximum number of event to process before automatically disconnecting.
-     * @return The maximum number of events to process.
-     */
-    int getMaxEvents();
-    
-    /**
-     * Reset the number of events processed to zero.
-     */
-    void resetNumberOfEventsProcessed();
-    
-    /**
-     * Add a listener that will receive notifications during event processing.
-     * @param callme The ET event listener.
-     */
-    void addListener(EtEventListener callme);
-    
-    /**
-     * Request that the processor stop processing events.
-     */
-    void stop();
-    
-    /**
-     * Set the maximum number of events to process before disconnecting.
-     * @param maxEvents The maximum number of events to process.
-     */
-    void setMaxEvents(int maxEvents);
-    
-    /**
-     * Turn pause mode on or off.
-     * @param p The pause mode setting; true for on; false for off.
-     */
-    void pauseMode(boolean p);
-    
-    /**
-     * If using pause mode, this will get the next set of events and then pause again.
-     */
-    void nextEvents();
-    
-    /**
-     * Set the log level of this object.
-     * @param level The log level.
-     */
-    void setLogLevel(Level level);
-    
-    /**
-     * Check if the processor is done.
-     * @return True if processer is done processing events; false if not.
-     */
-    boolean done();
-    
-    /**
-     * Check if the processor is in the blocked state, e.g. if it is waiting 
-     * for events from the ET ring.
-     * @return True if blocked; false if not.
-     */
-    boolean blocked();
-           
-    /** 
-     * Exception that is thrown when an error occurs during event processing.
-     */
-    static class EventProcessingException extends Exception {
-
-        /**
-         * Class constructor.
-         * @param e Another Exception object.
-         */
-        EventProcessingException(Exception e) {
-            super(e);
-        }
-        
-        /**
-         * Class constructor.
-         * @param m The error message.
-         * @param e Another Exception object.
-         */
-        EventProcessingException(String m, Exception e) {
-            super(m, e);
-        }
-        
-        /**
-         * Class constructor.
-         * @param m The error message.
-         */
-        EventProcessingException(String m) {
-        	super(m);
-        }
-    }
-    
-    /**
-     * Exception that is throw when the {@link OldEtEventProcessor#getMaxEvents()} is exceeded.
-     */
-    static final class MaxEventsException extends Exception {
-        
-        /**
-         * Class constructor
-         */
-        MaxEventsException() {
-            super("Maximum number of events was reached.");
-        }
-    }
-}
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record
EventProcessingChain.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessingChain.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessingChain.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -1,5 +1,8 @@
 package org.hps.monitoring.record;
 
+import static org.freehep.record.loop.RecordLoop.Command.NEXT;
+
+import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.nio.BufferUnderflowException;
@@ -7,9 +10,13 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.freehep.record.loop.RecordLoop.Command;
+import org.freehep.record.source.NoSuchRecordException;
 import org.freehep.record.source.RecordSource;
 import org.hps.evio.EventConstants;
 import org.hps.evio.LCSimEventBuilder;
+import org.hps.monitoring.record.composite.CompositeRecord;
+import org.hps.monitoring.record.composite.CompositeRecordLoop;
 import org.hps.monitoring.record.etevent.EtEventLoop;
 import org.hps.monitoring.record.etevent.EtEventProcessor;
 import org.hps.monitoring.record.etevent.EtEventSource;
@@ -29,20 +36,19 @@
 import org.lcsim.util.loop.LCSimLoop;
 
 /**
- * This class provides a serial implementation of the 
- * ET to EVIO to LCIO event processing chain.
+ * This class provides a serial implementation of the monitoring event
+ * processing chain.  This is accomplished by chaining together implementations 
+ * of FreeHep's <tt>RecordLoop</tt>.
  * 
- * This is a flexible class for handling the event processing with
- * a number of different configurations and scenarios.  The processing
- * chain can be configured to execute the ET, EVIO event building, or
- * LCIO eventing building stages.  The source can be set to an ET ring,
+ * The processing chain can be configured to execute the ET, EVIO event building, 
+ * or LCIO eventing building stages.  The source can be set to an ET ring,
  * EVIO file source, or LCIO file source.  Any number of event processors
  * can be registered for processing the different record types, in order
- * to plot or otherwise visualize or analyze the events in that format.
+ * to plot, update a GUI component, or analyze the events.
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
-class EventProcessingChain {
+public class EventProcessingChain {
       
     /**
      * Type of source for events.
@@ -63,24 +69,27 @@
     }
     
     SourceType sourceType;    
-    ProcessingStage processingStage = ProcessingStage.BUILD_LCIO_EVENT;
-    PrintStream logStream = System.out;
-    List<EventProcessingStep> processingSteps = new ArrayList<EventProcessingStep>();
-    RecordSource recordSource;
+    ProcessingStage processingStage = ProcessingStage.BUILD_LCIO_EVENT;    
+    PrintStream logStream = System.out;    
+    List<EventProcessingStep> processingSteps = new ArrayList<EventProcessingStep>();    
+    RecordSource recordSource;    
     EtEventLoop etLoop = new EtEventLoop();
     EvioEventLoop evioLoop = new EvioEventLoop();
     LCSimLoop lcsimLoop = new LCSimLoop();
+    CompositeRecordLoop compositeLoop = new CompositeRecordLoop();            
     EvioEventQueue evioQueue = new EvioEventQueue();
     LcioEventQueue lcioQueue = new LcioEventQueue();
-    LCSimEventBuilder eventBuilder;
-    EtEvent currentEtEvent;
-    EvioEvent currentEvioEvent;
+    LCSimEventBuilder eventBuilder;        
     int totalEventsProcessed;
     String detectorName;
-    boolean stopRequested;
-    boolean paused;
     boolean stopOnEndRun;
-    
+    boolean continueOnErrors;
+    String steeringResource;
+    File steeringFile;
+    Exception lastException;
+    volatile boolean isDone;
+    volatile boolean paused;
+        
     /**
      * No argument constructor.  
      * The setter methods should be used to setup this class.
@@ -112,12 +121,26 @@
                 this.lcsimLoop.setRecordSource(lcioQueue);
             }
         }
+        
+        // Setup the composite loop.
+        compositeLoop.addProcessingSteps(processingSteps);
+        compositeLoop.registerRecordLoop(etLoop);
+        compositeLoop.registerRecordLoop(evioLoop);
+        compositeLoop.registerRecordLoop(lcsimLoop);
     }
     
     void setSourceType(SourceType sourceType) {
         this.sourceType = sourceType;
     }
+        
+    public void setSteeringFile(File steeringFile) {
+        this.steeringFile = steeringFile;
+    }
     
+    public void setSteeringResource(String steeringResource) {
+        this.steeringResource = steeringResource;
+    }
+    
     public void setProcessingStage(ProcessingStage processingStage) {
         this.processingStage = processingStage;
     }
@@ -153,7 +176,7 @@
     }
     
     public void add(Collection<Driver> drivers) {
-        for (Driver driver : drivers) {
+        for (Driver driver : drivers) { 
             this.lcsimLoop.add(driver);
         }
     }
@@ -177,102 +200,67 @@
     public void setStopOnEndRun() {
         this.stopOnEndRun = true;
     }
+    
+    public void setContinueOnErrors() {
+        this.continueOnErrors = true;
+    }
+    
+    public CompositeRecord getCompositeRecord() {
+        try {
+            return (CompositeRecord) compositeLoop.getRecordSource().getCurrentRecord();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
       
     /**
      * Process one event by executing the processing steps.
      * @throws IOException If some error occurs while processing events.
      */
-    void processEvent() throws IOException {
+    void processEvent() throws IOException, NoSuchRecordException {
         for (EventProcessingStep step : this.processingSteps) {
             step.execute();
         }
         ++this.totalEventsProcessed;
     }
-    
+        
     /**
-     * Stop event processing.
+     * This exception occurs when an EVIO end record is encountered
+     * in the event stream and the processing chain is configured
+     * to stop when this occurs.
      */
-    public void stop() {
-        this.stopRequested = true;
+    class EndRunException extends IOException {
+        EndRunException(String message) {
+            super(message);
+        }
     }
     
-    /**
-     * Pause event processing.
-     */
-    public void pause() {
-        this.paused = true;
-    }
-    
-    /**
-     * Resume event processing after pausing.
-     */
     public void resume() {
         this.paused = false;
     }
     
-    /**
-     * This exception occurs when the call to the event loop
-     * results in a null current record.
-     */
-    class EventsExhaustedException extends IOException {
-        EventsExhaustedException(String message) {
-            super(message);
+    public void loop() {
+        while (!isDone) {
+            if (!paused) {
+                compositeLoop.execute(Command.GO, false);
+            }
         }
     }
     
-    /**
-     * This exception occurs when an EVIO end record is encountered
-     * in the event stream.
-     */
-    class EndRunException extends IOException {
-        EndRunException(String message) {
-            super(message);
-        }
+    public void pause() {
+        compositeLoop.execute(Command.PAUSE);
+        paused = true;
     }
-    
-    /**
-     * Primary method for event processing.  This will run events
-     * until a stop or pause is requested, the event source is exhausted,
-     * or (if this behavior is enabled) the end of run record is reached.
-     */
-    public synchronized void run() {
-        this.stopRequested = false;
-        for (;;) {
-            try {
-                processEvent();
-            } catch (EventsExhaustedException e) {
-                this.logStream.println(e.getMessage());
-                break;
-            } catch (EndRunException e) {
-                this.logStream.println(e.getMessage());
-                break;
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
+        
+    public void finish() {
+        compositeLoop.execute(Command.STOP);
+        isDone = true;
+    }    
+        
+    public void next() {
+        compositeLoop.execute(Command.GO_N, 1L, true);
+    }
             
-            if (stopRequested) {
-                this.logStream.println("Stop was requested.  Processing will end!");
-                break;
-            }
-            
-            if (this.paused) {
-                synchronized (Thread.currentThread()) {
-                    for (;;) {
-                        try {
-                            // Sleep for 1 second.
-                            Thread.currentThread().wait(1000);
-                        } catch (InterruptedException e) {
-                            e.printStackTrace();
-                        }
-                        // Check if unpaused.
-                        if (!this.paused)
-                            break;
-                    }
-                }
-            }
-        }
-    }
-    
     /** 
      * Get the total number of events processed.
      * @return The number of events processed.
@@ -281,13 +269,10 @@
         return this.totalEventsProcessed;
     }
     
-    /**
-     * Interface for a single processing step which handles one type of record.
-     */
-    interface EventProcessingStep {
-       void execute() throws IOException;
+    public boolean isDone() {
+        return isDone;
     }
-
+        
     /**
      * ET processing step to load an <tt>EtEvent</tt> from the ET ring.
      */
@@ -296,12 +281,18 @@
         /**
          * Load the next <tt>EtEvent</tt>.
          */
-        public void execute() throws IOException {
+        public void execute() throws IOException, NoSuchRecordException {
             // Load the next EtEvent.
-            etLoop.loop(1);
+            etLoop.execute(NEXT);
             
             // Get an EtEvent from the loop.
-            currentEtEvent = (EtEvent) etLoop.getRecordSource().getCurrentRecord();
+            EtEvent nextEtEvent = (EtEvent) etLoop.getRecordSource().getCurrentRecord();
+            
+            // Failed to read an EtEvent from the ET server.
+            if (nextEtEvent == null)
+                throw new NoSuchRecordException("No current EtEvent is available.");
+            
+            getCompositeRecord().setEtEvent(nextEtEvent);
         }
     }
     
@@ -315,12 +306,14 @@
          * Load the next <tt>EvioEvent</tt>, either from a record source
          * or from the <tt>EtEvent</tt> data.
          */
-        public void execute() throws IOException {
+        public void execute() throws IOException, NoSuchRecordException {
             
             if (sourceType == SourceType.ET_EVENT) {
                 EvioEvent evioEvent = null;
                 try {
-                    evioEvent = createEvioEvent(currentEtEvent);
+                    evioEvent = createEvioEvent(getCompositeRecord().getEtEvent());                    
+                    if (evioEvent == null)
+                        throw new IOException("Failed to create EvioEvent from current EtEvent.");
                     setEventNumber(evioEvent);
                 } catch (EvioException e) {
                     throw new IOException(e);
@@ -331,16 +324,18 @@
             }
 
             // Process one EvioEvent.
-            evioLoop.loop(1);
-            currentEvioEvent = (EvioEvent) evioLoop.getRecordSource().getCurrentRecord();
+            evioLoop.execute(NEXT);         
+            EvioEvent nextEvioEvent = (EvioEvent) evioLoop.getRecordSource().getCurrentRecord();
             
             // The call to loop did not create a current record.
-            if (currentEvioEvent == null)
-                throw new EventsExhaustedException("No current EVIO event.");
+            if (nextEvioEvent == null)
+                throw new NoSuchRecordException("No current EVIO event.");
             
+            getCompositeRecord().setEvioEvent(nextEvioEvent);
+            
             // Encountered an end of run record.
-            if (EventConstants.isEndEvent(currentEvioEvent))
-                // If stop on end run is enabled then trigger an exception to end processing.
+            if (EventConstants.isEndEvent(nextEvioEvent))
+                // If stop on end run is enabled, then trigger an exception to end processing.
                 if (stopOnEndRun)
                     throw new EndRunException("EVIO end event received, and stop on end run is enabled.");
         }
@@ -361,18 +356,20 @@
         /**
          * When reading from ET data, the EVIO event number needs to be set manually
          * from the event ID bank.
-         * @param event The <tt>EvioEvent</tt> on which to set the event number.
+         * @param evioEvent The <tt>EvioEvent</tt> on which to set the event number.
          */
-        private void setEventNumber(EvioEvent event) {
+        private void setEventNumber(EvioEvent evioEvent) {
             int eventNumber = -1;
-            for (BaseStructure bank : event.getChildren()) {
-                if (bank.getHeader().getTag() == EventConstants.EVENTID_BANK_TAG) {
-                    eventNumber = bank.getIntData()[0];
-                    break;
+            if (evioEvent.getChildren() != null) {
+                for (BaseStructure bank : evioEvent.getChildren()) {
+                    if (bank.getHeader().getTag() == EventConstants.EVENTID_BANK_TAG) {
+                        eventNumber = bank.getIntData()[0];
+                        break;
+                    }
                 }
             }
             if (eventNumber != -1)
-                event.setEventNumber(eventNumber);
+                evioEvent.setEventNumber(eventNumber);
         }
     }
     
@@ -386,12 +383,14 @@
          * Create the next LCIO event either from the EVIO record
          * or from a direct LCIO file source.
          */
-        public void execute() throws IOException {
+        public void execute() throws IOException, NoSuchRecordException {
 
-            // When the loop does not have a direct event source, the events
-            // need to be built from EVIO.
+            // When the loop does not have a direct LCIO file source, 
+            // the events need to be built from the EVIO input.
             if (sourceType.ordinal() < SourceType.LCIO_FILE.ordinal()) {
             
+                EvioEvent currentEvioEvent = getCompositeRecord().getEvioEvent();
+                
                 // Set state on LCIO event builder.
                 eventBuilder.readEvioEvent(currentEvioEvent);
                 
@@ -409,19 +408,22 @@
                 }
             }
         
-            // Process the next LCIO event.
-            lcsimLoop.loop(1, null);
-            
-            // In this case, there are no more records in the file.
+            // If using an LCIO file source, check for EOF.
             if (sourceType == SourceType.LCIO_FILE) {
                 if (!lcsimLoop.getRecordSource().hasNext())
-                    throw new EventsExhaustedException("No next LCIO event.");
+                    throw new NoSuchRecordException("No next LCIO event.");
             }
             
-            // The last call to loop did not create a current record.
+            // Process the next LCIO event.
+            lcsimLoop.execute(NEXT);
+                                   
+            // The last call to the loop did not create a current record for some reason.
             if (lcsimLoop.getRecordSource().getCurrentRecord() == null) {
-                throw new EventsExhaustedException("No current LCIO event.");
+                throw new NoSuchRecordException("No current LCIO event.");
             }
+            
+            EventHeader lcioEvent = (EventHeader) lcsimLoop.getRecordSource().getCurrentRecord();
+            getCompositeRecord().setLcioEvent(lcioEvent);
         }
     }
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record
EventProcessingStep.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessingStep.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessingStep.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,12 @@
+package org.hps.monitoring.record;
+
+import java.io.IOException;
+
+import org.freehep.record.source.NoSuchRecordException;
+
+/**
+ * Interface for a single processing step which handles one type of record.
+ */
+public interface EventProcessingStep {    
+    void execute() throws IOException, NoSuchRecordException;    
+}
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record
EventProcessingThread.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessingThread.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessingThread.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -8,25 +8,26 @@
     
     EventProcessingChain processing;
     
-    EventProcessingThread(EventProcessingChain processing) {
+    public EventProcessingThread(EventProcessingChain processing) {
         super("EventProcessingThread");
         this.processing = processing;
     }
     
+    public EventProcessingChain getEventProcessingChain() {
+        return processing;
+    }
+    
     @Override
     public void run() {
-        processing.run();
+        processing.loop();
+        /*
+        while (!processing.isDone()) {
+            try {
+                sleep(1000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        */
     }
-    
-    public void pause() {
-        processing.pause();
-    }
-    
-    public void stopProcessing() {
-        processing.stop();
-    }
-    
-    public void resumeProcessing() {
-        processing.resume();
-    }
 }

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record
EventProcessor.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessor.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/EventProcessor.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -7,14 +7,32 @@
  * @param <EventType> The concrete type of the event record.
  */
 public interface EventProcessor<EventType> {
+       
+    /**
+     * Start of job action.
+     */
+    void startJob();
     
-    // void jobStart();
+    /**
+     * Start run action.
+     * @param event
+     */
+    void startRun(EventType event);
     
-    // void runStart(EventType event);
+    /**
+     * Process a single event.
+     * @param event
+     */
+    void processEvent(EventType event);
+
+    /**
+     * End of run action.
+     * @param event
+     */
+    void endRun(EventType event);
     
-    void processEvent(EventType event);    
-    
-    // void runEnd(EventType event);
-    
-    // void jobEnd();
+    /**
+     * End of job action.
+     */
+    void endJob();
 }

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite
CompositeRecord.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecord.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecord.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,41 @@
+package org.hps.monitoring.record.composite;
+
+import org.jlab.coda.et.EtEvent;
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.event.EventHeader;
+
+public class CompositeRecord {
+    
+    EtEvent etEvent;
+    EvioEvent evioEvent;
+    EventHeader lcioEvent;
+    //boolean isValid = true;
+    
+    public void setEtEvent(EtEvent etEvent) {
+        this.etEvent = etEvent;
+    }
+    
+    public void setEvioEvent(EvioEvent evioEvent) {
+        this.evioEvent = evioEvent;
+    }
+    
+    public void setLcioEvent(EventHeader lcioEvent) {
+        this.lcioEvent = lcioEvent;
+    }
+    
+    public EtEvent getEtEvent() {
+        return etEvent;
+    }
+    
+    public EvioEvent getEvioEvent() {
+        return evioEvent;
+    }
+    
+    public EventHeader getLcioEvent() {
+        return lcioEvent;
+    }
+    
+    //public void setInvalid() {
+    //    isValid = false;
+    //}
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite
CompositeRecordLoop.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecordLoop.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecordLoop.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,41 @@
+package org.hps.monitoring.record.composite;
+
+import java.util.List;
+
+import org.freehep.record.loop.DefaultRecordLoop;
+import org.freehep.record.loop.RecordLoop;
+import org.freehep.record.source.RecordSource;
+import org.hps.monitoring.record.EventProcessingStep;
+
+public class CompositeRecordLoop extends DefaultRecordLoop {
+
+    CompositeRecordSource recordSource = new CompositeRecordSource();
+    CompositeRecordLoopAdapter adapter = new CompositeRecordLoopAdapter();
+    
+    public CompositeRecordLoop() {
+        setRecordSource(recordSource);
+        addLoopListener(adapter);
+        addRecordListener(adapter);
+    }
+    
+    public void setRecordSource(RecordSource source) {
+        if (!source.getRecordClass().isAssignableFrom(CompositeRecord.class)) {
+            throw new IllegalArgumentException("The RecordSource has the wrong class.");
+        }        
+        super.setRecordSource(source);
+    }
+        
+    public void addProcessingSteps(List<EventProcessingStep> processingSteps) {
+        recordSource.addProcessingSteps(processingSteps);
+    }
+    
+    public void registerRecordLoop(RecordLoop loop) {
+        adapter.registerRecordLoop(loop);
+    }
+    
+    public void loop(long n) {
+        //super.loop();
+        //execute(Command.GO, true);
+        execute(Command.GO, true);
+    }
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite
CompositeRecordLoopAdapter.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecordLoopAdapter.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecordLoopAdapter.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,39 @@
+package org.hps.monitoring.record.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.freehep.record.loop.AbstractLoopListener;
+import org.freehep.record.loop.LoopEvent;
+import org.freehep.record.loop.RecordEvent;
+import org.freehep.record.loop.RecordListener;
+import org.freehep.record.loop.RecordLoop;
+import org.freehep.record.loop.RecordLoop.Command;
+
+public class CompositeRecordLoopAdapter extends AbstractLoopListener implements RecordListener {
+
+    List<RecordLoop> registeredLoops = new ArrayList<RecordLoop>();
+    
+    public void finish(LoopEvent event) {
+        System.out.println("CompositeRecordLoopAdapter.finish");
+        for (RecordLoop loop : registeredLoops) {
+            loop.execute(Command.STOP);
+        }
+    }
+        
+    void registerRecordLoop(RecordLoop loop) {
+        registeredLoops.add(loop);
+    }
+    
+    /*
+    public void suspend(LoopEvent loopEvent) {
+        for (RecordLoop loop : registeredLoops) {
+            loop.execute(Command.PAUSE);
+        }
+    }
+    */
+
+    @Override
+    public void recordSupplied(RecordEvent record) {
+    }    
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite
CompositeRecordSource.java added at 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecordSource.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/composite/CompositeRecordSource.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,82 @@
+package org.hps.monitoring.record.composite;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.freehep.record.source.AbstractRecordSource;
+import org.freehep.record.source.NoSuchRecordException;
+import org.hps.monitoring.record.EventProcessingStep;
+
+
+public class CompositeRecordSource extends AbstractRecordSource {
+
+    CompositeRecord currentRecord;
+    List<EventProcessingStep> processingSteps = new ArrayList<EventProcessingStep>();
+            
+    public void next() throws IOException, NoSuchRecordException {
+        currentRecord = new CompositeRecord();
+        
+        // Execute sub-processing that will alter the CompositeRecord.
+        // FIXME: Should this happen here???
+        for (EventProcessingStep step : this.processingSteps) {
+            try {
+                step.execute();
+            } catch (Exception e) {
+                System.out.println("Exception " + e.getClass().getCanonicalName() + " caught from " + step.getClass().getCanonicalName() + ".");                
+                System.out.println(e.getMessage());
+                currentRecord = null;
+                throw e;
+            }
+        }
+    }
+        
+    void addProcessingSteps(List<EventProcessingStep> processingSteps) {
+        this.processingSteps = processingSteps;
+    }    
+    
+    @Override
+    public Object getCurrentRecord() throws IOException {
+        return currentRecord;
+    }
+    
+    @Override
+    public boolean supportsCurrent() {
+        return true;
+    }
+
+    @Override
+    public boolean supportsNext() {
+        return true;
+    }
+  
+    @Override
+    public boolean supportsPrevious() {
+        return false;
+    }
+  
+    @Override
+    public boolean supportsIndex() {
+        return false;
+    }
+  
+    @Override 
+    public boolean supportsShift() {
+        return false;
+    }
+  
+    @Override
+    public boolean supportsRewind() {
+        return false;
+    }
+
+    @Override
+    public boolean hasCurrent() {
+        return currentRecord != null;
+    }
+
+    @Override
+    public boolean hasNext() {
+        return true;
+    }
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent
EtConnection.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtConnection.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtConnection.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -167,5 +167,13 @@
             Modify.NOTHING,
             getConnectionParameters().getWaitTime(), 
             getConnectionParameters().getChunkSize());
+        
     }
+    
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(this.param.toString());  
+        buffer.append("attachment: " + this.att.getStation().getName());
+        return buffer.toString();
+    }
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent
EtEventAdapter.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtEventAdapter.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtEventAdapter.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -29,14 +29,14 @@
     @Override
     public void start(LoopEvent event) {
         for (EtEventProcessor processor : processors) {
-            processor.start();
+            processor.startJob();
         }
     }
     
     @Override
     public void finish(LoopEvent event) {
         for (EtEventProcessor processor : processors) {
-            processor.stop();
+            processor.endJob();
         }            
     }    
     

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent
EtEventProcessor.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtEventProcessor.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtEventProcessor.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -14,9 +14,15 @@
     /**
      * Start of ET session.
      */
-    public void start() {
+    @Override
+    public void startJob() {
     }
     
+    @Override
+    public void startRun(EtEvent event) {
+        
+    }
+    
     /**
      * Process one <tt>EtEvent</tt>.
      */
@@ -24,19 +30,15 @@
     public void processEvent(EtEvent event) {
     }    
     
+    @Override
+    public void endRun(EtEvent event) {
+        
+    }
+    
     /**
      * End of ET session.
      */
-    public void stop() {        
-    }
-    
-    // from EtEventListener
-    //
-    // void begin();    
-    // void startOfEvent();
-    // void endOfEvent();
-    // void errorOnEvent();
-    // void finish();
-    // void prestart(int seconds, int runNumber);    
-    // void endRun(int seconds, int nevents);
+    @Override
+    public void endJob() {
+    }    
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent
EtEventSource.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtEventSource.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/etevent/EtEventSource.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -28,6 +28,8 @@
     
     public EtEventSource(EtConnection connection) {
         this.connection = connection;
+        System.out.println("EtEventSource using ET system parameters ...");
+        System.out.println(this.connection.toString());
     }
           
     @Override
@@ -77,8 +79,6 @@
     
     @Override
     public void next() throws IOException, NoSuchRecordException {
-
-        System.out.println("EtEventSource.next");
         
         // Fill the queue if there are no events cached.
         if (eventQueue.size() == 0) {

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio
EvioAdapter.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioAdapter.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioAdapter.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -4,13 +4,14 @@
 import java.util.List;
 
 import org.freehep.record.loop.AbstractLoopListener;
+import org.freehep.record.loop.LoopEvent;
 import org.freehep.record.loop.RecordEvent;
 import org.freehep.record.loop.RecordListener;
 import org.hps.evio.EventConstants;
 import org.jlab.coda.jevio.EvioEvent;
 
 /**
- * Adapter to process <tt>EvioEvent</tt> objects using a loop.
+ * Adapter to process <tt>EvioEvent</tt> objects using a record loop.
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public class EvioAdapter extends AbstractLoopListener implements RecordListener {
@@ -23,15 +24,32 @@
         if (object instanceof EvioEvent) {
             EvioEvent event = (EvioEvent)object;
             if (EventConstants.isPreStartEvent(event)) {
+                // Start of run.
                 startRun(event);
             } else if (EventConstants.isEndEvent(event)) {
+                // End of run.
                 endRun(event);
             } else if (EventConstants.isPhysicsEvent(event)) {
+                // Process one physics event.
                 processEvent(event);
             }
         }
     }
+     
+    @Override
+    public void start(LoopEvent event) {        
+        for (EvioEventProcessor processor : processors) {
+            processor.startJob();
+        }
+    }
     
+    @Override
+    public void finish(LoopEvent event) {
+        for (EvioEventProcessor processor : processors) {
+            processor.endJob();
+        }
+    }    
+    
     void addEvioEventProcessor(EvioEventProcessor processor) {
         processors.add(processor);
     }

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio
EvioEventLoop.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioEventLoop.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioEventLoop.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -3,6 +3,7 @@
 import java.io.IOException;
 
 import org.freehep.record.loop.DefaultRecordLoop;
+import org.freehep.record.loop.RecordLoop.Command;
 import org.freehep.record.source.RecordSource;
 import org.jlab.coda.jevio.EvioEvent;
 
@@ -24,13 +25,14 @@
         adapter.addEvioEventProcessor(processor);
     }
     
+    @Override
     public void setRecordSource(RecordSource source) {
         if (!source.getRecordClass().isAssignableFrom(EvioEvent.class)) {
             System.err.println("The class " + source.getRecordClass().getCanonicalName() + " is invalid.");
             throw new IllegalArgumentException("The record class is invalid.");
         }        
         super.setRecordSource(source);
-    }           
+    }
     
     public long loop(long number) throws IOException {
         if (number < 0L) {

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio
EvioEventProcessor.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioEventProcessor.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioEventProcessor.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -10,14 +10,24 @@
  */
 // TODO: Add handling for all event types (see EtEventListener).
 public abstract class EvioEventProcessor implements EventProcessor<EvioEvent> {
-        
+    
     @Override
-    public void processEvent(EvioEvent event) {
+    public void startJob() {        
     }
     
+    @Override
     public void startRun(EvioEvent event) { 
     }
     
+    @Override
+    public void processEvent(EvioEvent event) {
+    }
+            
+    @Override
     public void endRun(EvioEvent event) {
     }
+    
+    @Override
+    public void endJob() {        
+    }
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio
EvioFileSource.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioFileSource.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/record/evio/EvioFileSource.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -38,7 +38,9 @@
 
     private void openReader() {
         try {
+            System.out.println("Opening reader for file " + files.get(fileIndex) + " ...");
             reader = new EvioReader(files.get(fileIndex), false);
+            System.out.println("Done opening file.");
         } catch (EvioException | IOException e) {
             throw new RuntimeException(e);
         }

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/et
EtSystemMonitor.java 697 -> 698
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/et/EtSystemMonitor.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/et/EtSystemMonitor.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -18,7 +18,7 @@
     SystemInfo info = new SystemInfoImpl("EtSystem");    
     
     @Override
-    public void start() {
+    public void startJob() {
         info.getStatistics().start();
         info.getStatus().setStatus(StatusCode.OKAY, "EtSystemMonitor set okay.");
     }
@@ -29,7 +29,7 @@
     }    
     
     @Override
-    public void stop() {
+    public void endJob() {
         info.getStatistics().stop();
         info.getStatus().setStatus(StatusCode.OFFLINE, "EtSystemMonitor set offline.");
     }

java/trunk/monitoring-app/src/main/scripts
start_monitoring_application.sh 697 -> 698
--- java/trunk/monitoring-app/src/main/scripts/start_monitoring_application.sh	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/main/scripts/start_monitoring_application.sh	2014-06-10 23:01:18 UTC (rev 698)
@@ -3,10 +3,10 @@
 # Set the load library path.
 . ${project.build.directory}/scripts/ldpath.sh
 
-# Setup the classpath variable.
-classpath=${project.build.directory}/${project.artifactId}-${project.version}-bin.jar
+# The bin jar to run.
+jarfile=${project.build.directory}/${project.artifactId}-${project.version}-bin.jar
 
-# Start the monitoring application, sending any script arguments to the end of the command.
-prod="java -Xmx1024m -classpath $classpath org.hps.monitoring.MonitoringApplication $@"
+# Start the monitoring application with supplied arguments.
+prod="java -Xmx1024m -jar $jarfile $@"
 echo $prod
 exec $prod

java/trunk/monitoring-app/src/test/java/org/hps/monitoring/record
EventProcessingChainTest.java 697 -> 698
--- java/trunk/monitoring-app/src/test/java/org/hps/monitoring/record/EventProcessingChainTest.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/test/java/org/hps/monitoring/record/EventProcessingChainTest.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -15,11 +15,14 @@
 
 public class EventProcessingChainTest {
     
-    static String evioFilePath = "/work/data/hps/hps_001351.evio.0";
-    static String lcioFilePath = "/work/data/hps/hps_001351.evio.0_recon.slcio";
+    //static String evioFilePath = "/work/data/hps/hps_001351.evio.0";
+    static String evioFilePath = "/nfs/slac/g/hps3/data/testrun/runs/evio/hps_001351.evio.0";
+    //static String lcioFilePath = "/work/data/hps/hps_001351.evio.0_recon.slcio";
+    static String lcioFilePath = "/nfs/slac/g/hps3/data/testrun/runs/recon_new/hps_001351.evio.0_recon.slcio";
     static String detectorName = "HPS-TestRun-v8-5";
     
     // ET ring with streaming EVIO file must be running for this to work.
+    /*
     public void testEtSource() {
         EventProcessingChain processing = new EventProcessingChain();
         processing.setRecordSource(new EtEventSource());
@@ -29,8 +32,9 @@
         processing.add(new DummyDriver());
         processing.setStopOnEndRun();
         processing.configure();
-        processing.run();
+        processing.loop();
     }
+    */
     
     public void testEvioFile() {
         EventProcessingChain processing = new EventProcessingChain();
@@ -41,9 +45,10 @@
         processing.add(new DummyDriver());
         processing.setStopOnEndRun();
         processing.configure();
-        processing.run();
+        processing.loop();
     }
     
+    /*
     public void testLcioFile() {
         EventProcessingChain processing = new EventProcessingChain();
         try {
@@ -55,8 +60,9 @@
         processing.setDetectorName(detectorName);
         processing.add(new DummyDriver());
         processing.configure();
-        processing.run();
+        processing.loop();
     }
+    */
     
     static class DummyDriver extends Driver {
         public void process(EventHeader event) {
@@ -74,5 +80,4 @@
             System.out.println(this.getClass().getSimpleName() + " got EVIO event #" + event.getEventNumber());
         }
     }
-
 }

java/trunk/monitoring-app/src/test/java/org/hps/monitoring/record
EvioEventProcessingTest.java added at 698
--- java/trunk/monitoring-app/src/test/java/org/hps/monitoring/record/EvioEventProcessingTest.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/test/java/org/hps/monitoring/record/EvioEventProcessingTest.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -0,0 +1,79 @@
+package org.hps.monitoring.record;
+
+import java.io.File;
+
+import org.hps.evio.LCSimTestRunEventBuilder;
+import org.hps.monitoring.record.evio.EvioEventProcessor;
+import org.hps.monitoring.record.evio.EvioFileSource;
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.EventHeader.LCMetaData;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+
+
+public class EvioEventProcessingTest {
+    
+    static String evioFilePath = "/nfs/slac/g/hps3/data/testrun/runs/evio/hps_001351.evio.0";   
+    static String detectorName = "HPS-TestRun-v8-5";
+         
+    public void testEvioFile() {
+        EventProcessingChain processing = new EventProcessingChain();
+        processing.setRecordSource(new EvioFileSource(new File(evioFilePath)));
+        processing.setEventBuilder(new LCSimTestRunEventBuilder());
+        processing.setDetectorName(detectorName);
+        processing.add(new DummyEvioProcessor());
+        processing.add(new DummyDriver());
+        processing.setStopOnEndRun();
+        processing.configure();
+        processing.loop();
+        processing.finish();
+    }
+        
+    static class DummyDriver extends Driver {
+        
+        public void detectorChanged(Detector detector) {
+            System.out.println(this.getClass().getSimpleName() + ".detectorChanged - " + detector.getDetectorName());
+        }
+        
+        public void startOfData() {
+            System.out.println(this.getClass().getSimpleName() + ".startOfData");
+        }
+        
+        public void process(EventHeader event) {
+            System.out.println(this.getClass().getSimpleName() + " got LCIO event #" + event.getEventNumber());
+            for (LCMetaData metaData : event.getMetaData()) {
+                String collectionName = metaData.getName();
+                Class type = metaData.getType();
+                System.out.println (collectionName + " " + event.get(type, collectionName).size());
+            }
+        }
+        
+        public void endOfData() {
+            System.out.println(this.getClass().getSimpleName() + ".endOfData");
+        }
+    }
+    
+    static class DummyEvioProcessor extends EvioEventProcessor {
+        
+        public void startRun(EvioEvent event) {
+            System.out.println(this.getClass().getSimpleName() + ".startRun");
+        }
+        
+        public void endRun(EvioEvent event) {
+            System.out.println(this.getClass().getSimpleName() + ".endRun");
+        }
+        
+        public void startJob() {
+            System.out.println(this.getClass().getSimpleName() + ".startJob");
+        }
+        
+        public void endJob() {
+            System.out.println(this.getClass().getSimpleName() + ".endJob");
+        }
+        
+        public void processEvent(EvioEvent event) {
+            System.out.println(this.getClass().getSimpleName() + " got EVIO event #" + event.getEventNumber());
+        }
+    }
+}

java/trunk/monitoring-app/src/test/java/org/hps/monitoring/subsys/et
EtSystemMonitorTest.java 697 -> 698
--- java/trunk/monitoring-app/src/test/java/org/hps/monitoring/subsys/et/EtSystemMonitorTest.java	2014-06-10 15:01:54 UTC (rev 697)
+++ java/trunk/monitoring-app/src/test/java/org/hps/monitoring/subsys/et/EtSystemMonitorTest.java	2014-06-10 23:01:18 UTC (rev 698)
@@ -17,6 +17,7 @@
  */
 public class EtSystemMonitorTest extends TestCase {
 
+    /*
     public void testEtEventMonitoring() {
         
         EtEventLoop loop = new EtEventLoop();
@@ -72,5 +73,5 @@
             info.getStatistics().printSession(System.out);
         }
     }
-    
+    */
 }
SVNspam 0.1