LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  March 2015

HPS-SVN March 2015

Subject:

r2459 - in /java/trunk/monitoring-app: ./ src/main/java/org/hps/monitoring/application/ src/main/java/org/hps/monitoring/application/model/ src/main/java/org/hps/monitoring/application/util/ src/main/resources/org/hps/monitoring/config/

From:

[log in to unmask]

Reply-To:

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

Date:

Sun, 15 Mar 2015 18:31:23 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1810 lines)

Author: [log in to unmask]
Date: Sun Mar 15 11:31:15 2015
New Revision: 2459

Log:
Merge changes from monitoring dev branch into trunk.

Added:
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventDashboard.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventDashboard.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/EtEventFilter.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EtEventFilter.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/PhysicsSyncEventStation.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/PhysicsSyncEventStation.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/PreStartEtStation.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/PreStartEtStation.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/RunnableEtStation.java
      - copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/RunnableEtStation.java
Removed:
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/RunPanel.java
Modified:
    java/trunk/monitoring-app/   (props changed)
    java/trunk/monitoring-app/pom.xml
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java
    java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop

Modified: java/trunk/monitoring-app/pom.xml
 =============================================================================
--- java/trunk/monitoring-app/pom.xml	(original)
+++ java/trunk/monitoring-app/pom.xml	Sun Mar 15 11:31:15 2015
@@ -111,6 +111,10 @@
         </dependency>
         <dependency>
             <groupId>org.hps</groupId>
+            <artifactId>hps-ecal-recon</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
             <artifactId>hps-monitoring-drivers</artifactId>
         </dependency>       
         <dependency>
@@ -134,6 +138,16 @@
             <groupId>org.freehep</groupId>
             <artifactId>freehep-jaida-remote</artifactId>
             <version>3.4.11</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jdom</groupId>
+                    <artifactId>jdom</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-math</groupId>
+                    <artifactId>commons-math</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
     </dependencies>
-</project>
+</project>

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java	Sun Mar 15 11:31:15 2015
@@ -34,9 +34,10 @@
     // Save a screenshot
     static final String SAVE_SCREENSHOT = "saveScreenshot";
     
-    // Save the plots
+    // Plotting actions
     static final String SAVE_PLOTS = "savePlots";
     static final String CLEAR_PLOTS = "resetPlots";
+    static final String SAVE_SELECTED_PLOTS = "saveSelectedPlots";
     
     // Exit the application.
     static final String EXIT = "exit";

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java	Sun Mar 15 11:31:15 2015
@@ -45,7 +45,6 @@
         setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
 
         setLayout(new GridBagLayout());
-        // setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
 
         GridBagConstraints c = new GridBagConstraints();
         c.weightx = c.weighty = 1.0;

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java	Sun Mar 15 11:31:15 2015
@@ -80,10 +80,19 @@
             resumeButton.setEnabled(false);
             connectButton.setActionCommand(Commands.CONNECT);
             connectButton.setIcon(disconnectedIcon);
-        } else {
+            connectButton.setEnabled(true);
+        } else if (status.equals(ConnectionStatus.DISCONNECTING)) {
+            nextButton.setEnabled(false);
+            pauseButton.setEnabled(false);
+            resumeButton.setEnabled(false);
+            connectButton.setEnabled(false);
+        } else if (status.equals(ConnectionStatus.CONNECTED)) {
+            nextButton.setEnabled(false);            
             pauseButton.setEnabled(true);
+            resumeButton.setEnabled(false);
             connectButton.setActionCommand(Commands.DISCONNECT);
             connectButton.setIcon(connectedIcon);
+            connectButton.setEnabled(true);
         }
     }       
     

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java	Sun Mar 15 11:31:15 2015
@@ -4,6 +4,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Logger;
 
@@ -14,6 +15,9 @@
 import org.hps.monitoring.application.model.ConnectionStatus;
 import org.hps.monitoring.application.model.SteeringType;
 import org.hps.monitoring.application.util.EtSystemUtil;
+import org.hps.monitoring.application.util.PhysicsSyncEventStation;
+import org.hps.monitoring.application.util.PreStartEtStation;
+import org.hps.monitoring.application.util.RunnableEtStation;
 import org.hps.monitoring.subsys.et.EtSystemMonitor;
 import org.hps.monitoring.subsys.et.EtSystemStripCharts;
 import org.hps.record.LCSimEventBuilder;
@@ -24,26 +28,30 @@
 import org.hps.record.enums.DataSourceType;
 import org.hps.record.et.EtConnection;
 import org.hps.record.evio.EvioDetectorConditionsProcessor;
+import org.jlab.coda.et.EtSystem;
 import org.jlab.coda.et.exception.EtClosedException;
 import org.jlab.coda.et.exception.EtException;
+import org.lcsim.conditions.ConditionsListener;
 import org.lcsim.conditions.ConditionsManager;
 import org.lcsim.conditions.ConditionsReader;
 import org.lcsim.util.Driver;
 
 /**
- * This class encapsulates all of the logic involved with processing events 
- * and managing the related state and objects within the monitoring application.
+ * This class encapsulates all of the logic involved with processing events and managing the related
+ * state and objects within the monitoring application.
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
 class EventProcessing {
-    
+
     MonitoringApplication application;
     Logger logger;
     SessionState sessionState;
     List<CompositeRecordProcessor> processors;
     List<Driver> drivers;
-    
+    List<ConditionsListener> conditionsListeners;
+    int stationPosition;
+
     /**
      * This class is used to organize the objects for an event processing session.
      */
@@ -53,33 +61,54 @@
         CompositeLoop loop;
         EventProcessingThread processingThread;
         Thread sessionWatchdogThread;
+        ThreadGroup stationThreadGroup = new ThreadGroup("Station Threads");
+        List<RunnableEtStation> stations = new ArrayList<RunnableEtStation>();
         EtConnection connection;
     }
-    
-    /**
-     * Initialize with reference to the current monitoring application
-     * and a list of extra processors to add to the loop after 
-     * configuration.
+
+    /**
+     * Initialize with reference to the current monitoring application and a list of extra
+     * processors to add to the loop after configuration.
      * @param application The current monitoring application.
      * @param processors A list of processors to add after configuration is performed.
      */
     EventProcessing(
             MonitoringApplication application, 
-            List<CompositeRecordProcessor> processors,
-            List<Driver> drivers) {
+            List<CompositeRecordProcessor> processors, 
+            List<Driver> drivers, 
+            List<ConditionsListener> conditionsListeners) {
         this.application = application;
-        this.sessionState = new SessionState();        
+        this.sessionState = new SessionState();
         this.logger = MonitoringApplication.logger;
         this.processors = processors;
         this.drivers = drivers;
+        this.conditionsListeners = conditionsListeners;
+        this.stationPosition = application.configurationModel.getStationPosition();
     }
     
