Commit in lcsim on MAIN
project.xml+11-11.26 -> 1.27
src/org/lcsim/contrib/proulx/ganging/AveragedCalorimeterHit.java+114added 1.1
                                    /Compare.java+78added 1.1
                                    /CompareHitCollections.java+99added 1.1
                                    /GangedCalorimeterHitLinkedList.java+489added 1.1
                                    /GangingDriver.java+49added 1.1
                                    /UnGangedCalorimeterHitLinkedList.java+122added 1.1
                                    /UnGangingDriver.java+44added 1.1
+1006-1
7 added + 1 modified, total 8 files


lcsim
project.xml 1.26 -> 1.27
diff -u -r1.26 -r1.27
--- project.xml	7 Jan 2006 00:14:41 -0000	1.26
+++ project.xml	12 Jan 2006 21:52:55 -0000	1.27
@@ -138,7 +138,17 @@
     <className>fakeClass</className>
     <excludes>
      <exclude>org/lcsim/plugin/web/**</exclude>
-     <exclude>org/lcsim/contrib/**</exclude>
+     <!-- <exclude>org/lcsim/contrib/**</exclude> -->
+     <exclude>org/lcsim/contrib/CalAnal/**</exclude>
+     <exclude>org/lcsim/contrib/CarstenHensel/**</exclude>
+     <exclude>org/lcsim/contrib/JanStrube/**</exclude>
+     <exclude>org/lcsim/contrib/LeiXia/**</exclude>
+     <exclude>org/lcsim/contrib/SteveKuhlmann/**</exclude>
+     <exclude>org/lcsim/contrib/compile/**</exclude>
+     <exclude>org/lcsim/contrib/garfield/**</exclude>
+     <!-- <exclude>org/lcsim/contrib/proulx/**</exclude> -->
+     <exclude>org/lcsim/contrib/tracking/**</exclude>
+     <exclude>org/lcsim/contrib/uiowa/**</exclude>
     </excludes>
    </sourceModification>
   </sourceModifications>

lcsim/src/org/lcsim/contrib/proulx/ganging
AveragedCalorimeterHit.java added at 1.1
diff -N AveragedCalorimeterHit.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ AveragedCalorimeterHit.java	12 Jan 2006 21:52:55 -0000	1.1
@@ -0,0 +1,114 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.geometry.segmentation.ProjectiveCylinder;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.geometry.util.IDEncoder;
+import org.lcsim.geometry.util.IDDescriptor;
+
+class AveragedCalorimeterHit implements SimCalorimeterHit
+{
+    long cellID;
+    double rawEnergy;
+    double correctedEnergy;
+    org.lcsim.geometry.IDDecoder decoder;
+    double time;
+    Subdetector sub;
+    int size;
+    Vector<MCParticle> contributingParticles;
+    double contributedEnergy[];
+    double contributedTime[];
+    double position[] = null;
+
+    AveragedCalorimeterHit(long _cellID,
+			   double _rawEnergy,
+			   double _correctedEnergy,
+			   org.lcsim.geometry.IDDecoder _decoder,
+			   double _time,
+			   Subdetector _sub,
+			   int _size,
+			   Vector<MCParticle> _contributingParticles,
+			   double _contributedEnergy[],
+			   double _contributedTime[]
+			   ) 
+    {
+	cellID = _cellID;
+	rawEnergy = _rawEnergy;
+	correctedEnergy = _correctedEnergy;
+	decoder = _decoder;
+	time = _time;
+	sub = _sub;
+	size = _size;
+	contributingParticles = _contributingParticles;
+	contributedEnergy = _contributedEnergy;
+	contributedTime = _contributedTime;
+    }
+    
+    AveragedCalorimeterHit(SimCalorimeterHit hit) {
+	this(hit,1);
+    }
+
+    AveragedCalorimeterHit(SimCalorimeterHit hit,
+			   double scaleFactor)
+    {
+	cellID                = hit.getCellID();
+	rawEnergy             = hit.getRawEnergy();
+	correctedEnergy       = hit.getCorrectedEnergy();
+	decoder               = hit.getIDDecoder();
+	time                  = hit.getTime();
+	sub                   = hit.getSubdetector();
+
+	rawEnergy       *= scaleFactor;
+	correctedEnergy *= scaleFactor;
+
+	size                  = hit.getMCParticleCount();
+	contributingParticles = new Vector<MCParticle>(size);
+	contributedEnergy     = new double[size];
+	contributedTime       = new double[size];
+
+	for (int i=0; i<size; ++i) {
+	    contributingParticles.add(hit.getMCParticle(i));
+	    contributedEnergy[i] = hit.getContributedEnergy(i);
+	    contributedTime[i]   = hit.getContributedTime(i);
+	}
+    }
+
+    // CalorimeterCell methods
+    public long        getCellID()          { return cellID;}
+    public double      getCorrectedEnergy() { return correctedEnergy; }
+    public org.lcsim.geometry.IDDecoder getIDDecoder()
+    { return decoder; }
+    public double[] getPosition()
+    {
+	if (position == null)
+	    {
+		decoder.setID(cellID);
+		position = new double[3];
+		position[0] = decoder.getX();
+		position[1] = decoder.getY();
+		position[2] = decoder.getZ();
+	    }
+	return position;
+    }
+
+    public double      getRawEnergy()       { return rawEnergy; }
+    public Subdetector getSubdetector()     { return sub; }
+    public double      getTime()            { return time; }
+
+    // SimCalorimeterCell methods
+    public double     getContributedEnergy(int i) { return contributedEnergy[i]; }
+    public double     getContributedTime(int i)   { return contributedTime[i]; }
+    public MCParticle getMCParticle(int i) { return contributingParticles.get(i); }
+    public int        getMCParticleCount() { return contributingParticles.size(); }
+    public int        getPDG(int i) {
+	//return pdg[i];
+	return contributingParticles.get(i).getPDGID();
+    }
+}

lcsim/src/org/lcsim/contrib/proulx/ganging
Compare.java added at 1.1
diff -N Compare.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Compare.java	12 Jan 2006 21:52:55 -0000	1.1
@@ -0,0 +1,78 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.util.*;
+import org.lcsim.util.event.*;
+import org.lcsim.geometry.*;
+import org.lcsim.geometry.subdetector.*;
+import org.lcsim.geometry.util.*;
+import org.lcsim.geometry.segmentation.*;
+
+import org.lcsim.recon.cluster.cheat.*;
+
+import hep.aida.*;
+import hep.physics.vec.*;
+
+import org.lcsim.util.aida.AIDA;
+
+
+
+final public class Compare extends Driver
+{
+  //private AIDA aida = AIDA.defaultInstance();
+
+  public Compare() throws java.io.IOException
+  {
+    //add(new DescribeDetector());
+    add(new GangingDriver());
+    add(new UnGangingDriver());
+    add(new CompareHitCollections("EcalBarrHits","EcalBarrHitsGanged"));
+    add(new CompareHitCollections("EcalBarrHits","EcalBarrHitsUnGanged"));
+  }
+
+  protected void process(EventHeader event)
+  {
+    super.process(event);
+    System.out.println("\n\nANALYZING EVENT No. "+event.getEventNumber()+"\n");
+    /*
+    // Make histograms of the phi bins of the hits in each EMBarr collection
+    List<List<CalorimeterHit>> calHitCollections = event.get(CalorimeterHit.class);
+    for ( List<CalorimeterHit> calHits : calHitCollections ){
+      System.out.print(event.getMetaData(calHits).getName());
+      if (!event.getMetaData(calHits).getName().contains("EcalBarr")) {
+	System.out.println(" -- Bad" );
+      }
+      else {
+	EventHeader.LCMetaData meta = event.getMetaData(calHits);
+	ProjectiveCylinder calD = (ProjectiveCylinder) meta.getIDDecoder();
+	System.out.print(" "+calD.getPhiBins()+" ");
+	
+	System.out.print(" -- Good ");
+	String hist = "PhiBins - "+event.getMetaData(calHits).getName();
+	String hist2 = "X - "+event.getMetaData(calHits).getName();
+	boolean foo = false;
+	for (CalorimeterHit calHit : calHits) {
+	  ProjectiveCylinder calDecoder = (ProjectiveCylinder) calHit.getIDDecoder();
+	  if (!foo) {
+	    System.out.println(calDecoder.getPhiBins() + " Phi Bins");
+	    foo = true;
+	  }
+	  calDecoder.setID(calHit.getCellID());
+	  int phiBin = calDecoder.getValue(calDecoder.getIDDescription().indexOf("theta"));
+	  aida.cloud1D(hist).fill(phiBin);
+	  aida.cloud1D(hist2).fill(calHit.getPosition()[0]);
+	}
+	if (!foo) {
+	  System.out.println(" NO HITS!");
+	}
+      }
+    }
+    */
+  }
+}

