Commit in SlicDiagnostics/src/org/lcsim/slic/diagnostics on MAIN
calorimeterhit/SimCalHitLayerPlots.java+134added 1.1
              /SimCalHitNoDetectorPlots.java+170-1741.2 -> 1.3
util/CollectionHandler.java+61added 1.1
    /AbstractCollectionPlots.java+150-751.1 -> 1.2
+515-249
2 added + 2 modified, total 4 files
slicdiag work in progress from today

SlicDiagnostics/src/org/lcsim/slic/diagnostics/calorimeterhit
SimCalHitLayerPlots.java added at 1.1
diff -N SimCalHitLayerPlots.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SimCalHitLayerPlots.java	16 Oct 2009 01:54:33 -0000	1.1
@@ -0,0 +1,134 @@
+package org.lcsim.slic.diagnostics.calorimeterhit;
+
+import static org.lcsim.slic.diagnostics.util.AidaHelper.c2d;
+import static org.lcsim.slic.diagnostics.util.AidaHelper.h1d;
+import static org.lcsim.slic.diagnostics.util.AidaHelper.c1d;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.SimCalorimeterHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.slic.diagnostics.util.AbstractCollectionPlots;
+import static org.lcsim.units.clhep.SystemOfUnits.MeV;
+
+public class SimCalHitLayerPlots extends AbstractCollectionPlots<SimCalorimeterHit>
+{       
+    class LayerEnergyMap extends HashMap<Integer,Double> 
+    {
+        public void addEnergy(int layer, double energy)
+        {
+            if (!containsKey(layer))
+            {
+                super.put(layer, 0.);
+            }
+            double e = get(layer);
+            e += energy;
+            super.put(layer, e);
+        }        
+    }
+    
+    class CollectionEnergyMaps extends HashMap<String,LayerEnergyMap> 
+    {
+        public LayerEnergyMap get(String collectionName)
+        {
+            if (!containsKey(collectionName))
+            {
+                super.put(collectionName, new LayerEnergyMap());
+            }
+            return super.get(collectionName);
+        }
+    }
+    
+    CollectionEnergyMaps layerRawEnergyMaps = new CollectionEnergyMaps();
+    CollectionEnergyMaps layerCorrEnergyMaps = new CollectionEnergyMaps();
+    int nevents = 0;
+    
+    public void defineCollectionPlots() 
+    {           
+        c2d("Layer vs Hit Raw Energy","Layer Number", "Energy [GeV]");
+        c2d("Layer vs Hit Corr Energy","Layer Number", "Energy [GeV]");        
+    }
+    
+    public void defineSubdetectorPlots(Subdetector subdet)
+    {
+        int nlayers = subdet.getLayering().getLayerCount();
+        double maxlayer = nlayers - 1;
+        
+        h1d("Layer Number", nlayers, 0., maxlayer, "Layer Number", "Number of Hits");
+        h1d("Layer Weighted Raw E", nlayers, 0., maxlayer, "Layer Number", "Energy [GeV]");
+        h1d("Layer Average Raw E by Event", nlayers, 0., maxlayer, "Layer Number", "Energy [MeV]");
+        h1d("Layer Average Corr E by Event", nlayers, 0., maxlayer, "Layer Number", "Energy [GeV]");
+    }
+    
+    public Class<SimCalorimeterHit> getType() 
+    {
+        return SimCalorimeterHit.class;
+    }
+    
+    public void plotCollection(EventHeader event, String collectionName, List<SimCalorimeterHit> collection) 
+    {               
+        for (SimCalorimeterHit hit : collection)
+        {
+            int layern = hit.getLayerNumber();
+            double rawe = hit.getRawEnergy();
+            double corre = hit.getCorrectedEnergy();
+            
+            h1d("Layer Number").fill(layern);
+            c2d("Layer vs Hit Raw Energy").fill(layern, hit.getRawEnergy());
+            c2d("Layer vs Hit Corr Energy").fill(layern, hit.getCorrectedEnergy());
+            h1d("Layer Weighted Raw E").fill(layern, hit.getRawEnergy());
+            
+            layerRawEnergyMaps.get(collectionName).addEnergy(layern, rawe);
+            layerCorrEnergyMaps.get(collectionName).addEnergy(layern, corre);
+        }
+    }
+
+    protected void endOfData()
+    {                
+        for (String collectionName : getCollectionsProcessed())
+        {                        
+            // Fill layer raw energy.
+            LayerEnergyMap rawEnergyMap = layerRawEnergyMaps.get(collectionName);
+            cd(collectionName);
+            for (Entry<Integer,Double> entry : rawEnergyMap.entrySet())
+            {                
+                h1d("Layer Average Raw E by Event").fill(
+                        entry.getKey(), 
+                        entry.getValue() / ((double)nevents) / MeV);                
+            }
+            
+            // Fill layer corrected energy.
+            LayerEnergyMap corrEnergyMap = layerCorrEnergyMaps.get(collectionName);
+            cd(collectionName);
+            for (Entry<Integer,Double> entry : corrEnergyMap.entrySet())
+            {                
+                h1d("Layer Average Corr E by Event").fill(
+                        entry.getKey(), 
+                        entry.getValue() / ((double)nevents));
+            }                                 
+        }
+               
+        nevents = 0;
+        layerRawEnergyMaps = new CollectionEnergyMaps();
+    }        
+    
+    protected void process(EventHeader event) 
+    {    
+        super.process(event);
+        ++nevents;
+    }
+    
+    protected void startOfData() 
+    {
+        super.startOfData();
+    }
+    
+    protected void detectorChanged(Detector detector)
+    {
+        super.detectorChanged(detector);
+    }
+}
\ No newline at end of file

