Print

Print


Author: [log in to unmask]
Date: Thu Mar 12 16:53:02 2015
New Revision: 2425

Log:
Add first working version of reading DAQ config events on separate ET station.  HPSJAVA-464

Added:
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioDAQConfigStation.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java
Modified:
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java	Thu Mar 12 16:53:02 2015
@@ -14,6 +14,7 @@
 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.EvioDAQConfigStation;
 import org.hps.monitoring.subsys.et.EtSystemMonitor;
 import org.hps.monitoring.subsys.et.EtSystemStripCharts;
 import org.hps.record.LCSimEventBuilder;
@@ -32,20 +33,20 @@
 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;
-    
+
     /**
      * This class is used to organize the objects for an event processing session.
      */
@@ -57,27 +58,22 @@
         Thread sessionWatchdogThread;
         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<ConditionsListener> conditionsListeners) {
+    EventProcessing(MonitoringApplication application, 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;
     }
-    
+
     /**
      * Setup this class from the global configuration.
      * @param configurationModel The global configuration.
@@ -97,26 +93,28 @@
         MonitoringApplication.logger.config("Set steering to " + 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.
+
+            // 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) {
@@ -124,14 +122,14 @@
             } 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();
@@ -139,7 +137,7 @@
                 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.  
+                    // Freeze the conditions system to ignore run numbers from the events.
                     logger.config("user configured to freeze conditions system from monitoring app");
                     conditionsManager.freeze();
                 } else {
@@ -155,11 +153,11 @@
             // Catch all errors and rethrow 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.
      */
@@ -178,32 +176,25 @@
         // 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) {
 
-        CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
-            .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
-            .setStopOnErrors(configurationModel.getDisconnectOnError())
-            .setDataSourceType(configurationModel.getDataSourceType())
-            .setProcessingStage(configurationModel.getProcessingStage())
-            .setEtConnection(sessionState.connection)
-            .setFilePath(configurationModel.getDataSourcePath())
-            .setLCSimEventBuilder(sessionState.eventBuilder);
+        CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration().setStopOnEndRun(configurationModel.getDisconnectOnEndRun()).setStopOnErrors(configurationModel.getDisconnectOnError()).setDataSourceType(configurationModel.getDataSourceType()).setProcessingStage(configurationModel.getProcessingStage()).setEtConnection(sessionState.connection).setFilePath(configurationModel.getDataSourcePath()).setLCSimEventBuilder(sessionState.eventBuilder);
 
         if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
             long maxEvents = configurationModel.getMaxEvents();
             if (maxEvents > 0L) {
-                //logger.config("processing will stop after max events: " + maxEvents);
+                // 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");
         }
@@ -221,25 +212,25 @@
         }
 
         // 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.
         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.
@@ -260,14 +251,14 @@
         sessionState.jobManager.setup(is);
         is.close();
     }
-        
+
     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 {
@@ -278,58 +269,57 @@
                 e.printStackTrace();
             }
         }
-        
+
         // Stop event processing.
         logger.fine("commanding event processing to stop ...");
         sessionState.loop.execute(Command.STOP);
         logger.fine("event processing commanded to stop");
-        
+
         // Cleanup the event processing thread.
         try {
             logger.fine("joining on event processing thread ...");
             sessionState.processingThread.join();
             logger.fine("event processing thread joined");
-            
+
             // Invalidate event processing thread.
             sessionState.processingThread = null;
         } 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 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.
+
+    /**
+     * 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.
      */
@@ -341,7 +331,7 @@
         }
         logger.finest("paused");
     }
-    
+
     /**
      * Get next event if in pause mode.
      */
@@ -354,7 +344,7 @@
         }
         logger.finest("got next event");
     }
-    
+
     /**
      * Resume processing events from pause mode.
      */
@@ -362,12 +352,12 @@
         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.
      */
@@ -392,7 +382,7 @@
         }
         logger.fine("watchdog thread killed");
     }
-    
+
     /**
      * Cleanup the ET connection.
      */
@@ -408,7 +398,7 @@
             logger.fine("ET connection closed");
         }
     }
-    
+
     /**
      * True if the processing thread is active.
      * @return True if processing thread is active.
@@ -416,7 +406,7 @@
     boolean isActive() {
         return sessionState.processingThread != null && sessionState.processingThread.isAlive();
     }
-    
+
     /**
      * Connect to the ET system using the current connection settings.
      */