+    int getNextStationPosition() {
+        this.stationPosition += 1;
+        return this.stationPosition;        
+    }
+
     /**
      * Setup this class from the global configuration.
      * @param configurationModel The global configuration.
      */
     void setup(ConfigurationModel configurationModel) {
-        MonitoringApplication.logger.info("setting up LCSim");
+        
+        // Setup LCSim from the configuration.
+        setupLcsim(configurationModel);
+
+        // Now setup the CompositeLoop.
+        setupLoop(configurationModel);
+    }
+
+    /**
+     * @param configurationModel
+     */
+    private void setupLcsim(ConfigurationModel configurationModel) {
+        MonitoringApplication.logger.info("setting up lcsim");
 
         // Get steering resource or file as a String parameter.
         String steering = null;
@@ -90,22 +119,31 @@
             steering = configurationModel.getSteeringResource();
         }
 
-        MonitoringApplication.logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
+        MonitoringApplication.logger.config("set steering " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
 
         try {
-            // Create and the job manager.  The conditions manager is instantiated from this call but not configured.
+            // Create and the job manager. The conditions manager is instantiated from this call but
+            // not configured.
             sessionState.jobManager = new JobManager();
-            
+
+            // Add conditions listeners after new database conditions manager is initialized from
+            // job manager.
+            DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+            for (ConditionsListener conditionsListener : conditionsListeners) {
+                logger.config("adding conditions listener " + conditionsListener.getClass().getName());
+                conditionsManager.addConditionsListener(conditionsListener);
+            }
+
             if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
-                // Set a detector alias.                
+                // Set a detector alias.
                 ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias());
                 logger.config("using detector alias " + configurationModel.getDetectorAlias());
             }
-                        
+
             // Setup the event builder to translate from EVIO to LCIO.
             // This must happen before Driver setup so the builder's listeners are activated first!
             createEventBuilder(configurationModel);
-            
+
             // Configure the job manager for the XML steering.
             sessionState.jobManager.setPerformDryRun(true);
             if (steeringType == SteeringType.RESOURCE) {
@@ -113,24 +151,23 @@
             } else if (steeringType.equals(SteeringType.FILE)) {
                 setupSteeringFile(steering);
             }
-            
+
             // Set conditions tag.
             if (configurationModel.hasValidProperty(ConfigurationModel.CONDITIONS_TAG_PROPERTY) && !configurationModel.getConditionsTag().equals("")) {
-                logger.config("conditions tag is set to " + configurationModel.getConditionsTag());                
+                logger.config("conditions tag is set to " + configurationModel.getConditionsTag());
             } else {
                 logger.config("conditions NOT using a tag");
             }
-           
+
             // Is there a user specified run number from the JobPanel?
             if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
                 int userRunNumber = configurationModel.getUserRunNumber();
                 String detectorName = configurationModel.getDetectorName();
-                DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
                 logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
                 conditionsManager.setDetector(configurationModel.getDetectorName(), userRunNumber);
                 if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
-                    // Freeze the conditions system to ignore run numbers from the events.  
-                    logger.config("user configured to freeze conditions system from monitoring app");
+                    // Freeze the conditions system to ignore run numbers from the events.
+                    logger.config("user configured to freeze conditions system");
                     conditionsManager.freeze();
                 } else {
                     // Allow run numbers to be picked up from the events.
@@ -142,18 +179,15 @@
             logger.info("lcsim setup was successful");
 
         } catch (Throwable t) {
-            // Catch all errors and rethrow them as RuntimeExceptions.
+            // Catch all errors and re-throw them as RuntimeExceptions.
             application.errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException();
         }
-        
-        // Now setup the CompositeLoop.
-        setupLoop(configurationModel);
-    }
-    
+    }
+
     /**
      * Create the event builder for converting EVIO events to LCSim.
      */