SlicDiagnostics/src/org/lcsim/slic/diagnostics/calorimeterhit
SimCalHitNoDetectorPlots.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- SimCalHitNoDetectorPlots.java	7 Oct 2009 06:09:18 -0000	1.2
+++ SimCalHitNoDetectorPlots.java	16 Oct 2009 01:54:33 -0000	1.3
@@ -13,13 +13,11 @@
 import java.util.List;
 import java.util.Set;
 
-import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.MCParticle;
 import org.lcsim.event.SimCalorimeterHit;
 import org.lcsim.slic.diagnostics.util.AbstractCollectionPlots;
-import org.lcsim.slic.diagnostics.util.AidaHelper;
-import org.lcsim.util.aida.AIDA;
+import static org.lcsim.units.clhep.SystemOfUnits.MeV;
 
 /**
  * 
@@ -27,176 +25,174 @@
  * 
  * @author jeremym
  */
-public class SimCalHitNoDetectorPlots extends AbstractCollectionPlots 
+public class SimCalHitNoDetectorPlots extends AbstractCollectionPlots<SimCalorimeterHit>
 {	
-	public void definePlots()
-	{
-		c1d("Raw Energy by Event", "Energy [GeV]", "Number of Entries");
-                c1d("Hit Corrected Energy", "Energy [GeV]", "Number of Entries");
-                c1d("Corrected Energy by Event", "Energy [GeV]", "Number of Entries");
-                c2d("Event Energy vs Hits", "Energy [GeV]","Number of Hits"); 
-		c1d("Raw Energy", "Energy [GeV]", "Number of Entries");	
-		c1d("X Position", "X [mm]", "Number of Entries");
-		c1d("Y Position", "Y [mm]", "Number of Entries"); 
-		c1d("Z Position", "Z [mm]", "Number of Entries");
-		c2d("X vs Y", "X [mm]", "Y [mm]");			
-		c2d("Z vs X", "Z [mm]", "X [mm]");
-		c2d("Z vs Y", "Z [mm]", "Y [mm]");
-		c1d("Spherical Radius", "R [mm]", "Number of Entries");
-		c2d("Spherical Radius vs Raw Energy", "R [mm]", "Number of Entries");
-		c2d("Spherical Radius vs Time", "Spherical Radius", "Time");
-		c1d("Cylindrical Radius", "R [mm]", "Number of Entries");
-		c1d("Cos Theta", "cos(theta)", "Number of Entries");
-		c1d("Phi", "phi [radians]", "Number of Entries");
-		c1d("Hits by Event", "Hit Count", "Number of Entries");
-		c1d("Average Hit Energy by Event", "Energy [GeV]", "Number of Entries");
-		c1d("Minimum Hit Raw Energy by Event", "Energy [GeV]", "Number of Entries");
-		c1d("Maximum Hit Raw Energy by Event", "Energy [GeV]", "Number of Entries");
-		c1d("Minimum Cylindrical Radius by Event", "Radius [mm]", "Number of Entries");
-		c1d("Maximum Cylindrical Radius by Event", "Radius [mm]", "Number of Entries");
-		c1d("Minimum Spherical Radius by Event", "Radius [mm]", "Number of Entries");
-		c1d("Maximum Spherical Radius by Event", "Radius [mm]", "Number of Entries");
-		c1d("Particles per Hit", "Count", "Number of Entries");
-		c1d("Particles by Event", "Count", "Number of Entries");
-		c1d("Particle Contributions by Event", "Count", "Number of Entries");
-
-		ICloud1D time = c1d("Time","Time [ns]","Number of Entries");
-		time.annotation().addItem("xAxisScale", "log");
-		ICloud1D avgTime = c1d("Average Hit Time by Event","Time [ns]","Number of Entries");
-		avgTime.annotation().addItem("xAxisScale", "log");		
-	}	
-	
-	public void plotCollection(EventHeader event, String collectionName)
-	{
-		List<SimCalorimeterHit> collection = event.get(getType(), collectionName);
-
-		if (collection.size() == 0) 
-			return;
-		
-		AidaHelper.cd(getDirectory(collectionName));
-
-		int hits = 0;
-		int contribs = 0;
-		double timeSum = 0.;
-		double esum = 0.;
-                double cesum = 0.;
-		double mine = Double.MAX_VALUE;
-		double maxe = 0.;
-		double minsr = Double.MAX_VALUE;
-		double maxsr = 0.;
-		double mincr = Double.MAX_VALUE;
-		double maxcr = 0.;		
-		double mint = Double.MAX_VALUE;		
-		double maxt = 0.;
-		Set<MCParticle> uniqMcps = new HashSet<MCParticle>();
-
-		for (SimCalorimeterHit hit : collection)
-		{		
-			double e = hit.getRawEnergy();
-			double t = hit.getTime();
-			c1d("Time").fill(t);
-			if (t > maxt)
-				maxt = t;
-			if (t < mint)
-				mint = t;
-
-			c1d("Raw Energy").fill(e);
-			esum += e;
-			if (e > maxe)
-				maxe = e;
-			if (e < mine)
-				mine = e;
-			double ce=0.;
-			try 
-			{
-				// This could fail in a number of ways so catch anything!
-	                	ce = hit.getCorrectedEnergy();
-			}
-			catch (Throwable x)
-			{
-				// Oops!  No detector?
-			}
-                        cesum += ce;
-			c1d("Hit Corrected Energy").fill(ce);
-
-			double[] position = hit.getPosition();
-			Hep3Vector positionVector = 
-				new BasicHep3Vector(position[0], position[1], position[2]);
-			
-			c1d("X Position").fill(position[0]);
-			c1d("Y Position").fill(position[1]);
-			c1d("Z Position").fill(position[2]);
-			
-			c2d("X vs Y").fill(position[0], position[1]);				
-			c2d("Z vs X").fill(position[2], position[0]);
-			c2d("Z vs Y").fill(position[2], position[1]);
-
-			double sr = getSphericalRadius(position); 
-			c1d("Spherical Radius").fill(sr);
-			c2d("Spherical Radius vs Raw Energy").fill(sr,e);
-			c2d("Spherical Radius vs Time").fill(sr,e);
-			if (sr > maxsr)
-				maxsr = sr;
-			if (sr < minsr)
-				minsr = sr;
-
-			double cr = getCylindricalRadius(position); 			
-			c1d("Cylindrical Radius").fill(cr);
-			if (cr > maxcr)
-				maxcr = cr;
-			if (sr < mincr)
-				mincr = cr;
-
-			double cosTheta = VecOp.cosTheta(positionVector);
-                        double phi = VecOp.phi(positionVector);
-			c1d("Cos Theta").fill(cosTheta);
-                        c2d("Cos Theta vs Energy").fill(cosTheta,e);
-			c1d("Phi").fill(phi);
-                        c2d("Phi vs Energy").fill(phi,e);
-
-			int mcpCount = hit.getMCParticleCount();
-			c1d("Particles per Hit").fill(mcpCount);
-
-			contribs += mcpCount;			
-			++hits;
-			timeSum += t;
-
-			for (int i = 0; i < hit.getMCParticleCount(); i++)
-			{
-				uniqMcps.add(hit.getMCParticle(i));
-			}								
-		}        
-                c2d("Event Energy vs Hits").fill(esum, hits);
-		c1d("Average Hit Energy by Event").fill(esum/hits);
-		c1d("Hits by Event").fill(hits);
-		c1d("Raw Energy by Event").fill(esum);
-                c1d("Corrected Energy by Event").fill(cesum);
-		c1d("Average MC Contribs per Hit by Event").fill(contribs / hits);
-		c1d("Average Hit Time by Event","Time [ns]","Number of Entries").fill(timeSum/hits);
-		c1d("Particles by Event").fill(uniqMcps.size());
-		c1d("Maximum Hit Raw Energy by Event").fill(maxe);
-		c1d("Minimum Hit Raw Energy by Event").fill(mine);
-		c1d("Minimum Cylindrical Radius by Event").fill(mincr);
-		c1d("Maximum Cylindrical Radius by Event").fill(maxcr);
-		c1d("Minimum Spherical Radius by Event").fill(minsr);
-		c1d("Maximum Spherical Radius by Event").fill(maxsr);
-	}
-	
-	public SimCalHitNoDetectorPlots()
-	{}
-
-	public Class getType()
-	{
-		return SimCalorimeterHit.class;
-	}
-
-	public void process(EventHeader event)
-	{
-		super.process(event);
-	}
-
-	public void startOfData()
-	{   
-		super.startOfData();
-	}
+    public SimCalHitNoDetectorPlots()
+    {}
+
+    public void defineCollectionPlots()
+    {
+        c1d("Raw Energy by Event", "Energy [GeV]", "Number of Entries");
+        c1d("Hit Corrected Energy", "Energy [GeV]", "Number of Entries");
+        c1d("Corrected Energy by Event", "Energy [GeV]", "Number of Entries");
+        c2d("Event Raw Energy vs Hits", "Energy [GeV]","Number of Hits"); 
+        c2d("Event Corrected Energy vs Hits", "Energy [GeV]","Number of Hits"); 
+        c1d("Raw Energy", "Energy [MeV]", "Number of Entries");	
+        c1d("X Position", "X [mm]", "Number of Entries");
+        c1d("Y Position", "Y [mm]", "Number of Entries"); 
+        c1d("Z Position", "Z [mm]", "Number of Entries");
+        c2d("X vs Y", "X [mm]", "Y [mm]");			
+        c2d("Z vs X", "Z [mm]", "X [mm]");
+        c2d("Z vs Y", "Z [mm]", "Y [mm]");
+        c1d("Spherical Radius", "R [mm]", "Number of Entries");
+        c2d("Spherical Radius vs Raw Energy", "R [mm]", "Number of Entries");
+        c2d("Spherical Radius vs Time", "Spherical Radius", "Time");
+        c1d("Cylindrical Radius", "R [mm]", "Number of Entries");
+        c1d("Cos Theta", "cos(theta)", "Number of Entries");
+        c1d("Phi", "phi [radians]", "Number of Entries");
+        c1d("Hits by Event", "Hit Count", "Number of Entries");
+        c1d("Average Hit Energy by Event", "Energy [MeV]", "Number of Entries");
+        c1d("Minimum Hit Raw Energy by Event", "Energy [GeV]", "Number of Entries");
+        c1d("Maximum Hit Raw Energy by Event", "Energy [GeV]", "Number of Entries");
+        c1d("Minimum Cylindrical Radius by Event", "Radius [mm]", "Number of Entries");
+        c1d("Maximum Cylindrical Radius by Event", "Radius [mm]", "Number of Entries");
+        c1d("Minimum Spherical Radius by Event", "Radius [mm]", "Number of Entries");
+        c1d("Maximum Spherical Radius by Event", "Radius [mm]", "Number of Entries");
+        c1d("MCParticle Contributions per Hit", "Count", "Number of Entries");
+        c1d("Particles by Event", "Count", "Number of Entries");
+        c1d("Particle Contributions by Event", "Count", "Number of Entries");
+
+        ICloud1D time = c1d("Time","Time [ns]","Number of Entries");
+        time.annotation().addItem("xAxisScale", "log");
+        ICloud1D avgTime = c1d("Average Hit Time by Event","Time [ns]","Number of Entries");
+        avgTime.annotation().addItem("xAxisScale", "log");		
+    }	
+
+    public void plotCollection(EventHeader event, String collectionName, List<SimCalorimeterHit> collection)
+    {	    	   
+        if (collection.size() == 0) 
+            return;
+
+        int hits = 0;
+        int contribs = 0;
+        double timeSum = 0.;
+        double esum = 0.;
+        double cesum = 0.;
+        double mine = Double.MAX_VALUE;
+        double maxe = 0.;
+        double minsr = Double.MAX_VALUE;
+        double maxsr = 0.;
+        double mincr = Double.MAX_VALUE;
+        double maxcr = 0.;		
+        double mint = Double.MAX_VALUE;		
+        double maxt = 0.;
+        Set<MCParticle> uniqMcps = new HashSet<MCParticle>();
+
+        for (SimCalorimeterHit hit : collection)
+        {		
+            double e = hit.getRawEnergy();
+            double t = hit.getTime();
+            c1d("Time").fill(t);
+            if (t > maxt)
+                maxt = t;
+            if (t < mint)
+                mint = t;
+
+            c1d("Raw Energy").fill(e/MeV);
+            esum += e;
+            if (e > maxe)
+                maxe = e;
+            if (e < mine)
+                mine = e;
+            double ce=0.;
+            try 
+            {
+                // This could fail in a number of ways so catch anything!
+                ce = hit.getCorrectedEnergy();
+            }
+            catch (Throwable x)
+            {
+                // Oops!  No detector?
+            }
+            cesum += ce;
+            c1d("Hit Corrected Energy").fill(ce);
+
+            double[] position = hit.getPosition();
+            Hep3Vector positionVector = 
+                new BasicHep3Vector(position[0], position[1], position[2]);
+
+            c1d("X Position").fill(position[0]);
+            c1d("Y Position").fill(position[1]);
+            c1d("Z Position").fill(position[2]);
+
+            c2d("X vs Y").fill(position[0], position[1]);				
+            c2d("Z vs X").fill(position[2], position[0]);
+            c2d("Z vs Y").fill(position[2], position[1]);
+
+            double sr = getSphericalRadius(position); 
+            c1d("Spherical Radius").fill(sr);
+            c2d("Spherical Radius vs Raw Energy").fill(sr,e);
+            c2d("Spherical Radius vs Time").fill(sr,e);
+            if (sr > maxsr)
+                maxsr = sr;
+            if (sr < minsr)
+                minsr = sr;
+
+            double cr = getCylindricalRadius(position); 			
+            c1d("Cylindrical Radius").fill(cr);
+            if (cr > maxcr)
+                maxcr = cr;
+            if (sr < mincr)
+                mincr = cr;
+
+            double cosTheta = VecOp.cosTheta(positionVector);
+            double phi = VecOp.phi(positionVector);
+            c1d("Cos Theta").fill(cosTheta);
+            c2d("Cos Theta vs Energy").fill(cosTheta,e);
+            c1d("Phi").fill(phi);
+            c2d("Phi vs Energy").fill(phi,e);
+
+            int mcpCount = hit.getMCParticleCount();
+            c1d("MCParticle Contributions per Hit").fill(mcpCount);
+
+            contribs += mcpCount;			
+            ++hits;
+            timeSum += t;
+
+            for (int i = 0; i < hit.getMCParticleCount(); i++)
+            {
+                uniqMcps.add(hit.getMCParticle(i));
+            }								
+        }        
+        c2d("Event Raw Energy vs Hits").fill(esum, hits);
+        c2d("Event Corrected Energy vs Hits").fill(cesum, hits);
+        c1d("Average Hit Energy by Event").fill(esum/hits/MeV);
+        c1d("Hits by Event").fill(hits);
+        c1d("Raw Energy by Event").fill(esum);
+        c1d("Corrected Energy by Event").fill(cesum);
+        c1d("Average MC Contribs per Hit by Event").fill(contribs / hits);
+        c1d("Average Hit Time by Event","Time [ns]","Number of Entries").fill(timeSum/hits);
+        c1d("Particles by Event").fill(uniqMcps.size());
+        c1d("Maximum Hit Raw Energy by Event").fill(maxe);
+        c1d("Minimum Hit Raw Energy by Event").fill(mine);
+        c1d("Minimum Cylindrical Radius by Event").fill(mincr);
+        c1d("Maximum Cylindrical Radius by Event").fill(maxcr);
+        c1d("Minimum Spherical Radius by Event").fill(minsr);
+        c1d("Maximum Spherical Radius by Event").fill(maxsr);
+    }
+
+    public Class<SimCalorimeterHit> getType()
+    {
+        return SimCalorimeterHit.class;
+    }
+
+    public void process(EventHeader event)
+    {
+        super.process(event);
+    }
+
+    public void startOfData()
+    {   
+        super.startOfData();
+    }
 }

