1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                      Grid_Filter                      //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //                 diversity_shannon.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_shannon.h"
50 
51 
52 ///////////////////////////////////////////////////////////
53 //														 //
54 //														 //
55 //														 //
56 ///////////////////////////////////////////////////////////
57 
58 //---------------------------------------------------------
CDiversity_Shannon(void)59 CDiversity_Shannon::CDiversity_Shannon(void)
60 {
61 	//-----------------------------------------------------
62 	Set_Name		(_TL("Shannon Index"));
63 
64 	Set_Author		("O.Conrad (c) 2019");
65 
66 	Set_Description	(_TW(
67 		"Grid based analysis of diversity with the Shannon 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("Pielou, E.C.", "1969",
74 		"An Introduction to Mathematical Ecology",
75 		"John Wiley, New York."
76 	);
77 
78 	Add_Reference("Shannon, C.", "1948",
79 		"A mathematical theory of communication",
80 		"Bell Syst. Tech. J. 27,379�423.",
81 		SG_T("https://doi.org/10.1002%2Fj.1538-7305.1948.tb01338.x"), SG_T("doi:10.1002/j.1538-7305.1948.tb01338.x")
82 	);
83 
84 	Add_Reference("Spellerberg, I.F. & Fedor, P.J.", "2003",
85 		"A tribute to Claude Shannon (1916�2001) and a plea for more rigorous use of species richness, species diversity and the 'Shannon-Wiener' Index",
86 		"Global Ecology and Biogeography 12 (3), p. 177�179.",
87 		SG_T("https://doi.org/10.1046/j.1466-822X.2003.00015.x"), SG_T("doi:10.1046/j.1466-822X.2003.00015.x.")
88 	);
89 
90 	//-----------------------------------------------------
91 	Parameters.Add_Grid("",
92 		"CATEGORIES"	, _TL("Categories"),
93 		_TL(""),
94 		PARAMETER_INPUT
95 	);
96 
97 	Parameters.Add_Grid("",
98 		"COUNT"			, _TL("Number of Categories"),
99 		_TL("number of different categories (unique values) within search area"),
100 		PARAMETER_OUTPUT_OPTIONAL, true, SG_DATATYPE_Short
101 	);
102 
103 	Parameters.Add_Grid("",
104 		"INDEX"			, _TL("Shannon Index"),
105 		_TL(""),
106 		PARAMETER_OUTPUT
107 	);
108 
109 	Parameters.Add_Grid("",
110 		"EVENNESS"		, _TL("Evenness"),
111 		_TL(""),
112 		PARAMETER_OUTPUT_OPTIONAL
113 	);
114 
115 	CSG_Grid_Cell_Addressor::Add_Parameters(Parameters);
116 }
117 
118 
119 ///////////////////////////////////////////////////////////
120 //														 //
121 ///////////////////////////////////////////////////////////
122 
123 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)124 int CDiversity_Shannon::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
125 {
126 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
127 }
128 
129 
130 ///////////////////////////////////////////////////////////
131 //														 //
132 ///////////////////////////////////////////////////////////
133 
134 //---------------------------------------------------------
On_Execute(void)135 bool CDiversity_Shannon::On_Execute(void)
136 {
137 	//-----------------------------------------------------
138 	m_pClasses	= Parameters("CATEGORIES")->asGrid();
139 
140 	CSG_Grid	*pCount	= Parameters("COUNT"   )->asGrid();
141 	CSG_Grid	*pIndex	= Parameters("INDEX"   )->asGrid();
142 	CSG_Grid	*pEvenn	= Parameters("EVENNESS")->asGrid();
143 
144 	if( pCount ) pCount->Fmt_Name("%s [%s]", m_pClasses->Get_Name(), _TL("Count"        ));
145 	if( pIndex ) pIndex->Fmt_Name("%s [%s]", m_pClasses->Get_Name(), _TL("Shannon Index"));
146 	if( pEvenn ) pEvenn->Fmt_Name("%s [%s]", m_pClasses->Get_Name(), _TL("Evenness"     ));
147 
148 	//-----------------------------------------------------
149 	if( !m_Kernel.Set_Parameters(Parameters) )
150 	{
151 		Error_Set(_TL("could not initialize kernel"));
152 
153 		return( false );
154 	}
155 
156 	//-----------------------------------------------------
157 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
158 	{
159 		#pragma omp parallel for
160 		for(int x=0; x<Get_NX(); x++)
161 		{
162 			int	Count;	double	Index;
163 
164 			if( Get_Index(x, y, Count, Index) )
165 			{
166 				if( pCount ) pCount->Set_Value(x, y, Count);
167 				if( pIndex ) pIndex->Set_Value(x, y, Index);
168 				if( pEvenn ) pEvenn->Set_Value(x, y, Count > 1 ? Index / log((double)Count) : 0.);
169 			}
170 			else
171 			{
172 				if( pCount ) pCount->Set_NoData(x, y);
173 				if( pIndex ) pIndex->Set_NoData(x, y);
174 				if( pEvenn ) pEvenn->Set_NoData(x, y);
175 			}
176 		}
177 	}
178 
179 	//-----------------------------------------------------
180 	m_Kernel.Destroy();
181 
182 	return( true );
183 }
184 
185 
186 ///////////////////////////////////////////////////////////
187 //														 //
188 ///////////////////////////////////////////////////////////
189 
190 //---------------------------------------------------------
Get_Index(int x,int y,int & Count,double & Index)191 bool CDiversity_Shannon::Get_Index(int x, int y, int &Count, double &Index)
192 {
193 	if( m_pClasses->is_NoData(x, y) )
194 	{
195 		return( false );
196 	}
197 
198 	//-----------------------------------------------------
199 	CSG_Unique_Number_Statistics	Classes;
200 
201 	int	nTotal	= 0;
202 
203 	for(int iCell=0; iCell<m_Kernel.Get_Count(); iCell++)
204 	{
205 		int	ix	= m_Kernel.Get_X(iCell, x);
206 		int	iy	= m_Kernel.Get_Y(iCell, y);
207 
208 		if( m_pClasses->is_InGrid(ix, iy) )
209 		{
210 			Classes	+= m_pClasses->asDouble(ix, iy);
211 
212 			nTotal	++;
213 		}
214 	}
215 
216 	//-----------------------------------------------------
217 	Count	= Classes.Get_Count();
218 
219 	if( Count <= 1 )
220 	{
221 		Index	= 0.;
222 
223 		return( true );
224 	}
225 
226 	//-----------------------------------------------------
227 	Index	= 0.;
228 
229 	for(int iClass=0; iClass<Classes.Get_Count(); iClass++)
230 	{
231 		double	p	= Classes.Get_Count(iClass) / (double)nTotal;	// relative proportion of class members
232 
233 		Index	-= p * log(p);
234 	}
235 
236 	//-----------------------------------------------------
237 	return( true );
238 }
239 
240 
241 ///////////////////////////////////////////////////////////
242 //														 //
243 //														 //
244 //														 //
245 ///////////////////////////////////////////////////////////
246 
247 //---------------------------------------------------------
248