svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / statistics / DefaultStatistics.java @ 44831
History | View | Annotate | Download (11.8 KB)
1 | 44831 | jjdelcerro | package org.gvsig.raster.lib.buffer.impl.statistics; |
---|---|---|---|
2 | |||
3 | import java.util.Arrays; |
||
4 | import java.util.Iterator; |
||
5 | import java.util.List; |
||
6 | |||
7 | import org.gvsig.fmap.mapcontext.MapContextLocator; |
||
8 | import org.gvsig.fmap.mapcontext.layers.LayerInformationBuilder; |
||
9 | import org.gvsig.raster.lib.buffer.api.Band; |
||
10 | import org.gvsig.raster.lib.buffer.api.BufferLocator; |
||
11 | import org.gvsig.raster.lib.buffer.api.BufferManager; |
||
12 | import org.gvsig.raster.lib.buffer.api.statistics.HistogramBand; |
||
13 | import org.gvsig.raster.lib.buffer.api.statistics.Statistics; |
||
14 | import org.gvsig.raster.lib.buffer.api.statistics.StatisticsBand; |
||
15 | import org.gvsig.tools.ToolsLocator; |
||
16 | import org.gvsig.tools.i18n.I18nManager; |
||
17 | import org.gvsig.tools.task.SimpleTaskStatus; |
||
18 | |||
19 | /**
|
||
20 | * @author fdiaz
|
||
21 | *
|
||
22 | */
|
||
23 | public class DefaultStatistics implements Statistics { |
||
24 | |||
25 | StatisticsBand[] statisticsBands;
|
||
26 | boolean calculated;
|
||
27 | double[][] varCov; |
||
28 | |||
29 | /**
|
||
30 | *
|
||
31 | */
|
||
32 | public DefaultStatistics() {
|
||
33 | } |
||
34 | |||
35 | /**
|
||
36 | * @param bands
|
||
37 | */
|
||
38 | private void init(List<Band> bands) { |
||
39 | statisticsBands = new StatisticsBand[bands.size()];
|
||
40 | for (int i = 0; i < statisticsBands.length; i++) { |
||
41 | statisticsBands[i] = new DefaultStatisticsBand(bands.get(i));
|
||
42 | } |
||
43 | varCov = new double[statisticsBands.length][statisticsBands.length]; |
||
44 | calculated = false;
|
||
45 | } |
||
46 | |||
47 | @Override
|
||
48 | public long[] getNumberOfValues() { |
||
49 | if(!isCalculated()){
|
||
50 | throw new IllegalStateException("Not calculated statistics."); |
||
51 | } |
||
52 | long[] result = new long[statisticsBands.length]; |
||
53 | for (int i = 0; i < statisticsBands.length; i++) { |
||
54 | result[i]= statisticsBands[i].getBandLength()-statisticsBands[i].getNoDataValuesCount(); |
||
55 | } |
||
56 | return result;
|
||
57 | } |
||
58 | |||
59 | @Override
|
||
60 | public double[] getMax() { |
||
61 | double[] result = new double[statisticsBands.length]; |
||
62 | for (int i = 0; i < statisticsBands.length; i++) { |
||
63 | result[i]= statisticsBands[i].getMaximum(); |
||
64 | } |
||
65 | return result;
|
||
66 | } |
||
67 | |||
68 | @Override
|
||
69 | public double[] getSecondMax() { |
||
70 | double[] result = new double[statisticsBands.length]; |
||
71 | for (int i = 0; i < statisticsBands.length; i++) { |
||
72 | result[i]= statisticsBands[i].getSecondMax(); |
||
73 | } |
||
74 | return result;
|
||
75 | } |
||
76 | |||
77 | @Override
|
||
78 | public double[] getSecondMin() { |
||
79 | double[] result = new double[statisticsBands.length]; |
||
80 | for (int i = 0; i < statisticsBands.length; i++) { |
||
81 | result[i]= statisticsBands[i].getSecondMin(); |
||
82 | } |
||
83 | return result;
|
||
84 | } |
||
85 | |||
86 | @Override
|
||
87 | public double getMaximum() { |
||
88 | double result = Double.NEGATIVE_INFINITY; |
||
89 | for (int i = 0; i < statisticsBands.length; i++) { |
||
90 | double max = statisticsBands[i].getMaximum();
|
||
91 | if(result<max){
|
||
92 | result = max; |
||
93 | } |
||
94 | } |
||
95 | return result;
|
||
96 | } |
||
97 | |||
98 | @Override
|
||
99 | public double getMinimum() { |
||
100 | double result = Double.POSITIVE_INFINITY; |
||
101 | for (int i = 0; i < statisticsBands.length; i++) { |
||
102 | double min = statisticsBands[i].getMinimum();
|
||
103 | if(result>min){
|
||
104 | result = min; |
||
105 | } |
||
106 | } |
||
107 | return result;
|
||
108 | } |
||
109 | |||
110 | @Override
|
||
111 | public double[] getMean() { |
||
112 | double[] result = new double[statisticsBands.length]; |
||
113 | for (int i = 0; i < statisticsBands.length; i++) { |
||
114 | result[i]= statisticsBands[i].getMean(); |
||
115 | } |
||
116 | return result;
|
||
117 | } |
||
118 | |||
119 | @Override
|
||
120 | public double[] getMedian() { |
||
121 | double[] result = new double[statisticsBands.length]; |
||
122 | for (int i = 0; i < statisticsBands.length; i++) { |
||
123 | result[i]= statisticsBands[i].getMedian(); |
||
124 | } |
||
125 | return result;
|
||
126 | } |
||
127 | |||
128 | @Override
|
||
129 | public double[] getMin() { |
||
130 | double[] result = new double[statisticsBands.length]; |
||
131 | for (int i = 0; i < statisticsBands.length; i++) { |
||
132 | result[i]= statisticsBands[i].getMinimum(); |
||
133 | } |
||
134 | return result;
|
||
135 | } |
||
136 | |||
137 | @Override
|
||
138 | public double[] getVariance() { |
||
139 | double[] result = new double[statisticsBands.length]; |
||
140 | for (int i = 0; i < statisticsBands.length; i++) { |
||
141 | result[i]= statisticsBands[i].getVariance(); |
||
142 | } |
||
143 | return result;
|
||
144 | } |
||
145 | |||
146 | @Override
|
||
147 | public int getBandCount() { |
||
148 | return statisticsBands.length;
|
||
149 | } |
||
150 | |||
151 | @Override
|
||
152 | public boolean isCalculated() { |
||
153 | return calculated;
|
||
154 | } |
||
155 | |||
156 | @Override
|
||
157 | public void calculate(SimpleTaskStatus status, List<Band> bands) { |
||
158 | calculated = false;
|
||
159 | boolean isMyStatus = false; |
||
160 | if (status == null) { |
||
161 | status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Statistics");
|
||
162 | status.add(); |
||
163 | isMyStatus = true;
|
||
164 | } else {
|
||
165 | status.push(); |
||
166 | } |
||
167 | init(bands); |
||
168 | try {
|
||
169 | status.setIndeterminate(); |
||
170 | status.message("Calculating statistics");
|
||
171 | int count = 1; |
||
172 | int maxCount = statisticsBands.length*3; |
||
173 | for (int i = 0; i < statisticsBands.length; i++) { |
||
174 | status.message("Calculating statistics "+count++ +"/"+maxCount); |
||
175 | if (status.isCancellationRequested()) {
|
||
176 | status.cancel(); |
||
177 | return;
|
||
178 | } |
||
179 | if(!statisticsBands[i].isCalculated()){
|
||
180 | statisticsBands[i].calculate(status, bands.get(i)); |
||
181 | } |
||
182 | } |
||
183 | for (int i = 0; i < statisticsBands.length; i++) { |
||
184 | status.message("Calculating statistics "+count++ +"/"+maxCount); |
||
185 | if (status.isCancellationRequested()) {
|
||
186 | status.cancel(); |
||
187 | return;
|
||
188 | } |
||
189 | for (int j = i; j < statisticsBands.length; j++) { |
||
190 | this.varCov[i][j] = getCovariance(status,statisticsBands[i],bands.get(i), statisticsBands[j], bands.get(j));
|
||
191 | } |
||
192 | } |
||
193 | status.setIndeterminate(); |
||
194 | for (int i = 0; i < statisticsBands.length; i++) { |
||
195 | status.message("Calculating statistics "+count++ +"/"+maxCount); |
||
196 | if (status.isCancellationRequested()) {
|
||
197 | status.cancel(); |
||
198 | return;
|
||
199 | } |
||
200 | for (int j = 0; j < i; j++) { |
||
201 | varCov[i][j] = varCov[j][i]; |
||
202 | } |
||
203 | } |
||
204 | if (isMyStatus) {
|
||
205 | status.terminate(); |
||
206 | } else {
|
||
207 | status.pop(); |
||
208 | } |
||
209 | calculated = true;
|
||
210 | } catch (Exception e) { |
||
211 | status.abort(); |
||
212 | throw e;
|
||
213 | } |
||
214 | } |
||
215 | |||
216 | private double getCovariance(SimpleTaskStatus status, StatisticsBand statisticBand1, Band band1, StatisticsBand statisticBand2, Band band2) { |
||
217 | |||
218 | double sigma = 0; |
||
219 | int n = 0; |
||
220 | int rowCount = band1.getRows();
|
||
221 | status.setRangeOfValues(0, rowCount);
|
||
222 | for (int row = 0; row < rowCount; row++) { |
||
223 | status.setCurValue(row); |
||
224 | if (status.isCancellationRequested()) {
|
||
225 | status.cancel(); |
||
226 | return 0; |
||
227 | } |
||
228 | for (int column = 0; column < band1.getColumns(); column++) { |
||
229 | Double v1 = band1.getAsDouble(row, column);
|
||
230 | if (v1 != null) { |
||
231 | double factor1 = v1 - statisticBand1.getMean();
|
||
232 | Double v2 = band2.getAsDouble(row, column);
|
||
233 | if (v2 != null) { |
||
234 | double factor2 = v2 - statisticBand2.getMean();
|
||
235 | sigma+=(factor1*factor2); |
||
236 | } |
||
237 | } |
||
238 | n++; |
||
239 | } |
||
240 | } |
||
241 | return sigma/n;
|
||
242 | |||
243 | } |
||
244 | |||
245 | @Override
|
||
246 | public double[][] getVarianceCovarianceMatrix() { |
||
247 | return this.varCov; |
||
248 | } |
||
249 | |||
250 | @Override
|
||
251 | public HistogramBand[] getHistogram() { |
||
252 | HistogramBand[] histogramBands = new HistogramBand[statisticsBands.length]; |
||
253 | for (int i = 0; i < statisticsBands.length; i++) { |
||
254 | histogramBands[i]= statisticsBands[i].getHistogramBand(); |
||
255 | } |
||
256 | return histogramBands;
|
||
257 | } |
||
258 | |||
259 | @Override
|
||
260 | public double[][] getTailTrimValue(double percent) { |
||
261 | double[][] result = new double[statisticsBands.length][2]; |
||
262 | for (int i = 0; i < statisticsBands.length; i++) { |
||
263 | result[i]=statisticsBands[i].getTailTrimValue(percent); |
||
264 | } |
||
265 | return result;
|
||
266 | } |
||
267 | |||
268 | @Override
|
||
269 | public double[][] getTailTrimValue(int pos) { |
||
270 | double[][] result = new double[statisticsBands.length][2]; |
||
271 | for (int i = 0; i < statisticsBands.length; i++) { |
||
272 | result[i]=statisticsBands[i].getTailTrimValue(pos); |
||
273 | } |
||
274 | return result;
|
||
275 | } |
||
276 | |||
277 | @Override
|
||
278 | public Iterator<StatisticsBand> iterator() { |
||
279 | return Arrays.asList(statisticsBands).iterator(); |
||
280 | } |
||
281 | |||
282 | @Override
|
||
283 | public String toHTMLString() { |
||
284 | I18nManager i18n = ToolsLocator.getI18nManager(); |
||
285 | if( !this.calculated ) { |
||
286 | return i18n.getTranslation("_Need_calculate_statistics"); |
||
287 | } |
||
288 | |||
289 | LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder(); |
||
290 | |||
291 | double[][] matrix = this.getVarianceCovarianceMatrix(); |
||
292 | BufferManager bufferManager = BufferLocator.getBufferManager(); |
||
293 | int bandCounter = 0; |
||
294 | for (StatisticsBand statisticsBand : this) { |
||
295 | |||
296 | builder.title().labelkey(i18n.getTranslation("_band") + " " + bandCounter); |
||
297 | |||
298 | int dataType = statisticsBand.getDataType();
|
||
299 | builder.property().labelkey("_dataType").value(bufferManager.getBufferTypeName(dataType));
|
||
300 | |||
301 | Long dataCount = statisticsBand.getBandLength();
|
||
302 | builder.property().labelkey("_dataCount").value(dataCount.toString());
|
||
303 | |||
304 | Long noDataValuesCount = statisticsBand.getNoDataValuesCount();
|
||
305 | builder.property().labelkey("_noDataValuesCount").value(noDataValuesCount.toString());
|
||
306 | |||
307 | Double minimum = statisticsBand.getMinimum();
|
||
308 | builder.property().labelkey("_minimum").value(minimum.toString());
|
||
309 | |||
310 | Double maximum = statisticsBand.getMaximum();
|
||
311 | builder.property().labelkey("_maximum").value(maximum.toString());
|
||
312 | |||
313 | Double mean = statisticsBand.getMean();
|
||
314 | builder.property().labelkey("_mean").value(mean.toString());
|
||
315 | |||
316 | Double median = statisticsBand.getMedian();
|
||
317 | builder.property().labelkey("_median").value(median.toString());
|
||
318 | |||
319 | Double secondMin = statisticsBand.getSecondMin();
|
||
320 | builder.property().labelkey("_secondMin").value(secondMin.toString());
|
||
321 | |||
322 | Double secondMax = statisticsBand.getSecondMax();
|
||
323 | builder.property().labelkey("_secondMax").value(secondMax.toString());
|
||
324 | |||
325 | Double variance = statisticsBand.getVariance();
|
||
326 | builder.property().labelkey("_variance").value(variance.toString());
|
||
327 | Double standardDeviation = Math.sqrt(variance); |
||
328 | builder.property().labelkey("_standard_deviation").value(standardDeviation.toString());
|
||
329 | |||
330 | double[] covariance = matrix[bandCounter]; |
||
331 | for (int bandCounter2 = 0; bandCounter2 < covariance.length; bandCounter2++) { |
||
332 | builder.property().label(i18n.getTranslation("_covariance_with_band") + " " + bandCounter2) |
||
333 | .value(Double.toString(covariance[bandCounter2]));
|
||
334 | } |
||
335 | for (int bandCounter2 = 0; bandCounter2 < covariance.length; bandCounter2++) { |
||
336 | Double pearson = covariance[bandCounter2]/(statisticsBand.getVariance()*statisticsBands[bandCounter2].getVariance());
|
||
337 | builder.property().label(i18n.getTranslation("_pearson_correlation_coefficient_with_band") + " " + bandCounter2) |
||
338 | .value(pearson.isNaN()?"\u2015":pearson.toString());
|
||
339 | } |
||
340 | bandCounter++; |
||
341 | } |
||
342 | |||
343 | return builder.toString();
|
||
344 | } |
||
345 | |||
346 | |||
347 | } |