1
2
3
4
5
6
7
8
9 package org.lcsim.recon.cluster.localequivalence;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.SortedSet;
20 import org.lcsim.event.CalorimeterHit;
21 import org.lcsim.geometry.IDDecoder;
22
23
24
25
26
27
28
29 public class NNAlgo
30 {
31
32
33 private double _minValue = 0.;
34 private int _deltaLayer = 1;
35 private int _deltaTheta = 1;
36 private int _deltaPhi = 1;
37
38 public NNAlgo(double min)
39 {
40 _minValue = min;
41 }
42
43 public NNAlgo(double min, int deltaLayer, int deltaTheta, int deltaPhi)
44 {
45 _minValue = min;
46 _deltaLayer = deltaLayer;
47 _deltaTheta = deltaTheta;
48 _deltaPhi = deltaPhi;
49 }
50
51 public void setMinValue(double min)
52 {
53 _minValue = min;
54 }
55
56 public List<NNCluster> cluster(Map<Long, CalorimeterHit> hitmap)
57 {
58 List<Cell> cells = new ArrayList<Cell>();
59 Map<Long, Cell> cellmap = new HashMap<Long, Cell>();
60 Collection<CalorimeterHit> hits = hitmap.values();
61 for(CalorimeterHit hit : hits)
62 {
63 Cell3D cell = new Cell3D(hit);
64 cells.add(cell);
65 long key = hit.getCellID();
66 cellmap.put(key, cell);
67
68 }
69 Collections.sort(cells);
70 Collections.reverse(cells);
71
72
73 for(Cell cell : cells)
74 {
75 Cell3D c3d = (Cell3D) cell;
76
77 Cell pointsto = cell.pointsTo();
78 double max = cell.value();
79 CalorimeterHit c = c3d.getCalorimeterHit();
80 IDDecoder decoder = c.getIDDecoder();
81 decoder.setID(c.getCellID());
82
83 long[] neighbors = decoder.getNeighbourIDs(_deltaLayer, _deltaTheta, _deltaPhi);
84
85
86
87 for (int j=0; j<neighbors.length; ++j)
88 {
89
90
91
92 CalorimeterHit h = hitmap.get(neighbors[j]);
93
94
95 if (h != null)
96 {
97
98 Cell neigh = cellmap.get(neighbors[j]);
99
100 if (neigh.value() > max)
101 {
102 max = neigh.value();
103 pointsto = neigh;
104 }
105 }
106 }
107
108 if (cell != pointsto)
109 {
110 cell.pointsTo(pointsto);
111 pointsto.pointedTo().pointsTo(cell);
112 cell.pointedTo(pointsto.pointedTo());
113 pointsto.pointedTo(cell);
114 }
115 }
116
117
118
119
120
121
122
123 List<NNCluster> clusters = new ArrayList<NNCluster>();
124
125 Set set = cellmap.entrySet();
126
127 int cluster = 0;
128 int size = cellmap.size();
129 Iterator it;
130 while(size>0)
131 {
132 it = set.iterator();
133 Map.Entry entry = (Map.Entry) it.next();
134 Cell cell = (Cell) entry.getValue();
135 Cell nextcell = cell.pointsTo();
136
137 ++cluster;
138 NNCluster clus = new NNCluster();
139
140 while(cellmap.containsValue(cell))
141 {
142 clus.addCell(cell);
143 cellmap.remove(cell.cellID());
144
145 cell = nextcell;
146 nextcell = cell.pointsTo();
147 }
148
149
150 if(clus.value()>_minValue)
151 {
152 clusters.add(clus);
153 SortedSet clusCells = clus.cells();
154 for(Object o : clusCells)
155 {
156 Cell3D c = (Cell3D) o;
157
158 hitmap.remove(c.cellID());
159 }
160 }
161 size = cellmap.size();
162 }
163 return clusters;
164 }
165
166 public String toString()
167 {
168 return "A Nearest Neighbor Clusterer with min value "+_minValue;
169 }
170
171 String decodeCalHit(CalorimeterHit hit)
172 {
173 StringBuffer sb = new StringBuffer();
174 IDDecoder decoder = hit.getIDDecoder();
175 decoder.setID(hit.getCellID());
176 int nFields = decoder.getFieldCount();
177 for(int i=0; i<nFields; ++i)
178 {
179 sb.append(" "+decoder.getFieldName(i)+" : "+decoder.getValue(i));
180 }
181 return sb.toString();
182 }
183
184 String decodeCellID(long key, IDDecoder decoder)
185 {
186 StringBuffer sb = new StringBuffer();
187 decoder.setID(key);
188 int nFields = decoder.getFieldCount();
189 for(int i=0; i<nFields; ++i)
190 {
191 sb.append(" "+decoder.getFieldName(i)+" : "+decoder.getValue(i));
192 }
193 return sb.toString();
194 }
195 }