-    void createEventBuilder(ConfigurationModel configurationModel) {
+    private void createEventBuilder(ConfigurationModel configurationModel) {
 
         // Get the class for the event builder.
         String eventBuilderClassName = configurationModel.getEventBuilderClassName();
@@ -168,12 +202,12 @@
         // Add the builder as a listener so it is notified when conditions change.
         ConditionsManager.defaultInstance().addConditionsListener(sessionState.eventBuilder);
     }
-    
+
     /**
      * Setup the loop from the global configuration.
      * @param configurationModel The global configuration.
      */
-    void setupLoop(ConfigurationModel configurationModel) {
+    private void setupLoop(ConfigurationModel configurationModel) {
 
         CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
             .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
@@ -187,13 +221,12 @@
         if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
             long maxEvents = configurationModel.getMaxEvents();
             if (maxEvents > 0L) {
-                //logger.config("processing will stop after max events: " + maxEvents);
                 loopConfig.setMaxRecords(maxEvents);
             }
         }
-        
+
         // Add all Drivers from the JobManager.
-        for (Driver driver : sessionState.jobManager.getDriverExecList()) {            
+        for (Driver driver : sessionState.jobManager.getDriverExecList()) {
             loopConfig.add(driver);
             logger.config("added Driver " + driver.getName() + " to job");
         }
@@ -211,30 +244,30 @@
         }
 
         // Add extra CompositeRecordProcessors to the loop config.
-        for (CompositeRecordProcessor processor : processors) {            
-            loopConfig.add(processor);   
+        for (CompositeRecordProcessor processor : processors) {
+            loopConfig.add(processor);
             logger.config("added extra processor " + processor.getClass().getSimpleName() + " to job");
         }
-        
+
         // Add extra Drivers to the loop config.
-        for (Driver driver : drivers) {            
+        for (Driver driver : drivers) {
             loopConfig.add(driver);
             logger.config("added extra Driver " + driver.getName() + " to job");
         }
-                
-        // Enable conditions system activation from EVIO event information.
+
+        // Enable conditions system activation from EVIO event data in case the PRESTART is missed.
         logger.config("added EvioDetectorConditionsProcessor to job with detector " + configurationModel.getDetectorName());
         loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
 
         // Create the CompositeLoop with the configuration.
-        sessionState.loop = new CompositeLoop(loopConfig);        
-    }    
-    
+        sessionState.loop = new CompositeLoop(loopConfig);
+    }
+
     /**
      * Setup a steering file on disk.
      * @param steering The steering file.
      */
-    void setupSteeringFile(String steering) {
+    private void setupSteeringFile(String steering) {
         sessionState.jobManager.setup(new File(steering));
     }
 
@@ -243,83 +276,121 @@
      * @param steering The steering resource.
      * @throws IOException if there is a problem setting up or accessing the resource.
      */
-    void setupSteeringResource(String steering) throws IOException {
+    private void setupSteeringResource(String steering) throws IOException {
         InputStream is = this.getClass().getClassLoader().getResourceAsStream(steering);
         if (is == null)
             throw new IOException("Steering resource is not accessible or does not exist.");
         sessionState.jobManager.setup(is);
         is.close();
     }
+
+    synchronized void stop() {
+
+        // Kill session watchdog thread.
+        killWatchdogThread();
+
+        // Wake up all ET stations to unblock the system and make sure secondary stations are detached.
+        wakeUpEtStations();
         
-    synchronized void stop() {
-        
-        // Kill session watchdog thread.
-        logger.fine("killing watchdog thread ...");
-        killWatchdogThread();
-        logger.fine("watchdog thread killed");
-        
-        // Wake up ET system in case it is blocked in a getEvents() call.
-        if (sessionState.connection != null) {
-            try {
-                logger.fine("waking up ET stations ...");
-                sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation());
-                logger.fine("ET stations woken up");
-            } catch (IOException | EtException | EtClosedException e) {
-                e.printStackTrace();
-            }
-        }
-        
-        // Stop event processing.
-        logger.fine("commanding event processing to stop ...");
+        // Stop the event processing now that ET system is unblocked.
+        logger.fine("sending STOP command to loop ...");
         sessionState.loop.execute(Command.STOP);
-        logger.fine("event processing commanded to stop");
-        
-        // Cleanup the event processing thread.
+        logger.fine("loop got command STOP");
+
+        // Cleanup the event processing thread since it was told to stop now.
         try {
-            logger.fine("joining on event processing thread ...");
+            logger.fine("waiting for event processing thread to end ...");
             sessionState.processingThread.join();
-            logger.fine("event processing thread joined");
-            
-            // Invalidate event processing thread.
-            sessionState.processingThread = null;
+            logger.fine("event processing thread ended");   
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
-        
+
         // Notify of last error that occurred in event processing.
         if (sessionState.loop.getLastError() != null) {
             // Log the error.
             application.errorHandler.setError(sessionState.loop.getLastError()).log();
         }
+
+        // Invalidate the loop.
+        sessionState.loop = null;
+
+        // Disconnect from the ET system.
+        disconnect();
         
-        // Invalidate loop.
-        sessionState.loop = null;
-               
-        // Disconnect from the ET system.
-        logger.fine("disconnecting from ET system ...");
-        disconnect();
-        logger.fine("ET system disconnected");
-    }
-    
-    /**
-     * Start event processing on the event processing thread
-     * and start the watchdog thread.
+        // Invalidate the event processing object so it is unusable now.
+        invalidate();
+    }
+
+    /**
+     * Wake up all ET stations associated with event processing.
+     */
+    private void wakeUpEtStations() {
+        if (sessionState.connection != null) {
+            logger.fine("waking up ET stations ...");
+
+            // Wake up secondary ET stations.
+            for (RunnableEtStation station : sessionState.stations) {
+                if (station.getEtStation().isUsable()) {
+                    // Wake up the station which will automatically trigger a detach.
+                    try {
+                        logger.finest("waking up " + station.getEtStation().getName() + " ...");
+                        sessionState.connection.getEtSystem().wakeUpAll(station.getEtStation());
+                        logger.finest(station.getEtStation().getName() + " woken up");
+                    } catch (IOException | EtException | EtClosedException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+
+            // Wait for station threads to die after being woken up.
+            while (sessionState.stationThreadGroup.activeCount() != 0) {
+                logger.finest("waiting for station threads to die ...");
+                Object lock = new Object();
+                synchronized (lock) {
+                    try {
+                        lock.wait(500);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+
+            logger.finest("destroying station thread group");
+            sessionState.stationThreadGroup.destroy();
+            logger.finest("station thread group destroyed");
+
+            // Wake up the primary ET station doing the event processing.
+            logger.finest("waking up event processing station ...");
+            try {
+                sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation());
+                logger.finest("event processing station woken up");
+            } catch (IOException | EtException | EtClosedException e) {
+                e.printStackTrace();
+            }
+
+            logger.finest("ET stations woken up");
+        }
+    }
+
+    /**
+     * Start event processing on the event processing thread and start the watchdog thread.
      */
     synchronized void start() {
-        
+
         logger.fine("event processing threads are starting");
-        
+
         // Start the event processing thread.
         sessionState.processingThread = new EventProcessingThread(sessionState.loop);
         sessionState.processingThread.start();
-        
+
         // Start the watchdog thread which will auto-disconnect when event processing is done.
         sessionState.sessionWatchdogThread = new SessionWatchdogThread(sessionState.processingThread);
         sessionState.sessionWatchdogThread.start();
-        
+
         logger.fine("started event processing threads");
     }
-    
+
     /**
      * Notify the event processor to pause processing.
      */
@@ -331,7 +402,7 @@
         }
         logger.finest("paused");
     }
-    
+
     /**
      * Get next event if in pause mode.
      */
@@ -344,7 +415,7 @@
         }
         logger.finest("got next event");
     }
-    
+
     /**
      * Resume processing events from pause mode.
      */
@@ -352,19 +423,19 @@
         logger.finest("resuming");
         if (application.connectionModel.getPaused()) {
             // Notify event processor to continue.
-            sessionState.loop.resume();        
+            sessionState.loop.resume();
             application.connectionModel.setPaused(false);
         }
         logger.finest("resumed");
     }
-    
+
     /**
      * Interrupt and join to the processing watchdog thread.
      */
     synchronized void killWatchdogThread() {
-        logger.fine("killing watchdog thread");
         // Is the session watchdog thread not null?
         if (sessionState.sessionWatchdogThread != null) {
+            logger.finest("killing watchdog thread ...");
             // Is the thread still alive?
             if (sessionState.sessionWatchdogThread.isAlive()) {
                 // Interrupt the thread which should cause it to stop.
@@ -379,10 +450,10 @@
             }
             // Set the thread object to null.
             sessionState.sessionWatchdogThread = null;
-        }
-        logger.fine("watchdog thread killed");
-    }
-    
+            logger.finest("watchdog thread killed");
+        }
+    }
+
     /**
      * Cleanup the ET connection.
      */
@@ -390,15 +461,15 @@
         if (sessionState.connection != null) {
             logger.fine("closing ET connection");
             if (sessionState.connection.getEtSystem().alive()) {
-                logger.fine("cleaning up the connection ...");
+                logger.finest("cleaning up the connection ...");
                 sessionState.connection.cleanup();
-                logger.fine("connection cleanup successful");
+                logger.finest("connection cleanup successful");
             }
             sessionState.connection = null;
             logger.fine("ET connection closed");
         }
     }
-    
+
     /**
      * True if the processing thread is active.
      * @return True if processing thread is active.
@@ -406,71 +477,109 @@
     boolean isActive() {
         return sessionState.processingThread != null && sessionState.processingThread.isAlive();
     }
-    
+
     /**
      * Connect to the ET system using the current connection settings.
      */
-    synchronized void connect() throws IOException {
-        logger.fine("connecting to ET system");
+    synchronized void connect() throws IOException {        
         // Setup the network connection if using an ET server.
         if (usingEtServer()) {
             // Create a connection to the ET server.
             try {
+                logger.fine("connecting to ET system ...");
+                
+                // Create the main ET system connection.
                 createEtConnection();
+
+                // Add an attachment that listens for DAQ configuration changes via physics SYNC events.
+                createPhysicsSyncStation();
+                
+                // Add an attachment that listens for PRESTART events.
+                createPreStartStation();
+                
             } catch (Exception e) {
                 throw new IOException(e);
             }
+            
+            logger.fine("ET system is connected");
         } else {
             // This is when a direct file source is used and ET is not needed.
             application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
         }
-        logger.fine("ET system is connected");
-    }
-    
+        
+    }
+
     /**
      * True if using an ET server.
      * @return True if using an ET server.
      */
     boolean usingEtServer() {
         return application.configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER);
-    }    
-    
-    /**
-     * Create a connection to an ET system using current parameters from the GUI. If successful, the
-     * application's ConnectionStatus is changed to CONNECTED.
-     */
-    void createEtConnection() {
+    }
+
+    /**
+     * Create a connection to an ET system using current parameters from the GUI. 
+     */
+    synchronized void createEtConnection() {
         // Setup connection to ET system.
         sessionState.connection = EtSystemUtil.createEtConnection(application.configurationModel);
 
         if (sessionState.connection != null) {
             // Set status to connected as there is now a live ET connection.
             application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
-            //logger.info("successfully connected to ET system");
         } else {
             application.errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException();
         }
     }
+
+    /**
+     * Create the ET that listens for DAQ configuration change via SYNC events.
+     */
+    private void createPhysicsSyncStation() {
+        logger.fine("creating physics SYNC station ...");       
+        PhysicsSyncEventStation configStation = new PhysicsSyncEventStation(
+                this.sessionState.connection.getEtSystem(),
+                this.sessionState.connection.getEtStation().getName() + "_PhysicsSync",
+                getNextStationPosition());
+        sessionState.stations.add(configStation);
+        new Thread(sessionState.stationThreadGroup, configStation).start();
+        logger.fine("physics SYNC station created");
+    }
     
     /**
-     * Disconnect from the current ET session with a particular status.
+     * Create the ET station that listens for GO events in order to initialize the conditions system.
+     */
+    private void createPreStartStation() {
+        logger.fine("creating PRESTART station ...");
+        String detectorName = this.application.configurationModel.getDetectorName();
+        EtSystem system = this.sessionState.connection.getEtSystem();
+        String stationName = this.sessionState.connection.getEtStation().getName() + "_PreStart";
+        int order = getNextStationPosition();
+        PreStartEtStation preStartStation = new PreStartEtStation(
+                detectorName, 
+                system, 
+                stationName, 
+                order);
+        sessionState.stations.add(preStartStation);
+        new Thread(sessionState.stationThreadGroup, preStartStation).start();
+        logger.fine("PRESTART station created");
+    }
+
+    /**
+     * Disconnect from the current ET session.
      * @param status The connection status.
      */
     synchronized void disconnect() {
-        
-        logger.fine("disconnecting");
                 
         // Cleanup the ET connection.
         closeEtConnection();
-                              
+
         // Change application state to disconnected.
         application.connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED);
-        
-        logger.fine("disconnected");
-    }    
-               
-    /**
-     * This class notifies the application to disconnect if the event processing thread completes.     
+    }
+
+    /**
+     * This class notifies the application to disconnect if the event processing thread completes.
      */
     class SessionWatchdogThread extends Thread {
 
@@ -479,21 +588,39 @@
         SessionWatchdogThread(Thread processingThread) {
             this.processingThread = processingThread;
         }
-        
+
         public void run() {
             try {
-                // When the event processing thread finishes, the session should be stopped and a
-                // disconnect should occur.
+                // This thread waits on the event processing thread to die.
                 processingThread.join();
-                                
+
                 // Activate a disconnect using the ActionEvent which is used by the disconnect button.
-                logger.fine("processing thread ended so automatic disconnect is happening");
+                logger.finest("processing thread ended so automatic disconnect is happening");
                 application.actionPerformed(new ActionEvent(Thread.currentThread(), 0, Commands.DISCONNECT));
-                               
+
             } catch (InterruptedException e) {
-                logger.fine("SessionWatchdogThread got interrupted");
+                logger.finest("SessionWatchdogThread got interrupted");
                 // This happens when the thread is interrupted by the user pressing the disconnect button.
-            }            
-        }
+            }
+        }
+    }
+    
+    void invalidate() {
+
+        this.application = null;
+        this.conditionsListeners = null;
+        this.drivers = null;
+        this.logger = null;
+        this.processors = null;        
+
+        this.sessionState.jobManager = null;
+        this.sessionState.eventBuilder = null;
+        this.sessionState.loop = null;
+        this.sessionState.processingThread = null;
+        this.sessionState.sessionWatchdogThread = null;
+        this.sessionState.stationThreadGroup = null;
+        this.sessionState.stations = null;
+        this.sessionState.connection = null;
+        this.sessionState = null;
     }
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java	Sun Mar 15 11:31:15 2015
@@ -13,7 +13,7 @@
 import org.hps.monitoring.application.model.ConfigurationModel;
 
 /**
- * 
+ * This is a combo box used to filter the log table messages by level.
  * @author Jeremy McCormick <[log in to unmask]>
  */
 class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener {

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	Sun Mar 15 11:31:15 2015
@@ -5,12 +5,10 @@
 import hep.aida.jfree.plotter.PlotterRegionListener;
 import hep.aida.ref.remote.rmi.client.RmiStoreFactory;
 
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
 import java.awt.image.BufferedImage;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
@@ -40,6 +38,7 @@
 import org.hps.monitoring.application.LogTable.LogRecordModel;
 import org.hps.monitoring.application.model.Configuration;
 import org.hps.monitoring.application.model.ConfigurationModel;
+import org.hps.monitoring.application.model.ConnectionStatus;
 import org.hps.monitoring.application.model.ConnectionStatusModel;
 import org.hps.monitoring.application.model.RunModel;
 import org.hps.monitoring.application.util.AIDAServer;
@@ -49,12 +48,11 @@
 import org.hps.monitoring.application.util.TableExporter;
 import org.hps.monitoring.plotting.MonitoringAnalysisFactory;
 import org.hps.monitoring.plotting.MonitoringPlotFactory;
-import org.hps.monitoring.subsys.StatusCode;
 import org.hps.monitoring.subsys.SystemStatus;
-import org.hps.monitoring.subsys.SystemStatusListener;
 import org.hps.monitoring.subsys.SystemStatusRegistry;
 import org.hps.record.composite.CompositeRecordProcessor;
 import org.hps.record.enums.DataSourceType;
+import org.lcsim.conditions.ConditionsListener;
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 import org.lcsim.util.log.DefaultLogFormatter;
@@ -62,12 +60,11 @@
 /**
  * This is the primary class that implements the monitoring GUI application.
  * It should not be used directly.  Instead the {@link Main} class should be
- * used from the command line or via the supplied script built automatically 
- * by Maven.
+ * used from the command line.
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
-final class MonitoringApplication implements ActionListener, PropertyChangeListener, SystemStatusListener {
+final class MonitoringApplication implements ActionListener, PropertyChangeListener {
 
     // Statically initialize logging, which will be fully setup later.
     static final Logger logger;
@@ -78,14 +75,15 @@
 
     // Default log stream.
     MonitoringApplicationStreamHandler streamHandler;
+    LogHandler logHandler;
     PrintStream sysOut = System.out;
     PrintStream sysErr = System.err;
     
     // Application error handling.
-    final ErrorHandler errorHandler;
+    ErrorHandler errorHandler;
    
     // The main GUI components inside a JFrame.
-    final MonitoringApplicationFrame frame;    
+    MonitoringApplicationFrame frame;    
     
     // The primary data models.
     final RunModel runModel = new RunModel();
@@ -150,41 +148,86 @@
             super.setOutputStream(out);
         }        
     }
-             
+                 
     /**
      * Instantiate and show the monitoring application with the given configuration.
      * @param configuration The Configuration object containing application settings.
      */
     MonitoringApplication(Configuration configuration) {
-                
-        // Setup the main GUI component.
-        frame = new MonitoringApplicationFrame(this);
-        
-        // Setup the error handler.
-        errorHandler = new ErrorHandler(frame, logger);
+        
+        try {
+        
+            // Setup the main GUI component.
+            frame = new MonitoringApplicationFrame(this);
+            
+            // Add window listener to perform clean shutdown.
+            frame.addWindowListener(new WindowListener() {
+
+                @Override
+                public void windowOpened(WindowEvent e) {
+                }
+
+                @Override
+                public void windowClosing(WindowEvent e) {
+                }
+
+                @Override
+                public void windowClosed(WindowEvent e) {
+                    exit();
+                }
+
+                @Override
+                public void windowIconified(WindowEvent e) {
+                }
+
+                @Override
+                public void windowDeiconified(WindowEvent e) {
+                }
+
+                @Override
+                public void windowActivated(WindowEvent e) {
+                }
+
+                @Override
+                public void windowDeactivated(WindowEvent e) {
+                }
+            });
+        
+            // Setup the error handler.
+            errorHandler = new ErrorHandler(frame, logger);
                        
-        // Add this class as a listener on the configuration model.
-        configurationModel.addPropertyChangeListener(this);
-        
-        // Setup the logger.
-        setupLogger();
+            // Add this class as a listener on the configuration model.
+            configurationModel.addPropertyChangeListener(this);
+        
+            // Setup the logger.
+            setupLogger();
                
-        // Setup AIDA plotting and connect it to the GUI.
-        setupAida();
-        
-        // Set the configuration.
-        if (configuration != null) {
-            // There was a user specified configuration.
-            this.configuration = configuration;
-        } else {
-            // Use the default configuration.
-            this.configuration = new Configuration(DEFAULT_CONFIGURATION);
-        }
+            // Setup AIDA plotting and connect it to the GUI.
+            setupAida();
+        
+            // Set the configuration.
+            if (configuration != null) {
+                // There was a user specified configuration.
+                this.configuration = configuration;
+            } else {
+                // Use the default configuration.
+                this.configuration = new Configuration(DEFAULT_CONFIGURATION);
+            }
                                       
-        // Load the configuration.
-        loadConfiguration(this.configuration);
-                
-        logger.info("application initialized successfully");
+            // Load the configuration.
+            loadConfiguration(this.configuration);
+        
+            frame.setEnabled(true);
+        
+            logger.info("application initialized successfully");
+        
+        } catch (Exception e) {
+            // Don't use the ErrorHandler here because we don't know that it initialized successfully.
+            System.err.println("MonitoringApplication failed to initialize without errors!");
+            DialogUtil.showErrorDialog(null, "Error Starting Monitoring Application", "Monitoring application failed to initialize.");
+            e.printStackTrace();
+            System.exit(1);
+        }        
     }
     
     /**
@@ -192,7 +235,8 @@
      */
     void setupLogger() {
         logger.setUseParentHandlers(false);        
-        logger.addHandler(new LogHandler());
+        logHandler = new LogHandler();
+        logger.addHandler(logHandler);
         streamHandler = new MonitoringApplicationStreamHandler(System.out);
         logger.addHandler(streamHandler);
         for (Handler handler : logger.getHandlers()) {
@@ -201,7 +245,7 @@
         logger.setLevel(DEFAULT_LEVEL);
         logger.info("logging initialized");
     }
-    
+        
     /**
      * Static utility method for creating new instance.
      * @param configuration The application settings.
@@ -217,7 +261,9 @@
      */
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
-        // TODO: Handle log level configuration change here.
+        if (evt.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) {
+            setLogLevel();
+        }
     }
     
     /**
@@ -232,11 +278,12 @@
         if (Commands.CONNECT.equals(command)) {
             startSession();
         } else if (Commands.DISCONNECT.equals(command)) {
-            processing.stop();
+            runDisconnectThread();
         } else if (Commands.SAVE_PLOTS.equals(command)) {
             savePlots();
         } else if (Commands.EXIT.equals(command)) {
-            exit();
+            // This will trigger the window closing action that cleans everything up.
+            frame.dispose();
         } else if (Commands.PAUSE.equals(command)) { 
             processing.pause();
         } else if (Commands.NEXT.equals(command)) {
@@ -265,8 +312,6 @@
             closeFile();
         } else if (Commands.SAVE_SCREENSHOT.equals(command)) {
             saveScreenshot();
-        } else if (Commands.LOG_LEVEL_CHANGED.equals(command)) {
-            setLogLevel();
         } else if (Commands.SAVE_LOG_TABLE.equals(command)) {
             saveLogTable();
         } else if (Commands.CLEAR_LOG_TABLE.equals(command)) {
@@ -327,11 +372,14 @@
      * Reset the plots and clear the tabs in the plot window.
      */
     void resetPlots() {
-
+        
+        // Clear global list of registered plotters.
+        MonitoringPlotFactory.getPlotterRegistry().clear();  
+        
         // Clear the static AIDA tree in case plots are hanging around from previous sessions.
         AIDA.defaultInstance().clearAll();
 
-        // Reset plot panel which removes all tabs.
+        // Reset plot panel which removes all its tabs.
         frame.plotPanel.reset();
         
         logger.info("plots were cleared");
@@ -341,43 +389,20 @@
      * Configure the system status monitor panel for a new job.
      */
     void setupSystemStatusMonitor() {
+        
         // Clear the system status monitor table.
-        frame.systemStatusTable.getTableModel().clear();
+        frame.systemStatusPanel.clear();
 
         // Get the global registry of SystemStatus objects.
         SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery();
 
         // Process the SystemStatus objects.
         for (SystemStatus systemStatus : registry.getSystemStatuses()) {
-            // Add a row to the table for every SystemStatus.
-            frame.systemStatusTable.getTableModel().addSystemStatus(systemStatus);
-
-            // Add this class as a listener so all status changes can be logged.
-            systemStatus.addListener(this);
+            // This will add the status to the two tables.
+            frame.systemStatusPanel.addSystemStatus(systemStatus);
         }
         
         logger.info("system status monitor initialized successfully");
-    }
-    
-    /**
-     * Hook for logging all status changes from the system status monitor.
-     */
-    @Override
-    public void statusChanged(SystemStatus status) {
-
-        // Choose the appropriate log level.
-        Level level = Level.FINE;
-        if (status.getStatusCode().equals(Level.WARNING)) {
-            level = Level.WARNING;
-        } else if (status.getStatusCode().ordinal() >= StatusCode.ERROR.ordinal()) {
-            level = Level.SEVERE;
-        }
-        
-        // Log all status changes.
-        logger.log(level, "STATUS, " + "subsys: " + status.getSubsystem() + ", " 
-                + "code: " + status.getStatusCode().name() 
-                + ", " + "descr: " + status.getDescription() 
-                + ", " + "mesg: " + status.getMessage());
     }
     
     /**
@@ -399,13 +424,18 @@
 
             // List of extra composite record processors including the updater for the RunPanel.
             List<CompositeRecordProcessor> processors = new ArrayList<CompositeRecordProcessor>();
-            processors.add(frame.runPanel.new RunPanelUpdater());
-            
+            processors.add(frame.dashboardPanel.new EventDashboardUpdater());
+            
+            // Add Driver to update the trigger diagnostics tables.
             List<Driver> drivers = new ArrayList<Driver>();
             drivers.add(frame.triggerPanel.new TriggerDiagnosticGUIDriver());
-            
-            // Initialize event processing with the list of processors and reference to the application.
-            processing = new EventProcessing(this, processors, drivers);
+
+            // Add listener to push conditions changes to conditions panel.
+            List<ConditionsListener> conditionsListeners = new ArrayList<ConditionsListener>();
+            conditionsListeners.add(frame.conditionsPanel.new ConditionsPanelListener());
+            
+            // Instantiate the event processing wrapper.
+            processing = new EventProcessing(this, processors, drivers, conditionsListeners);
             
             // Connect to the ET system, if applicable.
             processing.connect();
@@ -418,7 +448,7 @@
             // Setup the system status monitor table.
             setupSystemStatusMonitor();
                                             
-            // Start the event processing thread.
+            // Start the event processing thread.            
             processing.start();            
             
             logger.info("new session successfully initialized");
@@ -437,17 +467,17 @@
     }
            
     /**
-     * Exit from the application.
+     * Exit from the application from exit menu item or hitting close window button.
      */
     void exit() {        
-        if (processing != null && processing.isActive()) {
+        if (connectionModel.isConnected()) {
             processing.stop();
         }
-        frame.setVisible(false);
+        logHandler.setLevel(Level.OFF);
         logger.info("exiting the application");
-        logger.getHandlers()[0].flush();
+        streamHandler.flush();
         System.exit(0);
-    }              
+    }
             
     /**
      * Save AIDA plots to a file using a file chooser.
@@ -601,6 +631,7 @@
     /**
      * Save a screenshot to a file using a file chooser.
      */
+    // FIXME: This might need to be on a new thread to allow the GUI to redraw w/o chooser visible.
     void saveScreenshot() {
         JFileChooser fc = new JFileChooser();
         fc.setAcceptAllFileFilterUsed(false);
@@ -615,8 +646,17 @@
             if (!fileName.endsWith("." + format)) {
                 fileName += "." + format;
             }
+            frame.repaint();
+            Object lock = new Object();
+            synchronized (lock) {
+                try {
+                    lock.wait(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
             writeScreenshot(fileName, format);
-            DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file.");
+            DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file" + '\n' + fileName);
             logger.info("saved screenshot to " + fileName);
         }
     }
@@ -626,15 +666,13 @@
      * @param fileName The name of the output file.
      */
     void writeScreenshot(String fileName, String format) {
-        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-        Rectangle screenRectangle = new Rectangle(screenSize);
+        BufferedImage image = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_RGB);
+        frame.paint(image.getGraphics()); 
         try {
-            Robot robot = new Robot();
-            BufferedImage image = robot.createScreenCapture(screenRectangle);
             ImageIO.write(image, format, new File(fileName));
-        } catch (Exception e) {
-            errorHandler.setError(e).setMessage("Failed to take screenshot.").printStackTrace().log().showErrorDialog();
-        }
+        } catch (IOException e) {
+            errorHandler.setError(e).setMessage("Failed to save screenshot.").printStackTrace().log().showErrorDialog();
+        }        
     }            
     
     /**
@@ -785,5 +823,19 @@
         frame.menu.stopAIDAServer();
         logger.info("AIDA server was stopped");
         DialogUtil.showInfoDialog(frame, "AIDA Server Stopped", "The AIDA server was stopped.");
-    }       
+    }    
+    
+    /**
+     * 
+     */
+    void runDisconnectThread() {
+        new Thread() {
+            public void run() {
+                logger.fine("disconnect thread is running ...");
+                connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTING);
+                MonitoringApplication.this.processing.stop();
+                logger.fine("disconnect thread finished!");
+            }
+        }.run();
+    }
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java	Sun Mar 15 11:31:15 2015
@@ -3,14 +3,11 @@
 import java.awt.BorderLayout;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
-import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
 import java.awt.Rectangle;
 
-import javax.swing.BoxLayout;
-import javax.swing.JComponent;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
-import javax.swing.JScrollPane;
 import javax.swing.JSeparator;
 import javax.swing.JSplitPane;
 import javax.swing.JTabbedPane;
@@ -23,13 +20,14 @@
  */
 class MonitoringApplicationFrame extends JFrame {
             
-    RunPanel runPanel;    
+    EventDashboard dashboardPanel;    
     PlotPanel plotPanel;
     PlotInfoPanel plotInfoPanel;
     LogPanel logPanel;
-    SystemStatusTable systemStatusTable;
     JPanel buttonsPanel;
     TriggerDiagnosticsPanel triggerPanel;
+    ConditionsPanel conditionsPanel;
+    SystemStatusPanel systemStatusPanel;
     MenuBar menu; 
     
     JSplitPane mainSplitPane;
@@ -39,14 +37,10 @@
     DataSourceComboBox dataSourceComboBox;
     
     SettingsDialog settingsDialog;
-    
-    // Proportional layout parameters relative to the screen size.
-    static final double FULL_SIZE = 1.0;
-    static final double TOP_PANEL_HEIGHT = 0.05;
-    static final double BOTTOM_PANEL_HEIGHT = FULL_SIZE - TOP_PANEL_HEIGHT;
-    static final double LEFT_PANEL_WIDTH = 0.3;
-    static final double RIGHT_PANEL_WIDTH = FULL_SIZE - LEFT_PANEL_WIDTH;
-    static final double PLOT_PANEL_HEIGHT = 0.8;
+       
+    static final Rectangle BOUNDS = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
+    static final int PIXEL_WIDTH_MAX = (int) BOUNDS.getWidth();
+    static final int PIXEL_HEIGHT_MAX = (int) BOUNDS.getHeight();
     
     /**
      * 
@@ -54,20 +48,22 @@
      */
     public MonitoringApplicationFrame(
             MonitoringApplication application) {
+        
+        // Disable interaction until specifically enabled externally after initialization.
+        setEnabled(false);
                 
         // Create the content panel.
         JPanel contentPanel = new JPanel();
         setContentPane(contentPanel);
-        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
+        contentPanel.setLayout(new BorderLayout());
         contentPanel.setOpaque(true);
-        setProportionalSize(contentPanel, FULL_SIZE, FULL_SIZE);
-        
+        contentPanel.setPreferredSize(new Dimension(PIXEL_WIDTH_MAX, PIXEL_HEIGHT_MAX));
+                
         // Create the top panel.
         JPanel topPanel = new JPanel();
         topPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 0));
-        setProportionalSize(topPanel, FULL_SIZE, TOP_PANEL_HEIGHT);
-        contentPanel.add(topPanel);
-        
+        contentPanel.add(topPanel, BorderLayout.NORTH);
+                
         // Create the connection status panel.
         JPanel connectionPanel = new ConnectionStatusPanel(application.connectionModel);
         topPanel.add(connectionPanel);
@@ -83,7 +79,6 @@
         
         // Add vertical separator.
         sep = new JSeparator(SwingConstants.VERTICAL);
-        sep.setPreferredSize(new Dimension(5, topPanel.getPreferredSize().height));
         topPanel.add(sep);
         
         // Add the data source combo box.
@@ -93,16 +88,14 @@
         // Create the bottom panel.
         JPanel bottomPanel = new JPanel();
         bottomPanel.setLayout(new BorderLayout());
-        setProportionalSize(bottomPanel, FULL_SIZE, BOTTOM_PANEL_HEIGHT);
-        contentPanel.add(bottomPanel);
-                                
+        contentPanel.add(bottomPanel, BorderLayout.CENTER);
+                                        
         // Create the left panel.
         JPanel leftPanel = new JPanel();
         leftPanel.setLayout(new BorderLayout());
-        setProportionalSize(leftPanel, LEFT_PANEL_WIDTH, FULL_SIZE);
-                        
+                            
         // Create the run dashboard.
-        runPanel = new RunPanel(application.runModel);
+        dashboardPanel = new EventDashboard(application.runModel);
 
         // Create the tabbed pane for content in bottom of left panel such as log table and system monitor.
         JTabbedPane tableTabbedPane = new JTabbedPane();
@@ -112,76 +105,58 @@
         tableTabbedPane.addTab("Log Messages", logPanel);
         
         // Create the system monitor.
-        systemStatusTable = new SystemStatusTable();
-        tableTabbedPane.addTab("System Status Monitor", new JScrollPane(systemStatusTable));
+        //systemStatusTable = new SystemStatusTable();
+        systemStatusPanel = new SystemStatusPanel();
+        tableTabbedPane.addTab("System Status Monitor", systemStatusPanel);
         
         // Add the trigger diagnostics tables.
         triggerPanel = new TriggerDiagnosticsPanel();
         tableTabbedPane.addTab("Trigger Diagnostics", triggerPanel);
         
+        // Add the conditions panel.
+        conditionsPanel = new ConditionsPanel();
+        tableTabbedPane.addTab("Detector Conditions", conditionsPanel);
+        
         // Vertical split pane in left panel.
-        leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, runPanel, tableTabbedPane);
-        leftSplitPane.setResizeWeight(0.5);
+        leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, dashboardPanel, tableTabbedPane);
+        leftSplitPane.setDividerLocation(250);
         leftPanel.add(leftSplitPane, BorderLayout.CENTER);
                                 
         // Create the right panel.
         JPanel rightPanel = new JPanel();
         rightPanel.setLayout(new BorderLayout());
