Print

Print


Author: [log in to unmask]
Date: Sat Mar  7 16:10:48 2015
New Revision: 2359

Log:
Merge r2331 through r2358 into prod branch.

Added:
    java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java
      - copied unchanged from r2358, java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015ECalRecon.lcsim
      - copied unchanged from r2358, java/trunk/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015ECalRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim
      - copied unchanged from r2358, java/trunk/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim
Removed:
    java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationListener.java
    java/branches/prod/tracking/src/main/java/org/hps/recon/tracking/SvtSensorSetup.java
    java/branches/prod/tracking/src/test/java/org/hps/recon/tracking/SvtSensorSetupTest.java
Modified:
    java/branches/prod/   (props changed)
    java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java
    java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java
    java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
    java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java
    java/branches/prod/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java
    java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java
    java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java
    java/branches/prod/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java
    java/branches/prod/monitoring-app/   (props changed)
    java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java
    java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
    java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
    java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/Configuration.java
    java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToLcio.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPSTrackingDefaults.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio2014.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/GBLReco.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineNoPileupRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineTruthRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPSTrackingDefaultsRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/SimpleMCRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineRecon.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineReconTwoTrkFilter.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/MattsScrewAround.lcsim
    java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/NoTimeNoTriggerRecon.lcsim
    java/branches/prod/users/src/main/java/org/hps/users/celentan/LedAnalysis.java

Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java
 =============================================================================
--- java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java	(original)
+++ java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java	Sat Mar  7 16:10:48 2015
@@ -4,6 +4,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.HelpFormatter;
@@ -13,6 +14,8 @@
 import org.apache.commons.cli.PosixParser;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.lcsim.util.log.DefaultLogFormatter;
+import org.lcsim.util.log.LogUtil;
 
 /**
  * <p>
@@ -25,6 +28,8 @@
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public class CommandLineTool {
+    
+    static Logger logger = LogUtil.create(CommandLineTool.class.getSimpleName(), new DefaultLogFormatter(), Level.WARNING);
 
     Options options = new Options();
     Map<String, AbstractCommand> commands = new HashMap<String, AbstractCommand>();
@@ -42,12 +47,12 @@
                 printUsage();
                 exit(0);
             }
-
+            
             CommandLine commandLine = null;
             try {
                 commandLine = parser.parse(options, arguments, true);
             } catch (ParseException e) {
-                e.printStackTrace();
+                logger.log(Level.SEVERE, "error parsing the options", e);
                 printUsage();
                 exit(1);
             }
@@ -57,22 +62,29 @@
                 exit(0);
             }
 
+            // Set verbosity.
             if (commandLine.hasOption("v")) {
+                logger.setLevel(Level.ALL);
+                logger.getHandlers()[0].setLevel(Level.ALL);
                 verbose = true;
+                logger.config("verbose mode enabled");
             }
 
+            // Setup conditions manager from command line options.
             setupConditionsManager(commandLine);
 
+            // Get the sub-command to use.
             String commandName = commandLine.getArgs()[0];
-
             AbstractCommand command = commands.get(commandName);
             if (command == null) {
                 throw new IllegalArgumentException("Unknown command " + commandName);
             }
 
+            // Copy remaining arguments for sub-command.
             String[] commandArguments = new String[commandLine.getArgs().length - 1];
             System.arraycopy(commandLine.getArgs(), 1, commandArguments, 0, commandArguments.length);
 
+            // Excecute the sub-command.
             command.setVerbose(verbose);
             command.execute(commandArguments);
         } catch (Exception e) {
@@ -83,40 +95,64 @@
         }
     }
 
-    private void setupConditionsManager(CommandLine commandLine) {
+    void setupConditionsManager(CommandLine commandLine) {
+
+        logger.info("setting up conditions manager");
+        
+        // Create new manager.
         conditionsManager = new DatabaseConditionsManager();
-        if (verbose) {
-            conditionsManager.setLogLevel(Level.ALL);
-        } else {
-            conditionsManager.setLogLevel(Level.WARNING);
-        }
+
+        // Set log level.
+        conditionsManager.setLogLevel(logger.getLevel());
+
+        // Connection properties.
         if (commandLine.hasOption("p")) {
             File connectionPropertiesFile = new File(commandLine.getOptionValue("p"));
-            if (verbose)
-                System.out.println("using connection properties file " + connectionPropertiesFile.getPath());
             conditionsManager.setConnectionProperties(connectionPropertiesFile);
+            logger.config("connection properties -p " + connectionPropertiesFile);
         } 
+        
+        // XML config.
         if (commandLine.hasOption("x")) {
             File xmlConfigFile = new File(commandLine.getOptionValue("x"));
             conditionsManager.setXmlConfig(xmlConfigFile);
-        }         
+            logger.config("XML config -x " + xmlConfigFile);
+        }
         
-        String detectorName = null;
-        if (commandLine.hasOption("d")) {
-            detectorName = commandLine.getOptionValue("d");
-        } else {
-            throw new RuntimeException("Missing -d argument with name of detector.");
-        }
-        int runNumber = 0;
-        if (commandLine.hasOption("r")) {
-            runNumber = Integer.parseInt(commandLine.getOptionValue("r"));
-        } else {
-            throw new RuntimeException("Missing -r argument with run number.");
-        }
-        try {
-            DatabaseConditionsManager.getInstance().setDetector(detectorName, runNumber);
-        } catch (ConditionsNotFoundException e) {
-            throw new RuntimeException(e);
+        // If there is a run number or detector number then attempt to initialize the conditions system.
+        if (commandLine.hasOption("r") || commandLine.hasOption("d")) {
+            
+            logger.config("detector name or run number supplied so manager will be initialized");
+
+            // Set detector name.
+            String detectorName = null;
+            if (commandLine.hasOption("d")) {
+                detectorName = commandLine.getOptionValue("d");
+                logger.config("detector -d " + detectorName);
+            } else {
+                detectorName = "HPS-ECalCommissioning-v2";
+                logger.config("default detector " + detectorName + " is being used");
+            }
+
+            // Get run number.
+            Integer run = null;
+            if (commandLine.hasOption("r")) {
+                run = Integer.parseInt(commandLine.getOptionValue("r"));
+                logger.config("run -r " + run);
+            } else {
+                run = 0;
+                logger.config("default run number " + run + " is being used");
+            }
+
+            // Setup the conditions manager with user detector name and run number.
+            try {
+                logger.config("initializing conditions manager with detector " + detectorName + " and run " + run);
+                DatabaseConditionsManager.getInstance().setDetector(detectorName, run);
+                logger.config("conditions manager initialized successfully");
+                logger.getHandlers()[0].flush();
+            } catch (ConditionsNotFoundException e) {
+                throw new RuntimeException(e);
+            }
         }
     }
 
@@ -143,10 +179,8 @@
     static CommandLineTool create() {
         CommandLineTool cli = new CommandLineTool();
         cli.options.addOption(new Option("h", false, "Print help and exit"));
-        cli.options.addOption(new Option("d", true, "Set the detector name (required)"));
-        cli.options.getOption("d").setRequired(true);
-        cli.options.addOption(new Option("r", true, "Set the run number (required)"));
-        cli.options.getOption("r").setRequired(true);
+        cli.options.addOption(new Option("d", true, "Set the detector name"));
+        cli.options.addOption(new Option("r", true, "Set the run number"));
         cli.options.addOption(new Option("v", false, "Enable verbose print output"));
         cli.options.addOption(new Option("p", true, "Set the database connection properties file"));
         cli.options.addOption(new Option("x", true, "Set the conditions XML configuration file"));
@@ -155,4 +189,4 @@
         cli.registerCommand(new AddCommand());
         return cli;
     }
-}
+}

Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java
 =============================================================================
--- java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java	(original)
+++ java/branches/prod/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java	Sat Mar  7 16:10:48 2015
@@ -36,13 +36,16 @@
     // Field delimited for print out.
     char fieldDelimiter = ' ';
     
+    // Output file.
+    File outputFile;
+    
     DatabaseConditionsManager conditionsManager;
     
     PrintCommand() {
         super("print", "Print the table data for a conditions set");
         this.options.addOption(new Option("t", true, "Set the table name"));
         this.options.addOption(new Option("i", false, "Print the ID for the records (off by default)"));
-        this.options.addOption(new Option("f", true, "Write print output to a file"));
+        this.options.addOption(new Option("f", true, "Write print output to a file (must be used with -t option)"));
         this.options.addOption(new Option("H", false, "Suppress printing of conditions record and table info"));
         this.options.addOption(new Option("d", false, "Use tabs for field delimiter instead of spaces"));
         this.options.addOption(new Option("T", true, "Specify a conditions tag to use for filtering records"));
@@ -55,6 +58,10 @@
         super.execute(arguments);
         
         conditionsManager = DatabaseConditionsManager.getInstance();
+        
+        if (!conditionsManager.isInitialized()) {
+            throw new RuntimeException("conditions system is not initialized");
+        }
         
         // User specified tag of conditions records.
         if (this.commandLine.hasOption("T")) {            
@@ -68,17 +75,19 @@
         }                
         
         // Setup an output file for the print out if requested.
-        File outputFile = null;
         if (this.commandLine.hasOption("f")) {
-            outputFile = new File(commandLine.getOptionValue("f"));
+            if (!this.commandLine.hasOption("t")) {
+                throw new IllegalArgumentException("An output file may only be specified when using the -t option.");
+            }
+            String path = commandLine.getOptionValue("f");
+            if (new File(path).exists()) {
+                throw new IllegalArgumentException("File already exists: " + path);
+            }
+            outputFile = new File(path);
             try {
                 ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile, false)));
             } catch (FileNotFoundException e) {
-                throw new RuntimeException(e);
-            }
-            if (outputFile.exists()) {
-                System.err.println("Specified output file already exists.");
-                System.exit(1);
+                throw new IllegalArgumentException(e);
             }
         }              
         
@@ -102,15 +111,14 @@
         
         // Did the user specify a table to use?
         if (userConditionsKey == null) {
-            ps.println("printing all conditions");
+            System.out.println("printing all conditions");
             // Use all table names if there was not one specified.
             conditionsRecords.addAll(conditionsManager.getConditionsRecords());
         } else {            
-            ps.println("printing conditions with name: " + userConditionsKey);
+            System.out.println("printing conditions with name: " + userConditionsKey);
             // Get records only for the user specified table name.
             conditionsRecords.addAll(conditionsManager.findConditionsRecords(userConditionsKey));
         }
-        System.out.println(conditionsRecords.size() + " conditions records found");
         
         // Sort the records by key (table name).
         conditionsRecords.sortByKey();
@@ -122,15 +130,18 @@
         printConditionsRecords(conditionsKeys);   
         ps.flush();           
         ps.close();
+        
+        if (outputFile != null) {
+            System.out.println("wrote collection data to file " + outputFile.getPath());
+        }
     }
 
     private void printConditionsRecords(Set<String> conditionsKeys) {
-        ps.print("printing conditions sets: ");
+        System.out.print("printing conditions sets: ");
         for (String conditionsKey : conditionsKeys) {
-            ps.print(conditionsKey + " ");
-        }
-        ps.println();
-        ps.println();
+            System.out.print(conditionsKey + " ");
+        }
+        System.out.println();
         // Loop over the conditions keys from the conditions records.
         for (String conditionsKey : conditionsKeys) {
                                    
@@ -165,8 +176,8 @@
             }
             printColumnNames(collection.getTableMetaData());
             printCollection(collection);
-            ps.println();
-        }
+            System.out.println();
+        }        
         ps.flush();
     }
 
@@ -180,16 +191,17 @@
             buffer.setLength(buffer.length() - 1);
             buffer.append('\n');
         }
+        buffer.setLength(buffer.length() - 1);
         ps.print(buffer.toString());
         ps.flush();
     }
 
     private void printCollectionHeader(ConditionsObjectCollection<?> collection) {        
-        ps.println("--------------------------------------");
-        ps.print(collection.getConditionsRecord());
-        ps.println("--------------------------------------");
-        ps.println();
-        ps.flush();
+        System.out.println("--------------------------------------");
+        System.out.print(collection.getConditionsRecord());
+        System.out.println("--------------------------------------");
+        System.out.println();
+        System.out.flush();
     }
 
     private void printColumnNames(TableMetaData tableMetaData) {

Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
 =============================================================================
--- java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java	(original)
+++ java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java	Sat Mar  7 16:10:48 2015
@@ -697,6 +697,13 @@
     public Subdetector getEcalSubdetector() {
         return this.getDetectorObject().getSubdetector(ecalName);
     }
+    
+    /**
+     * True if conditions manager is properly initialized.
+     */
+    public boolean isInitialized() {
+        return isInitialized;
+    }
 
     /*
      *******************************

Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java
 =============================================================================
--- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java	(original)
+++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java	Sat Mar  7 16:10:48 2015
@@ -57,12 +57,17 @@
         if (enabled) {
             DatabaseConditionsManager manager = (DatabaseConditionsManager) event.getConditionsManager();
             Subdetector subdetector = manager.getDetectorObject().getSubdetector(svtName);
-            if (manager.isTestRun()) {
-                TestRunSvtConditions svtConditions = manager.getCachedConditions(TestRunSvtConditions.class, "test_run_svt_conditions").getCachedData();
-                loadTestRun(subdetector, svtConditions);
+            if (subdetector != null) {
+                if (manager.isTestRun()) {
+                    TestRunSvtConditions svtConditions = manager.getCachedConditions(TestRunSvtConditions.class, "test_run_svt_conditions").getCachedData();
+                    loadTestRun(subdetector, svtConditions);
+                } else {
+                    SvtConditions svtConditions = manager.getCachedConditions(SvtConditions.class, "svt_conditions").getCachedData();
+                    loadDefault(subdetector, svtConditions);
+                }
             } else {
-                SvtConditions svtConditions = manager.getCachedConditions(SvtConditions.class, "svt_conditions").getCachedData();
-                loadDefault(subdetector, svtConditions);
+                logger.warning("no SVT detector was found so SvtDetectorSetup was NOT activated");
+                enabled = false;
             }
         } else {
             logger.config("disabled");

Modified: java/branches/prod/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java
 =============================================================================
--- java/branches/prod/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java	(original)
+++ java/branches/prod/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java	Sat Mar  7 16:10:48 2015
@@ -19,6 +19,8 @@
 public class ConditionsDriverTest extends TestCase {
            
     public void testConditionsDriverTestRun() throws Exception {
+        
+        new DatabaseConditionsManager();
         
         FileCache cache = new FileCache();
         File inputFile = cache.getCachedFile(new URL("http://www.lcsim.org/test/hps-java/ConditionsTest.slcio"));

Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java
 =============================================================================
--- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java	(original)
+++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java	Sat Mar  7 16:10:48 2015
@@ -1,5 +1,7 @@
 package org.hps.recon.ecal;
 
+import java.awt.List;
+import java.util.ArrayList;
 import java.util.Map;
 
 import org.hps.conditions.database.DatabaseConditionsManager;
@@ -16,18 +18,33 @@
 
 /**
  * This class is used to convert {@link org.lcsim.event.RawCalorimeterHit}
- * objects to {@link org.lcsim.event.CalorimeterHit} objects with energy
- * information. It has methods to convert pedestal subtracted ADC counts to
- * energy.
- *
- * TODO: Switch all mode's HitDtoAs to use a clipped pedestal for clipped pulses.
- *       This requires another parameter, the window size.
+ * and {@link org.lcsim.event.RawTrackerHit} to {@link org.lcsim.event.CalorimeterHit}
+ * objects with energy information.
  *
  * @author Sho Uemura <[log in to unmask]>
  * @author Jeremy McCormick <[log in to unmask]>
  * @author Andrea Celentano <[log in to unmask]>
- * @author <[log in to unmask]>
+ * @author Nathan Baltzell <[log in to unmask]>
+ *
+ *
+ * baltzell:  New in 2015:  (default behavior is still unchanged)
+ *
+ * Implemented conversion of Mode-1 to Mode-3.
  * 
+ * Now using NSA/NSB for pedestal subtraction instead of integralWindow, to allow
+ * treating all FADC Modes uniformly.  (New) NSA+NSB == (Old) integralWindow*4(ns) 
+ * 
+ * Pedestal subtracting clipped pulses more correctly for all Modes.
+ * 
+ * Changed threshold cut for Mode-1 to >= instead of > to emulate SSP instead of
+ * FADC firmware for trigger diagnostics.
+ *
+ * Implemented finding multiple peaks for Mode-1.
+ * 
+ * Implemented conversion of Mode-1 to Mode-7 with high-resolution timing.
+ * Only some of the special cases in the firmware for when this algorithm fails due
+ * to bad pulses (e.g. clipping) are already implemented.  Not yet writing Mode-7's
+ * min/max to data stream. 
  */
 public class EcalRawConverter {
 
@@ -43,23 +60,46 @@
     private static final int nsPerSample = 4;
     
     /*
-     * The leading-edge threshold, relative to pedestal, for readout and pulse time
-     * determination.  Units = ADC.  This is used to convert mode-1 readout into
-     * mode-3/7 for clustering.
+     * The leading-edge threshold, relative to pedestal, for pulse-finding and
+     * time determination.  Units = ADC.  Used to convert mode-1 readout into
+     * mode-3/7 used by clustering.
      * 
      * The default value of 12 is what we used for most of the 2014 run.
      */
     private double leadingEdgeThreshold=12;
     
     /*
-     * Integration range after (NSA) and before (NSB) threshold crossing.  (units = ns)
-     * These must be multiples of 4 ns.
+     * Integration range after (NSA) and before (NSB) threshold crossing.  Units=ns,
+     * same as the DAQ configuration files.  These must be multiples of 4 ns.  Used
+     * for pulse integration in Mode-1, and pedestal subtraction in all modes.
      * 
      * The default values of 20/100 are what we had during the entire 2014 run.
      */
     private int NSB=20;
     private int NSA=100;
-    
+  
+    /*
+     * The number of samples in the FADC readout window.  Needed in order to
+     * properly pedestal-correct clipped pulses for Mode-3/7.  Ignored for
+     * mode-1 input, since it already knows its number of samples.
+     * 
+     * A non-positive number disables pulse-clipped pedestals and reverts to
+     * the old behavior which assumed integration range was constant.
+     * 
+     */
+    private int windowSamples=-1;
+    
+    /*
+     * The maximum number of peaks to be searched for.
+     */
+    private int nPeak=3;
+   
+    /*
+     * Convert Mode-1 into Mode-7, else Mode-3.
+     */
+    private boolean mode7=false;
+
+
     private EcalConditions ecalConditions = null;
 
     public EcalRawConverter() {
@@ -80,7 +120,20 @@
         }
         NSB=nsb;
     }
