[GRASS-SVN] r66153 - in grass-addons/grass7/raster: . r.biodiversity

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Sep 9 09:29:19 PDT 2015


Author: pvanbosgeo
Date: 2015-09-09 09:29:19 -0700 (Wed, 09 Sep 2015)
New Revision: 66153

Added:
   grass-addons/grass7/raster/r.biodiversity/
   grass-addons/grass7/raster/r.biodiversity/Makefile
   grass-addons/grass7/raster/r.biodiversity/r.biodiversity.py
   grass-addons/grass7/raster/r.biodiversity/r_biodiversity.html
Log:
Addon to calculate few (bio)diversity indici across layers (different from r.diversity, which computes landscape diversity using moving window). Suggestions to improve this much welcome. I am planning to add other indici later.

Added: grass-addons/grass7/raster/r.biodiversity/Makefile
===================================================================
--- grass-addons/grass7/raster/r.biodiversity/Makefile	                        (rev 0)
+++ grass-addons/grass7/raster/r.biodiversity/Makefile	2015-09-09 16:29:19 UTC (rev 66153)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.biodiversity
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script


Property changes on: grass-addons/grass7/raster/r.biodiversity/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/raster/r.biodiversity/r.biodiversity.py
===================================================================
--- grass-addons/grass7/raster/r.biodiversity/r.biodiversity.py	                        (rev 0)
+++ grass-addons/grass7/raster/r.biodiversity/r.biodiversity.py	2015-09-09 16:29:19 UTC (rev 66153)
@@ -0,0 +1,319 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+########################################################################
+#
+# MODULE:       r.biodiversity
+# AUTHOR(S):    Paulo van Breugel <p.vanbreugel AT gmail.com>
+# PURPOSE:      Compute biodiversity indici over input layers
+#
+# COPYRIGHT: (C) 2014 Paulo van Breugel
+#            http://ecodiv.org
+#            http://pvanb.wordpress.com/
+#
+#            This program is free software under the GNU General Public
+#            License (>=v2). Read the file COPYING that comes with GRASS
+#            for details.
+#
+########################################################################
+#
+#%Module
+#% description: Compute biodiversity indici over input layers
+#% keyword: raster
+#% keyword: diversity index
+#% keyword: renyi entrophy
+#% keyword: shannon
+#% keyword: simpson
+#% keyword: richness
+#% keyword: biodiversity
+#%End
+
+#%option
+#% key: input
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input layers
+#% label: input layers
+#% key_desc: name
+#% required: yes
+#% multiple: yes
+#%end
+
+#%option
+#% key: output
+#% type: string
+#% gisprompt: new,cell,raster
+#% description: prefix name output layer
+#% key_desc: name
+#% required: yes
+#% multiple: no
+#%end
+
+#%flag
+#% key: r
+#% description: Compute the renyi enthropy index
+#% guisection: Indices
+#%end
+
+#%option
+#% key: alpha
+#% type: double
+#% description: Order of generalized entropy
+#% key_desc: number(s)
+#% multiple: yes
+#% options: 0.0-*
+#% guisection: Indices
+#%end
+
+#%rules
+#% collective: -r,alpha
+#%end
+
+#%flag
+#% key: s
+#% description: Compute the richness index
+#% guisection: Indices
+#%end
+
+#%flag
+#% key: h
+#% description: Compute the Shannon index
+#% guisection: Indices
+#%end
+
+#%flag
+#% key: d
+#% description: Compute the Simpson index
+#% guisection: Indices
+#%end
+
+#%flag
+#% key: p
+#% description: Compute the Reversed Simpson index
+#% guisection: Indices
+#%end
+
+#%flag
+#% key: g
+#% description: Compute the Gini-Simpson index
+#% guisection: Indices
+#%end
+
+#%rules
+#% required: -r,-s,-h,-d,-p,-g
+#%end
+
+#----------------------------------------------------------------------------
+# Standard
+#----------------------------------------------------------------------------
+
+# import libraries
+import os
+import sys
+import uuid
+import atexit
+import string
+import grass.script as grass
+if not os.environ.has_key("GISBASE"):
+    grass.message( "You must be in GRASS GIS to run this program." )
+    sys.exit(1)
+
+#----------------------------------------------------------------------------
+# Functions
+#----------------------------------------------------------------------------
+
+# create set to store names of temporary maps to be deleted upon exit
+clean_rast = set()
+def cleanup():
+    for rast in clean_rast:
+        grass.run_command("g.remove",
+        type="rast", name = rast, quiet = True)
+
+def CheckLayer(envlay):
+    for chl in xrange(len(envlay)):
+        ffile = grass.find_file(envlay[chl], element = 'cell')
+        if ffile['fullname'] == '':
+            grass.fatal("The layer " + envlay[chl] + " does not exist.")
+
+# Create temporary name
+def tmpname(name):
+    tmpf = name + "_" + str(uuid.uuid4())
+    tmpf = string.replace(tmpf, '-', '_')
+    clean_rast.add(tmpf)
+    return tmpf
+
+#----------------------------------------------------------------------------
+# main function
+#----------------------------------------------------------------------------
+
+def main():
+    #options = {"input":"spec1,spec2", "output":"test", "alpha":""}
+    #flags = {"r":"False", "s":True, "h":True, "d":True, "p":True, "g":False}
+
+    #--------------------------------------------------------------------------
+    # Variables
+    #--------------------------------------------------------------------------
+
+    # Layers
+    OUT = options['output']
+    IN = options['input']
+    IN = IN.split(',')
+    CheckLayer(IN)
+    
+    # Diversity indici
+    flag_r = flags['r']
+    flag_s = flags['s']
+    flag_h = flags['h']
+    flag_d = flags['d']
+    flag_p = flags['p']
+    flag_g = flags['g']
+    if options['alpha']:
+        Q = map(float, options['alpha'].split(',')) 
+    else:
+        Q = map(float, [])
+    Qoriginal = list(Q)
+
+    #--------------------------------------------------------------------------
+    # Create list of what need to be computed
+    #--------------------------------------------------------------------------
+    if not flag_r:
+        flag_r = []
+    if flag_s and not 0.0 in Q:
+        Q.append(0.0)
+    if flag_h and not 1.0 in Q:
+        Q.append(1.0)
+    if flag_d and not 2.0 in Q:
+        Q.append(2.0)
+    if flag_p and not 2.0 in Q:
+        Q.append(2.0)
+    if flag_g and not 2.0 in Q:
+        Q.append(2.0)
+
+    #--------------------------------------------------------------------------
+    # Renyi entropy
+    #--------------------------------------------------------------------------
+    tmpt = tmpname("sht")
+    clean_rast.add(tmpt)
+    grass.run_command("r.series", quiet=True, output=tmpt, 
+                      input=IN, method="sum")  
+
+    for n in xrange(len(Q)):
+        
+        Qn = str(Q[n])
+        Qn = Qn.replace('.', '_')
+        out_renyi = OUT + "_Renyi_" + Qn
+        tmpl = []
+        
+        if Q[n] == 1:      
+            # When alpha = 1
+            for i in xrange(len(IN)):
+                tmpi = tmpname('shi' + str(i) + "_")
+                tmpl.append(tmpi)
+                clean_rast.add(tmpi)
+                grass.mapcalc("$tmpi = ($inl/$tmpt) * log(($inl/$tmpt))", 
+                              tmpi=tmpi,
+                              inl=IN[i],
+                              tmpt=tmpt,
+                              quiet=True)
+            grass.run_command("r.series", output=out_renyi, input=tmpl, 
+                                  method="sum", quiet=True)  
+            grass.mapcalc("$outl = -1 * $outl", 
+                              outl=out_renyi,
+                              overwrite=True,
+                              quiet=True)
+        else:
+            # If alpha != 1
+            for i in xrange(len(IN)):
+                tmpi = tmpname('reni')
+                tmpl.append(tmpi)       
+                grass.mapcalc("$tmpi = pow($inl/$tmpt,$alpha)", 
+                              tmpi=tmpi,
+                              tmpt=tmpt,
+                              inl=IN[i],
+                              alpha=Q[n],
+                              quiet=True)
+            grass.run_command("r.series", output=out_renyi, input=tmpl, 
+                              method="sum", quiet=True, overwrite=True)
+            grass.mapcalc("$outl = (1/(1-$alpha)) * log($outl)", 
+                              outl=out_renyi,
+                              alpha=Q[n],
+                              overwrite=True,
+                              quiet=True)
+        grass.run_command("g.remove", type="raster", 
+                          name=tmpl, flags="f", quiet=True)
+        
+    #--------------------------------------------------------------------------
+    # Species richness
+    #--------------------------------------------------------------------------
+    if flag_s:
+        out_div = OUT + "_richness"      
+        in_div = OUT + "_Renyi_0_0"
+        grass.mapcalc("$out_div = exp($in_div)",
+                      out_div=out_div,
+                      in_div=in_div,
+                      quiet=True)
+        if 0.0 not in Qoriginal:
+            grass.run_command("g.remove", flags="f", type="raster", 
+                              name=in_div, quiet=True)
+
+    #--------------------------------------------------------------------------
+    # Shannon index
+    #--------------------------------------------------------------------------
+    if flag_h:
+        out_div = OUT + "_shannon"      
+        in_div = OUT + "_Renyi_1_0"
+        if 1.0 in Qoriginal:
+            grass.run_command("g.copy", raster=(in_div,out_div), quiet=True)
+        else:
+            grass.run_command("g.rename", raster=(in_div,out_div), quiet=True)
+                
+    #--------------------------------------------------------------------------
+    # Simpson index
+    #--------------------------------------------------------------------------
+    if flag_d:
+        out_div = OUT + "_simpson"      
+        in_div = OUT + "_Renyi_2_0"
+        grass.mapcalc("$out_div = 1.0 / (exp($in_div))",
+                      out_div=out_div,
+                      in_div=in_div,
+                      quiet=True)
+        if 2.0 not in Qoriginal:
+            grass.run_command("g.remove", flags="f", type="raster", 
+                              name=in_div, quiet=True)
+       
+    #--------------------------------------------------------------------------
+    # Inversed Simpson index
+    #--------------------------------------------------------------------------
+    if flag_d:
+        out_div = OUT + "_invsimpson"      
+        in_div = OUT + "_Renyi_2_0"
+        grass.mapcalc("$out_div = exp($in_div)",
+                      out_div=out_div,
+                      in_div=in_div,
+                      quiet=True)
+        if 2.0 not in Qoriginal:
+            grass.run_command("g.remove", flags="f", type="raster", 
+                              name=in_div, quiet=True)
+        
+    #--------------------------------------------------------------------------
+    # Gini Simpson index
+    #--------------------------------------------------------------------------
+    if flag_d:
+        out_div = OUT + "_ginisimpson"      
+        in_div = OUT + "_Renyi_2_0"
+        grass.mapcalc("$out_div = 1.0 - (1.0 / exp($in_div))",
+                      out_div=out_div,
+                      in_div=in_div,
+                      quiet=True)
+        if 2.0 not in Qoriginal:
+            grass.run_command("g.remove", flags="f", type="raster", 
+                              name=in_div, quiet=True)
+        
+    # Clean up temporary files
+    grass.run_command("g.remove", type="raster", name=tmpt, 
+                      flags="f", quiet=True)
+  
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    atexit.register(cleanup)
+    sys.exit(main())