lcsim/src/org/lcsim/contrib/proulx/ganging
CompareHitCollections.java added at 1.1
diff -N CompareHitCollections.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ CompareHitCollections.java	12 Jan 2006 21:52:55 -0000	1.1
@@ -0,0 +1,99 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.util.*;
+import org.lcsim.util.event.*;
+import org.lcsim.geometry.*;
+import org.lcsim.geometry.util.*;
+import org.lcsim.geometry.segmentation.*;
+
+import hep.aida.*;
+import hep.physics.vec.*;
+
+import org.lcsim.util.aida.AIDA;
+
+public class CompareHitCollections extends Driver
+{
+  private String nameStandard;
+  private String nameNew;
+  private AIDA aida = AIDA.defaultInstance();
+
+  IAnalysisFactory     af     = IAnalysisFactory.create();
+  ITree                tree   = af.createTreeFactory().create();
+  IDataPointSetFactory dpsf   = af.createDataPointSetFactory(tree);
+  IFunctionFactory     funcF  = af.createFunctionFactory(tree);
+  IFitFactory          fitF   = af.createFitFactory();
+  IHistogramFactory     hf     = af.createHistogramFactory(tree);
+  
+  IHistogram1D energyHist;
+  
+  public CompareHitCollections()
+  {
+    this ("EMCalBarrHits","EMCalBarrHitsRegrouped");
+  }
+  
+  public CompareHitCollections(String nameStandard, String nameNew)
+  {
+    this.nameStandard = nameStandard;
+    this.nameNew      = nameNew;
+
+    energyHist = hf.createHistogram1D("energy difference between "+nameStandard+" and "+nameNew+" per hit",100,-.01,.01);
+  }
+  
+  protected void process(EventHeader event)
+  {
+    System.out.println("Running CompareHitCollections.process ...");
+    List<CalorimeterHit> listStandard = null;
+    List<CalorimeterHit> listNew      = null;
+
+    List<List<CalorimeterHit>> calHitCollections = event.get(CalorimeterHit.class);
+    for ( List<CalorimeterHit> calHits : calHitCollections )
+    {
+      String name = event.getMetaData(calHits).getName();
+      if (name.equals(nameStandard)) { listStandard = calHits; }
+      if (name.equals(nameNew))      { listNew      = calHits; }
+    }
+
+    if (listStandard==null || listNew==null) { return; }
+
+    System.out.println("Quitting after printing list sizes");
+    System.out.println(listStandard.size()+" hits in "+nameStandard);
+    System.out.println(listNew.size()+" hits in "+nameNew);
+    if (listStandard.size()>-1) return;
+    
+    int matches = 0;
+    double energyStandard = 0;
+    double energyNew = 0;
+    
+    for (CalorimeterHit hitStandard : listStandard) {
+      energyStandard += hitStandard.getRawEnergy();
+      for (CalorimeterHit hitNew : listNew) {
+	if (hitStandard.getCellID() == hitNew.getCellID()) {
+	  matches++;
+	  double energyDiff = hitStandard.getRawEnergy() - hitNew.getRawEnergy();
+	  energyHist.fill(energyDiff);
+	  break;
+	}
+      }
+    }
+    for (CalorimeterHit hitNew1 : listNew) {
+      energyNew += hitNew1.getRawEnergy();
+    }
+
+    double sizeStandard = listStandard.size();
+    double sizeNew      = listNew.size();
+
+    aida.cloud1D("matches between "+nameStandard+" and "+nameNew+" hits as a fraction of "+nameStandard+" hits").fill(matches/sizeStandard);
+    aida.cloud1D("energy difference per event between "+nameStandard+" and "+nameNew).fill(energyStandard-energyNew);
+    
+    aida.cloud1D(nameNew+" hits as a fraction of "+nameStandard+" hits").fill(sizeNew/sizeStandard);
+    aida.cloud1D(nameNew+" hits").fill(sizeNew);
+    aida.cloud1D(nameStandard+" hits").fill(sizeStandard);
+  }
+}