-    
+    public void setWindowSamples(int windowSamples) {
+        this.windowSamples=windowSamples;
+    }
+    public void setNPeak(int nPeak) {
+        if (nPeak<1 || nPeak>3) {
+            throw new RuntimeException("Npeak must be 1, 2, or 3.");
+        }
+        this.nPeak=nPeak;
+    }
+    public void setMode7(boolean mode7)
+    {
+        this.mode7=mode7;
+    }
+
     public void setGain(double gain) {
         constantGain = true;
         this.gain = gain;
@@ -93,25 +146,48 @@
     public void setUseRunningPedestal(boolean useRunningPedestal) {
         this.useRunningPedestal=useRunningPedestal;
     }
-    
+
     public void setUseTimeWalkCorrection(boolean useTimeWalkCorrection) {
         this.useTimeWalkCorrection=useTimeWalkCorrection;
     }
-  
-    /*
-     * NAB 2015/02/11 
-     * Choose whether to use static pedestal from database or running pedestal.
-     * This can only used for Mode-7 data.
-     */
-    public double getMode7Pedestal(EventHeader event,RawCalorimeterHit hit)
-    {
-        if (useRunningPedestal) {
+
+    /*
+     * This should probably be deprecated.  It just integrates the entire window.
+     */
+    public int sumADC(RawTrackerHit hit) {
+        EcalChannelConstants channelData = findChannel(hit.getCellID());
+        double pedestal = channelData.getCalibration().getPedestal();
+        int sum = 0;
+        short samples[] = hit.getADCValues();
+        for (int isample = 0; isample < samples.length; ++isample) {
+            sum += (samples[isample] - pedestal);
+        }
+        return sum;
+    }
+
+    /*
+     * This should probably be deprecated.  HitDtoA(EventHeader,RawTrackerHit)
+     * has the same functionality if NSA+NSB > windowSamples, with the exception
+     * that that one also finds pulse time instead of this one's always reporting zero.
+     */
+    public CalorimeterHit HitDtoA(RawTrackerHit hit) {
+        double time = hit.getTime();
+        long id = hit.getCellID();
+        double rawEnergy = adcToEnergy(sumADC(hit), id);
+        return CalorimeterHitUtilities.create(rawEnergy, time, id);
+    }
+
+    /*
+     * Get pedestal for a single ADC sample.
+     * Choose whether to use static pedestal from database or running pedestal from mode-7.
+     */
+    public double getSingleSamplePedestal(EventHeader event,long cellID) {
+        if (useRunningPedestal && event!=null) {
             if (event.hasItem("EcalRunningPedestals")) {
                 Map<EcalChannel, Double> runningPedMap=
                         (Map<EcalChannel, Double>)
                         event.get("EcalRunningPedestals");
-                EcalChannel chan = ecalConditions.getChannelCollection().
-                        findGeometric(hit.getCellID());
+                EcalChannel chan = ecalConditions.getChannelCollection().findGeometric(cellID);
                 if (!runningPedMap.containsKey(chan)){
                     System.err.println("************** Missing Pedestal");
                 } else {
@@ -125,65 +201,39 @@
                 useRunningPedestal = false;
             }
         }
-        return findChannel(hit.getCellID()).getCalibration().getPedestal();
-    }
-    
-    public short sumADC(RawTrackerHit hit) {
-        EcalChannelConstants channelData = findChannel(hit.getCellID());
-        double pedestal = channelData.getCalibration().getPedestal();
-        short sum = 0;
+        return findChannel(cellID).getCalibration().getPedestal();
+    }
+
+    /*
+     * Get pedestal for entire pulse integral.  Account for clipping if
+     * windowSamples is greater than zero.
+     */
+    public double getPulsePedestal(EventHeader event,long cellID,int windowSamples,int thresholdCrossing) {
+        int firstSample,lastSample;
+        if ( windowSamples>0 && (NSA+NSB)/nsPerSample >= windowSamples ) {
+            // special case where firmware always integrates entire window
+            firstSample = 0;
+            lastSample = windowSamples-1;
+        } else {
+            firstSample = thresholdCrossing - NSB/nsPerSample;
+            lastSample  = thresholdCrossing + NSA/nsPerSample-1;
+            if (windowSamples > 0) {
+                // properly pedestal subtract pulses clipped by edge(s) of readout window:
+                if (firstSample < 0) firstSample=0;
+                if (lastSample >= windowSamples) lastSample=windowSamples-1;
+            }
+        }
+        return (lastSample-firstSample+1)*getSingleSamplePedestal(event,cellID); 
+    }
+   
+    
+    /*
+     * Emulate the FADC250 firmware emulation Mode-1 waveform to a Mode-3/7 pulse,
+     * given a time for threshold crossing.
+     */
+    public double[] convertWaveformToPulse(RawTrackerHit hit,int thresholdCrossing,boolean mode7) {
         short samples[] = hit.getADCValues();
-        for (int isample = 0; isample < samples.length; ++isample) {
-            sum += (samples[isample] - pedestal);
-        }
-        return sum;
-    }
-
-    /*
-     * This should this be replaced by firmwareHitDtoA, as that has the
-     * same functionality if NSA+NSB > window size. Left for now.
-     */
-    public CalorimeterHit HitDtoA(RawTrackerHit hit) {
-        double time = hit.getTime();
-        long id = hit.getCellID();
-        double rawEnergy = adcToEnergy(sumADC(hit), id);
-        return CalorimeterHitUtilities.create(rawEnergy, time, id);
-    }
-
-    /*
-     * NAB 2015/02/26
-     * This HitDtoA is for emulating the conversion of Mode-1 readout (RawTrackerHit)
-     * into what EcalRawConverter would have created from a Mode-3 readout.
-     * 
-     */
-    public CalorimeterHit firmwareHitDtoA(RawTrackerHit hit) {
-     
-        long id = hit.getCellID();
-        short samples[] = hit.getADCValues();
-        if (samples.length==0) return null;
-        EcalChannelConstants channelData = findChannel(hit.getCellID());
-        double pedestal = channelData.getCalibration().getPedestal();
-        double absoluteThreshold = pedestal+leadingEdgeThreshold;
-        
-        // find threshold crossing:
-        int thresholdCrossing = -1;
-        if (samples[0] > absoluteThreshold) {
-            // special case, first sample above threshold:
-            thresholdCrossing=0;
-        } else {
-            for (int ii = 1; ii < samples.length; ++ii) {
-                if ( samples[ii]   >absoluteThreshold &&
-                     samples[ii-1]<=absoluteThreshold)
-                {
-                    // found threshold crossing:
-                    thresholdCrossing = ii;
-                    // one pulse only:
-                    break;
-                }
-            }
-        }
-        if (thresholdCrossing < 0) return null;
-
+        
         // choose integration range:
         int firstSample,lastSample;
         if ((NSA+NSB)/nsPerSample >= samples.length) {
@@ -194,43 +244,154 @@
             firstSample = thresholdCrossing - NSB/nsPerSample;
             lastSample  = thresholdCrossing + NSA/nsPerSample - 1;
         }
-         
+        
+        // mode-7 min and max:
+        double minADC=0;
+        double maxADC=0;
+        int sampleMaxADC=0;
+        
         // pulse integral:
-        short sum = 0;
+        short sumADC = 0;
+        
         for (int jj=firstSample; jj<=lastSample; jj++) {
+        
             if (jj<0) continue;
             if (jj>=samples.length) break;
-            sum += samples[jj];
-        }
-
-        // pedestal subtraction:
-        sum -= pedestal*(NSA+NSB)/nsPerSample;
+            
+            // integrate pulse:
+            sumADC += samples[jj];
+           
+            // compute "minimum" at beginning of window:
+            if (jj<4) minADC+=samples[jj];
+          
+            // find pulse maximum:
+            if (jj>firstSample && jj<samples.length-5) {
+                if (samples[jj+1]<samples[jj]) {
+                    sampleMaxADC=jj;
+                    maxADC=samples[jj];
+                }
+            }
+        }
+       
+        // minADC is the average of first four samples:
+        minADC/=4;
       
-        // conversion of ADC to energy:
-        double rawEnergy = adcToEnergy(sum, id);
-        
-        // pulse time:
-        double time = thresholdCrossing*nsPerSample;
-        if (useTimeWalkCorrection) {
-           time = EcalTimeWalk.correctTimeWalk(time,rawEnergy);
-        }
-
-        return CalorimeterHitUtilities.create(rawEnergy, time, id);
-    }
-
-    /*
-     * This HitDtoA is for Mode-3 data.
-     * A time-walk correction can be applied.
-     */
-    public CalorimeterHit HitDtoA(RawCalorimeterHit hit, double timeOffset) {
+        // pulse time with 4ns resolution:
+        double pulseTime=thresholdCrossing*nsPerSample;
+        
+        // calculate Mode-7 high-resolution time:
+        if (mode7) {
+            if (thresholdCrossing < 4) {
+                maxADC=0;
+            }
+            else if (maxADC>0) {
+                // linear interpolation between threshold crossing and
+                // pulse maximum to find time at pulse half-height:
+                double t0 = thresholdCrossing*nsPerSample;
+                double a0 = samples[thresholdCrossing];
+                double t1 = sampleMaxADC*nsPerSample;
+                double a1 = maxADC;
+                double slope = (a1-a0)/(t1-t0);
+                double halfMax = (maxADC+minADC)/2;
+                double tmpTime = t1 - (a1 - halfMax) / slope;
+                if (slope>0 && tmpTime>0) {
+                    pulseTime = tmpTime;
+                }
+            }
+        }
+        
+        return new double []{pulseTime,sumADC,minADC,maxADC};
+    }
+   
+    
+    /*
+     * This HitDtoA is for emulating the conversion of Mode-1 readout (RawTrackerHit)
+     * into what EcalRawConverter would have created from a Mode-3 or Mode-7 readout.
+     * Clustering classes will read the resulting CalorimeterHits same as if they were
+     * directly readout from the FADCs in Mode-3/7.
+     * 
+     * For Mode-3, hit time is just the time of threshold crossing, with an optional
+     * time-walk correction.  For Mode-7, it is a "high-resolution" one calculated
+     * by linear interpolation between threshold crossing and pulse maximum.
+     *
+     * TODO: Generate GenericObject (and corresponding LCRelation) to store min and max
+     * to fully emulate mode-7.  This is less important for now.
+     *
+     * NOTE: March 7, 2015. Threshold crossing requirement currently emulates the current
+     * SSP firmware (>=) instead of FADC firmware (>) to aid trigger studies.  Firmware will
+     * be changed to make them identical.  But for now this code prefers SSP over FADC.
+     */
+    public ArrayList <CalorimeterHit> HitDtoA(EventHeader event,RawTrackerHit hit) {
+     
+        final long cellID = hit.getCellID();
+        final short samples[] = hit.getADCValues();
+        if (samples.length==0) return null;
+        
+        // threshold is pedestal plus threshold configuration parameter:
+        final int absoluteThreshold = (int)(getSingleSamplePedestal(event,cellID)+leadingEdgeThreshold);
+       
+        ArrayList <Integer> thresholdCrossings = new ArrayList<Integer>();
+        
+        // special case, first sample is above threshold:
+        if (samples[0] >= absoluteThreshold) { // SSP/FADC firmware discrepancy.
+            thresholdCrossings.add(0);
+        } 
+
+        // search for threshold crossings:
+        for (int ii = 1; ii < samples.length; ++ii) {
+            if ( samples[ii]   >=  absoluteThreshold &&
+                 samples[ii-1] <   absoluteThreshold) // SSP/FADC firmware discrepancy.
+            {
+                // found one:
+                thresholdCrossings.add(ii);
+
+                // search for next threshold crossing begins at end of this pulse:
+                ii += NSA/nsPerSample-1; 
+
+                // firmware limit on # of peaks:
+                if (thresholdCrossings.size() >= nPeak) break;
+            }
+        }
+
+        // make hits
+        ArrayList <CalorimeterHit> newHits=new ArrayList<CalorimeterHit>();
+        for (int thresholdCrossing : thresholdCrossings) {
+           
+            // do pulse integral:
+            final double[] data = convertWaveformToPulse(hit,thresholdCrossing,mode7);
+            double time = data[0];
+            double sum = data[1];
+            final double min = data[2]; // TODO: stick min and max in a GenericObject with an 
+            final double max = data[3]; // LCRelation to finish mode-7 emulation
+            
+            // do pedestal subtraction:
+            sum -= getPulsePedestal(event,cellID,samples.length,thresholdCrossing);
+          
+            // do gain scaling:
+            double energy = adcToEnergy(sum, cellID);
+            
+            // do time-walk correction, mode-3 only:
+            if (!mode7 && useTimeWalkCorrection) {
+                time = EcalTimeWalk.correctTimeWalk(time,energy);
+            }
+            
+            newHits.add(CalorimeterHitUtilities.create(energy,time,cellID));
+        }
+        
+        return newHits;
+    }
+
+    /*
+     * This HitDtoA is for Mode-3 data.  A time-walk correction can be applied.
+     */
+    public CalorimeterHit HitDtoA(EventHeader event,RawCalorimeterHit hit, double timeOffset) {
         if (hit.getTimeStamp() % 64 != 0) {
             System.out.println("unexpected timestamp " + hit.getTimeStamp());
         }
         double time = hit.getTimeStamp() / 16.0;
         long id = hit.getCellID();
-        EcalChannelConstants channelData = findChannel(id);
-        int window = (NSA+NSB)/nsPerSample;
-        double adcSum = hit.getAmplitude() - window * channelData.getCalibration().getPedestal();
+        double pedestal = getPulsePedestal(event,id,windowSamples,(int)time/nsPerSample);
+        double adcSum = hit.getAmplitude() - pedestal;
         double rawEnergy = adcToEnergy(adcSum, id);
         if (useTimeWalkCorrection) {
            time = EcalTimeWalk.correctTimeWalk(time,rawEnergy);
@@ -240,15 +401,12 @@
 
     /*
      * This HitDtoA is exclusively for Mode-7 data, hence the GenericObject parameter.
-     * The decision to call this method is made in EcalRawConverterDriver based on the
-     * format of the input EVIO data.  EventHeader is also passed in order to allow access
-     * to running pedestals, which is only applicable to Mode-7 data.  (NAB, 2015/02/11)
      */
     public CalorimeterHit HitDtoA(EventHeader event,RawCalorimeterHit hit, GenericObject mode7Data, double timeOffset) {
         double time = hit.getTimeStamp() / 16.0; //timestamps use the full 62.5 ps resolution
         long id = hit.getCellID();
-        int window = (NSA+NSB)/nsPerSample;
-        double adcSum = hit.getAmplitude() - window * getMode7Pedestal(event,hit);
+        double pedestal = getPulsePedestal(event,id,windowSamples,(int)time/nsPerSample);
+        double adcSum = hit.getAmplitude() - pedestal;
         double rawEnergy = adcToEnergy(adcSum, id);        
         return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id);
     }
@@ -263,11 +421,11 @@
         // Get the channel data.
         EcalChannelConstants channelData = findChannel(id);
         int amplitude;
-        int window = (NSA+NSB)/nsPerSample;
+        double pedestal = getPulsePedestal(null,id,windowSamples,(int)hit.getTime()/nsPerSample);
         if (constantGain) {
-            amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + window * channelData.getCalibration().getPedestal());
+            amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + pedestal);
         } else {
-            amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / channelData.getGain().getGain() + window * channelData.getCalibration().getPedestal());
+            amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / channelData.getGain().getGain() + pedestal);
         }
         RawCalorimeterHit h = new BaseRawCalorimeterHit(id, amplitude, time);
         return h;
