1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                      Grid_Filter                      //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //                 diversity_simpson.cpp                 //
14 //                                                       //
15 //                 Copyright (C) 2019 by                 //
16 //                      Olaf Conrad                      //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'. SAGA is free software; you   //
22 // can redistribute it and/or modify it under the terms  //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the     //
25 // License, or (at your option) any later version.       //
26 //                                                       //
27 // SAGA is distributed in the hope that it will be       //
28 // useful, but WITHOUT ANY WARRANTY; without even the    //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
30 // PARTICULAR PURPOSE. See the GNU General Public        //
31 // License for more details.                             //
32 //                                                       //
33 // You should have received a copy of the GNU General    //
34 // Public License along with this program; if not, see   //
35 // <http://www.gnu.org/licenses/>.                       //
36 //                                                       //
37 //-------------------------------------------------------//
38 //                                                       //
39 //    e-mail:     oconrad@saga-gis.org                   //
40 //                                                       //
41 //    contact:    Olaf Conrad                            //
42 //                Institute of Geography                 //
43 //                University of Hamburg                  //
44 //                Germany                                //
45 //                                                       //
46 ///////////////////////////////////////////////////////////
47 
48 //---------------------------------------------------------
49 #include "diversity_simpson.h"
50 
51 
52 ///////////////////////////////////////////////////////////
53 //														 //
54 //														 //
55 //														 //
56 ///////////////////////////////////////////////////////////
57 
58 //---------------------------------------------------------
CDiversity_Simpson(void)59 CDiversity_Simpson::CDiversity_Simpson(void)
60 {
61 	//-----------------------------------------------------
62 	Set_Name		(_TL("Simpson Index"));
63 
64 	Set_Author		("O.Conrad (c) 2019");
65 
66 	Set_Description	(_TW(
67 		"Grid based analysis of diversity with the Simpson Index. "
68 		"The index is calculated locally for each grid cell using "
69 		"the specified kernel (aka 'moving window'). It is assumed "
70 		"that the grid cell values represent a classification. "
71 	));
72 
73 	Add_Reference("Simpson, E.H.", "1949",
74 		"Measurement of diversity",
75 		"Nature, 163:688.",
76 		SG_T("https://doi.org/10.1038/163688a0"), SG_T("doi:10.1038/163688a0.")
77 	);
78 
79 	//-----------------------------------------------------
80 	Parameters.Add_Grid("",
81 		"CATEGORIES"	, _TL("Categories"),
82 		_TL(""),
83 		PARAMETER_INPUT
84 	);
85 
86 	Parameters.Add_Grid("",
87 		"COUNT"			, _TL("Number of Categories"),
88 		_TL("number of different categories (unique values) within search area"),
89 		PARAMETER_OUTPUT_OPTIONAL, true, SG_DATATYPE_Short
90 	);
91 
92 	Parameters.Add_Grid("",
93 		"INDEX"			, _TL("Simpson Index"),
94 		_TL(""),
95 		PARAMETER_OUTPUT
96 	);
97 
98 	CSG_Grid_Cell_Addressor::Add_Parameters(Parameters);
99 }
100 
101 
102 ///////////////////////////////////////////////////////////
103 //														 //
104 ///////////////////////////////////////////////////////////
105 
106 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)107 int CDiversity_Simpson::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
108 {
109 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
110 }
111 
112 
113 ///////////////////////////////////////////////////////////
114 //														 //
115 ///////////////////////////////////////////////////////////
116 
117 //---------------------------------------------------------
On_Execute(void)118 bool CDiversity_Simpson::On_Execute(void)
119 {
120 	//-----------------------------------------------------
121 	m_pClasses	= Parameters("CATEGORIES")->asGrid();
122 
123 	CSG_Grid	*pCount	= Parameters("COUNT")->asGrid();
124 	CSG_Grid	*pIndex	= Parameters("INDEX")->asGrid();
125 
126 	if( pCount ) pCount->Fmt_Name("%s [%s]", m_pClasses->Get_Name(), _TL("Count"        ));
127 	if( pIndex ) pIndex->Fmt_Name("%s [%s]", m_pClasses->Get_Name(), _TL("Simpson Index"));
128 
129 	//-----------------------------------------------------
130 	if( !m_Kernel.Set_Parameters(Parameters) )
131 	{
132 		Error_Set(_TL("could not initialize kernel"));
133 
134 		return( false );
135 	}
136 
137 	//-----------------------------------------------------
138 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
139 	{
140 		#pragma omp parallel for
141 		for(int x=0; x<Get_NX(); x++)
142 		{
143 			int	Count;	double	Index;
144 
145 			if( Get_Index(x, y, Count, Index) )
146 			{
147 				if( pCount ) pCount->Set_Value(x, y, Count);
148 				if( pIndex ) pIndex->Set_Value(x, y, Index);
149 			}
150 			else
151 			{
152 				if( pCount ) pCount->Set_NoData(x, y);
153 				if( pIndex ) pIndex->Set_NoData(x, y);
154 			}
155 		}
156 	}
157 
158 	//-----------------------------------------------------
159 	m_Kernel.Destroy();
160 
161 	return( true );
162 }
163 
164 
165 ///////////////////////////////////////////////////////////
166 //														 //
167 ///////////////////////////////////////////////////////////
168 
169 //---------------------------------------------------------
Get_Index(int x,int y,int & Count,double & Index)170 bool CDiversity_Simpson::Get_Index(int x, int y, int &Count, double &Index)
171 {
172 	if( m_pClasses->is_NoData(x, y) )
173 	{
174 		return( false );
175 	}
176 
177 	//-----------------------------------------------------
178 	CSG_Unique_Number_Statistics	Classes;
179 
180 	int	nTotal	= 0;
181 
182 	for(int iCell=0; iCell<m_Kernel.Get_Count(); iCell++)
183 	{
184 		int	ix	= m_Kernel.Get_X(iCell, x);
185 		int	iy	= m_Kernel.Get_Y(iCell, y);
186 
187 		if( m_pClasses->is_InGrid(ix, iy) )
188 		{
189 			Classes	+= m_pClasses->asDouble(ix, iy);
190 
191 			nTotal	++;
192 		}
193 	}
194 
195 	//-----------------------------------------------------
196 	Count	= Classes.Get_Count();
197 
198 	if( Count <= 1 )
199 	{
200 		Index	= 0.;
201 
202 		return( true );
203 	}
204 
205 	//-----------------------------------------------------
206 	Index	= 1.;
207 
208 	for(int iClass=0; iClass<Classes.Get_Count(); iClass++)
209 	{
210 		double	p	= Classes.Get_Count(iClass) / (double)nTotal;	// relative proportion of class members
211 
212 		Index	-= p*p;
213 	}
214 
215 	//-----------------------------------------------------
216 	return( true );
217 }
218 
219 
220 ///////////////////////////////////////////////////////////
221 //														 //
222 //														 //
223 //														 //
224 ///////////////////////////////////////////////////////////
225 
226 //---------------------------------------------------------
227