Commit in projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence on MAIN
Cell.java+54added 2977
Cell3D.java+115added 2977
NNAlgo.java+195added 2977
NNAlgoClusterDriver.java+121added 2977
NNCluster.java+99added 2977
+584
5 added files
Nearest-Neighbor Clustering with a local equivalence based on cell energy

projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence
Cell.java added at 2977
--- projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/Cell.java	                        (rev 0)
+++ projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/Cell.java	2014-02-12 00:36:53 UTC (rev 2977)
@@ -0,0 +1,54 @@
+/*
+ * Cell.java
+ *
+ * Created on April 4, 2006, 11:09 AM
+ *
+ * $Id: $
+ */
+package org.lcsim.recon.cluster.localequivalence;
+
+/**
+ * A cell with properties adapted to a nearest-neighbor clustering algorithm
+ * whose metric for "nearest" is based on value().
+ *
+ * @author Norman Graf
+ */
+public abstract class Cell implements Comparable
+{
+    /**
+     *
+     * @return A value for weighting multiple neighbors.
+     */
+    public abstract double value();
+
+    /**
+     *
+     * @return A unique identifier associated with this cell
+     */
+    public abstract long cellID();
+
+    /**
+     *
+     * @return A Cell to which this Cell points.
+     */
+    public abstract Cell pointsTo();
+
+    /**
+     *
+     * @param pointsto Assign a Cell to which this Cell points.
+     */
+    public abstract void pointsTo(Cell pointsto);
+
+    /**
+     *
+     * @param cell Assign a Cell which points to this Cell.
+     */
+    public abstract void pointedTo(Cell cell);
+
+    /**
+     *
+     * @return A Cell which points to this Cell.
+     */
+    public abstract Cell pointedTo();
+
+}
\ No newline at end of file

projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence
Cell3D.java added at 2977
--- projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/Cell3D.java	                        (rev 0)
+++ projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/Cell3D.java	2014-02-12 00:36:53 UTC (rev 2977)
@@ -0,0 +1,115 @@
+/*
+ * Cell3D.java
+ *
+ * Created on April 4, 2006, 11:11 AM
+ *
+ * $Id: $
+ */
+
+package org.lcsim.recon.cluster.localequivalence;
+
+import org.lcsim.event.CalorimeterHit;
+
+/**
+ * A Cell based on a CalorimeterHit
+ * 
+ * @author Norman Graf
+ */
+public class Cell3D extends Cell
+{
+    private double _value;
+    private Cell _pointsTo;
+    private Cell _pointedTo;
+    private CalorimeterHit _calhit;
+    
+    
+    /** Basic Constructor
+     * @param value The value of this Cell.
+     */
+    public Cell3D(double value)
+    {
+        _value = value;
+        _pointsTo = this;
+        _pointedTo = this;
+        _calhit = null;
+    }
+    
+    /**
+     * @param value The value of this Cell.
+     * @param hit   The CalorimeterHit on which this Cell is based.
+     */
+    public Cell3D(double value, CalorimeterHit hit)
+    {
+        _value = value;
+        _pointsTo = this;
+        _pointedTo = this;
+        _calhit = hit;
+    }
+    
+    /**
+     *
+     * @param hit Assign the CalorimeterHit to this Cell
+     */
+    public Cell3D(CalorimeterHit hit)
+    {
+        _value = hit.getCorrectedEnergy();
+        _pointsTo = this;
+        _pointedTo = this;
+        _calhit = hit;
+    }    
+    
+    public double value()
+    {
+        return _value;
+    }
+    
+    public Cell pointsTo()
+    {
+        return _pointsTo;
+    }
+    
+    public void pointsTo(Cell pointsto)
+    {
+        _pointsTo = pointsto;
+    }
+    
+    public void pointedTo(Cell cell)
+    {
+        _pointedTo = cell;
+    }
+
+    public long cellID()
+    {
+        return _calhit.getCellID();
+    }
+    
+    public Cell pointedTo()
+    {
+        return _pointedTo;
+    }
+    
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer(" Cell3D "+cellID()+" with value "+_value+"\n");
+        sb.append("pointed to by: "+_pointedTo.cellID()+"\n");
+        sb.append("points to: "+_pointsTo.cellID()+"\n");
+        return sb.toString();
+   }
+    
+    // Comparable interface
+    public int compareTo(Object o)
+    {
+        double value = ( (Cell3D) o)._value;
+        return (_value < value ? -1 : (_value == value ? 0 : 1));
+    }
+    
+    /**
+     *
+     * @return The CalorimeterHit on which this Cell is based.
+     */
+    public CalorimeterHit getCalorimeterHit()
+    {
+        return _calhit;
+    }
+    
+}
\ No newline at end of file

projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence
NNAlgo.java added at 2977
--- projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/NNAlgo.java	                        (rev 0)
+++ projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/NNAlgo.java	2014-02-12 00:36:53 UTC (rev 2977)
@@ -0,0 +1,195 @@
+/*
+ * NNAlgo.java
+ *
+ * Created on April 4, 2006, 11:16 AM
+ *
+ * $Id: $
+ */
+
+package org.lcsim.recon.cluster.localequivalence;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.geometry.IDDecoder;
+
+/**
+ * A nearest-neighbor clustering algorithm which associates hits with their
+ * highest-energy neighboring hit
+ * 
+ * @author Norman Graf
+ */
+public class NNAlgo
+{
+    
+//  miniumum cluster energy...
+    private double _minValue = 0.;
+    private int _deltaLayer = 1;
+    private int _deltaTheta = 1;
+    private int _deltaPhi = 1;
+    
+    public NNAlgo(double  min)
+    {
+        _minValue = min;
+    }
+    
+    public NNAlgo(double  min, int deltaLayer, int deltaTheta, int deltaPhi)
+    {
+        _minValue = min;
+        _deltaLayer = deltaLayer;
+        _deltaTheta = deltaTheta;
+        _deltaPhi = deltaPhi;
+    }
+    
+    public void setMinValue(double min)
+    {
+        _minValue = min;
+    }
+    
+    public List<NNCluster> cluster(Map<Long, CalorimeterHit> hitmap)
+    {
+        List<Cell> cells = new ArrayList<Cell>();
+        Map<Long, Cell> cellmap = new HashMap<Long, Cell>();
+        Collection<CalorimeterHit> hits = hitmap.values();
+        for(CalorimeterHit hit : hits)
+        {
+            Cell3D cell = new Cell3D(hit);
+            cells.add(cell);
+            long key = hit.getCellID();
+            cellmap.put(key, cell);
+//            System.out.println(decodeCalHit(hit));
+        }
+        Collections.sort(cells);
+        Collections.reverse(cells);
+//        System.out.println(cells);
+        // now loop over the energy-sorted list of cells...
+        for(Cell cell : cells)
+        {
+            Cell3D c3d = (Cell3D) cell;
+//            System.out.println(c3d);
+            Cell pointsto = cell.pointsTo();
+            double max = cell.value();
+            CalorimeterHit c = c3d.getCalorimeterHit();
+            IDDecoder decoder = c.getIDDecoder();
+            decoder.setID(c.getCellID());
+            // loop over neighbors...
+            long[] neighbors = decoder.getNeighbourIDs(_deltaLayer, _deltaTheta, _deltaPhi);
+//            System.out.println("");
+//            System.out.println("");
+//            System.out.println("  hit "+decodeCalHit(c));
+            for (int j=0; j<neighbors.length; ++j)
+            {
+//                System.out.println("  j: "+j);
+//                System.out.println("  "+decodeCellID(neighbors[j],c.getIDDecoder()));
+//                System.out.println(c3d.cellID()+ " j= "+j+" neighbor= "+neighbors[j]);
+                CalorimeterHit h = hitmap.get(neighbors[j]);
+                // is the neighboring cell id hit?
+                // if so, does it meet or exceed threshold?
+                if (h != null)
+                {
+//                    System.out.println("   hit neighbor "+ decodeCalHit(h));
+                    Cell neigh = cellmap.get(neighbors[j]);
+                    // find highest neighbor to point to...
+                    if (neigh.value() > max) //Note difference between > and >=
+                    {
+                        max = neigh.value();
+                        pointsto = neigh;
+                    }
+                }
+            } // end of loop over neighbors...
+            // If cell does not point to itself set pointedto and pointsto
+            if (cell != pointsto)
+            {
+                cell.pointsTo(pointsto);
+                pointsto.pointedTo().pointsTo(cell);
+                cell.pointedTo(pointsto.pointedTo());           
+                pointsto.pointedTo(cell);
+            }
+        }
+        
+        // This is the end of the clustering algorithm
+//        System.out.println("Done clustering! \n");
+//        System.out.println(cells);
+        // Build clusters here, with deletion of map entries
+        
+        // A collection to hold the clusters
+        List<NNCluster> clusters = new ArrayList<NNCluster>();
+//                // The set of linked cells in the map
+        Set set = cellmap.entrySet();
+//
+        int cluster  = 0;
+        int size = cellmap.size();
+        Iterator it;
+        while(size>0)
+        {
+            it = set.iterator();
+            Map.Entry entry = (Map.Entry) it.next();
+            Cell cell = (Cell) entry.getValue();
+            Cell nextcell = cell.pointsTo();
+            
+            ++cluster;
+            NNCluster clus = new NNCluster();
+            // loop over all cells pointed to by this cell recursively
+            while(cellmap.containsValue(cell))
+            {
+                clus.addCell(cell);
+                cellmap.remove(cell.cellID());
+//
+                cell = nextcell;
+                nextcell = cell.pointsTo();
+            }
+            // done with this cluster
+            // If over threshold, add it to the list of clusters to return
+            if(clus.value()>_minValue)
+            {
+                clusters.add(clus);
+                SortedSet clusCells = clus.cells();
+                for(Object o : clusCells)
+                {
+                    Cell3D c = (Cell3D) o;
+                    // remove the associated calorimeter hit from the input map.
+                    hitmap.remove(c.cellID());
+                }
+            }
+            size = cellmap.size();
+        } // end of clustering loop over map
+        return clusters;
+    }
+    
+    public String toString()
+    {
+        return "A Nearest Neighbor Clusterer with min value "+_minValue;
+    }
+    
+    String decodeCalHit(CalorimeterHit hit)
+    {
+        StringBuffer sb = new StringBuffer();
+        IDDecoder decoder = hit.getIDDecoder();
+        decoder.setID(hit.getCellID());
+        int nFields = decoder.getFieldCount();
+        for(int i=0; i<nFields; ++i)
+        {
+            sb.append(" "+decoder.getFieldName(i)+" : "+decoder.getValue(i));
+        }
+        return sb.toString();
+    }
+    
+    String decodeCellID(long key, IDDecoder decoder)
+    {
+        StringBuffer sb = new StringBuffer();
+        decoder.setID(key);
+        int nFields = decoder.getFieldCount();
+        for(int i=0; i<nFields; ++i)
+        {
+            sb.append(" "+decoder.getFieldName(i)+" : "+decoder.getValue(i));
+        }
+        return sb.toString();
+    }
+}

projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence
NNAlgoClusterDriver.java added at 2977
--- projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/NNAlgoClusterDriver.java	                        (rev 0)
+++ projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/NNAlgoClusterDriver.java	2014-02-12 00:36:53 UTC (rev 2977)
@@ -0,0 +1,121 @@
+/*
+ * NNAlgoClusterDriver.java
+ *
+ * Created on April 4, 2006, 2:37 PM
+ *
+ * $Id: $
+ */
+
+package org.lcsim.recon.cluster.localequivalence;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.event.base.BaseCluster;
+import org.lcsim.lcio.LCIOConstants;
+
+/**
+ *
+ * @author Norman Graf
+ */
+public class NNAlgoClusterDriver extends Driver
+{
+    // the neighborhood in u to search
+    private int _dU;
+    // the neighborhood in v to search
+    private int _dV;
+    // the neighborood in layers to search
+    private int _dLayer;
+    // energy threshold
+    private double _thresh;
+    
+    private NNAlgo _clusterer;
+    
+    private boolean _doall;
+    private String[] _collNames;
+    private String _nameExt;
+   
+    private boolean debug;
+    
+    /** Creates a new instance of NNAlgoClusterDriver */
+    // JAS needs default constructor
+    public NNAlgoClusterDriver()
+    {
+        this(3, 3, 5, .1); // why was this 15?
+    }
+    // fully qualified constructor
+    public NNAlgoClusterDriver(int dU, int dV, int dLayer, double threshold)
+    {
+        _dU = dU;
+        _dV = dV;
+        _dLayer = dLayer;
+        _thresh = threshold;
+        _doall = false;
+        _collNames = new String[2];
+        _collNames[0] = "EcalBarrelHits";
+        _collNames[1] = "EcalEndcapHits";
+        _nameExt = "EMClusters";
+        _clusterer = new NNAlgo(_thresh, _dLayer, _dU, _dV);
+    }
+    
+    protected void process(EventHeader event)
+    {
+        //First look for clusters in individual collections
+        
+        List<List<CalorimeterHit>> collections = event.get(CalorimeterHit.class);
+        for (List<CalorimeterHit> collection: collections)
+        {
+            String name = event.getMetaData(collection).getName();
+            boolean doit = false;
+            if(_doall)
+            {
+                doit = true;
+            }
+            else
+            {
+                for(int i=0;i<_collNames.length;i++)
+                {
+                    if(name.compareTo(_collNames[i]) == 0)
+                    {
+                        doit = true;
+                        break;
+                    }
+                }
+            }
+            if(doit)
+            {
+                Map<Long, CalorimeterHit> hitmap = new HashMap<Long, CalorimeterHit>();
+                for(CalorimeterHit hit : collection)
+                {
+                    hitmap.put(hit.getCellID(), hit);
+                }
+                List<NNCluster> clusters = _clusterer.cluster(hitmap);
+                
+                List<BaseCluster> bclus = new ArrayList<BaseCluster>();
+                for(NNCluster clus : clusters)
+                {
+                    if (clus.size()>5) // TODO fix this hard-coded cut
+                    {
+                        BaseCluster bc = new BaseCluster();
+                        List<CalorimeterHit> hits = clus.hits();
+                        for(CalorimeterHit hit: hits)
+                        {
+                            bc.addHit(hit);
+                        }
+                        bclus.add(bc);
+                    }
+                }
+                if (bclus.size() > 0)
+                {
+                    int flag = 1 << LCIOConstants.CLBIT_HITS;
+                    event.put(name+_nameExt,bclus,Cluster.class,(1<<31));
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence
NNCluster.java added at 2977
--- projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/NNCluster.java	                        (rev 0)
+++ projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence/NNCluster.java	2014-02-12 00:36:53 UTC (rev 2977)
@@ -0,0 +1,99 @@
+/*
+ * NNCluster.java
+ *
+ * Created on April 4, 2006, 11:16 AM
+ *
+ * $Id: $
+ */
+
+package org.lcsim.recon.cluster.localequivalence;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.lcsim.event.CalorimeterHit;
+
+/**
+ * A simple Cluster which contains a list of constituent CalorimeterHits
+ * @author Norman Graf
+ */
+public class NNCluster implements Comparable
+{
+    // attributes
+    private SortedSet _cells;
+    private double _value = 0;
+    private List<CalorimeterHit> _hits = new ArrayList<CalorimeterHit>();
+    
+    // methods
+    
+    //Constructor
+    
+    public NNCluster()
+    {
+        _cells = new TreeSet( new Comparator()
+        {
+            public int compare(Object o1, Object o2)
+            {
+                // sort first on the value of the cell...
+                double value1 = ((Cell)o1).value();
+                double value2 = ((Cell)o2).value();
+                if(value1!=value2) return (value1< (value2) ? -1 : (value1 == (value2) ? 0 : 1));
+                // if both cells have the same value, let the cellID decide
+                long ndx1 = ((Cell)o1).cellID();
+                long ndx2 = ((Cell)o2).cellID();
+                return (ndx1<ndx2 ? -1 : ((ndx1==ndx2) ? 0 : 1));
+                
+            }
+        }
+        );
+    }
+    
+    public SortedSet cells()
+    {
+        return _cells;
+    }
+    
+    public int size()
+    {
+        return _cells.size();
+    }
+    
+    public void addCell(Cell cell)
+    {
+        _cells.add(cell);
+        _value+=cell.value();
+        Cell3D c3d = (Cell3D) cell;
+        _hits.add(c3d.getCalorimeterHit());
+    }
+    
+    public List<CalorimeterHit> hits()
+    {
+        return _hits;
+    }
+    
+    public Cell highestCell()
+    {
+        return (Cell)_cells.last();
+    }
+    
+    public double value()
+    {
+        return _value;
+    }
+    
+    // Comparable interface
+    public int compareTo(Object o)
+    {
+        double value = ( (NNCluster) o)._value;
+//        System.out.println("in compareTo this.value= "+_value+" that.value = "+value);
+//        System.out.println(_value < value ? -1 : (_value == value ? 0 : 1));
+        return (_value < value ? -1 : (_value == value ? 0 : 1));
+    }    
+    
+    public String toString()
+    {
+        return "\n NNCluster with "+size()+" cells, centered at "+highestCell().cellID()+" value= "+_value+"\n"+_cells;
+    }
+}
SVNspam 0.1


Use REPLY-ALL to reply to list

To unsubscribe from the LCDET-SVN list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCDET-SVN&A=1