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
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
}