@@ -314,5 +472,6 @@
      */
     public EcalChannelConstants findChannel(long cellID) {
         return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
-    }    
+    }
+    
 }

Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java
 =============================================================================
--- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java	(original)
+++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java	Sat Mar  7 16:10:48 2015
@@ -20,15 +20,18 @@
  *
  * @version $Id: HPSEcalRawConverterDriver.java,v 1.2 2012/05/03 00:17:54
  * phansson Exp $
- *
- * baltzell: Feb 26, 2015:
- * added firmware emulation for converting from Mode-1 readout (RawTrackerHit)
+ * baltzell
+ * 
+ * 
+ * baltzell New in 2015:  (default behavior is unchanged)
+ * Added firmware emulation for converting from Mode-1 readout (RawTrackerHit)
  * to Mode-3 pulse (CalorimeterHit).  Turn it on with "emulateFirmware", else
- * defaults to previous behavior.  Removed integralWindow in favor of NSA and
- * NSB in EcalRawConverter, so that all conversions can use the same window.
- * March 3, 2015:  Removed integralWindow in favor of NSA/NSB in order to treat
- * all modes uniformly.
+ * defaults to previous behavior.  
+ *  
+ * Removed integralWindow in favor of NSA/NSB to allow treating all Modes uniformly.
+ * (New) NSA+NSB == (Old) integralWindow*4(ns) 
  * 
+ * Implemented finding multiple peaks for Mode-1.
  */
 public class EcalRawConverterDriver extends Driver {
 
@@ -41,7 +44,6 @@
     private String ecalCollectionName = "EcalCalHits";
 
     private static final String extraDataRelationsName = "EcalReadoutExtraDataRelations";
-//    private static final String extraDataCollectionName = "EcalReadoutExtraData";
 
     private boolean debug = false;
     private double threshold = Double.NEGATIVE_INFINITY;
@@ -80,17 +82,26 @@
         this.threshold = threshold;
     }
 
+    public void setEmulateMode7(boolean mode7) {
+        converter.setMode7(mode7);
+    }
     public void setEmulateFirmware(boolean emulateFirmware) {
         this.emulateFirmware = emulateFirmware;
     }
     public void setLeadingEdgeThreshold(double threshold) {
         converter.setLeadingEdgeThreshold(threshold);
     }