SlicDiagnostics/src/org/lcsim/slic/diagnostics/util
CollectionHandler.java added at 1.1
diff -N CollectionHandler.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ CollectionHandler.java	16 Oct 2009 01:54:34 -0000	1.1
@@ -0,0 +1,61 @@
+package org.lcsim.slic.diagnostics.util;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.lcsim.util.Driver;
+
+public abstract class CollectionHandler extends Driver
+{
+    Set<String> collections = new HashSet<String>();
+    
+    public CollectionHandler()
+    {}
+        
+    public CollectionHandler(List<String> collectionNames)
+    {        
+        for (String collection : collectionNames)
+        {
+            this.collections.add(collection);
+        }
+    }
+    
+    public CollectionHandler(String[] collectionNames)
+    {        
+        for (String collection : collectionNames)
+        {
+            this.collections.add(collection);
+        }
+    }
+    
+    public void setCollectionNames(String[] collectionNames)
+    {
+    	collections.addAll(Arrays.asList(collectionNames));
+    }
+    
+    public void setCollectionName(String collection)
+    {
+    	collections.add(collection);
+    }
+    
+    public Set<String> getCollectionNames()
+    {
+        return collections;
+    }
+ 
+    /**
+     * Return whether this CollectionHandler can handle the collection called 
+     * <code>collectionName</code>.  
+     * @param collectionName
+     * @return True if <code>collections</code> is empty or if 
+     *         collections contains </code>collectionName</code>; 
+     *         false if does not contain </code>collectionName</code>.
+     */
+    public boolean canHandle(String collectionName)
+    {
+    	if (collections.size() == 0) return true;
+        return collections.contains(collectionName);
+    }
+}