-        
+                
         // Create the plot info panel.
         plotInfoPanel = new PlotInfoPanel();
                 
         // Create the plot panel.
-        plotPanel = new PlotPanel();
-        plotPanel.setVisible(true); // DEBUG
-        setProportionalSize(plotPanel, RIGHT_PANEL_WIDTH, PLOT_PANEL_HEIGHT);
+        plotPanel = new PlotPanel();        
+        plotInfoPanel.saveButton.addActionListener(plotPanel);
         
         // Create the right panel vertical split pane for displaying plots and their information and statistics.
         rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, plotPanel, plotInfoPanel);
-        setProportionalSize(rightSplitPane, RIGHT_PANEL_WIDTH, FULL_SIZE);
-        rightSplitPane.setResizeWeight(0.8);
+        rightSplitPane.setResizeWeight(0.7);
         rightPanel.add(rightSplitPane, BorderLayout.CENTER);
                        
         // Create the main horizontal split pane for dividing the left and right panels.
         mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
-        mainSplitPane.setResizeWeight(0.15);
+        mainSplitPane.setResizeWeight(0.2);
         bottomPanel.add(mainSplitPane, BorderLayout.CENTER);
         
         // Create the menu bar.
         menu = new MenuBar(application.configurationModel, application.connectionModel, application);
         setJMenuBar(menu);
         dataSourceComboBox.addActionListener(menu);