@@ -426,7 +416,11 @@
         if (usingEtServer()) {
             // Create a connection to the ET server.
             try {
+                // Create the main ET system connection.
                 createEtConnection();
+
+                // Add an attachment that listens for DAQ configuration changes.
+                createEvioDAQConfigStation();
             } catch (Exception e) {
                 throw new IOException(e);
             }
@@ -436,15 +430,15 @@
         }
         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.
@@ -456,31 +450,43 @@
         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");
+            // 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.
+     */
+    void createEvioDAQConfigStation() {
+        logger.fine("starting EVIO DAQ config station ...");
+        EvioDAQConfigStation configStation = new EvioDAQConfigStation(this.sessionState.connection);
+        configStation.setup();
+        Thread configThread = new Thread(configStation);
+        configThread.start();
+        logger.fine("EVIO DAQ config station started");
+    }
+
     /**
      * Disconnect from the current ET session with a particular status.
      * @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 {
 
@@ -489,21 +495,23 @@
         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.
                 processingThread.join();
-                                
-                // Activate a disconnect using the ActionEvent which is used by the disconnect button.
+
+                // Activate a disconnect using the ActionEvent which is used by the disconnect
+                // button.
                 logger.fine("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");
-                // This happens when the thread is interrupted by the user pressing the disconnect button.
-            }            
+                // This happens when the thread is interrupted by the user pressing the disconnect
+                // button.
+            }
         }
     }
 }

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	Thu Mar 12 16:53:02 2015
@@ -40,6 +40,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;
@@ -245,7 +246,10 @@
             startSession();
         } else if (Commands.DISCONNECT.equals(command)) {
             // TODO: Start this on new thread.
-            processing.stop();
+            //processing.stop();
+            System.out.println("MonitoringApplication.actionPerformed - running disconnect thread ...");
+            runDisconnectThread();
+            System.out.println("MonitoringApplication.actionPerformed - disconnect thread is done!");
         } else if (Commands.SAVE_PLOTS.equals(command)) {
             savePlots();
         } else if (Commands.EXIT.equals(command)) {
@@ -458,12 +462,12 @@
      * Exit from the application.
      */
     void exit() {        
-        if (processing != null && processing.isActive()) {
+        if (connectionModel.isConnected()) {
             processing.stop();
         }
-        frame.setVisible(false);
         logger.info("exiting the application");
         logger.getHandlers()[0].flush();
+        frame.setVisible(false);
         System.exit(0);
     }              
             
@@ -803,5 +807,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();
+    }
 }