SlicDiagnostics/src/org/lcsim/slic/diagnostics/util
AbstractCollectionPlots.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- AbstractCollectionPlots.java	7 Oct 2009 03:17:27 -0000	1.1
+++ AbstractCollectionPlots.java	16 Oct 2009 01:54:34 -0000	1.2
@@ -2,134 +2,209 @@
 
 import static org.lcsim.slic.diagnostics.util.AidaHelper.tree;
 
-import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.lcsim.event.EventHeader;
-import org.lcsim.util.Driver;
+import org.lcsim.event.SimCalorimeterHit;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.EventHeader.LCMetaData;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.compact.Subdetector;
 
 /**
  * 
  * @author jeremym
- *
  */
-public abstract class AbstractCollectionPlots extends Driver
+public abstract class AbstractCollectionPlots<T> extends CollectionHandler
 {
-	List<String> inputCollectionNames = new ArrayList<String>();
-	List<String> directories = new ArrayList<String>();
 	Map<String,String> nameToDir = new HashMap<String,String>();
+	Set<String> collectionsProcessed = new HashSet<String>();
     
-    public AbstractCollectionPlots()
+    protected AbstractCollectionPlots()
     {}
     
     /**
-     * 
-     * @return
+     * Make plots for the collection given an event.
+     * @param event The LCSim event.
+     * @param collection The name of the collection.
      */
-    public abstract Class getType();
+    public abstract void plotCollection(EventHeader event, String collectionName, List<T> collection);
     
     /**
-     * 
+     * Return the type of object this Driver plots. 
+     * @return The type of object.
      */
-    protected abstract void definePlots();
+    public abstract Class<T> getType();
     
     /**
-     * 
+     * Define plots for single collection.
+     */
+    protected void defineCollectionPlots()
+    {}
+        
+    /**
+     * Define plots for Readout's subdetector (optional).
+     * @param subdet
      */
-    public void defineAllPlots()
+    public void defineSubdetectorPlots(Subdetector subdet)
+    {}
+    
+    /**
+     * Define all the plots by calling definePlots() for each collection.
+     */
+    public final void defineAllPlots()
 	{
-		for (String inputCollection : inputCollectionNames)
+		for (String inputCollection : getCollectionNames())
 		{
-			AidaHelper.cd(getDirectory(inputCollection));
-			definePlots();
+			cd(inputCollection);
+			defineCollectionPlots();
 		}
 	}
-    
-    /**
-     * 
-     * @param event
-     * @param collection
-     */
-    public abstract void plotCollection(EventHeader event, String collection);
-    
+        
     /**
-     * 
+     * Get directory for collection.
      * @param collectionName
      * @return
      */
     public final String getDirectory(String collectionName)
     {
-    	return nameToDir.get(collectionName);
+        if (collectionName.contains("/"))
+            throw new RuntimeException("The collection name <" + collectionName + "> contains slash characters.");
+        if (!nameToDir.containsKey(collectionName))
+        {
+            makeDirectory(collectionName);
+        }
+        return nameToDir.get(collectionName);        
     }
-       
+           
     /**
-     * 
-     * @return
+     * Change to collection's AIDA plots directory.
+     * @param collectionName The name of the collection.
      */
-    public final List<String> getDirectories()
+    protected final void cd(String collectionName)
+    {
+        AidaHelper.cd(getDirectory(collectionName));
+    }
+    
+    public final Collection<String> getDirectories()
     {
-    	return directories;
+        return nameToDir.values();
+    }
+    
+    public final Set<String> getCollectionsProcessed()
+    {
+        return collectionsProcessed;
     }
     
     /**
-     * 
-     * @param inputCollectionName
+     * Create AIDA directory for a collection name.
+     * @param collectionName
      */
-    public final void setInputCollectionName(String inputCollectionName)
-	{
-		inputCollectionNames.add(inputCollectionName);
-	}
+    private void makeDirectory(String collectionName)
+    {
+        String dir = "/" + getType().getSimpleName() + "/" + collectionName;
+                
+        try
+        {
+            tree().mkdirs(dir);
+            nameToDir.put(collectionName, dir);
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("Error creating the AIDA directory <" + dir + ">.",e);
+        }
+    }
     
     /**
-     * 
-     * @param inputCollectionNames
-     */
-    public final void setInputCollectionNames(String inputCollectionNames[])
+     * Start of data setup.
+     */    
+    protected void startOfData()
+    {    	
+    	defineAllPlots();
+    }    
+     
+    protected void endOfData()
     {
-    	this.inputCollectionNames.addAll(Arrays.asList(inputCollectionNames));
-    }    	   
-        
+        super.endOfData();
+    }
+    
     /**
      * 
      */
