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