Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / statisticalMethods / multipleRegression / MultipleRegressionAlgorithm.java @ 59

History | View | Annotate | Download (9.72 KB)

1
package es.unex.sextante.statisticalMethods.multipleRegression;
2

    
3
import java.text.DecimalFormat;
4
import java.util.ArrayList;
5

    
6
import com.vividsolutions.jts.geom.Coordinate;
7
import com.vividsolutions.jts.geom.Geometry;
8

    
9
import es.unex.sextante.additionalInfo.AdditionalInfoMultipleInput;
10
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
11
import es.unex.sextante.core.AnalysisExtent;
12
import es.unex.sextante.core.GeoAlgorithm;
13
import es.unex.sextante.core.Sextante;
14
import es.unex.sextante.dataObjects.IFeature;
15
import es.unex.sextante.dataObjects.IFeatureIterator;
16
import es.unex.sextante.dataObjects.IRasterLayer;
17
import es.unex.sextante.dataObjects.IVectorLayer;
18
import es.unex.sextante.docEngines.html.HTMLDoc;
19
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
20
import es.unex.sextante.exceptions.IteratorException;
21
import es.unex.sextante.exceptions.OptionalParentParameterException;
22
import es.unex.sextante.exceptions.RepeatedParameterNameException;
23
import es.unex.sextante.exceptions.UndefinedParentParameterNameException;
24
import es.unex.sextante.math.regression.MultipleRegression;
25
import es.unex.sextante.outputs.OutputVectorLayer;
26
import es.unex.sextante.rasterWrappers.GridCell;
27

    
28
public class MultipleRegressionAlgorithm
29
         extends