lcsim/src/org/lcsim/contrib/proulx/ganging
GangedCalorimeterHitLinkedList.java added at 1.1
diff -N GangedCalorimeterHitLinkedList.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ GangedCalorimeterHitLinkedList.java	12 Jan 2006 21:52:55 -0000	1.1
@@ -0,0 +1,489 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.geometry.segmentation.ProjectiveCylinder;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.geometry.util.IDEncoder;
+import org.lcsim.geometry.util.IDDescriptor;
+
+//import org.lcsim.util.*;
+//import org.lcsim.util.event.*;
+//import org.lcsim.geometry.*;
+//import org.lcsim.geometry.util.*;
+//import org.lcsim.geometry.segmentation.*;
+
+//import hep.aida.*;
+import hep.physics.vec.*;
+
+public class GangedCalorimeterHitLinkedList
+{
+  // Data
+  private Vector<SimCalorimeterHit> gangedHitList = new Vector<SimCalorimeterHit>();
+  private ProjectiveCylinder descoder = null;
+  private int gangedCalorimeterHitID;
+
+  private IDEncoder encoder = null;
+  private IDDecoder decoder = null;
+  private IDDescriptor descriptor = null;
+
+  // Description of ganging
+  private int nGroup;
+  private boolean[][] entries;
+  private boolean offset;
+
+  // Description of hits
+  private boolean lEnergy = false;
+  private double rawEnergy;
+  private double correctedEnergy;
+
+  // Links
+  public GangedCalorimeterHitLinkedList prev = null;
+  public GangedCalorimeterHitLinkedList next = null;
+
+  public GangedCalorimeterHitLinkedList() {
+    this(null);
+  }
+
+  public GangedCalorimeterHitLinkedList(List<CalorimeterHit> list)
+  {
+    this(list, 2);
+  }
+
+  public GangedCalorimeterHitLinkedList(List<CalorimeterHit> list,
+					int n)
+  {
+    this(list, n, true);
+  }
+
+  public GangedCalorimeterHitLinkedList(List<CalorimeterHit> list,
+					boolean off)
+  {
+    this(list, 2, off);
+  }
+
+  public GangedCalorimeterHitLinkedList(List<CalorimeterHit> list,
+					int n, boolean off)
+  {
+    //int iHit = 0;
+    //for (CalorimeterHit h : list) {
+    //System.out.println("here's a hit:"+iHit); iHit++
+    //}
+    //System.out.println("List size = "+list.size());
+    if (list.size()>0) {
+      this.init((SimCalorimeterHit) list.get(0),n,off);
+      gangedHitList.clear();
+      for (CalorimeterHit h : list) {
+	SimCalorimeterHit sh = (SimCalorimeterHit) h;
+	this.insertElement(sh);
+      }
+    } 
+    else 
+    {
+      System.out.println("no hits in collection");
+    }
+    //System.out.println("terminated constructor");
+  }
+  
+  public GangedCalorimeterHitLinkedList(SimCalorimeterHit h,
+					int n,
+					boolean off)
+  {
+    this.init(h,n,off);
+  }
+  
+  private void init(SimCalorimeterHit h,
+		    int n,
+		    boolean off)
+  {
+    //CalorimeterHit hit = gangedHitList.get(0);
+    decoder = h.getIDDecoder();
+    descriptor = decoder.getIDDescription();
+    encoder = new IDEncoder(descriptor);
+
+    nGroup = n;
+    offset = off;
+    gangedCalorimeterHitID = getGangedCalorimeterID(h);
+    addHit(h);
+  }
+
+  public GangedCalorimeterHitLinkedList(SimCalorimeterHit h,
+					GangedCalorimeterHitLinkedList old)
+  {
+    decoder = old.decoder;
+    encoder = old.encoder;
+    descriptor = old.descriptor;
+    
+    nGroup = old.getNGroup();
+    offset = old.getOffset();
+    gangedCalorimeterHitID = getGangedCalorimeterID(h);
+    addHit(h);
+  }
+
+  private int getGangedCalorimeterID(SimCalorimeterHit h)
+  {
+    return getGangedCalorimeterID(getLayer(h),
+				  getPhiBin(h),
+				  getThetaBin(h));
+  }
+    
+  public int getGangedCalorimeterID(int layer, int phi, int theta) {
+    ProjectiveCylinder projective = (ProjectiveCylinder) decoder;
+    int phiMax   = projective.getPhiBins();
+    int thetaMax = projective.getThetaBins();
+
+    if (offset) {
+      phi   += (layer%2)*(nGroup/2);
+      theta += (layer%2)*(nGroup/2);
+    }
+
+    phi   = (phi%phiMax) / nGroup;
+    theta = (theta%phiMax) / nGroup;
+
+    return layer*1024*1024 + phi*1024 + theta;	
+  }
+
+  private int getLayer()
+  {
+    return (gangedCalorimeterHitID/1024/1024)%1024;
+  }
+  private int getPhiBin()
+  {
+    return (gangedCalorimeterHitID/1024)%1024;
+  }
+  private int getThetaBin()
+  {
+    return (gangedCalorimeterHitID)%1024;
+  }
+
+  public int getNGroup()
+  {
+    return nGroup;
+  }
+
+  public double getCorrectedEnergy() {
+    if (lEnergy) { return correctedEnergy; }
+
+    rawEnergy = correctedEnergy = 0;
+    for (SimCalorimeterHit hit : gangedHitList) {
+      rawEnergy       += hit.getRawEnergy();
+      correctedEnergy += hit.getCorrectedEnergy();
+    }
+    lEnergy = true;
+    return correctedEnergy;
+  }
+
+  public double getRawEnergy() {
+    if (lEnergy) { return rawEnergy; }
+
+    rawEnergy = correctedEnergy = 0;
+    for (SimCalorimeterHit hit : gangedHitList) {
+      rawEnergy       += hit.getRawEnergy();
+      correctedEnergy += hit.getCorrectedEnergy();
+    }
+    lEnergy = true;
+    return rawEnergy;
+  }
+  
+  public boolean getOffset()
+  {
+    return offset;
+  }
+
+  public int getID()
+  {
+    return gangedCalorimeterHitID;
+  }
+
+  public GangedCalorimeterHitLinkedList insertElement(SimCalorimeterHit h)
+  {
+    int id = getGangedCalorimeterID(h);
+    GangedCalorimeterHitLinkedList current = this;
+    GangedCalorimeterHitLinkedList return_value;
+    // move forward until you find something bigger, or the end
+    while (current.next != null &&
+	   id > current.getID()) {
+      current = current.next;
+    }
+    // now move back until you find something smaller, or the beginning
+    while (current.prev != null &&
+	   id < current.getID()) {
+      current = current.prev;
+    }
+
+    // found list node with same id -- just add the hit
+    if (id == current.getID()) {
+      current.addHit(h);
+    }
+    // if reached the beginning, insert before
+    else if (id < current.getID()) {
+      return_value = new GangedCalorimeterHitLinkedList(h,this);
+      current.insertBeforeThis(return_value);
+      current = return_value;
+    }
+    // otherwise, add after
+    else {
+      return_value = new GangedCalorimeterHitLinkedList(h,this);
+      current.insertAfterThis(return_value);
+      current = return_value;
+    }
+    return current;
+  }
+
+  public void addHit(SimCalorimeterHit h) 
+  {
+    //decoder.setID(h.getCellID());
+    //int layer    = decoder.getIDDescription().indexOf("layer");
+    //int phi      = decoder.getIDDescription().indexOf("phi");
+    //int theta    = decoder.getIDDescription().indexOf("theta");	
+    //System.out.println("adding hit:");
+    //System.out.print("id of node is: ");
+    //this.printID();
+    //System.out.println("layer = "+layer+
+    //	       " ; phiBin = "+phi+
+    //	       " ; thetaBin = "+theta);
+    gangedHitList.add(h);
+    lEnergy = false;
+  }
+
+  public void insertBeforeThis(GangedCalorimeterHitLinkedList insert)
+  {
+    //System.out.print("-");
+    insert.next = this;
+    insert.prev = this.prev;
+
+    if (this.prev != null)
+      this.prev.next = insert;
+    this.prev = insert;
+  }
+
+  public void insertAfterThis(GangedCalorimeterHitLinkedList insert)
+  {
+    //System.out.print("+");
+    insert.prev = this;
+    insert.next = this.next;
+
+    if (this.next != null)
+      this.next.prev = insert;
+    this.next      = insert;
+  }
+
+  public void printID() 
+  {
+    System.out.println("layer = "+(gangedCalorimeterHitID/(1024*1024))+
+		       " ; phiBin = "+((gangedCalorimeterHitID/1024)%1024)+
+		       " ; thetaBin = "+(gangedCalorimeterHitID%1024));
+  }
+
+  public void print()
+  {
+    GangedCalorimeterHitLinkedList current = this;
+    while (current.prev != null) {
+      current = current.prev;
+    }
+    int iNode=0;
+    while (current != null) {
+      System.out.print("Node "+iNode+": \t"); iNode++;
+      current.printID();
+      int iHit = 0;
+      for (SimCalorimeterHit h : current.gangedHitList){
+	System.out.print("     Hit "+iHit+": \t"); iHit++;
+	System.out.println("layer = "+getLayer(h)+
+			   " ; phiBin = "+getPhiBin(h)+
+			   " ; thetaBin = "+getThetaBin(h));
+      }
+      current = current.next;
+    }
+  }
+
+  public int getLayer(SimCalorimeterHit h) 
+  {
+    decoder.setID(h.getCellID());
+    int layer = decoder.getValue("layer");
+    return layer;//decoder.getValue(descriptor.indexOf("layer"));
+  }
+
+  public int getPhiBin(SimCalorimeterHit h) 
+  {
+    decoder.setID(h.getCellID());
+    return decoder.getValue("phi");
+  }
+
+  public int getThetaBin(SimCalorimeterHit h) 
+  {
+    decoder.setID(h.getCellID());
+    return decoder.getValue("theta");
+  }
+
+  public Vector<SimCalorimeterHit> getAveragedHitList()
+  {
+    Vector<SimCalorimeterHit> averagedHitList = new Vector<SimCalorimeterHit>();
+    GangedCalorimeterHitLinkedList current = this;
+    while (current.prev != null) { current = current.prev; }
+    while (current != null) {
+      averagedHitList.addAll(current.getAveragedHits());
+      current = current.next;
+    }
+    return averagedHitList;
+  }
+
+  public Vector<SimCalorimeterHit> getAveragedHits()
+  {
+    // need the following items for a CalorimeterHit:
+    long cellID; // separate for each
+    double rawEnergy = 0; // computed below
+    double correctedEnergy = 0; // computed below
+    IDDecoder decoder = this.decoder; // = gangedHitList.get(0).getIDDecoder();
+    double time = 0; // computed below
+    if (gangedHitList.size() == 0) {
+      return null;
+    }
+    
+    Subdetector sub = gangedHitList.get(0).getSubdetector();
+
+    Vector<MCParticle> contributingParticles = new Vector<MCParticle>();
+    for (SimCalorimeterHit hit : gangedHitList) {
+      rawEnergy       += hit.getRawEnergy();
+      correctedEnergy += hit.getCorrectedEnergy();
+      time            += hit.getTime();
+      for (int i=0; i<hit.getMCParticleCount(); ++i){
+	MCParticle part = hit.getMCParticle(i);
+	if (! contributingParticles.contains(part)) {
+	  contributingParticles.add(part);
+	}
+      }
+    }
+    rawEnergy /= (nGroup*nGroup);
+    correctedEnergy /= (nGroup*nGroup);
+    time /= gangedHitList.size();
+
+    // need these (and contributingParticles Vector) for a SimCalorimeterHit
+    int size = contributingParticles.size();
+    double contributedEnergy[] = new double[size];
+    double contributedTime[] = new double[size];
+
+    for (SimCalorimeterHit hit : gangedHitList) {
+      for (int i=0; i<hit.getMCParticleCount(); ++i) {
+	MCParticle part = hit.getMCParticle(i);
+	int j = contributingParticles.indexOf(part);
+	contributedEnergy[j] += hit.getContributedEnergy(i);
+	contributedTime[j] = hit.getContributedTime(i); // approximation
+      }
+    }
+    // average the energy contribution
+    for (int j=0; j<contributingParticles.size(); ++j) {
+      contributedEnergy[j] /= (nGroup*nGroup);
+    }
+
+    Vector<SimCalorimeterHit> hits
+      = new Vector<SimCalorimeterHit>(nGroup*nGroup);
+
+    for (int i=0; i<nGroup; ++i) {
+      for (int j=0; j<nGroup; ++j) {
+	cellID = makeConstituentHitID(i,j);
+	hits.add(new AveragedCalorimeterHit(cellID,
+					    rawEnergy,
+					    correctedEnergy,
+					    decoder,
+					    time,
+					    sub,
+					    size,
+					    contributingParticles,
+					    contributedEnergy,
+					    contributedTime));
+      }
+    }
+    return hits;
+  }
+
+  private long makeConstituentHitID(int i, int j)
+  {
+    //CalorimeterHit hit = gangedHitList.get(0);
+    //ProjectiveCylinder decoder = (ProjectiveCylinder) hit.getIDDecoder();
+    //IDDescriptor descriptor = decoder.getIDDescription();
+    IDEncoder encoder = new IDEncoder(descriptor);
+
+    decoder.setID(gangedHitList.get(0).getCellID());
+
+    //int buffer[] = new int[descriptor.fieldCount()];
+
+    for (int index=0; index<descriptor.fieldCount(); ++index) {
+      encoder.setValue(index, decoder.getValue(descriptor.fieldName(index)));
+    }
+
+    //int layer               = decoder.getValue("layer");
+    //int thetaBin            = decoder.getValue("theta");
+    //int phiBin              = decoder.getValue("phi");
+    //thetaBin += i - thetaBin%nGroup;
+    //phiBin   += j - phiBin%nGroup;
+
+    //if (offset) {
+    //  phiBin   -= (layer%2)*(nGroup/2);
+    //  thetaBin -= (layer%2)*(nGroup/2);
+    //}
+
+    ProjectiveCylinder projective = (ProjectiveCylinder) decoder;
+    int thetaMax = projective.getThetaBins();
+    int phiMax   = projective.getPhiBins();
+
+    int layer    = this.getLayer();
+    int thetaBin = this.getThetaBin();
+    int phiBin   = this.getPhiBin();
+
+    thetaBin *= nGroup;
+    phiBin   *= nGroup;
+    if (offset) {
+      thetaBin -= (layer%2)*(nGroup/2);
+      phiBin   -= (layer%2)*(nGroup/2);
+    }
+    thetaBin += i;
+    phiBin   += j;
+    if (thetaBin < 0) { thetaBin += thetaMax; }
+    if (phiBin   < 0) { phiBin   += phiMax;   }
+    thetaBin = thetaBin % thetaMax;
+    phiBin   = phiBin   % phiMax;
+    
+    encoder.setValue("theta", thetaBin);
+    encoder.setValue("phi",   phiBin);
+
+    return encoder.getID();
+  }
+
+  public void printListData()
+  {
+    GangedCalorimeterHitLinkedList current = this;
+    while (this.prev != null) { current = this.prev; }
+    while (current != null) {
+      current.printData();
+      current = current.next;
+    }
+  }
+
+  public void printData()
+  {
+    System.out.println("node: (layer,phi,theta) = ("+
+		       this.getLayer()+","+
+		       this.getPhiBin()+","+
+		       this.getThetaBin()+")");
+    for (SimCalorimeterHit h : gangedHitList) {
+      ProjectiveCylinder d = (ProjectiveCylinder) h.getIDDecoder();
+      d.setID(h.getCellID());
+      int layer = d.getValue(d.getIDDescription().indexOf("layer"));
+      int theta = d.getValue(d.getIDDescription().indexOf("theta"));
+      int phi   = d.getValue(d.getIDDescription().indexOf("phi"));
+      double energy = h.getRawEnergy();
+      System.out.println("Hit: "+
+			 "layer = "+layer+"  \t; "+
+			 "theta = "+theta+"  \t; "+
+			 "phi   = "+phi+"  \t; "+
+			 "energy = "+energy);
+    }
+    System.out.println();
+  }
+}