Property changes on: grass-addons/grass7/raster/r.biodiversity/r.biodiversity.py
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/raster/r.biodiversity/r_biodiversity.html
===================================================================
--- grass-addons/grass7/raster/r.biodiversity/r_biodiversity.html	                        (rev 0)
+++ grass-addons/grass7/raster/r.biodiversity/r_biodiversity.html	2015-09-09 16:29:19 UTC (rev 66153)
@@ -0,0 +1,140 @@
+<h2>DESCRIPTION</h2>
+
+<p><em>r.biodiversity</em> computes one or more biodiversity indici 
+based on 2 or more input layers. Each layer should represents a 
+species (or other categories being used), and its raster values the 
+species count. The name of the output layers will consist of the 
+base name provided by the user.
+
+<p>Currently implemented are the Rényi entropy index and three 
+specialized cases of the Renyi enthropy, viz.the species richness, the 
+Shannon index and the Simpson index (Legendre & Legendre, 1998). 
+
+<h4>The Renyi enthropy</h4>
+
+This index uantify the diversity, uncertainty, or randomness of a 
+system. The user can define the order of diversity by setting the 
+order (<i>alpha</i>) value. The order of a diversity indicates its 
+sensitivity to common and rare species. The diversity of order zero 
+( <i>alpha</i> = 0)  is completely insensitive to species 
+frequencies and is better known as species richness. Increasing the 
+order diminishes the relative weights of rare species in the 
+resulting index (Jost 2006, Legendre & Legendre 1998). The name of 
+the output layer is composed of the basename + renyi + alpha.
+
+<h4>Species richness</h4>
+
+<p>The species richness is simply the count of the number of layers. 
+It is a special case of the Reny enthropy: <pre>s = exp(R0)</pre>, 
+whereby <i>s</i> is the species richness <i>R0</i> the renyi index 
+for <i>alpha=0</i>. The name of the output layer is composed of the basename + 
+richness.
+
+<h4>Shannon index</h4>
+
+<p>The Shannon (also called the Shannon–Weaver or Shannon–Wiener) 
+index is defined as <pre>H = -sum(p_i x log(p_i))</pre>, where <i>p_i
+</i> is the proportional abundance of species <i>i</i>. The 
+r.biodiversity uses the natural logarithm (one can also use other 
+bases for the log, but that is currently not implemented, and 
+doesn't make a real difference). Note the Shannon index is a special 
+case of the Renyi enthropy for <i>alpha = 2<i>. The name of the output 
+layer is composed of the basename + shannon.
+
+<h4>Simpson (concentration) index</h4>
+
+<p>The Simpson's index is defined as <pre>D = sum p_i^2</pre>. This 
+is equivalent to <pre>-1 * 1 / exp(R2)</pre>, with <i>R2</i> the renyi 
+index for <i>alpha=2</i>. With this index, 0 represents infinite 
+diversity and 1, no diversity. The name of the output 
+layer is composed of the basename + simpson.
+
+<h4>Inverse Simpson index (Simpson's Reciprocal Index)</h4>
+
+<p>D obtains small values in datasets of high diversity and large 
+values in datasets of low diversity. This is counterintuitive 
+behavior for a diversity index. An alternative is the inverse 
+Simpson index, which is <pre>ID = 1 / D)</pre>. The index represents 
+the probability that two individuals randomly selected from a sample 
+will belong to different species. The value ranges between 0 and 1, 
+but now, the greater the value, the greater the sample diversity. 
+The name of the output layer is composed of the basename + invsimpson.
+
+<h4>Gini–Simpson index</h4>
+
+<p>An alternative way to overcome the problem of the 
+counter-intuitive nature of Simpson's Index is to use <pre>1 - D)</pre>. The lowest value of 
+this index is 1 and represent a community containing only one 
+species. The higher the value, the greater the diversity. The 
+maximum value is the number of species in the sample. The name of the output 
+layer is composed of the basename + ginisimpson.
+
+<h2>NOTES</h2>
+
+<p>Note that if you are interested in the landscape diversity, you 
+should have a look at the <a href= 
+"https://grass.osgeo.org/grass70/manuals/addons/r.diversity.html"> 
+r.diversity</a> addon or the various related r.li.* addons (see 
+below). These functions requires one input layer and compute the 
+diversity using a moving window.
+
+<h2>EXAMPLES</h2>
+
+<p>Suppose we have five layers, each representing number of 
+individuals of a different species. To keep it simple, let's assume 
+individuals of all five species are homogeneous distributed, with 
+respectively 60, 10, 25, 1 and 4 individuals / raster cell densities.
+
+<div class="code"><pre>
+r.mapcalc "spec1 = 60"
+r.mapcalc "spec2 = 10"
+r.mapcalc "spec3 = 25"
+r.mapcalc "spec4 = 1"
+r.mapcalc "spec5 = 4"
+</pre></div>
+
+Now we can calculate the renyi index for alpha is 0, 1 and 2 (this 
+will give you 1.61, 1.06 and 0.83 respectively)
+
+<div class="code"><pre>
+r.biodiversity in=spec1,spec2,spec3,spec4,spec5 out=renyi alpha=0,1,2
+</pre></div>
+
+You can also compute the species richness, shannon, simpson, inverse 
+simpson and gini-simpson indici
+
+<div class="code"><pre>
+r.biodiversity -s -h -d -p -g in=spec1,spec2,spec3,spec4,spec5 out=biodiversity
+</pre></div>
+
+The species richness you get should of course be 5. The shannon 
+index is the same as the renyi index with alpha=1 (1.06). The 
+simpson should be 0.43, and inverse simpson and gini-simpson will be 
+2.3 and 0.57 respectively.
+
+<h2>SEE ALSO</h2>
+1<em>
+<a href="r.li.html">r.li</a>,
+60	<a href="r.li.pielou.html">r.li.pielou</a>,
+61	<a href="r.li.renyi.html">r.li.renyi</a>,
+62	<a href="r.li.shannon.html">r.li.shannon</a>,
+63	<a href="r.li.simpson.html">r.li.simpson</a>
+</em>
+153	
+
+<h2>CITATION</h2> <p>Suggested citation: <p>van Breugel P, 
+r.biodiversity, a grass addon to compute biodiversity indici based 
+on 2 or more input layers. Available from 
+https://grass.osgeo.org/grass70/manuals/addons/r.biodiversity.html
+
+<h2>REFERENCES</h2>
+<ul>
+<li>Jost L. 2006. Entropy and diversity. Oikos 113:363–75</li>
+<li>Legendre P, Legendre L. 1998. Numerical Ecology. Second English edition. Elsevier, Amsterdam</li>
+</ul>
+
+
+<h2>AUTHOR</h2>
+Paulo van Breugel, paulo at ecodiv.org
+
+<p><i>Last changed: $Date$</i>


Property changes on: grass-addons/grass7/raster/r.biodiversity/r_biodiversity.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native



More information about the grass-commit mailing list