30
            GeoAlgorithm {
31

    
32
   public static final String INPUT           = "INPUT";
33
   public static final String FIELD           = "FIELD";
34
   public static final String POINTS          = "POINTS";
35
   public static final String RESULT          = "RESULT";
36
   public static final String RESIDUALS       = "RESIDUALS";
37
   public static final String REGRESSION_INFO = "REGRESSION_INFO";
38

    
39
   private int                m_iField;
40
   private IVectorLayer       m_Residuals;
41
   private IRasterLayer       m_Windows[];
42
   private IRasterLayer       m_Result;
43
   private MultipleRegression m_Regression;
44
   private ArrayList          m_RasterLayers;
45
   private IVectorLayer       m_Points;
46

    
47

    
48
   @Override
49
   public void defineCharacteristics() {
50

    
51
      setUserCanDefineAnalysisExtent(true);
52
      setGroup(Sextante.getText("Statistical_methods"));
53
      this.setName(Sextante.getText("Multiple_regression"));
54

    
55
      try {
56
         m_Parameters.addInputVectorLayer(POINTS, Sextante.getText("Points"), AdditionalInfoVectorLayer.SHAPE_TYPE_POINT, true);
57
         m_Parameters.addTableField(FIELD, Sextante.getText("Field"), POINTS);
58
         m_Parameters.addMultipleInput(INPUT, Sextante.getText("Predictors"), AdditionalInfoMultipleInput.DATA_TYPE_RASTER, false);
59
         addOutputRasterLayer(RESULT, Sextante.getText("Result"));
60
         addOutputVectorLayer(RESIDUALS, Sextante.getText("Residuals"), OutputVectorLayer.SHAPE_TYPE_POINT);
61
         addOutputText(REGRESSION_INFO, Sextante.getText("Regression_values"));
62
      }
63
      catch (final RepeatedParameterNameException e) {
64
         Sextante.addErrorToLog(e);
65
      }
66
      catch (final UndefinedParentParameterNameException e) {
67
         Sextante.addErrorToLog(e);
68
      }
69
      catch (final OptionalParentParameterException e) {
70
         Sextante.addErrorToLog(e);
71
      }
72

    
73
   }
74

    
75

    
76
   @Override
77
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
78

    
79
      int i;
80

    
81
      final String sFieldNames[] = { Sextante.getText("Real_value"), Sextante.getText("Estimated_value"),
82
               Sextante.getText("Diference") };
83
      final Class types[] = { Double.class, Double.class, Double.class };
84

    
85
      m_RasterLayers = m_Parameters.getParameterValueAsArrayList(INPUT);
86
      m_iField = m_Parameters.getParameterValueAsInt(FIELD);
87
      m_Points = m_Parameters.getParameterValueAsVectorLayer(POINTS);
88

    
89
      if ((m_RasterLayers.size() == 0) || (m_Points.getShapesCount() < 3)) {
90
         throw new GeoAlgorithmExecutionException(Sextante.getText("Invalid_input_data"));
91
      }
92

    
93
      m_Result = getNewRasterLayer(RESULT, Sextante.getText("Multiple_regression"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
94

    
95
      m_Windows = new IRasterLayer[m_RasterLayers.size()];
96

    
97
      for (i = 0; i < m_RasterLayers.size(); i++) {
98
         m_Windows[i] = (IRasterLayer) m_RasterLayers.get(i);
99
         m_Windows[i].setWindowExtent(m_Result.getWindowGridExtent());
100
         m_Windows[i].setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline);
101
      }
102

    
103
      m_Residuals = getNewVectorLayer(RESIDUALS, Sextante.getText("Residuals"), IVectorLayer.SHAPE_TYPE_POINT, types, sFieldNames);
104

    
105
      calculateRegression();
106
      if (!m_Task.isCanceled()) {
107
         calculateResultingGrid();
108
         calculateResiduals();
109
         createAdditionalInfo();
110
      }
111

    
112
      return !m_Task.isCanceled();
113

    
114
   }
115

    
116

    
117
   private void calculateResiduals() throws IteratorException {
118

    
119
      double dValue;
120
      double dGridValue;
121
      final Object value[] = new Object[3];
122
      final AnalysisExtent extent = m_Result.getWindowGridExtent();
123
      GridCell cell;
124

    
125
      final IFeatureIterator iter = m_Points.iterator();
126
      while (iter.hasNext()) {
127
         final IFeature feature = iter.next();
128
         final Geometry geom = feature.getGeometry();
129
         final Coordinate pt = geom.getCoordinate();
130
         dValue = Double.parseDouble(feature.getRecord().getValue(m_iField).toString());
131
         cell = extent.getGridCoordsFromWorldCoords(pt.x, pt.y);
132
         dGridValue = m_Result.getCellValueAsDouble(cell.getX(), cell.getY());
133
         if (!m_Result.isNoDataValue(dGridValue)) {
134
            value[1] = new Double(dValue);
135
            value[0] = new Double(dGridValue);
136
            value[2] = new Double(dGridValue - dValue);
137
            m_Residuals.addFeature(geom, value);
138
         }
139
      }
140
      iter.close();
141

    
142
   }
143

    
144

    
145
   private void calculateResultingGrid() {
146

    
147
      int i;
148
      int x, y;
149
      int iNX, iNY;
150
      double z;
151
      double dValue;
152
      boolean bNoDataValue;
153

    
154
      iNX = m_Windows[0].getNX();
155
      iNY = m_Windows[0].getNY();
156

    
157
      setProgressText(Sextante.getText("Calculating_regression"));
158

    
159
      for (y = 0; (y < iNY) && setProgress(y, iNY); y++) {
160
         for (x = 0; x < iNX; x++) {
161
            bNoDataValue = false;
162
            z = m_Regression.getConstant();
163
            for (i = 0; i < m_Windows.length; i++) {
164
               dValue = m_Windows[i].getCellValueAsDouble(x, y);
165
               if (m_Windows[i].isNoDataValue(dValue)) {
166
                  m_Result.setNoData(x, y);
167
                  bNoDataValue = true;
168
                  break;
169
               }
170
               else {
171
                  z += dValue * m_Regression.getCoeff(i);
172
               }
173
            }
174
            if (!bNoDataValue) {
175
               m_Result.setCellValue(x, y, z);
176
            }
177
         }
178
      }
179

    
180
   }
181

    
182

    
183
   private void calculateRegression() throws GeoAlgorithmExecutionException {
184

    
185
      int i, j;
186
      int iCount;
187
      double dValuePt;
188
      final double dValueGrid[] = new double[m_Windows.length];
189
      boolean bNoDataValue;
190

    
191
      m_Regression = new MultipleRegression(m_Windows.length);
192

    
193
      i = 0;
194
      iCount = m_Points.getShapesCount();
195
      final IFeatureIterator iter = m_Points.iterator();
196
      while (iter.hasNext() && setProgress(i, iCount)) {
197
         final IFeature feature = iter.next();
198
         final Geometry geom = feature.getGeometry();
199
         final Coordinate pt = geom.getCoordinate();
200
         bNoDataValue = false;
201
         for (j = 0; j < m_Windows.length; j++) {
202
            dValueGrid[j] = m_Windows[j].getValueAt(pt.x, pt.y);
203
            if (m_Windows[j].isNoDataValue(dValueGrid[j])) {
204
               bNoDataValue = true;
205
               break;
206
            }
207
         }
208
         if (!bNoDataValue) {
209
            try {
210
               dValuePt = Double.parseDouble(feature.getRecord().getValue(m_iField).toString());
211
               m_Regression.addValue(dValueGrid, dValuePt);
212
            }
213
            catch (final NumberFormatException e) {}
214
         }
215
      }
216
      iter.close();
217

    
218
      if (m_Task.isCanceled()) {
219
         return;
220
      }
221
      else {
222
         boolean bResult = m_Regression.calculate();
223
         if (!bResult) {
224
            throw new GeoAlgorithmExecutionException(Sextante.getText("Could_not_calculate_regression"));
225
         }
226
      }
227
   }
228

    
229

    
230
   private void createAdditionalInfo() {
231

    
232
      int i, j;
233
      IRasterLayer layer;
234

    
235
      final DecimalFormat df = new DecimalFormat("##.###");
236
      final HTMLDoc doc = new HTMLDoc();
237
      doc.open(Sextante.getText("Multiple_regression"));
238
      doc.addHeader(Sextante.getText("Multiple_regression"), 2);
239
      doc.startUnorderedList();
240

    
241
      final StringBuffer sb = new StringBuffer(" Y = " + Double.toString(m_Regression.getConstant()));
242

    
243
      for (i = 0; i < m_RasterLayers.size(); i++) {
244

    
245
         if (((j = m_Regression.getOrdered(i)) >= 0) && (j < m_RasterLayers.size())) {
246
            layer = (IRasterLayer) m_RasterLayers.get(j);
247
            sb.append(" + " + Double.toString(m_Regression.getCoeff(j)) + " * [" + layer.getName() + "]");
248
         }
249
      }
250
      doc.addListElement(sb.toString());
251
      doc.closeUnorderedList();
252

    
253
      doc.startUnorderedList();
254
      doc.addHeader(Sextante.getText("Correlation"), 2);
255

    
256
      for (i = 0; i < m_RasterLayers.size(); i++) {
257
         if (((j = m_Regression.getOrdered(i)) >= 0) && (j < m_RasterLayers.size())) {
258
            layer = (IRasterLayer) m_RasterLayers.get(j);
259
            doc.addListElement(Integer.toString(i + 1) + ": R2 = " + df.format(100.0 * m_Regression.getR2(j)) + "["
260
                               + df.format(100.0 * m_Regression.getR2Change(j)) + "] -> " + layer.getName());
261
         }
262
      }
263

    
264
      doc.closeUnorderedList();
265
      doc.close();
266

    
267
      addOutputText(REGRESSION_INFO, Sextante.getText("Regression_values"), doc.getHTMLCode());
268

    
269

    
270
   }
271

    
272
}