Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / 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 @ 43868

History | View | Annotate | Download (11.8 KB)

1 43803 fdiaz
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 43867 jjdelcerro
            status.setIndeterminate();
170 43803 fdiaz
            status.message("Calculating statistics");
171 43867 jjdelcerro
            int count = 1;
172
            int maxCount = statisticsBands.length*3;
173 43803 fdiaz
            for (int i = 0; i < statisticsBands.length; i++) {
174 43867 jjdelcerro
                status.message("Calculating statistics "+count++ +"/"+maxCount);
175 43868 jjdelcerro
               if (status.isCancellationRequested()) {
176
                    status.cancel();
177 43803 fdiaz
                    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 43867 jjdelcerro
                status.message("Calculating statistics "+count++ +"/"+maxCount);
185 43868 jjdelcerro
                if (status.isCancellationRequested()) {
186
                    status.cancel();
187 43803 fdiaz
                    return;
188
                }
189
                for (int j = i; j < statisticsBands.length; j++) {
190 43867 jjdelcerro
                    this.varCov[i][j] = getCovariance(status,statisticsBands[i],bands.get(i), statisticsBands[j], bands.get(j));
191 43803 fdiaz
                }
192
            }
193 43867 jjdelcerro
            status.setIndeterminate();
194 43803 fdiaz
            for (int i = 0; i < statisticsBands.length; i++) {
195 43867 jjdelcerro
                status.message("Calculating statistics "+count++ +"/"+maxCount);
196 43868 jjdelcerro
                if (status.isCancellationRequested()) {
197
                    status.cancel();
198 43803 fdiaz
                    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 43867 jjdelcerro
    private double getCovariance(SimpleTaskStatus  status, StatisticsBand statisticBand1, Band band1, StatisticsBand statisticBand2, Band band2) {
217 43803 fdiaz
218
        double sigma = 0;
219
        int n = 0;
220 43867 jjdelcerro
        int rowCount = band1.getRows();
221
        status.setRangeOfValues(0, rowCount);
222
        for (int row = 0; row < rowCount; row++) {
223
            status.setCurValue(row);
224 43868 jjdelcerro
            if (status.isCancellationRequested()) {
225
                status.cancel();
226
                return 0;
227
            }
228 43803 fdiaz
            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 43868 jjdelcerro
        I18nManager i18n = ToolsLocator.getI18nManager();
285
        if( !this.calculated ) {
286
            return i18n.getTranslation("_Need_calculate_statistics");
287
        }
288 43803 fdiaz
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 43868 jjdelcerro
            builder.title().labelkey(i18n.getTranslation("_band") + " " + bandCounter);
297 43803 fdiaz
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 43868 jjdelcerro
                builder.property().label(i18n.getTranslation("_covariance_with_band") + " " + bandCounter2)
333 43803 fdiaz
                .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 43868 jjdelcerro
                builder.property().label(i18n.getTranslation("_pearson_correlation_coefficient_with_band") + " " + bandCounter2)
338 43803 fdiaz
                .value(pearson.isNaN()?"\u2015":pearson.toString());
339
            }
340
            bandCounter++;
341
        }
342
343
        return builder.toString();
344
    }
345
346
347
}