-                        
+        
+        // Setup the settings dialog box (invisible until activated).
+        settingsDialog = new SettingsDialog(application.configurationModel, application);        
+               
         // Setup the frame now that all components have been added.        
         pack();
         setExtendedState(JFrame.MAXIMIZED_BOTH);
-        setVisible(true);
-        
-        // Setup the settings dialog box.
-        settingsDialog = new SettingsDialog(application.configurationModel, application);
+        setVisible(true); 
     }
-    
-    /**
-     * Set the size of a Swing component using proportions of the current screen bounds.
-     * @param component The component to resize.
-     * @param scaleX The X scaling (must be between 0 and 1).
-     * @param scaleY The Y scaling (must be between 0 and 1).
-     * @param setSize Call the setSize method as well as setPreferredSize (which is the default).
-     * @return
-     */
-    void setProportionalSize(JComponent component, double scaleX, double scaleY) {                    
-        GraphicsConfiguration graphics = this.getGraphicsConfiguration();        
-        Rectangle bounds = graphics.getBounds();        
-        if (scaleX < 0 || scaleX > 1) {
-            throw new IllegalArgumentException("scaleX must be > 0 and <= 1.");
-        }
-        if (scaleY < 0 || scaleY > 1) {
-            throw new IllegalArgumentException("scaleY must be > 0 and <= 1.");
-        }
-        Dimension scaledDimension = new Dimension((int)(bounds.getWidth() * scaleX), (int)(bounds.getHeight() * scaleY));
-        component.setPreferredSize(scaledDimension);
-    }           
-    
+             
     /**
      * Restore default window settings.
      */

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java	Sun Mar 15 11:31:15 2015
@@ -15,10 +15,10 @@
 import hep.aida.ref.function.FunctionDispatcher;
 import hep.aida.ref.function.FunctionListener;
 
