Unit 12 - Script tuning

In Unit 10 - Python intro and Unit 11 - Scripting we gain basic knowledge of GRASS Scripting Library, we know how to run GRASS modules using different functions (core.run_command, core.read_command, and core.parse_command). We are also able to parse module output in simply way. Beside core package the GRASS Scripting Library also offers useful functions which can simplify our scripts.

  • db Database related functions
  • raster Raster related functions
  • raster3d Raster3d related functions
  • vector Vector related functions

In our case we could replace v.db.select caller by vector.vector_db_select function. In other worlds replace code below

# v.db.select: don't print column names (-c)
ret = read_command('v.db.select', flags='c', map='ndvi_vector', separator='comma')
for line in ret.splitlines():
    # parse line (eg. 1,,-0.433962264150943,0.740350877192983,0.051388909449992)
    cat,label,min,max,mean = line.split(',')
    print ('NDVI class {0}: {1:.4f} (min) {2:.4f} (max) {3:.4f} (mean)'.format(
    cat, float(min), float(max), float(mean)))

by

from grass.script.vector import vector_db_select
data = vector_db_select('ndvi_vector')
for vals in data['values'].itervalues():
    # unfortunately we need to cast values by float
    print ('NDVI class {0}: {1:.4f} (min) {2:.4f} (max) {3:.4f} (mean)'.format(
    vals[0], float(vals[2]), float(vals[3]), float(vals[4])))

There is one problem with our script, some modules (r.recode, r.colors) uses hardcoded path to input files. This will not work when running script on different computer as we know. See code below (concretely rules options).

run_command("r.recode",
            overwrite = True,
            input = "ndvi",
            output = "ndvi_class",
            rules = "/home/landa/geodata/jena/models/reclass.txt")

run_command("r.colors",
            map = "ndvi_class",
            rules = "/home/landa/geodata/jena/models/colors.txt")

By GRASS Scripting Library we can define content of input file as a string object and transfer it to the command via standard input. This operation is allowed by core.feed_command function.

    p1 = feed_command("r.recode",
                      overwrite = True,
                      input = "ndvi",
                      output = "ndvi_class",
                      rules = "-")
    p1.stdin.write("""-1:0.1:1
0.1:0.5:2
0.5:1:3""")
    p1.stdin.close()
    p1.wait()

    p2 = feed_command("r.colors",
                      map = "ndvi_class",
                      rules = "-")
    p2.stdin.write("""1 grey
2 255 255 0
3 green""")
    p2.stdin.close()
    p2.wait()

First a command object is created, input string written to stdin, closed and than the command finally performed by wait().

We can also define cleanup routine which removes all intermediate data when compution is finished.

def cleanup():
    run_command('g.remove', flags='f', name='region_mask', type='vector')

User input

Our script lacks user input, all the input paramaters are hardcoded. We have to modify our script similarly as we did for model Unit 09 - Model tuning. Do you remember our first modification of model in Unit 11 - Scripting?

Let’s add previously removed lines back to the script.

#%module
#% description: NDVI model version 2
#%end