lcsim/src/org/lcsim/contrib/proulx/ganging
GangingDriver.java added at 1.1
diff -N GangingDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ GangingDriver.java	12 Jan 2006 21:52:55 -0000	1.1
@@ -0,0 +1,49 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.util.*;
+import org.lcsim.util.event.*;
+import org.lcsim.geometry.*;
+import org.lcsim.geometry.util.*;
+import org.lcsim.geometry.segmentation.*;
+
+import hep.aida.*;
+import hep.physics.vec.*;
+
+final public class GangingDriver extends Driver
+{
+  protected void process(EventHeader event)
+  {
+    System.out.println("called GangingDriver.process() for event "+event.getEventNumber());
+    
+    List<List<CalorimeterHit>> calHitCollections = event.get(CalorimeterHit.class);
+    for ( List<CalorimeterHit> calHits : calHitCollections )
+    {
+      EventHeader.LCMetaData metaData = event.getMetaData(calHits);
+      String hitListName = metaData.getName();
+      int flags = metaData.getFlags();
+      if (hitListName.contains("Ecal") && hitListName.contains("Barr")) 
+      {
+	if (calHits.size()>0) {
+	  //System.out.println("executing ganging");
+	  GangedCalorimeterHitLinkedList linkedList = new GangedCalorimeterHitLinkedList(calHits,true);
+	  event.put(hitListName+"Ganged",linkedList.getAveragedHitList(),SimCalorimeterHit.class,flags,hitListName);
+	  
+	}
+      }
+    }
+  } //end process
+}
+
+
+
+
+
+
+