+import java.awt.Color;
 import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.EventObject;
@@ -27,6 +27,8 @@
 import java.util.TimerTask;
 
 import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JList;
 import javax.swing.JPanel;
@@ -47,6 +49,8 @@
     JComboBox<Object> plotComboBox;
     JTable infoTable = new JTable();
     DefaultTableModel model;
+    JButton saveButton;
+    
     PlotterRegion currentRegion;
     Object currentObject;
     static final int INSET_SIZE = 5;
@@ -63,11 +67,18 @@
      */
     @SuppressWarnings("unchecked")
     PlotInfoPanel() {
-
-        setLayout(new GridBagLayout());
-        setBorder(BorderFactory.createEmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
-
-        GridBagConstraints c;
+                
+        setLayout(new FlowLayout(FlowLayout.LEFT));
+
+        JPanel leftPanel = new JPanel();
+        leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
+           
+        JPanel buttonPanel = new JPanel();
+        saveButton = new JButton("Save Plots ...");
+        saveButton.setActionCommand(Commands.SAVE_SELECTED_PLOTS);
+        buttonPanel.add(saveButton);       
+        //c.anchor = GridBagConstraints.NORTHWEST;
+        leftPanel.add(buttonPanel);
 
         plotComboBox = new JComboBox<Object>();
         plotComboBox.setActionCommand(PLOT_SELECTED);
@@ -85,26 +96,17 @@
             }
         });
         plotComboBox.addActionListener(this);
