Commit in projects/lcsim/trunk/cal-recon/src/main/java/org/lcsim/recon/cluster/localequivalence on MAIN | |||
Cell.java | +54 | added 2977 | |
Cell3D.java | +115 | added 2977 | |
NNAlgo.java | +195 | added 2977 | |
NNAlgoClusterDriver.java | +121 | added 2977 | |
NNCluster.java | +99 | added 2977 | |
+584 |
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 (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 (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 (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 (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 (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; + } +}
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