lcsim/src/org/lcsim/contrib/proulx/ganging
UnGangedCalorimeterHitLinkedList.java added at 1.1
diff -N UnGangedCalorimeterHitLinkedList.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ UnGangedCalorimeterHitLinkedList.java	12 Jan 2006 21:52:55 -0000	1.1
@@ -0,0 +1,122 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.geometry.segmentation.ProjectiveCylinder;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.geometry.util.IDEncoder;
+import org.lcsim.geometry.util.IDDescriptor;
+
+public class UnGangedCalorimeterHitLinkedList extends GangedCalorimeterHitLinkedList
+{
+  public UnGangedCalorimeterHitLinkedList (List<CalorimeterHit> calHits,
+					   boolean off)
+  {
+    super(calHits,off);
+  }
+
+  public Vector<SimCalorimeterHit> getAveragedHitList()
+  {
+    Vector<SimCalorimeterHit> averagedHitList = new Vector<SimCalorimeterHit>();
+    GangedCalorimeterHitLinkedList current = this;
+    while (current.prev != null) { current = current.prev; }
+
+    while (current != null) {
+      Vector<SimCalorimeterHit> newHits = this.getAveragedHits(current);
+      averagedHitList.addAll(newHits);
+      System.out.println("Added "+newHits.size()+" hits");
+      current = current.next;
+    }
+    return averagedHitList;
+  }
+
+  public Vector<SimCalorimeterHit> getAveragedHits(GangedCalorimeterHitLinkedList node) {
+    System.out.println("debug");
+    Vector<SimCalorimeterHit> hits
+      = new Vector<SimCalorimeterHit>();
+
+    // this works only if there is an offset of 1/2 per layer
+    if (!node.getOffset() || node.getNGroup()!=2) {
+      return node.getAveragedHits();
+    }
+
+    Vector<SimCalorimeterHit> averagedHits = node.getAveragedHits();
+    // get total energy in neighbors
+    double neighborEnergy = 0;
+
+    // make sure there are neighbors so that you can do something
+    for (SimCalorimeterHit hit : averagedHits) {
+      int idAbove = getGangedIDAbove(hit);
+      int idBelow = getGangedIDBelow(hit);
+      // loop through the list to get the neighbors
+      GangedCalorimeterHitLinkedList current = node;
+      while (current.prev != null) { current = current.prev; }
+      while (current != null) {
+	if (current.getID() == idAbove ||
+	    current.getID() == idBelow) {
+	  neighborEnergy += current.getRawEnergy();
+	}
+
+	// go to the next event
+	current = current.next;
+      }
+    }
+
+    if (neighborEnergy > 0) {
+      for (SimCalorimeterHit hit : averagedHits) {
+	System.out.println("Hit: ("+
+			   node.getLayer(hit)+","+
+			   node.getPhiBin(hit)+","+
+			   node.getThetaBin(hit)+")");
+	double scaleFactor = 0;
+	int idAbove = getGangedIDAbove(hit);
+	int idBelow = getGangedIDBelow(hit);
+	// loop through the list to get the neighbors
+	GangedCalorimeterHitLinkedList current = node;
+	while (current.prev != null) { current = current.prev; }
+	while (current != null) {
+	  if (current.getID() == idAbove ||
+	      current.getID() == idBelow) {
+	    scaleFactor += current.getRawEnergy();
+	  }
+	  // go to the next event
+	  current = current.next;
+	}
+	scaleFactor /= neighborEnergy;
+	scaleFactor *= 4;
+
+	if (scaleFactor>0) {
+	  hits.add(new AveragedCalorimeterHit(hit,scaleFactor));
+	}
+      }
+    } else {
+      for (SimCalorimeterHit hit : averagedHits) {
+	hits.add(new AveragedCalorimeterHit(hit));
+      }
+    }
+    
+    return hits;
+  }
+
+  private int getGangedIDAbove(SimCalorimeterHit h) {
+    return getGangedIDNeighbor(h,1,0,0);
+  }
+
+  private int getGangedIDBelow(SimCalorimeterHit h) {
+    return getGangedIDNeighbor(h,-1,0,0);
+  }
+
+  private int getGangedIDNeighbor(SimCalorimeterHit h,
+				  int layer, int phibins, int thetabins) {
+    return this.getGangedCalorimeterID(this.getLayer(h)    + layer,
+				       this.getPhiBin(h)   + phibins,
+				       this.getThetaBin(h) + thetabins);
+
+  }
+}