-        c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = 0;
-        c.fill = GridBagConstraints.HORIZONTAL;
-        c.insets = new Insets(0, 0, INSET_SIZE, 0);
-        add(plotComboBox, c);
-
+        leftPanel.add(plotComboBox);
+        
         String data[][] = new String[0][0];
         model = new DefaultTableModel(data, COLUMN_NAMES);
         infoTable.setModel(model);
-
-        // FIXME: Are these adequate column size settings? Could prob be bigger...
         infoTable.getColumn("Field").setMinWidth(25);
         infoTable.getColumn("Value").setMinWidth(20);
-
-        c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = 1;
-        c.fill = GridBagConstraints.BOTH;
-        add(infoTable, c);
+        infoTable.setMinimumSize(new Dimension(100, 200));
+        leftPanel.add(infoTable);
+        
+        add(leftPanel);
     }
 
     /**

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java	Sun Mar 15 11:31:15 2015
@@ -1,15 +1,26 @@
 package org.hps.monitoring.application;
 
+import hep.aida.IPlotter;
+
 import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
 
+import javax.swing.JFileChooser;
 import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
+
+import org.hps.monitoring.application.util.DialogUtil;
+import org.hps.monitoring.plotting.MonitoringPlotFactory;
 
 /**
  * This is the panel containing the tabs with the monitoring plots.
  * @author Jeremy McCormick <[log in to unmask]>
  */
