gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / statistics / DefaultHistogramBand.java @ 8800
History | View | Annotate | Download (7.92 KB)
1 | 5456 | dmartinezizquierdo | package org.gvsig.raster.lib.buffer.impl.statistics; |
---|---|---|---|
2 | |||
3 | import java.util.ArrayList; |
||
4 | 5482 | fdiaz | import java.util.Collections; |
5 | 5533 | fdiaz | import java.util.Iterator; |
6 | 5456 | dmartinezizquierdo | import java.util.List; |
7 | |||
8 | import org.gvsig.raster.lib.buffer.api.Band; |
||
9 | 5493 | fdiaz | import org.gvsig.raster.lib.buffer.api.BufferManager; |
10 | 5456 | dmartinezizquierdo | import org.gvsig.raster.lib.buffer.api.statistics.HistogramBand; |
11 | import org.gvsig.raster.lib.buffer.api.statistics.HistogramClass; |
||
12 | |||
13 | |||
14 | 5482 | fdiaz | /**
|
15 | * @author fdiaz
|
||
16 | *
|
||
17 | */
|
||
18 | 5456 | dmartinezizquierdo | public class DefaultHistogramBand implements HistogramBand { |
19 | |||
20 | Band band; |
||
21 | List<HistogramClass> histogramClasses;
|
||
22 | |||
23 | 5482 | fdiaz | |
24 | 5456 | dmartinezizquierdo | public DefaultHistogramBand(Band band){
|
25 | this.band=band;
|
||
26 | this.histogramClasses=new ArrayList<HistogramClass>(); |
||
27 | } |
||
28 | |||
29 | 5482 | fdiaz | public DefaultHistogramBand(Band band, List<HistogramClass> histogramClasses){ |
30 | this.band=band;
|
||
31 | this.histogramClasses=histogramClasses;
|
||
32 | Collections.sort(this.histogramClasses); |
||
33 | } |
||
34 | |||
35 | 5456 | dmartinezizquierdo | @Override
|
36 | 5533 | fdiaz | public long getNumValues() { |
37 | long count = 0; |
||
38 | for (Iterator iterator = histogramClasses.iterator(); iterator.hasNext();) { |
||
39 | HistogramClass histogramClass = (HistogramClass) iterator.next(); |
||
40 | count += histogramClass.getValue(); |
||
41 | } |
||
42 | |||
43 | return count;
|
||
44 | 5456 | dmartinezizquierdo | } |
45 | |||
46 | @Override
|
||
47 | public int getDataType() { |
||
48 | return this.band.getDataType(); |
||
49 | } |
||
50 | |||
51 | @Override
|
||
52 | 5473 | dmartinezizquierdo | public long getHistogramValue(double value) { |
53 | HistogramClass histogramClass=getHistogramClass(value); |
||
54 | if (histogramClass==null){ |
||
55 | return 0; |
||
56 | }else{
|
||
57 | return histogramClass.getValue();
|
||
58 | } |
||
59 | 5456 | dmartinezizquierdo | } |
60 | |||
61 | 5473 | dmartinezizquierdo | private HistogramClass getHistogramClass(double value){ |
62 | for (HistogramClass histogramClass: histogramClasses){
|
||
63 | if (histogramClass.isIn(value)){
|
||
64 | return histogramClass;
|
||
65 | } |
||
66 | } |
||
67 | 5533 | fdiaz | |
68 | 5528 | llmarques | if(histogramClasses.size() == 0){ |
69 | return null; |
||
70 | } |
||
71 | 5533 | fdiaz | |
72 | 5528 | llmarques | HistogramClass lastHistogramClass = histogramClasses.get(histogramClasses.size()-1);
|
73 | if(lastHistogramClass.getMax() == value){
|
||
74 | return lastHistogramClass;
|
||
75 | } |
||
76 | 5533 | fdiaz | |
77 | 5473 | dmartinezizquierdo | return null; |
78 | 5456 | dmartinezizquierdo | } |
79 | |||
80 | @Override
|
||
81 | public boolean union(HistogramBand hist) { |
||
82 | 5473 | dmartinezizquierdo | //First we must check that histograms are compatible
|
83 | 5533 | fdiaz | if (this.getNumClasses()==hist.getNumClasses()){ |
84 | 5473 | dmartinezizquierdo | for (int i=0; i<histogramClasses.size(); i++){ |
85 | if ( this.getIntervalMin(i)!=hist.getIntervalMin(i) || |
||
86 | this.getIntervalMax(i)!=hist.getIntervalMax(i)){
|
||
87 | return false; |
||
88 | } |
||
89 | } |
||
90 | }else{
|
||
91 | return false; |
||
92 | } |
||
93 | //Once checked compatibility, values are added
|
||
94 | for (int i=0; i<histogramClasses.size(); i++){ |
||
95 | histogramClasses.get(i).increment(hist.getValueCount(i)); |
||
96 | } |
||
97 | return true; |
||
98 | 5456 | dmartinezizquierdo | } |
99 | |||
100 | @Override
|
||
101 | 5473 | dmartinezizquierdo | public long[] getFrequencies() { |
102 | 8582 | fdiaz | |
103 | Integer dataType = getDataType();
|
||
104 | |||
105 | int size;
|
||
106 | int rangeMin;
|
||
107 | int rangeMax;
|
||
108 | switch (dataType) {
|
||
109 | case BufferManager.TYPE_BYTE:
|
||
110 | rangeMin = 0;
|
||
111 | rangeMax = 255;
|
||
112 | size = 256;
|
||
113 | break;
|
||
114 | case BufferManager.TYPE_SHORT:
|
||
115 | rangeMin = Short.MIN_VALUE;
|
||
116 | rangeMax = Short.MAX_VALUE;
|
||
117 | size = rangeMax-rangeMin+1;
|
||
118 | break;
|
||
119 | case BufferManager.TYPE_USHORT:
|
||
120 | rangeMin = 0;
|
||
121 | rangeMax = Math.abs(Short.MIN_VALUE) + Short.MAX_VALUE; |
||
122 | size = rangeMax-rangeMin+1;
|
||
123 | break;
|
||
124 | case BufferManager.TYPE_INT:
|
||
125 | rangeMin = Integer.MIN_VALUE;
|
||
126 | rangeMax = Integer.MAX_VALUE;
|
||
127 | size = rangeMax-rangeMin+1;
|
||
128 | break;
|
||
129 | default:
|
||
130 | throw new IllegalArgumentException("Can't process type '" + dataType + "'"); |
||
131 | 5473 | dmartinezizquierdo | } |
132 | 8582 | fdiaz | long[] table = new long[size]; |
133 | for (int j = 0; j < table.length; j++) { |
||
134 | table[j] = getHistogramValue(j); |
||
135 | } |
||
136 | return table;
|
||
137 | |||
138 | 5456 | dmartinezizquierdo | } |
139 | |||
140 | @Override
|
||
141 | 5533 | fdiaz | public int getNumClasses() { |
142 | 5473 | dmartinezizquierdo | return histogramClasses.size();
|
143 | 5456 | dmartinezizquierdo | } |
144 | |||
145 | @Override
|
||
146 | 5473 | dmartinezizquierdo | public long getValueCount(int interval) { |
147 | return histogramClasses.get(interval).getValue();
|
||
148 | 5456 | dmartinezizquierdo | } |
149 | |||
150 | @Override
|
||
151 | 5473 | dmartinezizquierdo | public double getIntervalMin(int interval) { |
152 | return histogramClasses.get(interval).getMin();
|
||
153 | 5456 | dmartinezizquierdo | } |
154 | |||
155 | @Override
|
||
156 | 5473 | dmartinezizquierdo | public double getIntervalMax(int interval) { |
157 | return histogramClasses.get(interval).getMax();
|
||
158 | 5456 | dmartinezizquierdo | } |
159 | |||
160 | @Override
|
||
161 | 5473 | dmartinezizquierdo | public double getMedian() { |
162 | 5533 | fdiaz | double halfn=(getNumValues())/2d; |
163 | 5493 | fdiaz | return getUmpteenth(halfn);
|
164 | } |
||
165 | |||
166 | /**
|
||
167 | 5528 | llmarques | * Obtiene el en?simo valor
|
168 | 5493 | fdiaz | * @param n
|
169 | * @return
|
||
170 | */
|
||
171 | 5528 | llmarques | private double getUmpteenth(double n) { |
172 | long contValues = 0; |
||
173 | |||
174 | if (this.getDataType() == BufferManager.TYPE_FLOAT |
||
175 | || this.getDataType() == BufferManager.TYPE_DOUBLE) { // Valores no |
||
176 | // discretos
|
||
177 | |||
178 | for (int i = 0; i < histogramClasses.size(); i++) { |
||
179 | HistogramClass histogramClass = histogramClasses.get(i); |
||
180 | long anteriorCont = contValues;
|
||
181 | if (n == contValues) {
|
||
182 | return histogramClass.getMin();
|
||
183 | } |
||
184 | contValues += histogramClass.getValue(); |
||
185 | if (n == contValues) {
|
||
186 | return histogramClass.getMax();
|
||
187 | } |
||
188 | if (n < contValues) {
|
||
189 | double median;
|
||
190 | |||
191 | double nM = n; // getBandLenght() / 2; |
||
192 | double nA = anteriorCont;
|
||
193 | double fI = histogramClass.getValue();
|
||
194 | double interval = histogramClass.getMax() - histogramClass.getMin();
|
||
195 | double min = histogramClass.getMin();
|
||
196 | |||
197 | median = min + ((nM - nA) / fI) * interval; |
||
198 | return median;
|
||
199 | } |
||
200 | 5473 | dmartinezizquierdo | } |
201 | 5528 | llmarques | |
202 | } else { // Valores discretos |
||
203 | double antMax = Double.NEGATIVE_INFINITY; |
||
204 | |||
205 | for (int i = 0; i < histogramClasses.size(); i++) { |
||
206 | HistogramClass histogramClass = histogramClasses.get(i); |
||
207 | |||
208 | if (n == contValues) {
|
||
209 | return (histogramClass.getMin() + antMax) / 2; |
||
210 | 5486 | fdiaz | } |
211 | 5528 | llmarques | |
212 | contValues += histogramClass.getValue(); |
||
213 | |||
214 | if (n < contValues) {
|
||
215 | |||
216 | return histogramClass.getMin();
|
||
217 | } |
||
218 | antMax = histogramClass.getMax(); |
||
219 | 5473 | dmartinezizquierdo | } |
220 | 5528 | llmarques | |
221 | 5473 | dmartinezizquierdo | } |
222 | 5456 | dmartinezizquierdo | return 0; |
223 | } |
||
224 | |||
225 | 5493 | fdiaz | /**
|
226 | * Adds value to histogram
|
||
227 | *
|
||
228 | * @param value
|
||
229 | */
|
||
230 | 5482 | fdiaz | public void addValue(double value){ |
231 | HistogramClass histogramClass = getHistogramClass(value); |
||
232 | if(histogramClass == null){ |
||
233 | histogramClass = new DefaultHistogramClass(value, value);
|
||
234 | histogramClass.setValue(1);
|
||
235 | histogramClasses.add(histogramClass); |
||
236 | 8577 | fdiaz | // So that the list is always sorted
|
237 | 5482 | fdiaz | Collections.sort(histogramClasses);
|
238 | } else {
|
||
239 | histogramClass.increment(1);
|
||
240 | } |
||
241 | } |
||
242 | 5456 | dmartinezizquierdo | |
243 | 5493 | fdiaz | @Override
|
244 | 5534 | fdiaz | public double[] getTailTrimValue(double percent) { |
245 | 5493 | fdiaz | if(percent>100 || percent <0){ |
246 | StringBuilder builder = new StringBuilder(); |
||
247 | builder.append("Percent ");
|
||
248 | builder.append(percent); |
||
249 | builder.append(" is out of range [0,100]");
|
||
250 | throw new IllegalArgumentException(builder.toString()); |
||
251 | } |
||
252 | 5533 | fdiaz | long lowPosition = Math.round(getNumValues()*percent/100); |
253 | long upperPosition = Math.round(getNumValues()*(100-percent)/100); |
||
254 | 5493 | fdiaz | |
255 | double[] result = new double[2]; |
||
256 | |||
257 | result[0] = getUmpteenth(lowPosition);
|
||
258 | result[1] = getUmpteenth(upperPosition);
|
||
259 | return result;
|
||
260 | } |
||
261 | |||
262 | @Override
|
||
263 | 5534 | fdiaz | public double[] getTailTrimValue(int pos) { |
264 | 5493 | fdiaz | long lowPosition = pos;
|
265 | 5533 | fdiaz | long upperPosition = getNumValues()-pos;
|
266 | 5493 | fdiaz | |
267 | double[] result = new double[2]; |
||
268 | |||
269 | result[0] = getUmpteenth(lowPosition);
|
||
270 | result[1] = getUmpteenth(upperPosition);
|
||
271 | return result;
|
||
272 | } |
||
273 | |||
274 | 8577 | fdiaz | |
275 | |||
276 | 5456 | dmartinezizquierdo | } |