Added: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioDAQConfigStation.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioDAQConfigStation.java	(added)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioDAQConfigStation.java	Thu Mar 12 16:53:02 2015
@@ -0,0 +1,134 @@
+/**
+ * 
+ */
+package org.hps.monitoring.application.util;
+
+import java.util.List;
+
+import org.hps.evio.TriggerConfigEvioReader;
+import org.hps.readout.ecal.daqconfig.ConfigurationManager;
+import org.hps.readout.ecal.daqconfig.EvioDAQParser;
+import org.hps.record.et.EtConnection;
+import org.jlab.coda.et.EtAttachment;
+import org.jlab.coda.et.EtConstants;
+import org.jlab.coda.et.EtEvent;
+import org.jlab.coda.et.EtStation;
+import org.jlab.coda.et.EtStationConfig;
+import org.jlab.coda.et.enums.Mode;
+import org.jlab.coda.et.enums.Modify;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioReader;
+import org.lcsim.event.base.BaseLCSimEvent;
+
+/**
+ * This is an ET station that looks for DAQ configuration events
+ * from the ET server and updates the global DAQ configuration if
+ * it finds one.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EvioDAQConfigStation implements Runnable {
+    
+    private static final String TRIGGER_CONFIG = "TriggerConfig";
+    EtConnection connection;
+    EtAttachment attachment;
+    TriggerConfigEvioReader configReader = new TriggerConfigEvioReader();
+    EventTagFilter filter = new PhysicsTagFilter();
+        
+    public EvioDAQConfigStation(EtConnection connection) {
+        this.connection = connection;
+    }
+    
+    public EvioDAQConfigStation(EtConnection connection, EventTagFilter filter) {
+        this.connection = connection;
+        this.filter = filter;
+    }
+    
+    public void setup() {
+        EtStationConfig stationConfig = new EtStationConfig();
+        try {
+            stationConfig.setFlowMode(EtConstants.stationSerial);
+            stationConfig.setBlockMode(EtConstants.stationNonBlocking);
+            stationConfig.setPrescale(1);
+      
+            EtStation station = connection.getEtSystem().createStation(
+                stationConfig,
+                connection.getEtStation().getName() + "_EvioDAQConfigStation",
+                connection.getEtSystem().getStationPosition(connection.getEtStation()) + 1);
+            
+            attachment = connection.getEtSystem().attach(station);
+            
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    public void run() {
+        for(;;) {
+            try {
+                EtEvent[] events = 
+                    connection.getEtSystem().getEvents(attachment, Mode.SLEEP, Modify.NOTHING, 0, 100);
+                for (EtEvent event : events) {
+                    int eventTag = event.getControl()[0];
+                    if (filter.accept(eventTag)) {
+                        EvioEvent evioEvent = new EvioReader(event.getDataBuffer()).parseNextEvent();     
+                        BaseLCSimEvent lcsimEvent = new BaseLCSimEvent(9999, 9999, "dummy", 0, false);
+                        configReader.getDAQConfig(evioEvent, lcsimEvent);
+                        if (lcsimEvent.hasCollection(EvioDAQParser.class, TRIGGER_CONFIG)) {
+                            List<EvioDAQParser> configList = lcsimEvent.get(EvioDAQParser.class, TRIGGER_CONFIG);
+                            if (!configList.isEmpty()) {
+                                ConfigurationManager.updateConfiguration(configList.get(0));
+                            }
+                            break;
+                        }
+                     }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                break;
+            }
+        }
+        if (connection.getEtSystem().alive()) {
+            disconnect();
+        }
+    }
+    
+    static interface EventTagFilter {
+        boolean accept(int eventTag);
+    }
+    
+    static class SyncTagFilter implements EventTagFilter {
+        public boolean accept(int eventTag) {
+            return (((eventTag >> 6) & 1) == 1);
+        }
+    }
+    
+    static class PhysicsTagFilter implements EventTagFilter {
+        public boolean accept(int eventTag) {
+            return (((eventTag >> 7) & 1) == 1);
+        }
+    }
+    
+    static boolean hasConfigBank(EvioEvent evioEvent) {
+        for (BaseStructure bank : evioEvent.getChildrenList()) {
+            if (bank.getChildCount() <= 0)
+                continue;
+            for (BaseStructure subBank : bank.getChildrenList()) {
+                if (subBank.getHeader().getTag() == EvioDAQParser.BANK_TAG) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    public void disconnect() {        
+        try {
+            connection.getEtSystem().wakeUpAttachment(attachment);
+            connection.getEtSystem().detach(attachment);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }        
+}

Added: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java	(added)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java	Thu Mar 12 16:53:02 2015
@@ -0,0 +1,44 @@
+package org.hps.monitoring.application.util;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.hps.evio.LCSimEngRunEventBuilder;
+import org.hps.record.evio.EvioEventUtilities;
+import org.jlab.coda.jevio.EvioEvent;
+import org.lcsim.event.EventHeader;
+
+
+/**
+ * Build LCSim events from EVIO data.
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class MonitoringApplicationEventBuilder extends LCSimEngRunEventBuilder {
+    
+    public MonitoringApplicationEventBuilder() {
+        super();
+    }
+           
+    @Override
+    public EventHeader makeLCSimEvent(EvioEvent evioEvent) {
+        
+        if (!EvioEventUtilities.isPhysicsEvent(evioEvent)) {
+            throw new RuntimeException("Not a physics event: event tag " + evioEvent.getHeader().getTag());
+        }
+
+        // Create a new LCSimEvent.
+        EventHeader lcsimEvent = getEventData(evioEvent);
+             
+        // Make RawCalorimeterHit collection, combining top and bottom section
+        // of ECal into one list.
+        try {
+            ecalReader.makeHits(evioEvent, lcsimEvent);
+        } catch (Exception e) {
+            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making ECal hits", e);
+        }
+
+        return lcsimEvent;
+    }           
+}