-class PlotPanel extends JPanel {
+class PlotPanel extends JPanel implements ActionListener {
     
     private JTabbedPane plotPane;    
     
@@ -23,8 +34,55 @@
     JTabbedPane getPlotPane() {
         return plotPane;
     }
+
+    /**
+     * Get the indices of the current selected tabs.
+     * @return The indices of the current tabs.
+     */
+    int[] getSelectedTabs() {
+        int[] indices = new int[2];
+        indices[0] = plotPane.getSelectedIndex();
+        Component component = plotPane.getSelectedComponent();
+        if (component instanceof JTabbedPane) {
+            indices[1] = ((JTabbedPane)component).getSelectedIndex();
+        } 
+        return indices;
+    }
+    
+    public void actionPerformed(ActionEvent event) {
+        if (event.getActionCommand().equals(Commands.SAVE_SELECTED_PLOTS)) {
+            int[] indices = getSelectedTabs();
+            IPlotter plotter = MonitoringPlotFactory.getPlotterRegistry().find(indices[0], indices[1]);
+            if (plotter != null) {
+                savePlotter(plotter);
+            } else {
+                DialogUtil.showErrorDialog(this, "Error Finding Plots", "No plots found in selected tab.");
+            }
+        }
+    }
+            
+    static final String DEFAULT_FORMAT = "png";
+    void savePlotter(IPlotter plotter) {
+        JFileChooser fc = new JFileChooser();
+        fc.setAcceptAllFileFilterUsed(false);
+        fc.setDialogTitle("Save Plots - " + plotter.title());
+        fc.setCurrentDirectory(new File("."));
+        int r = fc.showSaveDialog(this);
+        if (r == JFileChooser.APPROVE_OPTION) {                        
+            String path = fc.getSelectedFile().getPath();
+            if (path.lastIndexOf(".") == -1) {
+                path += "." + DEFAULT_FORMAT;
+            }
+            try {
+                plotter.writeToFile(path);
+            } catch (IOException e) {
+                e.printStackTrace();
+                DialogUtil.showErrorDialog(this, "Error Saving Plots", "There was an error saving the plots.");
+            }
+        }        
+    }
     
     void reset() {
-        plotPane.removeAll();
-    }
+        plotPane.removeAll();        
+    }    
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java	Sun Mar 15 11:31:15 2015
@@ -1,6 +1,5 @@
 package org.hps.monitoring.application;
 
-import java.awt.Color;
 import java.awt.Component;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
@@ -17,8 +16,7 @@
 import org.hps.monitoring.subsys.StatusCode;
 
 /**
- * A GUI window for showing changes to {@link org.hps.monitoring.subsys.SystemStatus} objects using
- * a <code>JTable</code>.
+ * This table shows the current state of {@link org.hps.monitoring.subsys.SystemStatus} objects.
  */
 class SystemStatusTable extends JTable {
 
@@ -37,28 +35,7 @@
 
                 // Color code the cell by its status.
                 StatusCode statusCode = StatusCode.valueOf((String) value);
-                if (statusCode.ordinal() >= StatusCode.ERROR.ordinal()) {
-                    // Any type of error is red.
-                    label.setBackground(Color.RED);
-                } else if (statusCode.equals(StatusCode.WARNING)) {
-                    // Warnings are yellow.
-                    label.setBackground(Color.YELLOW);
-                } else if (statusCode.equals(StatusCode.OKAY)) {
-                    // Okay is green.
-                    label.setBackground(Color.GREEN);
-                } else if (statusCode.equals(StatusCode.OFFLINE)) {
-                    // Offline is orange.
-                    label.setBackground(Color.ORANGE);
-                } else if (statusCode.equals(StatusCode.UNKNOWN)) {
-                    // Unknown is gray.
-                    label.setBackground(Color.GRAY);
-                } else if (statusCode.equals(StatusCode.CLEARED)) {
-                    // Cleared is light gray.
-                    label.setBackground(Color.LIGHT_GRAY);
-                } else {
-                    // Default is white, though this shouldn't happen!
-                    label.setBackground(Color.WHITE);
-                }
+                label.setBackground(statusCode.getColor());
                 return label;
             }
         });

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java	Sun Mar 15 11:31:15 2015
@@ -10,6 +10,7 @@
 public enum ConnectionStatus {
 
     DISCONNECTED(Color.RED),
+    DISCONNECTING(Color.YELLOW),
     CONNECTED(Color.GREEN);
     
     Color color;    

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java	Sun Mar 15 11:31:15 2015
@@ -50,4 +50,16 @@
             listener.propertyChange(new PropertyChangeEvent(this, PAUSED_PROPERTY, oldValue, this.paused));
         }
     }
+    
+    public boolean isConnected() {
+        return this.connectionStatus == ConnectionStatus.CONNECTED;
+    }
+    
+    public boolean isDisconnected() {
+        return this.connectionStatus == ConnectionStatus.DISCONNECTED;
+    }
+    
+    public boolean isDisconnecting() {
+        return this.connectionStatus == ConnectionStatus.DISCONNECTING;
+    }
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java	Sun Mar 15 11:31:15 2015
@@ -3,7 +3,7 @@
 import java.util.Date;
 
 /**
- * Backing model for run information that shows in the {@link org.hps.monitoring.application.RunPanel}.
+ * Backing model for run information that shows in the {@link org.hps.monitoring.application.EventDashboard}.
  */
 public final class RunModel extends AbstractModel {
 

Modified: java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop
 =============================================================================
--- java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop	(original)
+++ java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop	Sun Mar 15 11:31:15 2015
@@ -29,8 +29,7 @@
 Host=localhost
 Port=11111
 StationPosition=1
-# Prescale was 1
-Prescale=0
+Prescale=1
 QueueSize=0
 StationName=MY_STATION
 Verbose=false

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

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

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

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

Privacy Notice, Security Notice and Terms of Use