-    public final void setup()
-    {    	
-    	for (String collectionName : inputCollectionNames)
-    	{
-    		String dir = "/" + getType().getSimpleName() + "/" + collectionName;
-    		try
+    protected void detectorChanged(Detector detector)
+    {
+        if (getCollectionNames().size() > 0)
+        {
+            // Send to specified collections.
+            for (String collectionName : getCollectionNames())
             {
-                tree().mkdirs(dir);
-                directories.add(dir);
-                nameToDir.put(collectionName, dir);
+                for (Subdetector subdet : detector.getSubdetectors().values())
+                {
+                    if (subdet.getReadout().getName().equals(collectionName))
+                    {
+                        cd(collectionName);
+                        defineSubdetectorPlots(subdet);
+                    } 
+                }
             }
-            catch (Exception e)
+        }
+        else
+        {
+            // Send to all relevant collections.
+            for (Subdetector subdet : detector.getSubdetectors().values())
             {
-            	throw new RuntimeException("Problem creating AIDA directory " + dir + ".",e);
+                if ((getType().equals(SimCalorimeterHit.class) && subdet.isCalorimeter()) ||
+                        (getType().equals(SimTrackerHit.class) && subdet.isTracker()))
+                {
+                    if (subdet.getReadout() != null)
+                    {
+                        cd(subdet.getReadout().getName());
+                        defineSubdetectorPlots(subdet);
+                    }
+                }
             }
-    	}
-    }
+        }
+    }           
     
     /**
-     * 
-     */
-    public void startOfData()
-    {    	
-    	setup();
-    	defineAllPlots();
-    }    
-    
-    /**
-     * 
+     * Generic process routine.
      */
-    public void process(EventHeader event)
-	{
-    	for (String collectionName : inputCollectionNames)
-    	{
-    		plotCollection(event, collectionName);	
-    	}
+    protected void process(EventHeader event)
+	{        
+        Set<String> collectionNames = getCollectionNames();
+                
+        if (collectionNames.size() > 0)
+        {
+            // Plot specific collections.
+            for (String collectionName : getCollectionNames())
+            {
+                if (canHandle(collectionName))
+                {    	        
+                    cd(collectionName);
+                    plotCollection(event, collectionName, event.get(getType(), collectionName));
+                    collectionsProcessed.add(collectionName);
+                }
+            }
+        }        
+        else
+        {
+            // Plot all collections that match the type.
+            List<List<T>> collections = event.get(getType());
+            for (List<T> collection : collections)
+            {
+                LCMetaData meta = event.getMetaData(collection);
+                String collectionName = meta.getName();
+                cd(collectionName);
+                plotCollection(event, collectionName, event.get(getType(), collectionName));
+                collectionsProcessed.add(collectionName);
+            }
+        }
+        
+        super.process(event);
 	}
 }
\ No newline at end of file
CVSspam 0.2.8