+    public void setWindowSamples(int windowSamples) {
+        converter.setWindowSamples(windowSamples);
+    }
     public void setNsa(int nsa) {
         converter.setNSA(nsa);
     }
     public void setNsb(int nsb) {
         converter.setNSB(nsb);
+    }
+    public void setNPeak(int nPeak) {
+        converter.setNPeak(nPeak);
     }
     
     public void setGain(double gain) {
@@ -196,37 +207,48 @@
         if (!runBackwards) {
             ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>();
 
-            // Get the list of ECal hits.
+            /*
+             * This is for FADC Mode-1 data:    
+             */
             if (event.hasCollection(RawTrackerHit.class, rawCollectionName)) {
                 List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName);
 
                 for (RawTrackerHit hit : hits) {
-                    
-                    CalorimeterHit newHit = null;
+           
+                    ArrayList<CalorimeterHit> newHits2 = new ArrayList<CalorimeterHit>();
                     if (emulateFirmware) {
-                        newHit = converter.firmwareHitDtoA(hit);
-                        if (newHit==null) continue;
+                        newHits2.addAll(converter.HitDtoA(event,hit));
                     } else {
-                        newHit = converter.HitDtoA(hit);
-                    }
-                
-
-                    // Get the channel data.
-                    EcalChannelConstants channelData = findChannel(newHit.getCellID());
-
-                    if (applyBadCrystalMap && channelData.isBadChannel()) {
-                        continue;
-                    }
-                    if (dropBadFADC && isBadFADC(newHit)) {
-                        continue;
-                    }
-                    if (newHit.getRawEnergy() > threshold) {
-                        newHits.add(newHit);
+                        newHits2.add(converter.HitDtoA(hit));
+                    }
+               
+                    for (CalorimeterHit newHit : newHits2) {
+
+                        // Get the channel data.
+                        EcalChannelConstants channelData = findChannel(newHit.getCellID());
+
+                        if (applyBadCrystalMap && channelData.isBadChannel()) {
+                            continue;
+                        }
+                        if (dropBadFADC && isBadFADC(newHit)) {
+                            continue;
+                        }
+                        if (newHit.getRawEnergy() > threshold) {
+                            newHits.add(newHit);
+                        }
                     }
                 }
                 event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
             }
-            if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { //A.C. this is the case of the RAW pulse hits
+           
+            /*
+             * This is for FADC pulse mode data (Mode-3 or Mode-7):
+             */
+            if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { 
+
+                /*
+                 * This is for FADC Mode-7 data:
+                 */
                 if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from mode 7 readout
                     List<LCRelation> extraDataRelations = event.get(LCRelation.class, extraDataRelationsName);
                     for (LCRelation rel : extraDataRelations) {
@@ -252,13 +274,16 @@
 
                     }
                 } else {
+                    /*
+                     * This is for FADC Mode-3 data:
+                     */
                     List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, rawCollectionName);
                     for (RawCalorimeterHit hit : hits) {
                         if (debug) {
                             System.out.format("old hit energy %d\n", hit.getAmplitude());
                         }
                         CalorimeterHit newHit;
-                        newHit = converter.HitDtoA(hit, timeOffset);
+                        newHit = converter.HitDtoA(event, hit, timeOffset);
                         if (newHit.getRawEnergy() > threshold) {
                             if (applyBadCrystalMap && isBadCrystal(newHit)) {
                                 continue;
@@ -295,6 +320,7 @@
                 event.put(rawCollectionName, newHits, RawCalorimeterHit.class, flags, ecalReadoutName);
             }
         }
+        
     }
 
     /**

Modified: java/branches/prod/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java
 =============================================================================
--- java/branches/prod/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java	(original)
+++ java/branches/prod/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java	Sat Mar  7 16:10:48 2015
@@ -494,6 +494,7 @@
     public void tearDown() {
         try {
             AIDA.defaultInstance().saveAs(testOutputDir.getPath() + File.separator + this.getClass().getSimpleName() + ".aida");
+            //AIDA.defaultInstance().saveAs(testOutputDir.getPath() + File.separator + this.getClass().getSimpleName() + ".root");
         } catch (IOException e) {
             throw new RuntimeException(e);
         }

Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java
 =============================================================================
--- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java	(original)
+++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java	Sat Mar  7 16:10:48 2015
@@ -11,7 +11,6 @@
 import javax.swing.JComboBox;
 
 import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem;
-import org.hps.monitoring.application.model.ConfigurationListener;
 import org.hps.monitoring.application.model.ConfigurationModel;
 import org.hps.monitoring.application.model.ConnectionStatus;
 import org.hps.monitoring.application.model.ConnectionStatusModel;
@@ -28,7 +27,7 @@
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
-class DataSourceComboBox extends JComboBox<DataSourceItem> implements PropertyChangeListener, ActionListener, ConfigurationListener {
+class DataSourceComboBox extends JComboBox<DataSourceItem> implements PropertyChangeListener, ActionListener{
 
     ConnectionStatusModel connectionModel;
     ConfigurationModel configurationModel;
@@ -65,16 +64,9 @@
         setEditable(false);
         this.configurationModel = configurationModel;
         connectionModel.addPropertyChangeListener(this);                
-        configurationModel.addConfigurationListener(this);
+        configurationModel.addPropertyChangeListener(this);
     }
             
-    void setSelectedItem() {
-        DataSourceItem item = findItem(configurationModel.getDataSourcePath(), getDataSourceType(configurationModel.getDataSourcePath()));
-        if (item != null) {
-            setSelectedItem(item);
-        }
-    }
-
     boolean contains(DataSourceItem item) {
         return ((DefaultComboBoxModel<DataSourceItem>) getModel()).getIndexOf(item) != -1;
     }
@@ -91,12 +83,35 @@
                     setEnabled(false);
                 }
             } else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) {
-                String path = configurationModel.getDataSourcePath();
-                DataSourceType type = getDataSourceType(path);
-                addDataSourceItem(path, type);
-                setSelectedItem();
+                if (configurationModel.hasValidProperty(ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY)) {
+                    String path = configurationModel.getDataSourcePath();
+                    DataSourceType type = getDataSourceType(path);
+                    if (type.isFile()) {
+                        DataSourceItem item = findItem(path, type);
+                        if (item == null) {
+                            item = addDataSourceItem(path, type);
+                        }
+                        if (configurationModel.getDataSourceType().isFile()) {
+                            setSelectedItem(item);
+                        }
+                    }
+                }
             } else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY)) {
-                setSelectedItem();
+                if (configurationModel.getDataSourceType() == DataSourceType.ET_SERVER) {
+                    DataSourceItem item = findEtItem();
+                    if (item == null) {
+                        item = new DataSourceItem(configurationModel.getEtPath(), DataSourceType.ET_SERVER);
+                    }
+                    setSelectedItem(item);
+                } else {
+                    if (configurationModel.hasValidProperty(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) {
+                        DataSourceItem item = findItem(configurationModel.getDataSourcePath(), configurationModel.getDataSourceType());
+                        if (item == null) {
+                            item = addDataSourceItem(configurationModel.getDataSourcePath(), configurationModel.getDataSourceType());
+                        }
+                        setSelectedItem(item);
+                    }
+                }
             } else if (evt.getPropertyName().equals(ConfigurationModel.HOST_PROPERTY)) {
                 updateEtItem();
             } else if (evt.getPropertyName().equals(ConfigurationModel.ET_NAME_PROPERTY)) {
@@ -125,46 +140,18 @@
                 // Update the model with data source settings.
                 configurationModel.removePropertyChangeListener(this);
                 DataSourceItem item = (DataSourceItem) getSelectedItem();
-                configurationModel.setDataSourceType(item.type);
-                if (item.type != DataSourceType.ET_SERVER) {
-                    configurationModel.setDataSourcePath(item.name);
+                if (item != null) {
+                    configurationModel.setDataSourceType(item.type);
+                    if (item.type != DataSourceType.ET_SERVER) {
+                        configurationModel.setDataSourcePath(item.name);
+                    }
                 }
             } finally {
                 configurationModel.addPropertyChangeListener(this);
             }
         } 
     }
-    
-    public void configurationChanged(ConfigurationModel configurationModel) {
-               
-        // Clear the data source list.
-        removeAllItems();
-        
-        // Add the default ET item.
-        this.removeActionListener(this);
-        try {
-            addItem(new DataSourceItem(configurationModel.getEtPath(), DataSourceType.ET_SERVER));
-                
-            // Add a file source if one has been provided.
-            if (configurationModel.getDataSourcePath() != null) {
-                // Add an item for this data source.
-                DataSourceItem newItem = new DataSourceItem(configurationModel.getDataSourcePath(), configurationModel.getDataSourceType());
-                //System.out.println("adding new item " + newItem.name + " " + newItem.type);
-                addItem(newItem);            
-                if (configurationModel.getDataSourceType().isFile()) {
-                    //System.out.println("setting selected");
-                    setSelectedItem(newItem);
-                }
-            }
-        } finally {
-            this.addActionListener(this);    
-        }
-        
-        // Don't add as property change listener until after configuration has been initialized.
-        configurationModel.removePropertyChangeListener(this);
-        configurationModel.addPropertyChangeListener(this);
-    }
-
+       
     public void addItem(DataSourceItem item) {
         // Do not add invalid looking items.
         if (item.name == null || item.name.length() == 0) { 
@@ -196,15 +183,19 @@
         return null;
     }
 
-    void addDataSourceItem(String path, DataSourceType type) {
+    DataSourceItem addDataSourceItem(String path, DataSourceType type) {
         DataSourceItem newItem = new DataSourceItem(path, type);
-        if (!contains(newItem)) {
-            addItem(newItem);
-        }
+        addItem(newItem);
+        return newItem;
     }
     
     void updateEtItem() {
         DataSourceItem item = findEtItem();
-        item.name = configurationModel.getEtPath();
+        if (item == null) {
+            item = new DataSourceItem(configurationModel.getEtPath(), DataSourceType.ET_SERVER);
+            addItem(item);
+        } else {
+            item.name = configurationModel.getEtPath();
+        }
     }
 }

Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
 =============================================================================
--- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	(original)
+++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	Sat Mar  7 16:10:48 2015
@@ -280,6 +280,10 @@
      * @param configuration The new configuration.
      */
     void loadConfiguration(Configuration configuration) {
+        
+        // HACK: Clear data source combo box for new config.
+        frame.dataSourceComboBox.removeAllItems();
+        
         // Set the Configuration on the ConfigurationModel which will trigger all the PropertyChangelListeners.
         configurationModel.setConfiguration(configuration);
         if (configuration.getFile() != null)

Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
 =============================================================================
--- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java	(original)
+++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java	Sat Mar  7 16:10:48 2015
@@ -120,6 +120,7 @@
         
         // Vertical split pane in left panel.
         leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, runPanel, tableTabbedPane);
+        leftSplitPane.setResizeWeight(0.5);
         leftPanel.add(leftSplitPane, BorderLayout.CENTER);
                                 
         // Create the right panel.

Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/Configuration.java
 =============================================================================
--- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/Configuration.java	(original)
+++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/Configuration.java	Sat Mar  7 16:10:48 2015
@@ -75,7 +75,11 @@
      * @return True if configuration has value for the key.
      */
     boolean hasKey(String key) {
-        return properties.getProperty(key) != null;
+        try {
+            return properties.containsKey(key);
+        } catch (java.lang.NullPointerException e) {
+            return false;
+        }
     }
 
     /**
@@ -164,7 +168,7 @@
      * @param key The properties key.
      * @return True if properties key is valid.
      */
-    private boolean checkKey(String key) {
+    boolean checkKey(String key) {
         return hasKey(key) && properties.getProperty(key) != null;
     }
 

Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java
 =============================================================================
--- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java	(original)
+++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java	Sat Mar  7 16:10:48 2015
@@ -1,8 +1,6 @@
 package org.hps.monitoring.application.model;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.logging.Level;
 
 import org.hps.record.enums.DataSourceType;
@@ -16,8 +14,6 @@
 public final class ConfigurationModel extends AbstractModel {
 
     Configuration configuration;    
-    
-    List<ConfigurationListener> listeners = new ArrayList<ConfigurationListener>();
     
     // Job setting properties.
     public static final String DETECTOR_NAME_PROPERTY = "DetectorName";
@@ -69,22 +65,11 @@
         fireModelChanged();
     }
     
-    public void addConfigurationListener(ConfigurationListener listener) {
-        listeners.add(listener);
-    }
-
     public void setConfiguration(Configuration configuration) {
         this.configuration = configuration;
         fireModelChanged();
-        fireConfigurationChanged();
-    }
-    
-    void fireConfigurationChanged() {        
-        for (ConfigurationListener listener : listeners) {
-            listener.configurationChanged(this);
-        }
-    }
-    
+    }
+     
     public Configuration getConfiguration() {
         return this.configuration;
     }
@@ -423,7 +408,7 @@
     }
 
     public boolean hasValidProperty(String key) {
-        return configuration.hasKey(key) && configuration.get(key) != null;
+        return configuration.checkKey(key);
     }
 
     @Override

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim	Sat Mar  7 16:10:48 2015
@@ -6,7 +6,6 @@
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver"/>
-        <driver name="SvtSensorSetup" />
         <driver name="StarterAnalysisDriver"/>   
         <driver name="AidaSaveDriver"/>
     </execute> 
@@ -14,7 +13,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver> 
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="StarterAnalysisDriver" type="org.hps.analysis.examples.StarterAnalysisDriver">
         </driver>
         <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim	Sat Mar  7 16:10:48 2015
@@ -14,7 +14,7 @@
         <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">
             <applyBadCrystalMap>false</applyBadCrystalMap>
         </driver>
-        <driver name="EcalEventDisplay" type="org.hps.monitoring.ecal.plots.EcalEventDisplay">
+        <driver name="EcalEventDisplay" type="org.hps.monitoring.ecal.plots.EcalEventDisplayWithRawWaveform">
             <inputCollection>EcalCalHits</inputCollection>
             <inputCollectionRaw>EcalReadoutHits</inputCollectionRaw>
             <inputClusterCollection>EcalClusters</inputClusterCollection>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim	Sat Mar  7 16:10:48 2015
@@ -32,8 +32,8 @@
             <useTimeWalkCorrection>false</useTimeWalkCorrection>
             <emulateFirmware>true</emulateFirmware>
             <leadingEdgeThreshold>12</leadingEdgeThreshold>
-            <nsa>20</nsa>
-            <nsb>100</nsb>
+            <nsa>100</nsa>
+            <nsb>20</nsb>
         </driver>
         <driver name="GTPTestDriver" type="org.hps.recon.ecal.cluster.GTPOnlineClusterDriver">
             <inputHitCollectionName>EcalCalHits</inputHitCollectionName>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim	Sat Mar  7 16:10:48 2015
@@ -10,7 +10,6 @@
     </control>    
     <execute>
         <driver name="EventMarkerDriver"/>
-        <driver name="SvtSensorSetup" />
         <driver name="EcalEdepToTriggerConverterDriver"/>
         <driver name="EcalReadoutConverterDriver"/>
         <driver name="EcalTriggerClusterer"/>
@@ -23,7 +22,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="EcalEdepToTriggerConverterDriver" type="org.hps.recon.ecal.EcalEdepToTriggerConverterDriver">
             <readoutCollection>EcalReadoutAnalogHits</readoutCollection>
             <applyBadCrystalMap>false</applyBadCrystalMap>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim	Sat Mar  7 16:10:48 2015
@@ -10,7 +10,6 @@
     </control>    
     <execute>
         <driver name="EventMarkerDriver"/>   
-        <driver name="SvtSensorSetup" />
         <driver name="EcalReadout"/>
         <driver name="EcalConverter"/>
         <driver name="EcalClusterer"/>
@@ -24,7 +23,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver> 
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="TestRunReconToEvio" type="org.hps.evio.TestRunTriggeredReconToEvio">
             <evioOutputFile>${outputFile}.evio</evioOutputFile>
         </driver>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToLcio.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToLcio.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToLcio.lcsim	Sat Mar  7 16:10:48 2015
@@ -9,7 +9,6 @@
     </control>
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="EcalReadout" />
         <driver name="EcalConverter" />
         <driver name="EcalClusterer" />
@@ -24,7 +23,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
             <outputFile>${outputFile}.slcio</outputFile>
         </driver>
@@ -64,4 +62,4 @@
             <collectionNames>TrackerHits</collectionNames>
         </driver>
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim	Sat Mar  7 16:10:48 2015
@@ -11,7 +11,6 @@
     </control>    
     <execute>
         <driver name="EventMarkerDriver"/>   
-        <driver name="SvtSensorSetup" />
         <driver name="EcalReadout"/>
         <driver name="EcalConverter"/>
         <driver name="EcalClusterer"/>
@@ -26,7 +25,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver> 
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
             <outputFile>${outputFile}.slcio</outputFile>
             <rejectBackground>true</rejectBackground>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPSTrackingDefaults.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPSTrackingDefaults.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/HPSTrackingDefaults.lcsim	Sat Mar  7 16:10:48 2015
@@ -7,7 +7,6 @@
     </control>
     <execute>
         <driver name="EventMarkerDriver"/>   
-        <driver name="SvtSensorSetup" />
         <driver name="TrackerDigiDriver"/>
         <driver name="HelicalTrackHitDriver"/>
         <driver name="TrackerReconDriver"/>
@@ -17,7 +16,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="TrackerDigiDriver" type="org.hps.recon.tracking.SimpleTrackerDigiDriver">
 <!--            <dropBadChannels>true</dropBadChannels>-->
             <debug>false</debug>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim	Sat Mar  7 16:10:48 2015
@@ -5,7 +5,6 @@
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="RawTrackerHitSensorSetup"/>   
-        <driver name="SvtSensorSetup" />
         <driver name="DummyTrigger"/>
         <driver name="TestRunReconToEvio"/>
         <driver name="ClockDriver"/>
@@ -13,7 +12,6 @@
 
     <drivers>
         <driver name="RawTrackerHitSensorSetup" type="org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup"/>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="DummyTrigger" type="org.hps.readout.ecal.DummyTriggerDriver">
             <period>1</period>
             <deadTime>0</deadTime>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim	Sat Mar  7 16:10:48 2015
@@ -6,7 +6,6 @@
     </control>    
     <execute>
         <driver name="EventMarkerDriver"/>   
-        <driver name="SvtSensorSetup" />
         <driver name="EcalRawConverter"/>
         <driver name="EcalRawConverterDriver"/>
         <driver name="EcalTriggerFilter"/>
@@ -20,7 +19,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalEdepToTriggerConverterDriver">
             <readoutCollection>EcalReadoutAnalogHits</readoutCollection>
         </driver>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim	Sat Mar  7 16:10:48 2015
@@ -5,7 +5,6 @@
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver"/>   
-        <driver name="SvtSensorSetup" />
         <driver name="BadChannelFilter" />
         <driver name="EcalReadout"/>
         <driver name="EcalConverter"/>
@@ -21,7 +20,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver> 
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="BadChannelFilter" type="org.hps.recon.tracking.SVTBadChannelFilterDriver" /> 		
         <driver name="EcalReadout" type="org.hps.readout.ecal.FADCEcalReadoutDriver">
             <coincidenceWindow>8</coincidenceWindow>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio.lcsim	Sat Mar  7 16:10:48 2015
@@ -4,7 +4,6 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="BadChannelFilter" />
         <driver name="EcalReadout" />
         <driver name="EcalConverter" />
@@ -20,7 +19,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="BadChannelFilter" type="org.hps.recon.tracking.SVTBadChannelFilterDriver" />
         <driver name="EcalReadout" type="org.hps.readout.ecal.FADCEcalReadoutDriver">
             <coincidenceWindow>8</coincidenceWindow>
@@ -67,4 +65,4 @@
             <collectionNames>TrackerHits</collectionNames>
         </driver>
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio2014.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio2014.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToLcio2014.lcsim	Sat Mar  7 16:10:48 2015
@@ -7,7 +7,6 @@
         <driver name="ConditionsDriver"/>   
 -->
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="BadChannelFilter" />
         <driver name="EcalReadout" />
         <driver name="EcalConverter" />
@@ -30,7 +29,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="BadChannelFilter" type="org.hps.recon.tracking.SVTBadChannelFilterDriver" />
         <driver name="EcalReadout" type="org.hps.readout.ecal.FADCEcalReadoutDriver">
             <coincidenceWindow>8</coincidenceWindow>
@@ -77,4 +75,4 @@
             <collectionNames>TrackerHits</collectionNames>
         </driver>
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/GBLReco.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/GBLReco.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/GBLReco.lcsim	Sat Mar  7 16:10:48 2015
@@ -6,7 +6,6 @@
     </control>
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup" />
         <driver name="BadChannelFilter" />
         <driver name="RawTrackerHitFitterDriver" />
@@ -28,7 +27,6 @@
             <gblFileName>gblinput.txt</gblFileName>
         </driver>
         <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver" />
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         
         <!-- Reconstruction drivers below -->
         <driver name="RawTrackerHitSensorSetup" type="org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup" />
@@ -62,4 +60,4 @@
         </driver>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineNoPileupRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineNoPileupRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineNoPileupRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -7,7 +7,6 @@
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver"/>       
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup"/>
         <driver name="RawTrackerHitFitterDriver" />
         <driver name="TrackerHitDriver"/>
@@ -25,7 +24,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>        
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup" type="org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup"/>
         <driver name="RawTrackerHitFitterDriver" type="org.hps.recon.tracking.RawTrackerHitFitterDriver">
             <fitAlgorithm>Analytic</fitAlgorithm>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -6,7 +6,6 @@
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver"/>
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup"/>
         <driver name="RawTrackerHitFitterDriver" />
         <driver name="TrackerHitDriver"/>
@@ -21,7 +20,6 @@
         <driver name="CleanupDriver"/>
     </execute>    
     <drivers>    
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />   
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>        

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineTruthRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineTruthRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPS2014OfflineTruthRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -7,7 +7,6 @@
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver"/>
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup"/>
         <driver name="RawTrackerHitFitterDriver" />
         <driver name="TrackerHitDriver"/>
@@ -22,7 +21,6 @@
         <driver name="CleanupDriver"/>
     </execute>    
     <drivers>    
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>        

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPSTrackingDefaultsRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPSTrackingDefaultsRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/HPSTrackingDefaultsRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -6,7 +6,6 @@
     </control>
     <execute>
         <driver name="EventMarkerDriver"/>
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup"/>
         <driver name="SVTBadChannelFilterDriver"/>
         <driver name="RawTrackerHitFitterDriver" />
@@ -20,7 +19,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="SVTBadChannelFilterDriver" type="org.hps.recon.tracking.SVTBadChannelFilterDriver"/>
         <driver name="RawTrackerHitSensorSetup" type="org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup"/>
         <driver name="RawTrackerHitFitterDriver" type="org.hps.recon.tracking.RawTrackerHitFitterDriver">

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/SimpleMCRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/SimpleMCRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/SimpleMCRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -15,8 +15,6 @@
     <execute>
         <!-- Print out event numbers. -->
         <driver name="EventMarkerDriver"/>
-        <!-- Setup the SVT sensors. -->   
-        <driver name="SvtSensorSetup" />        
         <!-- Simple tracker hit digi. -->
         <driver name="TrackerDigiDriver"/>
         <!-- Create tracker hits. -->
@@ -36,7 +34,6 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>10</eventInterval>
         </driver>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="TrackerDigiDriver" type="org.hps.recon.tracking.SimpleTrackerDigiDriver">
             <debug>false</debug>
         </driver>
@@ -59,4 +56,4 @@
         </driver>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver"/>
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -5,7 +5,6 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup" />
         <driver name="BadChannelFilter" />
         <driver name="RawTrackerHitFitterDriver" />
@@ -20,7 +19,6 @@
         <driver name="CleanupDriver" />
     </execute>
     <drivers>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>100</eventInterval>
         </driver>
@@ -53,4 +51,4 @@
         </driver>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineReconTwoTrkFilter.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineReconTwoTrkFilter.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/recon/TestRunOfflineReconTwoTrkFilter.lcsim	Sat Mar  7 16:10:48 2015
@@ -1,7 +1,6 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup" />
         <driver name="RawTrackerHitFitterDriver" />
         <driver name="TrackerHitDriver" />
@@ -13,7 +12,6 @@
         <driver name="CleanupDriver" />
     </execute>
     <drivers>
-        <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver>
@@ -43,4 +41,4 @@
         </driver>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim	Sat Mar  7 16:10:48 2015
@@ -5,7 +5,6 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
       <driver name="TrackerDigiDriver"/>
 <!--  the 3 drivers below are for reading out 6-sample ADC data -->
 <!--        <driver name="RawTrackerHitSensorSetup" /> 
@@ -31,7 +30,6 @@
         <driver name="CleanupDriver" />
     </execute>
     <drivers>
-     <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />   
         <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver" />
          <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>10</eventInterval>
@@ -126,4 +124,4 @@
         </driver>  
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />       
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/MattsScrewAround.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/MattsScrewAround.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/MattsScrewAround.lcsim	Sat Mar  7 16:10:48 2015
@@ -5,7 +5,6 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EventMarkerDriver" />
-        <driver name="SvtSensorSetup" />
         <driver name="RawTrackerHitSensorSetup" />
         <driver name="RawTrackerHitFitterDriver" />
         <driver name="TrackerHitDriver" />
@@ -26,7 +25,6 @@
         <driver name="CleanupDriver" />
     </execute>
     <drivers>
-     <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />   
         <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver" />
          <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>10</eventInterval>
@@ -105,4 +103,4 @@
         </driver>  
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />       
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/NoTimeNoTriggerRecon.lcsim
 =============================================================================
--- java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/NoTimeNoTriggerRecon.lcsim	(original)
+++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/NoTimeNoTriggerRecon.lcsim	Sat Mar  7 16:10:48 2015
@@ -6,7 +6,6 @@
     </control>
     <execute>
         <driver name="EventMarkerDriver"/>
-        <driver name="SvtSensorSetup"/>
         <driver name="TrackerDigiDriver"/>
       <driver name="EcalEdepToTriggerConverterDriver"/>
         <driver name="EcalReadoutConverterDriver"/>
@@ -55,7 +54,6 @@
             <writeRejectedHitCollection>false</writeRejectedHitCollection>
         </driver>
 
-       <driver name="SvtSensorSetup" type="org.hps.recon.tracking.SvtSensorSetup" />
         <driver name="TrackerDigiDriver" type="org.hps.recon.tracking.SimpleTrackerDigiDriver">
             <!-- <dropBadChannels>true</dropBadChannels> -->
             <rawTrackerHitOutputCollectionName>SVTRawTrackerHits</rawTrackerHitOutputCollectionName>
@@ -129,4 +127,4 @@
        <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver"/>                                   
 
     </drivers>
-</lcsim>
+</lcsim>

Modified: java/branches/prod/users/src/main/java/org/hps/users/celentan/LedAnalysis.java
 =============================================================================
--- java/branches/prod/users/src/main/java/org/hps/users/celentan/LedAnalysis.java	(original)
+++ java/branches/prod/users/src/main/java/org/hps/users/celentan/LedAnalysis.java	Sat Mar  7 16:10:48 2015
@@ -3,6 +3,7 @@
 
 import hep.aida.ICloud1D;
 import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
 import hep.aida.IProfile1D;
 import hep.aida.ITuple;
 import hep.aida.IFunction;
@@ -10,11 +11,14 @@
 import hep.aida.IFitter;
 import hep.aida.IFitResult;
 import hep.aida.IFunctionFactory;
-
- 
-
-
-
+import hep.aida.IPlotterStyle;
+
+
+
+
+import javax.swing.JOptionPane; 
+
+import java.io.Console;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -48,443 +52,488 @@
  * @author Andrea Celentano  <[log in to unmask]>
  */
 public class LedAnalysis extends Driver{
-	
-	private static final int NUM_CHANNELS = 11 * 47;
-	
-	String inputCollectionRaw = "EcalReadoutHits";
-	String inputCollection = "EcalCalHits";	
-	AIDA aida;
-		
-	DatabaseConditionsManager conditionsManager;
-	
-	private EcalChannelCollection ChannelCollection;	
+
+    private static final int NUM_CHANNELS = 11 * 47;
+
+    String inputCollectionRaw = "EcalReadoutHits";
+    String inputCollection = "EcalCalHits";	
+    AIDA aida;
+
+    DatabaseConditionsManager conditionsManager;
+
+    private EcalChannelCollection ChannelCollection;	
     private EcalLedCollection LedCollection;
     private EcalConditions ecalConditions;
-    
+
     Map < Integer,Integer > LedTopMap;
     Map < Integer,Integer > LedBotMap;
-    
+
     private boolean useRawEnergy=false;
-    
+
     private static final String dbTag = "led";
     private static final String dbTableName = "ecal_led_calibrations";
     private static final int runNumberMax = 9999;
-	private static final int nDrivers = 8;
-	private static final int nSteps = 56;
-	
-	private int runNumber = 0;	
-	private int eventN    = 0;
+    private static final int nDrivers = 8;
+    private static final int nSteps = 56;
+
+    private int runNumber = 0;	
+    private int eventN    = 0;
     private int id,row,column,chid,ledid,driverid;
-	private  int[][] LEDStep = new int[][]{
-			//first 4 are the flasher1 sequence, TOP controller 
-			{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,434,44,45,46,47,48,49,50,51,52,53,54,55,56,-1},
-			{57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,-1},
-			{112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,136,137,138,130,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168}, //missing 135 is ok
-			{169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,-1},
-			//second 4 are the flasher2 sequence, BOTTOM controller 
-			{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,434,44,45,46,47,48,49,50,51,52,53,54,55,56,-1},	
-			{57,58,59,60,61,62,63,64,65,66,67,68,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113}, //missing 69 is OK
-			{114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,130,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,-1},	
-			{169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,-1},
-			};
-			
-	private int[] iStep = new int[nDrivers];
-	private int[] nEvents = new int[NUM_CHANNELS];
-	
-	private double energy,rawEnergy;
-	private long cellID;
-	//Histograms-functions-ntuples
-	private ArrayList<ITuple> iTuple;
-	private ArrayList<IProfile1D> cProfile;
-	private ArrayList<IFunction> fFunction;
-	private ArrayList<IFunction> fFunction1;
-	private ArrayList<IHistogram1D> hCharge;
+    private  int[][] LEDStep = new int[][]{
+            //first 4 are the flasher1 sequence, TOP controller 
+            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},
+            {56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111},
+            {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,-1}, //missing 135 is ok
+            {168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
+            //second 4 are the flasher2 sequence, BOTTOM controller 
+            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},	
+            {56,57,58,59,60,61,62,63,64,65,66,67,68,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,-1}, //missing 69 is OK
+            {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167},	
+            {168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
+    };
+
+    private int[] iStep = new int[nDrivers];
+    private int[] nEvents = new int[NUM_CHANNELS];
+
+    private double energy,fillEnergy,fillTime;
+    private long cellID;
+    //Histograms-functions-ntuples
+    private ArrayList<ITuple> iTuple;
+    private ArrayList<IProfile1D> cProfile;
+    private ArrayList<IFunction> fFunction;
+    private ArrayList<IFunction> fFunction1;
+    private ArrayList<IHistogram1D> hCharge;
+    private ArrayList<IHistogram2D> hChargeVsTime;
+    private ArrayList<IHistogram1D> hChargeALL;
+    private ArrayList<IHistogram2D> hChargeVsTimeALL;
+    IHistogram2D					hMeanCharge2D;
 
     public void setUseRawEnergy(boolean useRawEnergy) {
         this.useRawEnergy=useRawEnergy;
     }
-	
+
 
     private double skipInitial=0.1;
-	
-	@Override
-	protected void detectorChanged(Detector detector) {
-		System.out.println("LedAnalysis::Detector changed was called");
-
-		for (int ii=0;ii<nDrivers;ii++){
-			iStep[ii]=-1;
-		}
-		
-		// Setup conditions
-		
-		conditionsManager = DatabaseConditionsManager.getInstance();
-
-	    LedTopMap = new HashMap< Integer , Integer >(); //key: ecal channel ID. Value: 
-	    LedBotMap = new HashMap< Integer , Integer >();	
-		
+
+    @Override
+    protected void detectorChanged(Detector detector) {
+        System.out.println("LedAnalysis::Detector changed was called");
+
+        for (int ii=0;ii<nDrivers;ii++){
+            iStep[ii]=-1;
+        }
+
+        // Setup conditions
+
+        conditionsManager = DatabaseConditionsManager.getInstance();
+
+        LedTopMap = new HashMap< Integer , Integer >(); //key: ecal channel ID. Value: 
+        LedBotMap = new HashMap< Integer , Integer >();	
+
         ChannelCollection = conditionsManager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();	
-		LedCollection = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
-		ecalConditions = conditionsManager.getEcalConditions();		
-		
-		for (EcalChannel channel : ChannelCollection){
-			chid = channel.getChannelId();
-			for (EcalLed Led : LedCollection) {    	
-				if (Led.getEcalChannelId()==chid){
-					if (channel.getY()>0){
-						LedTopMap.put( chid , Led.getLedNumber() );
-					}
-					else if (channel.getY()<0){
-						LedBotMap.put( chid , Led.getLedNumber() );
-					}
-				}
-			}
-		}
-		
-		
-		// Setup plots
-		aida = AIDA.defaultInstance();
-		aida.tree().cd("/");
-		
-	  //  IPlotterFactory factory= aida.analysisFactory().createPlotterFactory("ECAL DAQ Plots");
-		iTuple = new ArrayList<ITuple>(NUM_CHANNELS);
-		cProfile= new ArrayList<IProfile1D>(NUM_CHANNELS);
-		fFunction= new ArrayList<IFunction>(NUM_CHANNELS);	
-		fFunction1= new ArrayList<IFunction>(NUM_CHANNELS);		
-		hCharge = new ArrayList<IHistogram1D>(NUM_CHANNELS);
-
-		
-		
-		
-		for (int ii=0;ii<NUM_CHANNELS;ii++){
-			int row = EcalMonitoringUtilities.getRowFromHistoID(ii);
-			int column = EcalMonitoringUtilities.getColumnFromHistoID(ii);	    
-	    	iTuple.add(aida.analysisFactory().createTupleFactory(aida.tree()).create("nTuple"+ii,"nTuple"+ii,"int fEvn=0 , double fCharge=0.",""));
-	    	
-		}
-		
-	}		
-	     
-	@Override
-	public void process(EventHeader event) {
-		runNumber = event.getRunNumber();
-		eventN++;
-		if (event.hasCollection(CalorimeterHit.class, inputCollection)) {
-			//List<BassRawCalorimeterHit> hits = event.get(BaseRawCalorimeterHit.class, inputCollectionRaw);
-			List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection);
-			for (CalorimeterHit hit : hits) {
-			
-				column = hit.getIdentifierFieldValue("ix");
-				row = hit.getIdentifierFieldValue("iy");
-				id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
-				cellID=hit.getCellID();
-				energy = hit.getCorrectedEnergy();
-				
-				if (useRawEnergy){
-					rawEnergy = getRawADCSum(energy,cellID);
-				}
-				else {
-					rawEnergy = energy;
-				}
-				
-				
-				//find the LED
-				chid = ChannelCollection.findGeometric(cellID).getChannelId();
-				if (row>0){
-					ledid=LedTopMap.get(chid);
-				}
-				else if (row<0){
-					ledid=LedBotMap.get(chid);
-				}
-				driverid=getDriver(ledid);
-				if (row<0) driverid+=4;
-				
-				/*First, check if this led is the one in the NEXT step. Therefore, increment by 1 the step*/
-				if (iStep[driverid]<(nSteps-1)){
-					if (ledid==LEDStep[driverid][iStep[driverid]+1]){
-						iStep[driverid]++;
-						System.out.println("LedAnalysis:: increment step for driver "+driverid+" "+ledid+" "+column+" "+row+" "+id);
-					}	
-				}
-				
-					
-				if (iStep[driverid]==-1) continue;
-				
-				/*Case 1: this led is the one in the corresponding step*/;
-				if (ledid==LEDStep[driverid][iStep[driverid]]){
-					//hRaw.get(id).fill(rawEnergy);
-					//cStrip.get(id).fill(nEvents[id],rawEnergy);
-					
-					iTuple.get(id).fill(0,nEvents[id]);
-					iTuple.get(id).fill(1,rawEnergy);
-					iTuple.get(id).addRow();
-					
-				
-					nEvents[id]++;
-				}
-				else{	/*Case 2: this led is not one in the corresponding step (but maybe is the neighborhood??Ctalk??)*/;
-					
-				}
-		
-				/*Add a debug print */
-				if (eventN % 10000==0){
-					System.out.println("Debug. LED ID: "+ledid+" DRIVER ID: "+driverid+" ECAL ID: "+id+" ROW: "+row+" COLUMN: "+column);
-				}
-		   }		
-	   }		
-	}
-	
-	/*
-	 * The endOfData() method analises each ntuple to find the LED response.
-	 * We cannot simply fit a gaussian to the energy distribution, since there is a high-energy tail due to the LED being turned on:
-	 * When the LED turns on, it is "cold", and emits more light. Immediately, it starts to heat, and due to temperature effects the
-	 * emitted light is less. This is clearly visible if one plots the charge VS the event number: the trend is decreasing, toward a
-	 * plateau, that corresponds to the value at thermal equilibrium.
-	 * 
-	 * For (few) channels, the first charge values are close to 0, then charge grows rapidly, then it returns back to the plateau.
-	 * To handle these, I always cut the first 10% events
-	 * To properly handle this:
-	 * 
-	 * 1) First create a profile histogram, charge VS event number.
-	 * 2) Fit it with something like "A*exp(-event_number/N0)+C. The function does not need to be extra-accurate at this stage
-	 * 3) Cut the events with event_number < 5*N0.
-	 * 4) Fit the remaining events with a gaussian.
-	 */
-	@Override
-	public void endOfData() {
-		System.out.println("LedAnalysis::end of data");
-		
-		
-		double e,eMin,eMax;
-		int n,nBins,nFits,nSkip;
-		
-		double[] fPars;	
-		double[] fParErrs;
-		String[] fParNames;	
-		IFunctionFactory fFactory=aida.analysisFactory().createFunctionFactory(aida.tree());
-		IPlotter pPlotter= aida.analysisFactory().createPlotterFactory().create();
-	    IFitResult fResult;
-		IFitter	   fFitter;
-	    
-		for (int id = 0; id < 11 * 47; id++) {
-	           
-			  eMin=9999;
-			  eMax=-9999;
-		      row = EcalMonitoringUtilities.getRowFromHistoID(id);
-              column = EcalMonitoringUtilities.getColumnFromHistoID(id);
-              
-			  /*Create the profile. Create it for all the channels, to keep sync.*/
-              nBins=nEvents[id]/100;
-              if (nBins<=0) nBins=1;
-              cProfile.add(aida.profile1D("strip_"+id,nBins,-0.5,nEvents[id]*(1-skipInitial)+0.5));
-
-			  /*Create the function for the profile fit and the gaus fit*/
-			  /* Create it for all the channels, to keep sync.*/
-			  fFunction.add(fFactory.createFunctionFromScript("fun0_"+id,1,"A*exp(-x[0]/tau)+B","A,tau,B","",null));
-			  fFunction1.add(fFactory.createFunctionByName("fun1_"+id,"G"));
-              
-			  if (EcalMonitoringUtilities.isInHole(row,column)==true){
-				  hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
-				  continue;
-			  }
-			  if (nEvents[id]==0) {
-				  hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
-				  //System.out.println("LedAnalysis: channel x= "+column+" y= "+row+" not found");
-				  continue;
-			  }			  
-			
-			  /*Fill the profile*/
-			  nSkip=(int)(nEvents[id]*skipInitial);
-			  iTuple.get(id).start();
-			  iTuple.get(id).skip(nSkip); /*This is the work-around for those channels with charge starting from 0 and rapidly growing*/
-			  n=0;
-			  iTuple.get(id).next(); e=iTuple.get(id).getDouble(1); eMax=e; n++; /*eMax is the first sample*/
-			  while ( iTuple.get(id).next() ){
-				  e=iTuple.get(id).getDouble(1);
-				  eMin=e;           			  /*eMin is the last sample*/
-				  cProfile.get(id).fill(1.*n,e);
-				  n++;
-			  }			
-			  
-
-			  /*Init function parameters*/
-			  double[] initialPars={eMax-eMin,nEvents[id]/10.,eMin};
-			  fFunction.get(id).setParameters(initialPars);
-			  
-			  /*Do the fit*/
-			  fFitter=aida.analysisFactory().createFitFactory().createFitter("chi2","","v");
-			  System.out.println("LedAnalysis:: do profile fit "+id+" "+fFitter.engineName()+" "+fFitter.fitMethodName());
-			  System.out.println("LedAnalysis:: initial parameters "+initialPars[0]+" "+initialPars[1]+" "+initialPars[2]);
-			  fResult=fFitter.fit(cProfile.get(id),fFunction.get(id));
-			  fPars     = fResult.fittedParameters();
-			  fParErrs  = fResult.errors();
-			  fParNames = fResult.fittedParameterNames();			
-			  System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-			  for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-				  System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-			  }  
-			  fFunction.get(id).setParameters(fPars);
-			
-			  
-			  /*Do again the fit: it is a terrible work-around*/
-			  nFits=0;
-			  while (Double.isNaN(fParErrs[1])){
-				  System.out.println("LedAnalysis:: redo fit");
-				  fFunction.get(id).setParameters(fPars);
-				  fResult=fFitter.fit(cProfile.get(id),fFunction.get(id));
-				  fPars     = fResult.fittedParameters();
-				  fParErrs  = fResult.errors();
-				  System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-				  for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-					  System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-				  }  
-				  fFunction.get(id).setParameters(fPars);
-				  nFits++;
-				  if (nFits>=10){
-					  System.out.println("LedAnalysis:: Error, too many fits without convergence");
-					  break;
-				  }
-			  }
-			  
-			  System.out.println("LedAnalysis:: fit "+id+" done");  
-			  /*plot*/
-			  pPlotter.region(0).clear();
-			  pPlotter.region(0).plot(cProfile.get(id));
-			  pPlotter.region(0).plot(fFunction.get(id));
-			//  plotter.show();
-			  
-			  /*Now we have the tau parameter. Take ONLY the events that are with N>5*tau/
+        LedCollection = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
+        ecalConditions = conditionsManager.getEcalConditions();		
+
+        for (EcalChannel channel : ChannelCollection){
+            chid = channel.getChannelId();
+            for (EcalLed Led : LedCollection) {    	
+                if (Led.getEcalChannelId()==chid){
+                    if (channel.getY()>0){
+                        LedTopMap.put( chid , Led.getLedNumber() );
+                    }
+                    else if (channel.getY()<0){
+                        LedBotMap.put( chid , Led.getLedNumber() );
+                    }
+                }
+            }
+        }
+
+
+        // Setup plots
+        aida = AIDA.defaultInstance();
+        aida.tree().cd("/");
+
+        //  IPlotterFactory factory= aida.analysisFactory().createPlotterFactory("ECAL DAQ Plots");
+        iTuple = new ArrayList<ITuple>(NUM_CHANNELS);
+        cProfile= new ArrayList<IProfile1D>(NUM_CHANNELS);
+        fFunction= new ArrayList<IFunction>(NUM_CHANNELS);	
+        fFunction1= new ArrayList<IFunction>(NUM_CHANNELS);		
+        hCharge = new ArrayList<IHistogram1D>(NUM_CHANNELS);
+       // hChargeVsTime = new ArrayList<IHistogram2D>(NUM_CHANNELS);
+        hChargeALL = new ArrayList<IHistogram1D>(NUM_CHANNELS);
+        hChargeVsTimeALL = new ArrayList<IHistogram2D>(NUM_CHANNELS);
+        hMeanCharge2D = aida.histogram2D("Average LED response", 47, -23.5, 23.5, 11, -5.5, 5.5);
+
+        for (int ii=0;ii<NUM_CHANNELS;ii++){
+            int row = EcalMonitoringUtilities.getRowFromHistoID(ii);
+            int column = EcalMonitoringUtilities.getColumnFromHistoID(ii);	    
+            iTuple.add(aida.analysisFactory().createTupleFactory(aida.tree()).create("nTuple"+ii,"nTuple"+ii,"int fEvn=0 , double fCharge=0.,double fTime=0.",""));
+      
+            hChargeALL.add(aida.histogram1D("ChargeAllEvents_"+ii,400,0.,100.));
+            hChargeVsTimeALL.add(aida.histogram2D("ChargeVsTimeAllEvents_"+ii,100,0.,400.,100,0.,100.));
+        }
+
+    }		
+
+    @Override
+    public void process(EventHeader event) {
+        runNumber = event.getRunNumber();
+        eventN++;
+        if (event.hasCollection(CalorimeterHit.class, inputCollection)) {
+            //List<BassRawCalorimeterHit> hits = event.get(BaseRawCalorimeterHit.class, inputCollectionRaw);
+            List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection);
+            for (CalorimeterHit hit : hits) {
+
+                column = hit.getIdentifierFieldValue("ix");
+                row = hit.getIdentifierFieldValue("iy");
+                id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
+                cellID=hit.getCellID();
+                energy = hit.getCorrectedEnergy();
+
+                if (useRawEnergy){
+                    fillEnergy = getRawADCSum(energy,cellID);
+                }
+                else {
+                    fillEnergy = energy;
+                }
+                fillTime = hit.getTime();
+
+                //fill "all" histograms
+                hChargeALL.get(id).fill(fillEnergy);
+                hChargeVsTimeALL.get(id).fill(fillTime,fillEnergy);
+                
+                //find the LED
+                chid = ChannelCollection.findGeometric(cellID).getChannelId();
+                if (row>0){
+                    ledid=LedTopMap.get(chid);
+                }
+                else if (row<0){
+                    ledid=LedBotMap.get(chid);
+                }
+                driverid=getDriver(ledid);
+                if (row<0) driverid+=4;
+
+                /*First, check if this led is the one in the NEXT step. Therefore, increment by 1 the step*/
+                if (iStep[driverid]<(nSteps-1)){
+                    if (ledid==LEDStep[driverid][iStep[driverid]+1]){
+                        iStep[driverid]++;
+                        System.out.println("LedAnalysis:: increment step ("+iStep[driverid]+") for driver "+driverid+" . Led ID: "+ledid+" Column: "+column+" Row: "+row);
+                    }	
+                }
+
+
+                if (iStep[driverid]==-1) continue;
+
+                /*Case 1: this led is the one in the corresponding step*/;
+                if (ledid==LEDStep[driverid][iStep[driverid]]){
+                    //hRaw.get(id).fill(rawEnergy);
+                    //cStrip.get(id).fill(nEvents[id],rawEnergy);
+
+                    iTuple.get(id).fill(0,nEvents[id]);
+                    iTuple.get(id).fill(1,fillEnergy);
+                    iTuple.get(id).fill(2,fillTime);
+                    iTuple.get(id).addRow();
+
+
+                    nEvents[id]++;
+                }
+                else{	/*Case 2: this led is not one in the corresponding step (but maybe is the neighborhood??Ctalk??)*/;
+
+                }
+
+                /*Add a debug print */
+                if (eventN % 10000==0){
+                    System.out.println("Debug. LED ID: "+ledid+" DRIVER ID: "+driverid+" ECAL ID: "+id+" ROW: "+row+" COLUMN: "+column);
+                }
+            }
+            if (eventN % 10000==0){
+                System.out.println("\n");
+            }
+        }		
+    }
+
+    /*
+     * The endOfData() method analises each ntuple to find the LED response.
+     * We cannot simply fit a gaussian to the energy distribution, since there is a high-energy tail due to the LED being turned on:
+     * When the LED turns on, it is "cold", and emits more light. Immediately, it starts to heat, and due to temperature effects the
+     * emitted light is less. This is clearly visible if one plots the charge VS the event number: the trend is decreasing, toward a
+     * plateau, that corresponds to the value at thermal equilibrium.
+     * 
+     * For (few) channels, the first charge values are close to 0, then charge grows rapidly, then it returns back to the plateau.
+     * To handle these, I always cut the first 10% events
+     * To properly handle this:
+     * 
+     * 1) First create a profile histogram, charge VS event number.
+     * 2) Fit it with something like "A*exp(-event_number/N0)+C. The function does not need to be extra-accurate at this stage
+     * 3) Cut the events with event_number < 5*N0.
+     * 4) Fit the remaining events with a gaussian.
+     */
+    @Override
+    public void endOfData() {
+        System.out.println("LedAnalysis::end of data");
+
+
+        double e,eMin,eMax;
+        double t;
+        int n,nBins,nFits,nSkip;
+
+        double[] fPars;	
+        double[] fParErrs;
+        String[] fParNames;	
+        IFunctionFactory fFactory=aida.analysisFactory().createFunctionFactory(aida.tree());
+        IPlotter pPlotter= aida.analysisFactory().createPlotterFactory().create();
+        IFitResult fResult;
+        IFitter	   fFitter;
+
+        for (int id = 0; id < 11 * 47; id++) {
+
+            eMin=9999;
+            eMax=-9999;
+            row = EcalMonitoringUtilities.getRowFromHistoID(id);
+            column = EcalMonitoringUtilities.getColumnFromHistoID(id);
+
+            /*Create the profile. Create it for all the channels, to keep sync.*/
+            nBins=nEvents[id]/100;
+            if (nBins<=0) nBins=1;
+            cProfile.add(aida.profile1D("strip_"+id,nBins,-0.5,nEvents[id]*(1-skipInitial)+0.5));
+
+            /*Create the function for the profile fit and the gaus fit*/
+            /* Create it for all the channels, to keep sync.*/
+            fFunction.add(fFactory.createFunctionFromScript("fun0_"+id,1,"A*exp(-x[0]/tau)+B","A,tau,B","",null));
+            fFunction1.add(fFactory.createFunctionByName("fun1_"+id,"G"));
+
+            if (EcalMonitoringUtilities.isInHole(row,column)==true){
+                hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
+             //   hChargeVsTime.add(aida.histogram2D("chargeVsTime_"+id,200,0.,400.,200,0.,1.));
+                continue;
+            }
+            if (nEvents[id]==0) {
+                hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
+              //  hChargeVsTime.add(aida.histogram2D("chargeVsTime_"+id,200,0.,400.,200,0.,1.));            
+                //System.out.println("LedAnalysis: channel x= "+column+" y= "+row+" not found");
+                continue;
+            }			  
+
+            /*Fill the profile*/
+            nSkip=(int)(nEvents[id]*skipInitial);
+            iTuple.get(id).start();
+            iTuple.get(id).skip(nSkip); /*This is the work-around for those channels with charge starting from 0 and rapidly growing*/
+            n=0;
+            iTuple.get(id).next(); e=iTuple.get(id).getDouble(1); eMax=e; n++; /*eMax is the first sample*/
+            while ( iTuple.get(id).next() ){
+                e=iTuple.get(id).getDouble(1);
+                eMin=e;           			  /*eMin is the last sample*/
+                cProfile.get(id).fill(1.*n,e);
+                n++;
+            }			
+
+
+            /*Init function parameters*/
+            double[] initialPars={eMax-eMin,nEvents[id]/10.,eMin};
+            fFunction.get(id).setParameters(initialPars);
+
+            /*Do the fit*/
+            fFitter=aida.analysisFactory().createFitFactory().createFitter("chi2","","v");
+            System.out.println("LedAnalysis:: do profile fit "+id+" "+fFitter.engineName()+" "+fFitter.fitMethodName());
+            System.out.println("LedAnalysis:: initial parameters "+initialPars[0]+" "+initialPars[1]+" "+initialPars[2]);
+            fResult=fFitter.fit(cProfile.get(id),fFunction.get(id));
+            fPars     = fResult.fittedParameters();
+            fParErrs  = fResult.errors();
+            fParNames = fResult.fittedParameterNames();			
+            System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+            for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+                System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+            }  
+            fFunction.get(id).setParameters(fPars);
+
+
+            /*Do again the fit: it is a terrible work-around*/
+            nFits=0;
+            while (Double.isNaN(fParErrs[1])){
+                System.out.println("LedAnalysis:: redo fit");
+                fFunction.get(id).setParameters(fPars);
+                fResult=fFitter.fit(cProfile.get(id),fFunction.get(id));
+                fPars     = fResult.fittedParameters();
+                fParErrs  = fResult.errors();
+                System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+                for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+                    System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+                }  
+                fFunction.get(id).setParameters(fPars);
+                nFits++;
+                if (nFits>=10){
+                    System.out.println("LedAnalysis:: Error, too many fits without convergence");
+                    break;
+                }
+            }
+
+            System.out.println("LedAnalysis:: fit "+id+" done");  
+
+            /*Now we have the tau parameter. Take ONLY the events that are with N>5*tau/
 				As a cross-check, also verify that tau > Nevents/10, otherwise skip the first Nevents/2
 				and emit warning
-			   */
-			  hCharge.add(aida.histogram1D("charge_"+id,200,eMin*0.9,eMax*1.1));
-			  nSkip=(int)( fPars[1]*5);
-			  if (nSkip < (nEvents[id]/2)){
-				  System.out.println("LedAnalysis:: Skip number too low: "+nSkip+" Increment it to "+nEvents[id]/2);
-				  nSkip=nEvents[id]/2;
-			  }
-			  if (nSkip > nEvents[id]){
-				  System.out.println("LedAnalysis:: Skip number too high, reduce it");
-				  nSkip=nEvents[id]/2;
-			  }
-			  iTuple.get(id).start();
-			  iTuple.get(id).skip(nSkip); /*This is the work-around for those channels with charge starting from 0 and rapidly growing*/
-			  n=0;
-			  while ( iTuple.get(id).next() ){
-				  e=iTuple.get(id).getDouble(1);
-				  hCharge.get(id).fill(e);
-				  n++;
-			  }			
-			  
-			  /*Finally do the fit with the gaussian*/
-			  double[] initialPars1={hCharge.get(id).maxBinHeight(),hCharge.get(id).mean(),hCharge.get(id).rms()};
-			  
-			  System.out.println("LedAnalysis:: Gaus fit");
-			  System.out.println("LedAnalysis:: initial parameters "+initialPars1[0]+" "+initialPars1[1]+" "+initialPars1[2]);
-			  
-			  fFunction1.get(id).setParameters(initialPars1);
-			  fResult=fFitter.fit(hCharge.get(id),fFunction1.get(id));
-			  fPars     = fResult.fittedParameters();
-			  fParErrs  = fResult.errors();
-			  fParNames = fResult.fittedParameterNames();			
-			  System.out.println("Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-			  for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-				  System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-			  }  
-			  fFunction1.get(id).setParameters(fPars);
-	 	
-			  
-			  System.out.println("\n");
-		}/*End loop on channels*/
-		
-		
-		
-		
-		
-		
-		
-		
-		
-		
-	}/*End endOfData*/
-		  
-	
-	/**
-	 * This function returns the driver number (from 0 to 3) given the LED id.
-	 * @param led
-	 * @return
-	 */
-	public int getDriver(int led){
-		int ret=-1;	
-		if ((led>=2)&&(led<56)) ret=0;
-		else if ((led>=56)&&(led<112)) ret=1;
-		else if ((led>=112)&&(led<168)) ret=2;
-		else if ((led>=168)&&(led<224)) ret=3;
-		return ret;
-	}
-	
-/**
- * Very simple method to retreive the pedestal-subtracted raw Energy.
- * If the gain changes (because we do a re-calibration), I do not want to include this in the LED analysis
- * @param energy
- * @param cellID
- * @return
- */
-	public double getRawADCSum(double energy,long cellID){
-		  EcalChannelConstants channelData = ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
-		  double RawSum=energy / ECalUtils.GeV;
-		  double gain=channelData.getGain().getGain();
-		  double ret=RawSum/gain;
-		//  System.out.println("A:C "+RawSum+" "+ret);
-		  
-		  return ret;
-	
-	}
-	
-	private void uploadToDB() {
-		int x,y,id;
-		double mean,rms;
-		System.out.println(String.format("Uploading new led data to the database, runMin=%d, runMax=%d, tag=%s ....",
-				runNumber,runNumberMax,dbTag));
-		
-		EcalLedCalibrationCollection led_calibrations =  new EcalLedCalibrationCollection();
-		
-		TableMetaData tableMetaData = conditionsManager.findTableMetaData(dbTableName);
-		led_calibrations.setTableMetaData(tableMetaData);
-    
-		for (int cid = 1; cid <= 442; cid++) {/*This is a loop over the channel ID, as in the conditions system*/
-			EcalChannel cc = findChannel(cid);
-			x = cc.getX(); //This is the column
-			y = cc.getY(); //This is the row
-			id=EcalMonitoringUtilities.getHistoIDFromRowColumn(y,x);
-			mean=fFunction1.get(id).parameters()[1];
-			rms=fFunction1.get(id).parameters()[2];
-			led_calibrations.add(new EcalLedCalibration(cid,mean,rms));
-		}
-
-		int collectionId = conditionsManager.getNextCollectionID(dbTableName);
-		try {
-			led_calibrations.setCollectionId(collectionId);
-			System.err.println("CollectionID:  "+collectionId);
-			led_calibrations.insert();
-			ConditionsRecord conditionsRecord = new ConditionsRecord(
-                led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
-                "Generated by LedAnalysis from Run #"+runNumber, dbTag);
-			conditionsRecord.insert();
+             */
+            hCharge.add(aida.histogram1D("charge_"+id,200,eMin*0.9,eMax*1.1));
+           // hChargeVsTime.add(aida.histogram2D("chargeVsTime_"+id,200,0.,400.,200,eMin*0.9,eMax*1.1));     
+            nSkip=(int)( fPars[1]*5);
+            if (nSkip < (nEvents[id]/2)){
+                System.out.println("LedAnalysis:: Skip number too low: "+nSkip+" Increment it to "+nEvents[id]/2);
+                nSkip=nEvents[id]/2;
+            }
+            if (nSkip > nEvents[id]){
+                System.out.println("LedAnalysis:: Skip number too high, reduce it");
+                nSkip=nEvents[id]/2;
+            }
+            iTuple.get(id).start();
+            iTuple.get(id).skip(nSkip); /*This is the work-around for those channels with charge starting from 0 and rapidly growing*/
+            n=0;
+            while ( iTuple.get(id).next() ){
+                e=iTuple.get(id).getDouble(1);
+                t=iTuple.get(id).getDouble(2);
+                hCharge.get(id).fill(e);
+             //   hChargeVsTime.get(id).fill(t,e);
+                n++;
+            }			
+
+            /*Finally do the fit with the gaussian*/
+            double[] initialPars1={hCharge.get(id).maxBinHeight(),hCharge.get(id).mean(),hCharge.get(id).rms()};
+
+            System.out.println("LedAnalysis:: Gaus fit");
+            System.out.println("LedAnalysis:: initial parameters "+initialPars1[0]+" "+initialPars1[1]+" "+initialPars1[2]);
+
+            fFunction1.get(id).setParameters(initialPars1);
+            fResult=fFitter.fit(hCharge.get(id),fFunction1.get(id));
+            fPars     = fResult.fittedParameters();
+            fParErrs  = fResult.errors();
+            fParNames = fResult.fittedParameterNames();			
+            System.out.println("Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+            for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+                System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+            }  
+            fFunction1.get(id).setParameters(fPars);
+
+            hMeanCharge2D.fill(column,row,fPars[1]);
+            System.out.println("\n");
+        }/*End loop on channels*/
+
         
-		} catch (ConditionsObjectException | SQLException e) {
-			throw new RuntimeException(e);
-		}
-    
-
-	}
-	
-	
-	
-	 public EcalChannel findChannel(int channel_id) {
-	        return ecalConditions.getChannelCollection().findChannel(channel_id);
-	    }
-	
-	
-	
-	
+        pPlotter.createRegions(1,1);
+        IPlotterStyle style = pPlotter.region(0).style();
+        style.setParameter("hist2DStyle", "colorMap");
+        style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString());
+        
+        pPlotter.region(0).plot(hMeanCharge2D);
+        pPlotter.show();
+
+        int ret=JOptionPane.showConfirmDialog(null, "Do you want to load these conditions to the database\n"+
+                "for Runs: "+runNumber+" "+runNumberMax+" ? ", "Message", 
+                JOptionPane.YES_NO_OPTION);
+        if (ret == JOptionPane.YES_OPTION){
+            ret=JOptionPane.showConfirmDialog(null, "Confirm?", "Message", 
+                    JOptionPane.YES_NO_OPTION);
+            if (ret == JOptionPane.YES_OPTION){
+                System.out.println("You confirmed \n");
+                System.out.println("Load DB condtions \n");
+                //               uploadToDB();
+            }   
+        }
+       /* System.err.println("\n\n\n***************************************************************\n");
+        String userInput="";
+        String outputFilePrefix="";
+        userInput=cc.readLine("Enter filename prefix, or just press RETURN ...");
+        if (userInput==null || userInput.length()==0 || userInput=="") {
+            String home=System.getenv().get("HOME");
+            outputFilePrefix = home+"/LedAnalysis_"+runNumber+"_";
+        } else {
+            outputFilePrefix = userInput;
+        }*/
+
+        
+
+        
+       
+
+    }/*End endOfData*/
+
+
+    /**
+     * This function returns the driver number (from 0 to 3) given the LED id.
+     * @param led
+     * @return
+     */
+    public int getDriver(int led){
+        int ret=-1;	
+        if ((led>=2)&&(led<56)) ret=0;
+        else if ((led>=56)&&(led<112)) ret=1;
+        else if ((led>=112)&&(led<168)) ret=2;
+        else if ((led>=168)&&(led<224)) ret=3;
+        return ret;
+    }
+
+    /**
+     * Very simple method to retreive the pedestal-subtracted raw Energy.
+     * If the gain changes (because we do a re-calibration), I do not want to include this in the LED analysis
+     * @param energy
+     * @param cellID
+     * @return
+     */
+    public double getRawADCSum(double energy,long cellID){
+        EcalChannelConstants channelData = ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
+        double RawSum=energy / ECalUtils.GeV;
+        double gain=channelData.getGain().getGain();
+        double ret=RawSum/gain;
+        //  System.out.println("A:C "+RawSum+" "+ret);
+
+        return ret;
+
+    }
+
+    private void uploadToDB() {
+        int x,y,id;
+        double mean,rms;
+        System.out.println(String.format("Uploading new led data to the database, runMin=%d, runMax=%d, tag=%s ....",
+                runNumber,runNumberMax,dbTag));
+
+        EcalLedCalibrationCollection led_calibrations =  new EcalLedCalibrationCollection();
+
+        TableMetaData tableMetaData = conditionsManager.findTableMetaData(dbTableName);
+        led_calibrations.setTableMetaData(tableMetaData);
+
+        for (int cid = 1; cid <= 442; cid++) {/*This is a loop over the channel ID, as in the conditions system*/
+            EcalChannel cc = findChannel(cid);
+            x = cc.getX(); //This is the column
+            y = cc.getY(); //This is the row
+            id=EcalMonitoringUtilities.getHistoIDFromRowColumn(y,x);
+            mean=fFunction1.get(id).parameters()[1];
+            rms=fFunction1.get(id).parameters()[2];
+            led_calibrations.add(new EcalLedCalibration(cid,mean,rms));
+        }
+
+        int collectionId = conditionsManager.getNextCollectionID(dbTableName);
+        try {
+            led_calibrations.setCollectionId(collectionId);
+            System.err.println("CollectionID:  "+collectionId);
+            led_calibrations.insert();
+            ConditionsRecord conditionsRecord = new ConditionsRecord(
+                    led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
+                    "Generated by LedAnalysis from Run #"+runNumber, dbTag);
+            conditionsRecord.insert();
+
+        } catch (ConditionsObjectException | SQLException e) {
+            throw new RuntimeException(e);
+        }
+
+
+    }
+
+
+
+    public EcalChannel findChannel(int channel_id) {
+        return ecalConditions.getChannelCollection().findChannel(channel_id);
+    }
+
+
+
+
 }