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 @ 43867

History | View | Annotate | Download (11.5 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.isCancelled()) {
176
                    status.abort();
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.isCancelled()) {
186
                    status.abort();
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.isCancelled()) {
197
                    status.abort();
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
            for (int column = 0; column < band1.getColumns(); column++) {
225
                Double v1 = band1.getAsDouble(row, column);
226
                if (v1 != null) {
227
                    double factor1 = v1 - statisticBand1.getMean();
228
                    Double v2 = band2.getAsDouble(row, column);
229
                    if (v2 != null) {
230
                        double factor2 = v2 - statisticBand2.getMean();
231
                        sigma+=(factor1*factor2);
232
                    }
233
                }
234
                n++;
235
            }
236
        }
237
        return sigma/n;
238

    
239
    }
240

    
241
    @Override
242
    public double[][] getVarianceCovarianceMatrix() {
243
        return this.varCov;
244
    }
245

    
246
    @Override
247
    public HistogramBand[] getHistogram() {
248
        HistogramBand[] histogramBands = new HistogramBand[statisticsBands.length];
249
        for (int i = 0; i < statisticsBands.length; i++) {
250
            histogramBands[i]= statisticsBands[i].getHistogramBand();
251
        }
252
        return histogramBands;
253
    }
254

    
255
    @Override
256
    public double[][] getTailTrimValue(double percent) {
257
        double[][] result = new double[statisticsBands.length][2];
258
        for (int i = 0; i < statisticsBands.length; i++) {
259
            result[i]=statisticsBands[i].getTailTrimValue(percent);
260
        }
261
        return result;
262
    }
263

    
264
    @Override
265
    public double[][] getTailTrimValue(int pos) {
266
        double[][] result = new double[statisticsBands.length][2];
267
        for (int i = 0; i < statisticsBands.length; i++) {
268
            result[i]=statisticsBands[i].getTailTrimValue(pos);
269
        }
270
        return result;
271
    }
272

    
273
    @Override
274
    public Iterator<StatisticsBand> iterator() {
275
        return Arrays.asList(statisticsBands).iterator();
276
    }
277

    
278
    @Override
279
    public String toHTMLString() {
280
        I18nManager i18nManager = ToolsLocator.getI18nManager();
281

    
282
        LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder();
283

    
284
        double[][] matrix = this.getVarianceCovarianceMatrix();
285
        BufferManager bufferManager = BufferLocator.getBufferManager();
286
        int bandCounter = 0;
287
        for (StatisticsBand statisticsBand : this) {
288

    
289
            builder.title().labelkey(i18nManager.getTranslation("_band") + " " + bandCounter);
290

    
291
            int dataType = statisticsBand.getDataType();
292
            builder.property().labelkey("_dataType").value(bufferManager.getBufferTypeName(dataType));
293

    
294
            Long dataCount = statisticsBand.getBandLength();
295
            builder.property().labelkey("_dataCount").value(dataCount.toString());
296

    
297
            Long noDataValuesCount = statisticsBand.getNoDataValuesCount();
298
            builder.property().labelkey("_noDataValuesCount").value(noDataValuesCount.toString());
299

    
300
            Double minimum = statisticsBand.getMinimum();
301
            builder.property().labelkey("_minimum").value(minimum.toString());
302

    
303
            Double maximum = statisticsBand.getMaximum();
304
            builder.property().labelkey("_maximum").value(maximum.toString());
305

    
306
            Double mean = statisticsBand.getMean();
307
            builder.property().labelkey("_mean").value(mean.toString());
308

    
309
            Double median = statisticsBand.getMedian();
310
            builder.property().labelkey("_median").value(median.toString());
311

    
312
            Double secondMin = statisticsBand.getSecondMin();
313
            builder.property().labelkey("_secondMin").value(secondMin.toString());
314

    
315
            Double secondMax = statisticsBand.getSecondMax();
316
            builder.property().labelkey("_secondMax").value(secondMax.toString());
317

    
318
            Double variance = statisticsBand.getVariance();
319
            builder.property().labelkey("_variance").value(variance.toString());
320
            Double standardDeviation = Math.sqrt(variance);
321
            builder.property().labelkey("_standard_deviation").value(standardDeviation.toString());
322

    
323
            double[] covariance = matrix[bandCounter];
324
            for (int bandCounter2 = 0; bandCounter2 < covariance.length; bandCounter2++) {
325
                builder.property().label(i18nManager.getTranslation("_covariance_with_band") + " " + bandCounter2)
326
                .value(Double.toString(covariance[bandCounter2]));
327
            }
328
            for (int bandCounter2 = 0; bandCounter2 < covariance.length; bandCounter2++) {
329
                Double pearson = covariance[bandCounter2]/(statisticsBand.getVariance()*statisticsBands[bandCounter2].getVariance());
330
                builder.property().label(i18nManager.getTranslation("_pearson_correlation_coefficient_with_band") + " " + bandCounter2)
331
                .value(pearson.isNaN()?"\u2015":pearson.toString());
332
            }
333
            bandCounter++;
334
        }
335

    
336
        return builder.toString();
337
    }
338

    
339

    
340
}