lcsim/src/org/lcsim/contrib/proulx/ganging
UnGangingDriver.java added at 1.1
diff -N UnGangingDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ UnGangingDriver.java	12 Jan 2006 21:52:56 -0000	1.1
@@ -0,0 +1,44 @@
+package org.lcsim.contrib.proulx.ganging;
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.lcsim.event.*;
+import org.lcsim.util.*;
+import org.lcsim.util.event.*;
+import org.lcsim.geometry.*;
+import org.lcsim.geometry.util.*;
+import org.lcsim.geometry.segmentation.*;
+
+import hep.aida.*;
+import hep.physics.vec.*;
+
+final public class UnGangingDriver extends Driver
+{
+  protected void process(EventHeader event)
+  {
+    System.out.println("called UnGangingDriver.process() for event "+event.getEventNumber());
+    
+    List<List<CalorimeterHit>> calHitCollections = event.get(CalorimeterHit.class);
+    for ( List<CalorimeterHit> calHits : calHitCollections )
+    {
+      EventHeader.LCMetaData metaData = event.getMetaData(calHits);
+      String hitListName = metaData.getName();
+      int flags = metaData.getFlags();
+      if (hitListName.contains("Ecal") &&
+	  hitListName.contains("Barr") &&
+	  hitListName.contains("Ganged")) 
+      {
+	if (calHits.size()>0) {
+	  //System.out.println("executing ganging");
+	  UnGangedCalorimeterHitLinkedList linkedList = new UnGangedCalorimeterHitLinkedList(calHits,true);
+	  event.put("EcalBarrHitsUnGanged",linkedList.getAveragedHitList(),SimCalorimeterHit.class,flags,"EcalBarrHits");
+	  
+	}
+      }
+    }
+  } //end process
+}
CVSspam 0.2.8