Print

Print


Author: [log in to unmask]
Date: Tue Dec  2 15:16:38 2014
New Revision: 1624

Log:
Rename and Drivers and sync my users area with working copy.

Added:
    java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCPlotsDriver.java
    java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSignalPlotsDriver.java
    java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSumPlotsDriver.java
    java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCThresholdPlotsDriver.java
    java/trunk/users/src/main/java/org/hps/users/jeremym/EcalEnergyPlotsDriver.java
Modified:
    java/trunk/users/src/main/java/org/hps/users/jeremym/EcalRawModeMipAnalysisDriver.java

Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCPlotsDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCPlotsDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCPlotsDriver.java	Tue Dec  2 15:16:38 2014
@@ -0,0 +1,97 @@
+package org.hps.users.jeremym;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IHistogram1D;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+import hep.aida.IPlotterStyle;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannel;
+import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
+import org.hps.conditions.ecal.EcalConditions;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * This Driver will create a histogram for every channel in the ECAL and plot its ADC values
+ * from the LCSim event collection of raw hits.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalADCPlotsDriver extends Driver {
+
+    EcalConditions conditions = null;
+    EcalChannelCollection channels = null;
+
+    List<List<IPlotter>> plotterLists = new ArrayList<List<IPlotter>>();
+
+    AIDA aida = AIDA.defaultInstance();
+    IAnalysisFactory analysisFactory = aida.analysisFactory();
+
+    public void detectorChanged(Detector detector) {
+
+        conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();
+
+        channels = conditions.getChannelCollection();
+
+        Set<Integer> crates = new HashSet<Integer>();
+        Set<Integer> slots = new HashSet<Integer>();
+        Set<Integer> channels = new HashSet<Integer>();
+
+        for (EcalChannel channel : conditions.getChannelCollection()) {
+            crates.add(channel.getCrate());
+            slots.add(channel.getSlot());
+            channels.add(channel.getChannel());
+        }
+                
+        for (Integer crate : crates) {
+            IPlotterFactory plotterFactory = analysisFactory.createPlotterFactory("ECAL Raw ADC - Crate " + crate);
+            IPlotterStyle style = plotterFactory.createPlotterStyle();
+            style.dataStyle().lineStyle().setVisible(false);
+            style.legendBoxStyle().setVisible(false);
+            int plottersIndex = crate - 1;
+            plotterLists.add(new ArrayList<IPlotter>());
+            List<IPlotter> plotters = plotterLists.get(plottersIndex);
+            for (Integer slot : slots) {
+                IPlotter plotter = plotterFactory.create("Slot " + slot);
+                plotters.add(plotter);
+                plotter.createRegions(4, 4);
+                for (Integer channel : channels) {
+                    String histogramName = "ADC Values : " + crate + " : " + slot + " : " + channel;
+                    IHistogram1D histogram = aida.histogram1D(histogramName, 150, 50, 200.);
+                    plotter.region(channel).plot(histogram, style);
+                }
+                plotter.show();
+            }
+        }
+    }
+
+    public void process(EventHeader event) {
+        if (event.hasCollection(RawTrackerHit.class, "EcalReadoutHits")) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, "EcalReadoutHits");
+            for (RawTrackerHit hit : hits) {
+                EcalChannel channel = channels.findGeometric(hit.getCellID());
+                if (channel != null) {
+                    for (short adcValue : hit.getADCValues()) {
+                        try {
+                            aida.histogram1D("ADC Values : " + channel.getCrate() + " : " + channel.getSlot() + " : " + channel.getChannel()).fill(adcValue);
+                        } catch (IllegalArgumentException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                } else {
+                    System.err.println("EcalChannel not found for cell ID 0x" + String.format("%08d", Long.toHexString(hit.getCellID())));
+                }
+            }
+        }
+    }
+}

Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSignalPlotsDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSignalPlotsDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSignalPlotsDriver.java	Tue Dec  2 15:16:38 2014
@@ -0,0 +1,147 @@
+package org.hps.users.jeremym;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IHistogram1D;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannel;
+import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
+import org.hps.conditions.ecal.EcalChannelConstants;
+import org.hps.conditions.ecal.EcalConditions;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.subdetector.HPSEcal3;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * This Driver will process ECAL raw mode (window) data and extract hits 
+ * that look like signal, by requiring a certain number of ADC samples
+ * in a row that are above a sigma threshold.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalADCSignalPlotsDriver extends Driver {
+
+    EcalConditions conditions = null;
+    EcalChannelCollection channels = null;
+
+    Map<EcalChannel, Double[]> channelADCValues = new HashMap<EcalChannel, Double[]>();
+    Map<EcalChannel, Integer> channelEventCounts = new HashMap<EcalChannel, Integer>();
+    AIDA aida = AIDA.defaultInstance();
+    IAnalysisFactory analysisFactory = aida.analysisFactory();
+    double sigmaThreshold = 2.5;
+    int minimumSelectedHits = 3;
+    String outputHitsCollectionName = null;
+    String inputHitsCollectionName = "EcalReadoutHits";
+    HPSEcal3 ecal = null;
+    String ecalName = "Ecal";
+
+    /**
+     * Set the sigma threshold for an ADC value.
+     * @param sigmaThreshold The sigma threshold.
+     */
+    public void setSigmaThreshold(double sigmaThreshold) {
+        this.sigmaThreshold = sigmaThreshold;
+    }
+
+    /**
+     * Set the number of hits in a row which must be above threshold for the ADC values to be 
+     * saved for the event.
+     * @param selectedHits The minimum number of hits above threshold.
+     */
+    public void setMinimumHits(int selectedHits) {
+        this.minimumSelectedHits = selectedHits;
+    }
+    
+    public void setOutputHitsCollectionName(String outputHitsCollectionName) {
+        this.outputHitsCollectionName = outputHitsCollectionName;
+    }
+
+    public void detectorChanged(Detector detector) {
+        ecal = (HPSEcal3)detector.getSubdetector(ecalName);
+        conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();
+        channels = conditions.getChannelCollection();
+        for (EcalChannel channel : conditions.getChannelCollection()) {
+            channelADCValues.put(channel, new Double[100]);
+            channelEventCounts.put(channel, new Integer(0));            
+            Double[] adcValues = channelADCValues.get(channel); 
+            for (int adcSample = 0; adcSample < adcValues.length; adcSample++) {
+                adcValues[adcSample] = new Double(0.0);                
+            }
+        }
+    }
+
+    public void process(EventHeader event) {
+        if (event.hasCollection(RawTrackerHit.class, inputHitsCollectionName)) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, inputHitsCollectionName);
+            List<RawTrackerHit> selectedHitsList = new ArrayList<RawTrackerHit>();
+            for (RawTrackerHit hit : hits) {
+                EcalChannel channel = channels.findGeometric(hit.getCellID());
+                if (channel != null) {
+                    Double[] adcValues = channelADCValues.get(channel);
+                    if (adcValues == null) {
+                        throw new RuntimeException("The ADC values array is null.");
+                    }
+                    int nSelectedHits = 0;
+                    boolean saveHit = false;
+                    EcalChannelConstants channelConstants = conditions.getChannelConstants(channel);
+                    double pedestal = channelConstants.getCalibration().getPedestal();
+                    double noise = channelConstants.getCalibration().getNoise();
+                    double threshold = pedestal + sigmaThreshold * noise;
+                    adcThresholdLoop: for (int adcIndex = 0; adcIndex < hit.getADCValues().length; adcIndex++) {
+                        short adcValue = hit.getADCValues()[adcIndex];
+                        if (adcValue > threshold) {
+                            ++nSelectedHits;
+                            if (nSelectedHits >= minimumSelectedHits) {
+                                saveHit = true;
+                                break adcThresholdLoop;
+                            }
+                        } else {
+                            nSelectedHits = 0;
+                        }                        
+                    }
+                    if (saveHit) {
+                        for (int adcIndex = 0; adcIndex < hit.getADCValues().length; adcIndex++) {
+                            adcValues[adcIndex] += hit.getADCValues()[adcIndex];
+                        }
+                        Integer nEvents = channelEventCounts.get(channel);
+                        nEvents += 1;
+                        channelEventCounts.put(channel, nEvents);
+                        
+                        // Add hit to selected hits list.
+                        selectedHitsList.add(hit);
+                    }
+                } else {
+                    System.err.println("EcalChannel not found for cell ID 0x" + String.format("%08d", Long.toHexString(hit.getCellID())));
+                }
+            }
+            
+            if (outputHitsCollectionName != null) {
+                // Save selected hits list to event.
+                event.put(outputHitsCollectionName, selectedHitsList, RawTrackerHit.class, event.getMetaData(hits).getFlags(), ecal.getReadout().getName());
+            }
+        }
+    }
+
+    public void endOfData() {
+        for (EcalChannel channel : conditions.getChannelCollection()) {
+            int nEvents = channelEventCounts.get(channel);
+            IHistogram1D channelHistogram = aida.histogram1D("Average Signal ADC Values : " + channel.getChannelId(), 100, 0, 100);
+            Double[] adcValues = channelADCValues.get(channel);
+            for (int adcIndex = 0; adcIndex < adcValues.length; adcIndex++) {
+                // Calculate the average ADC value across number of events processed for this channel.
+                double averageAdcValue = adcValues[adcIndex] / nEvents;
+                
+                // Fill the ADC sample's bin, scaling by the ADC value.
+                channelHistogram.fill(adcIndex, averageAdcValue);
+            }
+        }
+    }
+}

Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSumPlotsDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSumPlotsDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCSumPlotsDriver.java	Tue Dec  2 15:16:38 2014
@@ -0,0 +1,104 @@
+package org.hps.users.jeremym;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IHistogram1D;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+import hep.aida.IPlotterStyle;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannel;
+import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
+import org.hps.conditions.ecal.EcalConditions;
+import org.hps.recon.ecal.EcalRawConverter;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * This Driver will create a histogram for every crystal in the ECAL and plot the sum of
+ * its ADC values for the raw hit, minus the channel's pedestal value from the conditions system.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalADCSumPlotsDriver extends Driver {
+
+    EcalConditions conditions = null;
+    EcalChannelCollection channels = null;
+    EcalRawConverter ecalRawConverter = null;
+
+    List<List<IPlotter>> plotterLists = new ArrayList<List<IPlotter>>();
+
+    AIDA aida = AIDA.defaultInstance();
+    IAnalysisFactory analysisFactory = aida.analysisFactory();
+
+    public void detectorChanged(Detector detector) {
+
+        conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();
+        
+        ecalRawConverter = new EcalRawConverter();
+        ecalRawConverter.setDetector(null);
+
+        channels = conditions.getChannelCollection();
+
+        Set<Integer> crates = new HashSet<Integer>();
+        Set<Integer> slots = new HashSet<Integer>();
+        Set<Integer> channels = new HashSet<Integer>();
+
+        for (EcalChannel channel : conditions.getChannelCollection()) {
+            if (channel == null) {
+                throw new RuntimeException("EcalChannel in collection is null.");
+            }
+            crates.add(channel.getCrate());
+            slots.add(channel.getSlot());
+            channels.add(channel.getChannel());
+        }
+                                
+        for (Integer crate : crates) {
+            IPlotterFactory plotterFactory = analysisFactory.createPlotterFactory("ECAL Sum ADC - Crate " + crate);
+            IPlotterStyle style = plotterFactory.createPlotterStyle();
+            style.dataStyle().lineStyle().setVisible(false);
+            style.legendBoxStyle().setVisible(false);
+            int plottersIndex = crate - 1;
+            plotterLists.add(new ArrayList<IPlotter>());
+            List<IPlotter> plotters = plotterLists.get(plottersIndex);
+            for (Integer slot : slots) {
+                IPlotter plotter = plotterFactory.create("Slot " + slot);
+                plotters.add(plotter);
+                plotter.createRegions(4, 4);
+                for (Integer channel : channels) {
+                    String adcSumPlotName = "Sum ADC Values : " + crate + " : " + slot + " : " + channel;
+                    IHistogram1D adcSumHistogram = aida.histogram1D(adcSumPlotName, 200, -100., 100.);
+                    plotter.region(channel).plot(adcSumHistogram, style);
+                }
+                plotter.show();
+            }
+        }
+    }
+
+    public void process(EventHeader event) {
+        if (event.hasCollection(RawTrackerHit.class, "EcalReadoutHits")) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, "EcalReadoutHits");
+            for (RawTrackerHit hit : hits) {
+                EcalChannel channel = channels.findGeometric(hit.getCellID());
+                if (channel != null) {
+                    try {
+                        aida.histogram1D("Sum ADC Values : " + channel.getCrate() + " : " + channel.getSlot() + " : " + channel.getChannel())
+                            .fill(ecalRawConverter.sumADC(hit));
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    System.err.println("EcalChannel not found for cell ID 0x" + String.format("%08d", Long.toHexString(hit.getCellID())));
+                }
+            }
+        }
+    }
+}

Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCThresholdPlotsDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCThresholdPlotsDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCThresholdPlotsDriver.java	Tue Dec  2 15:16:38 2014
@@ -0,0 +1,126 @@
+package org.hps.users.jeremym;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+import hep.aida.IPlotterStyle;
+
+import java.util.HashSet;
+import java.util.List;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannel;
+import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
+import org.hps.conditions.ecal.EcalConditions;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * This Driver plots the number of hits per event with at least one ADC value at or above 1 to 6 sigma.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+// TODO: Add plot of hist.fill(nSigmaHits / nTotalHits) to get percentage by event.  (X axis = 0 - 1.0 w/ 100 bins, Y axis = nEvents)
+public class EcalADCThresholdPlotsDriver extends Driver {
+
+    EcalConditions conditions = null;
+    EcalChannelCollection channels = null;
+    static int N_CRYSTALS = 442;
+
+    AIDA aida = AIDA.defaultInstance();
+    IAnalysisFactory analysisFactory = aida.analysisFactory();
+
+    @Override
+    public void detectorChanged(Detector detector) {
+        
+        conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();        
+        channels = conditions.getChannelCollection();                                       
+    }
+    
+    @Override
+    public void startOfData() {
+        IPlotterFactory plotterFactory = analysisFactory.createPlotterFactory("ECAL ADC Threshold Cuts");
+        IPlotter plotter = plotterFactory.create("ECAL ADC Threshold Cuts");
+        plotter.createRegion();
+        
+        IPlotterStyle style = plotterFactory.createPlotterStyle();
+        style.dataStyle().lineStyle().setVisible(true);
+        style.dataStyle().fillStyle().setVisible(false);
+        style.legendBoxStyle().setVisible(true);
+        style.yAxisStyle().setScaling("log");
+        
+        style.dataStyle().lineStyle().setColor("blue");
+        plotter.region(0).plot(aida.histogram1D("Hits Over 1 Sigma", N_CRYSTALS, 0, N_CRYSTALS), style);
+        
+        style.dataStyle().lineStyle().setColor("red");
+        plotter.region(0).plot(aida.histogram1D("Hits Over 2 Sigma", N_CRYSTALS, 0, N_CRYSTALS), style);
+        
+        style.dataStyle().lineStyle().setColor("green");
+        plotter.region(0).plot(aida.histogram1D("Hits Over 3 Sigma", N_CRYSTALS, 0, N_CRYSTALS), style);
+        
+        style.dataStyle().lineStyle().setColor("purple");
+        plotter.region(0).plot(aida.histogram1D("Hits Over 4 Sigma", N_CRYSTALS, 0, N_CRYSTALS), style);
+        
+        style.dataStyle().lineStyle().setColor("grey");
+        plotter.region(0).plot(aida.histogram1D("Hits Over 5 Sigma", N_CRYSTALS, 0, N_CRYSTALS), style);
+        
+        style.dataStyle().lineStyle().setColor("yellow");
+        plotter.region(0).plot(aida.histogram1D("Hits Over 6 Sigma", N_CRYSTALS, 0, N_CRYSTALS), style);
+        
+        plotter.show();
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        if (event.hasCollection(RawTrackerHit.class, "EcalReadoutHits")) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, "EcalReadoutHits");
+            HashSet<RawTrackerHit> sigma1Hits = new HashSet<RawTrackerHit>();
+            HashSet<RawTrackerHit> sigma2Hits = new HashSet<RawTrackerHit>();
+            HashSet<RawTrackerHit> sigma3Hits = new HashSet<RawTrackerHit>();
+            HashSet<RawTrackerHit> sigma4Hits = new HashSet<RawTrackerHit>();
+            HashSet<RawTrackerHit> sigma5Hits = new HashSet<RawTrackerHit>();
+            HashSet<RawTrackerHit> sigma6Hits = new HashSet<RawTrackerHit>();
+            for (RawTrackerHit hit : hits) {
+                EcalChannel channel = channels.findGeometric(hit.getCellID());
+                double pedestal = conditions.getChannelConstants(channel).getCalibration().getPedestal();
+                double noise = conditions.getChannelConstants(channel).getCalibration().getNoise();
+                for (short adcValue : hit.getADCValues()) {
+                    if ((double)adcValue >= (pedestal + noise)) {
+                        sigma1Hits.add(hit);
+                    }
+                    if ((double)adcValue >= (pedestal + noise * 2)) {
+                        sigma2Hits.add(hit);
+                    }                    
+                    if ((double)adcValue >= (pedestal + noise * 3)) {
+                        sigma3Hits.add(hit);
+                    } 
+                    if ((double)adcValue >= (pedestal + noise * 4)) {
+                        sigma4Hits.add(hit);
+                    } 
+                    if ((double)adcValue >= (pedestal + noise * 5)) {
+                        sigma5Hits.add(hit);
+                    }
+                    if ((double)adcValue >= (pedestal + noise * 6)) {
+                        sigma6Hits.add(hit);
+                    }
+                }                
+            }
+            if (sigma1Hits.size() > 0)
+                aida.histogram1D("Hits Over 1 Sigma").fill(sigma1Hits.size());
+            if (sigma2Hits.size() > 0)
+                aida.histogram1D("Hits Over 2 Sigma").fill(sigma2Hits.size());
+            if (sigma3Hits.size() > 0)
+                aida.histogram1D("Hits Over 3 Sigma").fill(sigma3Hits.size());
+            if (sigma4Hits.size() > 0)
+                aida.histogram1D("Hits Over 4 Sigma").fill(sigma4Hits.size());
+            if (sigma5Hits.size() > 0)
+                aida.histogram1D("Hits Over 5 Sigma").fill(sigma5Hits.size());
+            if (sigma6Hits.size() > 0)
+                aida.histogram1D("Hits Over 6 Sigma").fill(sigma6Hits.size());
+        } 
+    }
+}

Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalEnergyPlotsDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalEnergyPlotsDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalEnergyPlotsDriver.java	Tue Dec  2 15:16:38 2014
@@ -0,0 +1,91 @@
+package org.hps.users.jeremym;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IHistogram1D;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+import hep.aida.IPlotterStyle;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannel;
+import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
+import org.hps.conditions.ecal.EcalConditions;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.EventHeader;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * This Driver will create a histogram for every channel in the ECAL and plot its corrected energy.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalEnergyPlotsDriver extends Driver {
+
+    EcalConditions conditions = null;
+    EcalChannelCollection channels = null;
+
+    List<List<IPlotter>> plotterLists = new ArrayList<List<IPlotter>>();
+
+    AIDA aida = AIDA.defaultInstance();
+    IAnalysisFactory analysisFactory = aida.analysisFactory();
+
+    public void detectorChanged(Detector detector) {
+        
+        conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();
+        
+        channels = conditions.getChannelCollection();
+
+        Set<Integer> crates = new HashSet<Integer>();
+        Set<Integer> slots = new HashSet<Integer>();
+        Set<Integer> channels = new HashSet<Integer>();
+
+        for (EcalChannel channel : conditions.getChannelCollection()) {
+            crates.add(channel.getCrate());
+            slots.add(channel.getSlot());
+            channels.add(channel.getChannel());
+        }
+                                        
+        for (Integer crate : crates) {
+            IPlotterFactory plotterFactory = analysisFactory.createPlotterFactory("ECAL Energy - Crate " + crate);
+            IPlotterStyle style = plotterFactory.createPlotterStyle();
+            style.dataStyle().lineStyle().setVisible(false);
+            style.legendBoxStyle().setVisible(false);
+            int plottersIndex = crate - 1;
+            plotterLists.add(new ArrayList<IPlotter>());
+            List<IPlotter> plotters = plotterLists.get(plottersIndex);
+            for (Integer slot : slots) {
+                IPlotter plotter = plotterFactory.create("Slot " + slot);
+                plotters.add(plotter);
+                plotter.createRegions(4, 4);
+                for (Integer channel : channels) {
+                                        
+                    String energyPlotName = "Crystal Energy : " + crate + " : " + slot + " : " + channel;
+                    IHistogram1D energyHistogram = aida.histogram1D(energyPlotName, 500, -50., 200.);
+                    
+                    plotter.region(channel).plot(energyHistogram, style);
+                }
+                plotter.show();
+            }
+        }
+    }
+
+    public void process(EventHeader event) {
+        if (event.hasCollection(CalorimeterHit.class, "EcalCalHits")) {
+            List<CalorimeterHit> hits = event.get(CalorimeterHit.class, "EcalCalHits");
+            for (CalorimeterHit hit : hits) {
+                EcalChannel channel = channels.findGeometric(hit.getCellID());
+                if (channel != null) {
+                    aida.histogram1D("Crystal Energy : " + channel.getCrate() + " : " + channel.getSlot() + " : " + channel.getChannel())
+                        .fill(hit.getCorrectedEnergy() * 1000);
+                }                   
+            }
+        }
+    }
+}

Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalRawModeMipAnalysisDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalRawModeMipAnalysisDriver.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalRawModeMipAnalysisDriver.java	Tue Dec  2 15:16:38 2014
@@ -40,6 +40,8 @@
     int nMipEvents = 0;
     HPSEcal3 ecal  = null;
     
+    int minNeighbors = 1;
+    
     public void detectorChanged(Detector detector) {
         conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();        
         channels = conditions.getChannelCollection();
@@ -51,6 +53,10 @@
     
     public void setSigmaThreshold(double sigmaThreshold) {
         this.sigmaThreshold = sigmaThreshold;
+    }
+    
+    public void setMinNeighbors(int minNeighbors) {
+        this.minNeighbors = minNeighbors;
     }
     
     public void process(EventHeader event) {
@@ -108,7 +114,7 @@
                 throw new RuntimeException("No crystal geometry object is assigned to hit.");
             }            
             Set<Long> neighborHitIDs = findNeighborHitIDs(hit, mipCandidateHits); 
-            if (neighborHitIDs.size() > 0) {
+            if (neighborHitIDs.size() >= minNeighbors) {
                 hitList.add(hit);
             }
         }