Good afternoon Markus & Co. 😊
It appears that the latest version of r.width.funct.py is not functioning
properly ... We have a few Windows10 systems here running GRASS; I'm on v7.4.0
and another person has (had) 7.2.2. She was trying to run r.basin on a 30m
resolution DEM and kept getting the following error:
Traceback (most recent call last):
File "C:\Users\XXX\AppData\Roaming\GRASS7\addons/scripts/r.width.funct.py",
line 135, in <module>
sys.exit(main())
File "C:\Users\XXX\AppData\Roaming\GRASS7\addons/scripts/r.width.funct.py",
line 84, in main
prc[0,0] , prc[0,1] = findint(kl,0.05) , 0.05
File "C:\Users\XXX\AppData\Roaming\GRASS7\addons/scripts/r.width.funct.py",
line 128, in findint
z1, z2, f1, f2 = kl[int(Xf[0])][0], kl[int(Xf[0]-1)][0], kl[int(Xf[0])][1],
kl[int(Xf[0]-1)][1]
IndexError: invalid index to scalar variable.
I tried running the same tool on my 7.4.0 version and also had the problem.
Trying to troubleshoot we initially discovered that the resolution of our
region wasn't uniform NS and EW ... so resetting the extents to something
divisible exactly by 30 fixed the problem on the 7.4.0 system however the 7.2.2
system was still getting the errors.
We upgraded that system to the latest version of GRASS (7.4.2), rebuilt the UTM
location and mapset from scratch making sure that the difference of the extents
were divisible by 30 and reinstalled the addons (r.hypso, r.width.funct, and
all of the r.basin.* addons) for the whole system. We found that for some
reason r.basin wants r.hypso and r.width.funct installed locally so we
reinstalled those two locally as well.
We imported the DEM (a geoTIFF) same as we did on the 7.4.0 system, resampled
it to a smaller region which was also adjusted to something with extents
divisible by 30 same as on the 7.4.0 system.
We then ran r.basin with the outlet coordinates and while the 7.4.0 system
works fine, he now 7.4.2 system still has the same errors as listed above.
I looked into r.width.funct.py as it was the module with the error and noticed
the copy I have installed on the 7.4.0 system is different than the one
installed on the 7.4.2 system which should be newer as it's a fresh
installation of GRASS. I copied over r.width.funct.py from the 7.4.0 machine
to the .4.2 machine and guess what ... it works now.
Based on cause and effect, it appears r.width.funct.py has an issue. I hadn't
delved into the code itself but I'm including it here (it's not too long) ...
this is the one that works:
I'm not sure what you would like to do but if other users are having a problem,
then replace your r.width.funct.py with this and you should be okay.
😊
Chris
#!/usr/bin/env python
################################################################################
#
# MODULE: r.width.funct
#
# AUTHOR(S): Massimo Di Stefano, Francesco Di Stefano, Margherita Di Leo
#
# PURPOSE: The module produces the Width Function of a basin. The Width
# Function W(x) gives the number of the cells in a basin at a
# flow distance x from the outlet (distance-area function)
#
# COPYRIGHT: (c) 2010 Massimo Di Stefano, Francesco Di Stefano, Margherita
Di Leo
#
# This program is free software under the GNU General Public
# License (>=v2). Read the file COPYING that comes with GRASS
# for details.
#
# REQUIRES: Matplotlib
# http://matplotlib.sourceforge.net/
#
#
################################################################################
#%module
#% description: Calculates the Width Function of a watershed basin.
#% keyword: raster
#% keyword: hydrology
#%end
#%option G_OPT_R_INPUT
#% key: map
#% description: Distance to outlet map (from r.stream.distance)
#% required: yes
#%end
#%option G_OPT_F_OUTPUT
#% key: image
#% key_desc: image
#% description: Name for output graph file (png)
#% required: yes
#%END
import sys
import os
import matplotlib #required by windows
matplotlib.use('wx') #required by windows
import matplotlib.pyplot as plt
import grass.script as grass
import numpy as np
def main():
stats = grass.read_command('r.stats', input = options['map'], sep =
'space', nv = '*', nsteps = '255', flags = 'Anc').split('\n')[:-1]
# res = cellsize
res = grass.region()['nsres']
zn = np.zeros((len(stats),4),float)
kl = np.zeros((len(stats),2),float)
prc = np.zeros((9,2),float)
for i in range(len(stats)):
if i == 0:
zn[i,0], zn[i,1] = map(float, stats[i].split(' '))
zn[i,1] = zn[i,1]
zn[i,2] = zn[i,1] * res
if i != 0:
zn[i,0], zn[i,1] = map(float, stats[i].split(' '))
zn[i,2] = zn[i,1] + zn[i-1,2]
zn[i,3] = zn[i,1] * (res**2)
totcell = sum(zn[:,1])
print "Tot. cells", totcell
totarea = totcell * (res**2)
print "Tot. area", totarea
maxdist = max(zn[:,0])
print "Max distance", maxdist
for i in range(len(stats)):
kl[i,0] = zn[i,0]
kl[i,1] = zn[i,2] / totcell
# quantiles
prc[0,0] , prc[0,1] = findint(kl,0.05) , 0.05
prc[1,0] , prc[1,1] = findint(kl,0.15) , 0.15
prc[2,0] , prc[2,1] = findint(kl,0.3) , 0.3
prc[3,0] , prc[3,1] = findint(kl,0.4) , 0.4
prc[4,0] , prc[4,1] = findint(kl,0.5) , 0.5
prc[5,0] , prc[5,1] = findint(kl,0.6) , 0.6
prc[6,0] , prc[6,1] = findint(kl,0.7) , 0.7
prc[7,0] , prc[7,1] = findint(kl,0.85) , 0.85
prc[8,0] , prc[8,1] = findint(kl,0.95) , 0.95
# plot
plotImage(zn[:,0], zn[:,3],
options['image']+'_width_function.png','-','x','W(x)','Width Function')
print "==========================="
print "Width Function | quantiles"
print "==========================="
print '%.0f' %findint(kl,0.05) , "|", 0.05
print '%.0f' %findint(kl,0.15) , "|", 0.15
print '%.0f' %findint(kl,0.3) , "|", 0.3
print '%.0f' %findint(kl,0.4) , "|", 0.4
print '%.0f' %findint(kl,0.5) , "|", 0.5
print '%.0f' %findint(kl,0.6) , "|", 0.6
print '%.0f' %findint(kl,0.7) , "|", 0.7
print '%.0f' %findint(kl,0.85) , "|", 0.85
print '%.0f' %findint(kl,0.95) , "|", 0.95
print '\n'
print 'Done!'
def plotImage(x,y,image,type,xlabel,ylabel,title):
plt.plot(x, y, type)
plt.ylabel(ylabel)
plt.xlabel(xlabel)
plt.xlim( min(x), max(x) )
plt.ylim( min(y), max(y) )
plt.title(title)
plt.grid(True)
plt.savefig(image)
plt.close('all')
def findint(kl,f):
Xf = np.abs(kl-f); Xf = np.where(Xf==Xf.min())
#z1, z2, f1, f2 = kl[float(Xf[0])][0], kl[float(Xf[0]-1)][0],
kl[float(Xf[0])][1], kl[float(Xf[0]-1)][1]
z1, z2, f1, f2 = kl[int(Xf[0])][0], kl[int(Xf[0]-1)][0], kl[int(Xf[0])][1],
kl[int(Xf[0]-1)][1]
z = z1 + ((z2 - z1) / (f2 - f1)) * (f - f1)
return z
if __name__ == "__main__":
options, flags = grass.parser()
sys.exit(main())
_______________________________________________
grass-user mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/grass-user