<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://grasswiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%E2%9A%A0%EF%B8%8FBernardoBrenoPacas</id>
	<title>GRASS-Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://grasswiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%E2%9A%A0%EF%B8%8FBernardoBrenoPacas"/>
	<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/wiki/Special:Contributions/%E2%9A%A0%EF%B8%8FBernardoBrenoPacas"/>
	<updated>2026-04-21T14:09:51Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_Python_Scripting_Library&amp;diff=25020</id>
		<title>GRASS Python Scripting Library</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_Python_Scripting_Library&amp;diff=25020"/>
		<updated>2018-02-09T12:55:47Z</updated>

		<summary type="html">&lt;p&gt;⚠️BernardoBrenoPacas: detail regarding del_temp_region&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Python}}&lt;br /&gt;
Python API documentation:&lt;br /&gt;
&lt;br /&gt;
* [http://grass.osgeo.org/grass70/manuals/libpython/ Python API for GRASS GIS 7] and [http://grass.osgeo.org/grass70/manuals/libpython/script_intro.html Python Scripting Library]&lt;br /&gt;
* [http://grass.osgeo.org/programming6/pythonlib.html for GRASS GIS 6]: core.py, db.py, raster.py, vector.py, setup.py, array.py task.py&lt;br /&gt;
&lt;br /&gt;
The GRASS Python Scripting Library can be imported by statement&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import grass.script as gscript&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other packages such as PyGRASS can be imported in a similar way.&lt;br /&gt;
&lt;br /&gt;
The code in {{src|lib/python/|lib/python}} provides &amp;lt;tt&amp;gt;grass.script&amp;lt;/tt&amp;gt; and other packages in order to support GRASS scripts written in Python. The {{src|scripts}} directory of GRASS GIS 7 contains a series of examples actually provided to the end users (while the script in GRASS GIS 6 are shell scripts).&lt;br /&gt;
&lt;br /&gt;
For more general info, see also [[GRASS and Python]] and see also [[Converting Bash scripts to Python]] if you have some Bash scripts you want to rewrite to Python.&lt;br /&gt;
&lt;br /&gt;
== Uses for read, feed and pipe, start and exec commands ==&lt;br /&gt;
&lt;br /&gt;
All of the &amp;lt;tt&amp;gt;*_command&amp;lt;/tt&amp;gt; functions use {{pyapi|script|script.core|make_command}} to construct a command&lt;br /&gt;
line for a program which uses the {{cmd|g.parser|desc=GRASS parser}}. Most of them then pass&lt;br /&gt;
that command line to &amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; via {{pyapi|script|script.core|start_command}}, except&lt;br /&gt;
for {{pyapi|script|script.core|exec_command}} which uses &amp;lt;tt&amp;gt;os.execvpe()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[To be precise, they use &amp;lt;tt&amp;gt;grass.Popen()&amp;lt;/tt&amp;gt;, which just calls&lt;br /&gt;
&amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; with 'shell=True' on Windows and 'shell=False'&lt;br /&gt;
otherwise. On Windows, you need to use 'shell=True' to be able to&lt;br /&gt;
execute scripts (including batch files); 'shell=False' only works with&lt;br /&gt;
binary executables.]&lt;br /&gt;
&lt;br /&gt;
{{pyapi|script|script.core|start_command}} separates the arguments into those which&lt;br /&gt;
&amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; understands and the rest. The rest are passed to&lt;br /&gt;
&amp;lt;tt&amp;gt;make_command()&amp;lt;/tt&amp;gt; to construct a command line which is passed as the&lt;br /&gt;
&amp;quot;args&amp;quot; parameter to &amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In other words, {{pyapi|script|script.core|start_command}} is a GRASS-oriented interface to&lt;br /&gt;
&amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt;. It should be suitable for any situation where you&lt;br /&gt;
would use &amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; to execute a normal GRASS command (one&lt;br /&gt;
which uses the GRASS parser, which is almost all of them; the main&lt;br /&gt;
exception is {{cmd|r.mapcalc}} in 6.x).&lt;br /&gt;
&lt;br /&gt;
Most of the others are convenience wrappers around &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt;, for common use cases.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|run_command}} calls the wait() method on the process, so it doesn't return until the command has finished, and returns the command's exit code. Similar to &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|pipe_command}} calls &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt; with 'stdout=PIPE' and returns the process object. You can use the process' .stdout member to read the command's stdout. Similar to popen(..., &amp;quot;r&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|feed_command}} calls &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt; with stdin=PIPE and returns the process object. You can use the process' .stdin member to write to the command's stdout. Similar to popen(..., &amp;quot;w&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|read_command}} calls &amp;lt;tt&amp;gt;pipe_command()&amp;lt;/tt&amp;gt;, reads the data from the command's stdout, and returns it as a string. Similar to `backticks` in the shell.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|write_command}} calls &amp;lt;tt&amp;gt;feed_command()&amp;lt;/tt&amp;gt;, sends the string specified by the &amp;quot;stdin&amp;quot; argument to the command's stdin, waits for the command to finish and returns its exit code. Similar to &amp;quot;echo ... | command&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|parse_command}} calls &amp;lt;tt&amp;gt;read_command()&amp;lt;/tt&amp;gt; and parses its output as key-value pairs. Useful for obtaining information from {{cmd|g.region}}, {{cmd|g.proj}}, {{cmd|r.info}}, etc.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|exec_command}} doesn't use &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt; but &amp;lt;tt&amp;gt;os.execvpe()&amp;lt;/tt&amp;gt;. This causes the specified command to replace the current program (i.e. the Python script), so &amp;lt;tt&amp;gt;exec_command()&amp;lt;/tt&amp;gt; never returns. Similar to bash's &amp;quot;exec&amp;quot; command. This can be useful if the script is a &amp;quot;wrapper&amp;quot; around a single command, where you construct the command line and execute the command as the final step. Notes: exec_command() is rarely appropriate. You probably want run_command() instead. On Windows, exec_command() will probably require the &amp;quot;.exe&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
If you have any other questions, you might want to look at the code ({{src|lib/python/core.py}}). Most of these functions are only a few lines long.&lt;br /&gt;
&lt;br /&gt;
=== Hints for parse_command() ===&lt;br /&gt;
&lt;br /&gt;
To turn this command&lt;br /&gt;
        g.rename rast=old_name,new_name&lt;br /&gt;
into a g.parse_command() call, you need to consider that it is a function call with three arguments:&lt;br /&gt;
# &amp;quot;g.rename&amp;quot;&lt;br /&gt;
# rast=old_name&lt;br /&gt;
# new_name&lt;br /&gt;
&lt;br /&gt;
The second argument is a keyword argument, the first and third are&lt;br /&gt;
positional (non-keyword) arguments. Python doesn't allow positional&lt;br /&gt;
arguments to follow keyword arguments; positional arguments come&lt;br /&gt;
first, keyword arguments last.&lt;br /&gt;
&lt;br /&gt;
Given the context, it's safe to assume that you want to pass a pair of&lt;br /&gt;
map names as the value to the rast= option. This requires explicit&lt;br /&gt;
parentheses so that the comma is treated as forming a tuple rather&lt;br /&gt;
than as an argument separator:&lt;br /&gt;
&lt;br /&gt;
        g.parse_command(&amp;quot;g.rename&amp;quot;, rast=(old_name,new_name))&lt;br /&gt;
&lt;br /&gt;
The parentheses in a tuple value can only be omitted if it doesn't&lt;br /&gt;
result in the comma being ambiguous (as is the case in a function&lt;br /&gt;
call).&lt;br /&gt;
&lt;br /&gt;
== Interfacing ==&lt;br /&gt;
&lt;br /&gt;
=== Interfacing with NumPy ===&lt;br /&gt;
&lt;br /&gt;
The {{pyapi|script|script.array|array}} module defines a &amp;lt;code&amp;gt;class array&amp;lt;/code&amp;gt; which is a subclass of [http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html numpy.memmap] with &amp;lt;code&amp;gt;.read()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.write()&amp;lt;/code&amp;gt; methods to read/write the underlying file via {{cmd|r.out.bin}}/{{cmd|r.in.bin}}. Metadata can be read with {{pyapi|script|script.raster|raster_info}}:&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.array as garray&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    map = &amp;quot;elevation.dem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # read map&lt;br /&gt;
    a = garray.array()&lt;br /&gt;
    a.read(map)&lt;br /&gt;
&lt;br /&gt;
    # get raster map info&lt;br /&gt;
    print grass.raster_info(map)['datatype']&lt;br /&gt;
    i = grass.raster_info(map)&lt;br /&gt;
    &lt;br /&gt;
    # get computational region info&lt;br /&gt;
    c = grass.region()&lt;br /&gt;
    print &amp;quot;rows: %d&amp;quot; % c['rows']&lt;br /&gt;
    print &amp;quot;cols: %d&amp;quot; % c['cols']&lt;br /&gt;
&lt;br /&gt;
    # new array for result&lt;br /&gt;
    b = garray.array()&lt;br /&gt;
    # calculate new map from input map and store as GRASS raster map&lt;br /&gt;
    b[...] = (a / 50).astype(int) * 50&lt;br /&gt;
    b.write(&amp;quot;elev.50m&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The size of the array is taken from the current region ([[computational region]]).&lt;br /&gt;
&lt;br /&gt;
The main drawback of using numpy is that you're limited by available&lt;br /&gt;
memory. Using a subclass of &amp;lt;code&amp;gt;numpy.memmap&amp;lt;/code&amp;gt; lets you use files which may&lt;br /&gt;
be much larger, but processing the entire array in one go is likely to&lt;br /&gt;
produce in-memory results of a similar size.&lt;br /&gt;
&lt;br /&gt;
'''NULL (no data) management:'''&lt;br /&gt;
&lt;br /&gt;
For integer maps, the NULL value is -2^31 = -2147483648. For floating-point maps, the NULL value is NaN. Note that the null= parameter for read() and write() specifies the value in the numpy array which is mapped to/from null values in the GRASS raster map.&lt;br /&gt;
&lt;br /&gt;
If you're using floating-point numpy arrays, then use (Note: This assumes that atof() and sscanf(&amp;quot;%lf&amp;quot;) recognise &amp;quot;nan&amp;quot;; this is the case on Linux, but doesn't appear to work on Windows)&lt;br /&gt;
 null=numpy.nan&lt;br /&gt;
&lt;br /&gt;
For integer arrays, using&lt;br /&gt;
 null=-2147483648&lt;br /&gt;
will ensure that valid values don't collide with NYLLs.&lt;br /&gt;
&lt;br /&gt;
'''MASK support:'''&lt;br /&gt;
&lt;br /&gt;
The function grass.script.array.read() and ...write() use r.out.bin and r.in.bin respectively. r.out.bin respects the MASK.&lt;br /&gt;
&lt;br /&gt;
=== Interfacing with NumPy and SciPy  ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.scipy.org/doc/scipy/reference/index.html SciPy] offers simple access to complex calculations. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from scipy import stats&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.array as garray&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    map = &amp;quot;elevation.dem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    x = garray.array()&lt;br /&gt;
    x.read(map)&lt;br /&gt;
&lt;br /&gt;
    # Descriptive Statistics:&lt;br /&gt;
    print &amp;quot;max, min, mean, var:&amp;quot;&lt;br /&gt;
    print x.max(), x.min(), x.mean(), x.var()&lt;br /&gt;
    print &amp;quot;Skewness test: z-score and 2-sided p-value:&amp;quot;&lt;br /&gt;
    print stats.skewtest(stats.skew(x))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interfacing with NumPy, SciPy and Matlab ===&lt;br /&gt;
&lt;br /&gt;
One may also use the SciPy - Matlab interface:&lt;br /&gt;
    &lt;br /&gt;
    r.out.mat input=elevation output=elev.mat&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    ### PY ###&lt;br /&gt;
    import scipy.io as sio&lt;br /&gt;
    # load data&lt;br /&gt;
    elev = sio.loadmat('elev.mat')&lt;br /&gt;
    # retrive the actual array. the data set contains also the spatial reference&lt;br /&gt;
    elev.get('map_data')&lt;br /&gt;
    data = elev.get('map_data')&lt;br /&gt;
    # a first simple plot&lt;br /&gt;
    import pylab&lt;br /&gt;
    pylab.plot(data)&lt;br /&gt;
    pylab.show()&lt;br /&gt;
    # the contour plot&lt;br /&gt;
    pylab.contour(data)&lt;br /&gt;
    # obviously data needs to ne reversed&lt;br /&gt;
    import numpy as np&lt;br /&gt;
    data_rev = data[::-1]&lt;br /&gt;
    pylab.contour(data_rev)&lt;br /&gt;
    # =&amp;gt; this is a quick plot. basemap mapping may provide a nicer map!&lt;br /&gt;
    #######&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Display example ===&lt;br /&gt;
Example of Python script, which is processed by {{cmd|g.parser}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#&lt;br /&gt;
############################################################################&lt;br /&gt;
#&lt;br /&gt;
# MODULE:      d.shadedmap&lt;br /&gt;
# AUTHOR(S):   Unknown; updated to GRASS 5.7 by Michael Barton&lt;br /&gt;
#              Converted to Python by Glynn Clements&lt;br /&gt;
# PURPOSE:     Uses d.his to drape a color raster over a shaded relief map&lt;br /&gt;
# COPYRIGHT:   (C) 2004,2008,2009 by the GRASS Development Team&lt;br /&gt;
#&lt;br /&gt;
#              This program is free software under the GNU General Public&lt;br /&gt;
#              License (&amp;gt;=v2). Read the file COPYING that comes with GRASS&lt;br /&gt;
#              for details.&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
&lt;br /&gt;
#%Module&lt;br /&gt;
#% description: Drapes a color raster over a shaded relief map using d.his&lt;br /&gt;
#% keyword: display&lt;br /&gt;
#% keyword: raster&lt;br /&gt;
#%End&lt;br /&gt;
#%option&lt;br /&gt;
#% key: reliefmap&lt;br /&gt;
#% type: string&lt;br /&gt;
#% gisprompt: old,cell,raster&lt;br /&gt;
#% description: Name of shaded relief or aspect map&lt;br /&gt;
#% required : yes&lt;br /&gt;
#%end&lt;br /&gt;
#%option&lt;br /&gt;
#% key: drapemap&lt;br /&gt;
#% type: string&lt;br /&gt;
#% gisprompt: old,cell,raster&lt;br /&gt;
#% description: Name of raster to drape over relief map&lt;br /&gt;
#% required : yes&lt;br /&gt;
#%end&lt;br /&gt;
#%option&lt;br /&gt;
#% key: brighten&lt;br /&gt;
#% type: integer&lt;br /&gt;
#% description: Percent to brighten&lt;br /&gt;
#% options: -99-99&lt;br /&gt;
#% answer: 0&lt;br /&gt;
#%end&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
from grass.script import core as grass&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    drape_map = options['drapemap']&lt;br /&gt;
    relief_map = options['reliefmap']&lt;br /&gt;
    brighten = options['brighten']&lt;br /&gt;
    ret = grass.run_command(&amp;quot;d.his&amp;quot;, h_map = drape_map,  i_map = relief_map, brighten = brighten)&lt;br /&gt;
    sys.exit(ret)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    options, flags = grass.parser()&lt;br /&gt;
    main()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Parsing the options and flags  ===&lt;br /&gt;
&lt;br /&gt;
{{pyapi|script|script.core|parser}} is an interface to {{cmd|g.parser}}, and allows to parse the ''options'' and ''flags'' passed to your script on the command line. It is to be called at the top-level:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    options, flags = grass.parser()&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Global variables &amp;quot;options&amp;quot; and &amp;quot;flags&amp;quot; are Python dictionaries containing the options/flags values, keyed by lower-case option/flag names. The values in &amp;quot;options&amp;quot; are strings, those in &amp;quot;flags&amp;quot; are Python booleans. All those variables have to be previously declared in the header of your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; options, flags = grass.parser()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; options&lt;br /&gt;
{'input': 'my_map', 'output': 'map_out', 'option1': '21.472', 'option2': ''}&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; flags&lt;br /&gt;
{'c': True, 'm': False}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Passing several floats to a single option:'''&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python my.module.py input=input output=output myoption=0.1,0.2,0.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The values in the &amp;quot;options&amp;quot; dictionary returned from the parser()&lt;br /&gt;
function are always strings. You can parse the string with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
        myoption = map(float, options['myoption'].split(','))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The option definition in the script should have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
        #% type: double&lt;br /&gt;
        #% multiple: yes&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows g.parser to validate the option syntax, so you can rely&lt;br /&gt;
upon the string being in the correct format. If the values have a&lt;br /&gt;
fixed range, you can use e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
        #% options: 0.0-1.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to have the parser check that the values fall within the range.&lt;br /&gt;
&lt;br /&gt;
For more information on option definitions, see:&lt;br /&gt;
&lt;br /&gt;
http://grass.osgeo.org/programming7/gislib.html#Complete_Structure_Members_Table&lt;br /&gt;
&lt;br /&gt;
=== Example for embedding r.mapcalc (map algebra) ===&lt;br /&gt;
&lt;br /&gt;
{{pyapi|script|script.raster|mapcalc}} accepts a template string followed by keyword&lt;br /&gt;
arguments for the substitutions, e.g. (code snippets):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
grass.mapcalc(&amp;quot;${out} = ${rast1} + ${rast2}&amp;quot;,&lt;br /&gt;
              out = options['output'],&lt;br /&gt;
              rast1 = options['raster1'],&lt;br /&gt;
              rast2 = options['raster2'])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Best practice'': first copy all of the options[] into separate variables at the beginning of main(), i.e.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def main():&lt;br /&gt;
    output = options['output']&lt;br /&gt;
    raster1 = options['raster1']&lt;br /&gt;
    raster2 = options['raster2']&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    grass.mapcalc(&amp;quot;${out} = ${rast1} + ${rast2}&amp;quot;,&lt;br /&gt;
                  out = output,&lt;br /&gt;
                  rast1 = raster1,&lt;br /&gt;
                  rast2 = raster2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Performing multiple computations using &amp;lt;tt&amp;gt;grass.script.raster.mapcalc()&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
expr = &amp;quot;;&amp;quot;.join([&lt;br /&gt;
        &amp;quot;$out.r = r#$first * $frac + (1.0 - $frac) * r#$second&amp;quot;,&lt;br /&gt;
        &amp;quot;$out.g = g#$first * $frac + (1.0 - $frac) * g#$second&amp;quot;,&lt;br /&gt;
        &amp;quot;$out.b = b#$first * $frac + (1.0 - $frac) * b#$second&amp;quot;])&lt;br /&gt;
grass.mapcalc(expr, out=out, first=first, second=second, frac=percent/100.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hint: multi-line strings can be separated by using a semicolon instead of a newline.&lt;br /&gt;
&lt;br /&gt;
=== Looping over file names stored in an ASCII file ===&lt;br /&gt;
&lt;br /&gt;
When looping over file names stored in an ASCII file and getting the error&lt;br /&gt;
&lt;br /&gt;
   WARNING: Illegal filename &amp;lt;map.f1jan.05216.something&lt;br /&gt;
          &amp;gt;. Character &amp;lt;&lt;br /&gt;
          &amp;gt; not allowed.&lt;br /&gt;
&lt;br /&gt;
then the line terminators may be the reason.&lt;br /&gt;
When you iterate over a file, the strings include the line terminators (e.g. '\n' or '\r\n'). Use e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    for line in gl:&lt;br /&gt;
        renamed = line.rstrip().replace('.','_')&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to remove any trailing whitespace (including newlines) from each line.&lt;br /&gt;
&lt;br /&gt;
=== Example for parsing raster category labels ===&lt;br /&gt;
&lt;br /&gt;
How to obtain the text labels&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # dump cats to file to avoid &amp;quot;too many argument&amp;quot; problem:&lt;br /&gt;
    p = grass.pipe_command('r.category', map = rastertmp, separator = ';', quiet = True)&lt;br /&gt;
    cats = []&lt;br /&gt;
    for line in p.stdout:&lt;br /&gt;
        cats.append(line.rstrip('\r\n').split(';')[0])&lt;br /&gt;
    p.wait()&lt;br /&gt;
&lt;br /&gt;
    number = len(cats)&lt;br /&gt;
    if number &amp;lt; 1:&lt;br /&gt;
        grass.fatal(_(&amp;quot;No categories found in raster map&amp;quot;))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example for parsing category numbers ===&lt;br /&gt;
&lt;br /&gt;
'''Q:''' How to obtain the number of cells of a certain category?&lt;br /&gt;
&lt;br /&gt;
'''A:''' It is recommended to use {{pyapi|script|script.core|pipe_command}} and parse the output, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       p = grass.pipe_command('r.stats',flags='c',input='map')&lt;br /&gt;
       result = {}&lt;br /&gt;
       for line in p.stdout:&lt;br /&gt;
           val,count = line.strip().split()&lt;br /&gt;
           result[int(val)] = int(count)&lt;br /&gt;
       p.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example for getting the region's number of rows and columns ===&lt;br /&gt;
&lt;br /&gt;
'''Q:''' How to obtain the number of rows and columns of the current region?&lt;br /&gt;
&lt;br /&gt;
'''A:''' It is recommended to use the {{pyapi|script|script.core|region}} function which will create a dictionary with values for extents and resolution, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#-*- coding:utf-8 -*-&lt;br /&gt;
#&lt;br /&gt;
############################################################################&lt;br /&gt;
#&lt;br /&gt;
# MODULE:       g.region.resolution&lt;br /&gt;
# AUTHOR(S):    based on a post at GRASS-USER mailing list [1]               &lt;br /&gt;
# PURPOSE:	Parses &amp;quot;g.region -g&amp;quot;, prints out number of rows, cols&lt;br /&gt;
# COPYLEFT:     ;-)&lt;br /&gt;
# COMMENT:      ...a lot of comments to be easy-to-read for/by beginners&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
#%Module&lt;br /&gt;
#% description: Print number of rows, cols of current geographic region&lt;br /&gt;
#% keyword: region&lt;br /&gt;
#%end&lt;br /&gt;
&lt;br /&gt;
# importing required modules&lt;br /&gt;
import sys # the sys module [2]&lt;br /&gt;
from grass.script import core as grass # the core module [3]&lt;br /&gt;
&lt;br /&gt;
# information about imported modules can be obtained using the dir() function&lt;br /&gt;
# e.g.: dir(sys)&lt;br /&gt;
&lt;br /&gt;
# define the &amp;quot;main&amp;quot; function: get number of rows, cols of region&lt;br /&gt;
def main():&lt;br /&gt;
    &lt;br /&gt;
    # #######################################################################&lt;br /&gt;
    # the following commented code works but is kept only for learning purposes&lt;br /&gt;
     &lt;br /&gt;
    ## assigning the output of the command &amp;quot;g.region -g&amp;quot; in a string called &amp;quot;return_rows_x_cols&amp;quot;&lt;br /&gt;
    # return_rows_x_cols = grass.read_command('g.region', flags = 'g')&lt;br /&gt;
    &lt;br /&gt;
    ## parsing arguments of interest (rows, cols) in a dictionary named &amp;quot;rows_x_cols&amp;quot;&lt;br /&gt;
    # rows_x_cols = grass.parse_key_val(return_rows_x_cols)&lt;br /&gt;
    &lt;br /&gt;
    ## selectively print rows, cols from the dictionary &amp;quot;rows_x_cols&amp;quot;&lt;br /&gt;
    # print 'rows=%d \ncols=%d' % (int(rows_x_cols['rows']), int(rows_x_cols['cols']))&lt;br /&gt;
    &lt;br /&gt;
    # #######################################################################&lt;br /&gt;
    &lt;br /&gt;
    # faster/ easier way: use of the &amp;quot;grass.region()&amp;quot; function&lt;br /&gt;
    gregion = grass.region()&lt;br /&gt;
    rows = gregion['rows']&lt;br /&gt;
    cols = gregion['cols']&lt;br /&gt;
    &lt;br /&gt;
    # print rows, cols properly formated &lt;br /&gt;
    print 'rows=%d \ncols=%d' % (rows, cols)&lt;br /&gt;
&lt;br /&gt;
# this &amp;quot;if&amp;quot; condition instructs execution of code contained in this script, *only* if the script is being executed directly &lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;: # this allows the script to be used as a module in other scripts or as a standalone script&lt;br /&gt;
    options, flags = grass.parser() #&lt;br /&gt;
    sys.exit(main()) #&lt;br /&gt;
&lt;br /&gt;
# Links&lt;br /&gt;
# [1] http://n2.nabble.com/Getting-rows-cols-of-a-region-in-a-script-tp2787474p2787509.html&lt;br /&gt;
# [2] http://www.python.org/doc/2.5.2/lib/module-sys.html&lt;br /&gt;
# [3] http://grass.osgeo.org/grass71/manuals/libpython&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Managing mapsets ===&lt;br /&gt;
&lt;br /&gt;
To check if a certain mapset exists in the active location, use {{pyapi|script|script.core|mapsets}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.mapsets(False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... returns a list of mapsets in the current location.&lt;br /&gt;
&lt;br /&gt;
=== r.mapcalc example ===&lt;br /&gt;
&lt;br /&gt;
Example of Python script, which is processed by {{cmd|g.parser}}:&lt;br /&gt;
&lt;br /&gt;
The shell script line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  r.mapcalc &amp;quot;MASK = if(($cloudResampName &amp;lt; 0.01000),1,null())&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would be written like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
       ...&lt;br /&gt;
&lt;br /&gt;
       grass.mapcalc(&amp;quot;MASK=if(($cloudResampName &amp;lt; 0.01000),1,null())&amp;quot;,&lt;br /&gt;
                     cloudResampName = cloudResampName)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first argument to the mapcalc function is a template (see the Python library documentation for [http://docs.python.org/library/string.html string.Template]). Any keyword arguments (other than &amp;lt;tt&amp;gt;quiet&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;overwrite&amp;lt;/tt&amp;gt;) specify substitutions.&lt;br /&gt;
&lt;br /&gt;
=== r.mapcalc example: defining a moving window ===&lt;br /&gt;
&lt;br /&gt;
Moving window of 4 cell in every 8 direction and do a boolean comparison. Boolean value (e.g. the result of a comparison) is an integer, with 1 for true, 0 for false.&lt;br /&gt;
Then do a r.mapcalc calculation with the moving window.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
           &lt;br /&gt;
       # define a moving window of 4 cell in every 8 direction&lt;br /&gt;
       #&lt;br /&gt;
       # map[4,4]                                    map[4,0]                                    map[4,-4]		&lt;br /&gt;
       # 	    map[3,3]                         map[3,0]                         map[3,-3]			&lt;br /&gt;
       # 		       map[2,2]              map[2,0]              map[2,-2]				&lt;br /&gt;
       #                                  map[1,1]   map[1,0]   map[1,-1]	 				&lt;br /&gt;
       # map[0,4]   map[0,3]   map[0,2]   map[0,1]       x      map[0,-1]  map[0,-2]  map[0,-3]  map[0,-4]&lt;br /&gt;
       #                                  map[-1,1]  map[-1,0]  map[-1,-1]					&lt;br /&gt;
       #                       map[-2,2]             map[-2,0]             map[-2,-2]				&lt;br /&gt;
       #            map[-3,3]                        map[-3,0]                        map[-3,-3]			&lt;br /&gt;
       # map[-4,4]                                   map[-4,0]                                   map[-4,-4]&lt;br /&gt;
       &lt;br /&gt;
       # define the offet duplets&lt;br /&gt;
       &lt;br /&gt;
       offsets = [d&lt;br /&gt;
           for j in xrange(1,4+1)&lt;br /&gt;
           for i in [j,-j]&lt;br /&gt;
           for d in [(i,0),(0,i),(i,i),(i,-i)]]&lt;br /&gt;
       	&lt;br /&gt;
       # &amp;gt;&amp;gt;&amp;gt;offsets&lt;br /&gt;
       # [(1, 0), (0, 1), (1, 1), (1, -1), (-1, 0), (0, -1), (-1, -1), (-1, 1), (2, 0), (0, 2), (2, 2), (2, -2), (-2, 0), (0, -2), \&lt;br /&gt;
       # (-2, -2), (-2, 2), (3, 0), (0, 3), (3, 3), (3, -3), (-3, 0), (0, -3), (-3, -3), (-3, 3), (4, 0), (0, 4), (4, 4), (4, -4), \&lt;br /&gt;
       # (-4, 0), (0, -4), (-4, -4), (-4, 4)]&lt;br /&gt;
       &lt;br /&gt;
       # define the calculation term&lt;br /&gt;
       &lt;br /&gt;
       terms = [&amp;quot;(myelevnc[%d,%d] &amp;lt; myelevnc)&amp;quot; % d&lt;br /&gt;
                for d in offsets]&lt;br /&gt;
       &lt;br /&gt;
       # &amp;gt;&amp;gt;&amp;gt;terms&lt;br /&gt;
       # ['(myelevnc[1,0] &amp;lt; myelevnc)', '(myelevnc[0,1] &amp;lt; myelevnc)', '(myelevnc[1,1] &amp;lt; myelevnc)', '(myelevnc[1,-1] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-1,0] &amp;lt; myelevnc)', '(myelevnc[0,-1] &amp;lt; myelevnc)', '(myelevnc[-1,-1] &amp;lt; myelevnc)', '(myelevnc[-1,1] &amp;lt; myelevnc)',\&lt;br /&gt;
       # '(myelevnc[2,0] &amp;lt; myelevnc)', '(myelevnc[0,2] &amp;lt; myelevnc)', '(myelevnc[2,2] &amp;lt; myelevnc)', '(myelevnc[2,-2] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-2,0] &amp;lt; myelevnc)', '(myelevnc[0,-2] &amp;lt; myelevnc)', '(myelevnc[-2,-2] &amp;lt; myelevnc)', '(myelevnc[-2,2] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[3,0] &amp;lt; myelevnc)', '(myelevnc[0,3] &amp;lt; myelevnc)', '(myelevnc[3,3] &amp;lt; myelevnc)', '(myelevnc[3,-3] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-3,0] &amp;lt; myelevnc)', '(myelevnc[0,-3] &amp;lt; myelevnc)', '(myelevnc[-3,-3] &amp;lt; myelevnc)', '(myelevnc[-3,3] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[4,0] &amp;lt; myelevnc)', '(myelevnc[0,4] &amp;lt; myelevnc)', '(myelevnc[4,4] &amp;lt; myelevnc)', '(myelevnc[4,-4] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-4,0] &amp;lt; myelevnc)', '(myelevnc[0,-4] &amp;lt; myelevnc)', '(myelevnc[-4,-4] &amp;lt; myelevnc)', '(myelevnc[-4,4] &amp;lt; myelevnc)']&lt;br /&gt;
       &lt;br /&gt;
       # define the calculation expression&lt;br /&gt;
       &lt;br /&gt;
       expr = &amp;quot;elevation_percentile4 = (100.0 / 48.0) * (%s)&amp;quot; % &amp;quot; + &amp;quot;.join(terms)&lt;br /&gt;
       &lt;br /&gt;
       # &amp;gt;&amp;gt;&amp;gt;expr&lt;br /&gt;
       #  elevation_percentile4 = (100.0 / 48.0) * ((myelevnc[1,0] &amp;lt; myelevnc) + (myelevnc[0,1] &amp;lt; myelevnc) + (myelevnc[1,1] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[1,-1] &amp;lt; myelevnc) + (myelevnc[-1,0] &amp;lt; myelevnc) + (myelevnc[0,-1] &amp;lt; myelevnc) + (myelevnc[-1,-1] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[-1,1] &amp;lt; myelevnc) + (myelevnc[2,0] &amp;lt; myelevnc) + (myelevnc[0,2] &amp;lt; myelevnc) + (myelevnc[2,2] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[2,-2] &amp;lt; myelevnc) + (myelevnc[-2,0] &amp;lt; myelevnc) + (myelevnc[0,-2] &amp;lt; myelevnc) + (myelevnc[-2,-2] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[-2,2] &amp;lt; myelevnc) + (myelevnc[3,0] &amp;lt; myelevnc) + (myelevnc[0,3] &amp;lt; myelevnc) + (myelevnc[3,3] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[3,-3] &amp;lt; myelevnc) + (myelevnc[-3,0] &amp;lt; myelevnc) + (myelevnc[0,-3] &amp;lt; myelevnc) + (myelevnc[-3,-3] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[-3,3] &amp;lt; myelevnc) + (myelevnc[4,0] &amp;lt; myelevnc) + (myelevnc[0,4] &amp;lt; myelevnc) + (myelevnc[4,4] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[4,-4] &amp;lt; myelevnc) + (myelevnc[-4,0] &amp;lt; myelevnc) + (myelevnc[0,-4] &amp;lt; myelevnc) + (myelevnc[-4,-4] &amp;lt; myelevnc)\&lt;br /&gt;
       #  + (myelevnc[-4,4] &amp;lt; myelevnc))&lt;br /&gt;
       &lt;br /&gt;
       # do the r.mapcalc calculation with the moving window&lt;br /&gt;
       &lt;br /&gt;
       grass.mapcalc( expr )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using output from GRASS modules in the script ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you need to use the output of a module for the next step. There are dedicated functions to obtain the result of, for example, a statistical analysis.&lt;br /&gt;
&lt;br /&gt;
Example: get the range of a raster map and use it in {{cmd|r.mapcalc}}. Here you can use {{pyapi|script|script.raster|raster_info}}, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
       max = grass.raster_info(inmap)['max']&lt;br /&gt;
       grass.mapcalc(&amp;quot;$outmap = $inmap / $max&amp;quot;,&lt;br /&gt;
                     inmap = inmap, outmap = outmap, max = max)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using output from r.what ===&lt;br /&gt;
&lt;br /&gt;
''Q: How does one return attribute values from a call to the 'r.what' module running in a python script?''&lt;br /&gt;
&lt;br /&gt;
A: If you use &amp;lt;tt&amp;gt;grass.script.raster_what()&amp;lt;/tt&amp;gt;, it returns a list of dictionaries.&lt;br /&gt;
&lt;br /&gt;
PyGRASS which requires you to add &amp;lt;tt&amp;gt;stdout_=PIPE&amp;lt;/tt&amp;gt;, then you can get the output as a string from &amp;lt;tt&amp;gt;module.outputs.stdout&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Or using directly the C API through python with (North Carolina dataset example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
from grass.pygrass.raster import RasterRow&lt;br /&gt;
from grass.pygrass.gis.region import Region&lt;br /&gt;
&lt;br /&gt;
with RasterRow('elevation', mode='r') as rast:&lt;br /&gt;
    with VectorTopo('hospitals', mode='r') as hospitals:&lt;br /&gt;
        region = Region()&lt;br /&gt;
        for hosp in hospitals:&lt;br /&gt;
            value = rast.get_value(hosp, region)&lt;br /&gt;
            if value is not None:&lt;br /&gt;
                print(hosp.cat, value)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling a GRASS module in Python ===&lt;br /&gt;
&lt;br /&gt;
Imagine, you wanted to execute this command in Python:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  r.profile -g input=mymap output=newfile profile=12244.256,-295112.597,12128.012,-295293.77&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All arguments except the first (which is a flag) are keyword arguments, i.e. &amp;lt;tt&amp;gt;arg = val&amp;lt;/tt&amp;gt;. For the flag, use &amp;lt;tt&amp;gt;flags = 'g'&amp;lt;/tt&amp;gt; (note that &amp;quot;-g&amp;quot; would be the negative of a Python variable named &amp;quot;g&amp;quot;!). So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('r.profile',&lt;br /&gt;
               input = input_map,&lt;br /&gt;
               output = output_file,&lt;br /&gt;
               profile = [12244.256,-295112.597,12128.012,-295293.77]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
               profile = [(12244.256,-295112.597),(12128.012,-295293.77)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i.e. you need to provide the keyword, and the argument must be a valid Python expression. Function &amp;lt;code&amp;gt;run_command()&amp;lt;/code&amp;gt; etc accept lists and tuples.&lt;br /&gt;
&lt;br /&gt;
'''What is the proper way to include keyword-arguments tuples?'''&lt;br /&gt;
&lt;br /&gt;
For example, &amp;quot;g.list -f type=rast,vect&amp;quot; translates into:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&amp;quot;g.list&amp;quot;, flags=&amp;quot;f&amp;quot;, type=&amp;quot;rast,vect&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&amp;quot;g.list&amp;quot;, flags=&amp;quot;f&amp;quot;, type=[&amp;quot;rast&amp;quot;,&amp;quot;vect&amp;quot;])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The various *_command() functions accept arbitrary keyword arguments. Any keywords which don't have a specific meaning to either the *_command() function or the Popen constructor are treated as arguments to the GRASS module.&lt;br /&gt;
&lt;br /&gt;
'''What is the proper way to use multiple flags?'''&lt;br /&gt;
&lt;br /&gt;
How can I call a module with multiple flags set (e.g., -a and -b) in GRASS-Python?&lt;br /&gt;
&lt;br /&gt;
  flags = &amp;quot;ab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&amp;quot;r.info&amp;quot;, flags=&amp;quot;eg&amp;quot;, map=[&amp;quot;elevation&amp;quot;])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Differences between ''run_command()'' and ''read_command()'':'''&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|run_command}} executes the command and waits for it to terminate; it doesn't redirect any of the standard streams.&lt;br /&gt;
* {{pyapi|script|script.core|read_command}} executes the command with stdout redirected to a pipe, and reads everything written to it. Once the command terminates, it returns the data written to stdout as a string.&lt;br /&gt;
&lt;br /&gt;
'''How to retrieve error messages from ''read_command()'':'''&lt;br /&gt;
&lt;br /&gt;
None of the existing *_command functions redirect stderr. You can do so with e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def read2_command(*args, **kwargs):&lt;br /&gt;
   kwargs['stdout'] = grass.PIPE&lt;br /&gt;
   kwargs['stderr'] = grass.PIPE&lt;br /&gt;
   ps = grass.start_command(*args, **kwargs)&lt;br /&gt;
   return ps.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This behaves like &amp;lt;tt&amp;gt;read_command()&amp;lt;/tt&amp;gt; except that it returns a tuple of (stdout, stderr) rather than just stdout.&lt;br /&gt;
&lt;br /&gt;
=== Interface to copying maps (g.copy) ===&lt;br /&gt;
&lt;br /&gt;
Copy a raster map (for vector, replace &amp;quot;rast&amp;quot; with &amp;quot;vect&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('g.copy', rast = (input, output))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To generalize it, &amp;quot;datatype&amp;quot; is the form of grass data to copy (eg, rast, vect, etc)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('g.copy', **{datatype: (input, output)})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface to listing maps (g.list) ===&lt;br /&gt;
&lt;br /&gt;
You may use the functions in [http://grass.osgeo.org/programming7/namespacepython_1_1script_1_1core.html python.script.core.mlist_grouped()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
list_grouped('raster')['PERMANENT']&lt;br /&gt;
[..., 'lakes', ..., 'slope', ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
mlist_grouped('vector', pattern='*roads*')['PERMANENT']&lt;br /&gt;
['railroads', 'roadsmajor']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Python/pygrass#Sample_PyGRASS_scripts|Sample PyGRASS scripts]] for an alternative solution.&lt;br /&gt;
&lt;br /&gt;
=== i.group with patterns as name for input ===&lt;br /&gt;
&lt;br /&gt;
Imagery groups can be populated like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.gis import Mapset&lt;br /&gt;
&lt;br /&gt;
run_command(&amp;quot;i.group&amp;quot;, group=&amp;quot;mygroup&amp;quot;, input=mset.glist(&amp;quot;raster&amp;quot;, pattern=&amp;quot;mypattern_*&amp;quot;))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Percentage output for progress of computation ===&lt;br /&gt;
&lt;br /&gt;
A) Within a Python script, the {{pyapi|script|script.core|percent}} module method wraps the &amp;lt;tt&amp;gt;g.message -p&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
B) If you call a GRASS command within the Python code, you have to parse the output by setting &amp;lt;tt&amp;gt;GRASS_MESSAGE_FORMAT=gui&amp;lt;/tt&amp;gt; in the environment when running the command and read from the command's stderr; e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
       env = os.environ.copy()&lt;br /&gt;
       env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
       p = grass.start_command(..., stderr = grass.PIPE, env = env)&lt;br /&gt;
       # read from p.stderr&lt;br /&gt;
       p.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need to capture both stdout and stderr, you need to use threads, select, or non-blocking I/O to consume data from both streams as it is generated in order to avoid deadlock.&lt;br /&gt;
&lt;br /&gt;
ALTERNATIVE:&lt;br /&gt;
&lt;br /&gt;
Redirect both stdout and stderr to the same pipe (and hope that the normal output doesn't include anything which will be mistaken for progress/error/etc messages):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       p = grass.start_command(..., stdout = grass.PIPE, stderr = grass.STDOUT, env = env)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NULL data management ===&lt;br /&gt;
&lt;br /&gt;
How to analyse if there are only NULL cells in a map:&lt;br /&gt;
&lt;br /&gt;
If a map contains only null cells, its minimum and maximum will be &amp;quot;NULL&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
       $ r.mapcalc 'foo = null()'&lt;br /&gt;
       $ r.info -r foo&lt;br /&gt;
       min=NULL&lt;br /&gt;
       max=NULL&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the Python API, The 'min' and 'max' values in the result of the {{pyapi|script|script.raster|raster_info}} function will be &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Counting cells ===&lt;br /&gt;
&lt;br /&gt;
Counting cells is far more expensive than simply determining whether&lt;br /&gt;
there are any non-null cells. Counting cells requires reading the&lt;br /&gt;
entire map, while the {{cmd|r.info}} approach only needs to read the metadata&lt;br /&gt;
files.&lt;br /&gt;
&lt;br /&gt;
If you do need to count cells, {{cmd|r.stats}} is likely to be more efficient than {{cmd|r.univar}}.&lt;br /&gt;
&lt;br /&gt;
A count loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       while grass.raster_info(inmap)['max'] is not None:&lt;br /&gt;
           ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Display: overlayed map display with labels ===&lt;br /&gt;
&lt;br /&gt;
Example: display a vector map and overlay its labels on top of the map.&lt;br /&gt;
&lt;br /&gt;
If the environment contains the setting GRASS_PNG_READ=TRUE, d.* commands should overlay their output on an existing image (otherwise the first command creates the file map.png but the second command overwrites the file with only the labels). So the following should work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('d.vect', map='my_shape')&lt;br /&gt;
       env = os.environ.copy()&lt;br /&gt;
       env['GRASS_PNG_READ'] = 'TRUE'&lt;br /&gt;
       grass.run_command('d.labels', labels='my_shape_labels', env = env)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Path to GISDBASE ===&lt;br /&gt;
In order to a avoid hardcoded paths to GRASS mapset files like the SQLite DB file, you can get the GISDBASE variable from the environment:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
       import os.path&lt;br /&gt;
&lt;br /&gt;
       env = grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
       gisdbase = env['GISDBASE']&lt;br /&gt;
       location = env['LOCATION_NAME']&lt;br /&gt;
       mapset = env['MAPSET']&lt;br /&gt;
&lt;br /&gt;
       path = os.path.join(gisdbase, location, mapset, 'sqlite.db')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Creating a new location ===&lt;br /&gt;
&lt;br /&gt;
Use {{pyapi|script|script.core|create_location}} to create a new location.&lt;br /&gt;
&lt;br /&gt;
=== Use Python reserved keyword ===&lt;br /&gt;
&lt;br /&gt;
'''Q:''' ''r.resamp.bspline'' uses 'lambda' as a command line parameter name, but when you try to use it with {{pyapi|script|script.core|run_command}} or {{pyapi|script|script.core|start_command}} you get an error as lambda is a python reserved keyword. How to work around that?&lt;br /&gt;
&lt;br /&gt;
'''A:''' Append an underscore to the name, i.e.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('r.resamp.bspline', lambda_ = ...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this follows Python [http://legacy.python.org/dev/peps/pep-0008/#descriptive-naming-styles PEP8] style guide. In GRASS GIS version 6, you have to prepend the underscore.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the PNG display driver ===&lt;br /&gt;
&lt;br /&gt;
Code fragment to control the {{cmd|pngdriver}} in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
from grass.script import core as grass&lt;br /&gt;
def main():&lt;br /&gt;
       os.environ['GRASS_PNGFILE'] = filename&lt;br /&gt;
       os.environ['GRASS_WIDTH'] = str(width)&lt;br /&gt;
       os.environ['GRASS_HEIGHT'] = str(height)&lt;br /&gt;
       grass.run_command('d.his', i='elevation_shade', h='elevation')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sophisticated cleanup procedure ===&lt;br /&gt;
&lt;br /&gt;
Scripts which create several temporary files need a more sophisticated cleanup procedure which deletes all the tmp maps which have been created. This procedure should also work if the script stops (e.g due to an error).&lt;br /&gt;
&lt;br /&gt;
Solution: Define a list of map names which starts out empty and has names appended to it as the names are generated. Code fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import atexit, sys&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
       tmp_rast = []&lt;br /&gt;
&lt;br /&gt;
       def cleanup():&lt;br /&gt;
           for rast in tmp_rast:&lt;br /&gt;
               grass.run_command(&amp;quot;g.remove&amp;quot;,&lt;br /&gt;
                                 rast = rast,&lt;br /&gt;
                                 quiet = True)&lt;br /&gt;
&lt;br /&gt;
       def main():&lt;br /&gt;
           ...&lt;br /&gt;
           while ...:&lt;br /&gt;
               next_rast = ...&lt;br /&gt;
               tmp_rast.append(next_rast)&lt;br /&gt;
               ...&lt;br /&gt;
&lt;br /&gt;
       if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
           options, flags = grass.parser()&lt;br /&gt;
           atexit.register(cleanup)&lt;br /&gt;
           sys.exit(main())&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using temporary region for computations ===&lt;br /&gt;
&lt;br /&gt;
There are two possible ways how to define temporary region for raster-based computations within your scripts. First method uses environmental variable WIND_OVERRIDE, the second GRASS_REGION, see {{cmd|variables|desc=GRASS variables}} for more info. The key point is to recover the current region when the script is finished or terminated.&lt;br /&gt;
&lt;br /&gt;
* ''First method'' (WIND_OVERRIDE) is implemented as {{pyapi|script|script.core|use_temp_region}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
# store the current region settings and installs an atexit&lt;br /&gt;
# handler to recover the current region on script termination&lt;br /&gt;
grass.use_temp_region()&lt;br /&gt;
&lt;br /&gt;
grass.run_command('g.region', region='detail')&lt;br /&gt;
&lt;br /&gt;
grass.mapcalc('map = 1', overwrite=True)&lt;br /&gt;
&lt;br /&gt;
# after making operations using the temporary region,&lt;br /&gt;
# to unset the temporary WIND_OVERRIDE file and remove any &lt;br /&gt;
# region named by it, it is possible to use del_temp_region&lt;br /&gt;
grass.del_temp_region()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Second method'' (GRASS_REGION) doesn't store current region settings to any temporary region, it just defines GRASS_REGION which forces GIS Library to use this settings for raster-based computations instead of the settings stored in WIND file (ie. current region). See {{pyapi|script|script.core|region_env}}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
# copy environment and define GRASS_REGION environmental variable&lt;br /&gt;
# same as `g.region region=detail`&lt;br /&gt;
env = os.environ.copy()&lt;br /&gt;
env['GRASS_REGION'] = grass.region_env(region='detail')&lt;br /&gt;
 &lt;br /&gt;
grass.mapcalc('map = 1', overwrite=True, env=env)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Direct Access from wxGUI ==&lt;br /&gt;
&lt;br /&gt;
[[wxGUI]] Layer Manager in GRASS GIS comes with &amp;quot;Python shell&amp;quot; which enables users to type and execute python commands directly in wxGUI environment.&lt;br /&gt;
&lt;br /&gt;
[[Image:wxgui-pyshell.png|center|400px|Embedded interactive Python Shell in wxGUI Layer Manager]]&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[GRASS GIS Jupyter notebooks]]&lt;br /&gt;
* [[Working with GRASS without starting it explicitly‎]]&lt;br /&gt;
* Many more tutorials under [[:Category:Python]]&lt;/div&gt;</summary>
		<author><name>⚠️BernardoBrenoPacas</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=GRASS_Python_Scripting_Library&amp;diff=25019</id>
		<title>GRASS Python Scripting Library</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=GRASS_Python_Scripting_Library&amp;diff=25019"/>
		<updated>2018-02-09T12:44:52Z</updated>

		<summary type="html">&lt;p&gt;⚠️BernardoBrenoPacas: Included grass.del_temp_region() to delete the temporary region file&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Python}}&lt;br /&gt;
Python API documentation:&lt;br /&gt;
&lt;br /&gt;
* [http://grass.osgeo.org/grass70/manuals/libpython/ Python API for GRASS GIS 7] and [http://grass.osgeo.org/grass70/manuals/libpython/script_intro.html Python Scripting Library]&lt;br /&gt;
* [http://grass.osgeo.org/programming6/pythonlib.html for GRASS GIS 6]: core.py, db.py, raster.py, vector.py, setup.py, array.py task.py&lt;br /&gt;
&lt;br /&gt;
The GRASS Python Scripting Library can be imported by statement&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import grass.script as gscript&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other packages such as PyGRASS can be imported in a similar way.&lt;br /&gt;
&lt;br /&gt;
The code in {{src|lib/python/|lib/python}} provides &amp;lt;tt&amp;gt;grass.script&amp;lt;/tt&amp;gt; and other packages in order to support GRASS scripts written in Python. The {{src|scripts}} directory of GRASS GIS 7 contains a series of examples actually provided to the end users (while the script in GRASS GIS 6 are shell scripts).&lt;br /&gt;
&lt;br /&gt;
For more general info, see also [[GRASS and Python]] and see also [[Converting Bash scripts to Python]] if you have some Bash scripts you want to rewrite to Python.&lt;br /&gt;
&lt;br /&gt;
== Uses for read, feed and pipe, start and exec commands ==&lt;br /&gt;
&lt;br /&gt;
All of the &amp;lt;tt&amp;gt;*_command&amp;lt;/tt&amp;gt; functions use {{pyapi|script|script.core|make_command}} to construct a command&lt;br /&gt;
line for a program which uses the {{cmd|g.parser|desc=GRASS parser}}. Most of them then pass&lt;br /&gt;
that command line to &amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; via {{pyapi|script|script.core|start_command}}, except&lt;br /&gt;
for {{pyapi|script|script.core|exec_command}} which uses &amp;lt;tt&amp;gt;os.execvpe()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[To be precise, they use &amp;lt;tt&amp;gt;grass.Popen()&amp;lt;/tt&amp;gt;, which just calls&lt;br /&gt;
&amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; with 'shell=True' on Windows and 'shell=False'&lt;br /&gt;
otherwise. On Windows, you need to use 'shell=True' to be able to&lt;br /&gt;
execute scripts (including batch files); 'shell=False' only works with&lt;br /&gt;
binary executables.]&lt;br /&gt;
&lt;br /&gt;
{{pyapi|script|script.core|start_command}} separates the arguments into those which&lt;br /&gt;
&amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; understands and the rest. The rest are passed to&lt;br /&gt;
&amp;lt;tt&amp;gt;make_command()&amp;lt;/tt&amp;gt; to construct a command line which is passed as the&lt;br /&gt;
&amp;quot;args&amp;quot; parameter to &amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In other words, {{pyapi|script|script.core|start_command}} is a GRASS-oriented interface to&lt;br /&gt;
&amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt;. It should be suitable for any situation where you&lt;br /&gt;
would use &amp;lt;tt&amp;gt;subprocess.Popen()&amp;lt;/tt&amp;gt; to execute a normal GRASS command (one&lt;br /&gt;
which uses the GRASS parser, which is almost all of them; the main&lt;br /&gt;
exception is {{cmd|r.mapcalc}} in 6.x).&lt;br /&gt;
&lt;br /&gt;
Most of the others are convenience wrappers around &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt;, for common use cases.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|run_command}} calls the wait() method on the process, so it doesn't return until the command has finished, and returns the command's exit code. Similar to &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|pipe_command}} calls &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt; with 'stdout=PIPE' and returns the process object. You can use the process' .stdout member to read the command's stdout. Similar to popen(..., &amp;quot;r&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|feed_command}} calls &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt; with stdin=PIPE and returns the process object. You can use the process' .stdin member to write to the command's stdout. Similar to popen(..., &amp;quot;w&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|read_command}} calls &amp;lt;tt&amp;gt;pipe_command()&amp;lt;/tt&amp;gt;, reads the data from the command's stdout, and returns it as a string. Similar to `backticks` in the shell.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|write_command}} calls &amp;lt;tt&amp;gt;feed_command()&amp;lt;/tt&amp;gt;, sends the string specified by the &amp;quot;stdin&amp;quot; argument to the command's stdin, waits for the command to finish and returns its exit code. Similar to &amp;quot;echo ... | command&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|parse_command}} calls &amp;lt;tt&amp;gt;read_command()&amp;lt;/tt&amp;gt; and parses its output as key-value pairs. Useful for obtaining information from {{cmd|g.region}}, {{cmd|g.proj}}, {{cmd|r.info}}, etc.&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|exec_command}} doesn't use &amp;lt;tt&amp;gt;start_command()&amp;lt;/tt&amp;gt; but &amp;lt;tt&amp;gt;os.execvpe()&amp;lt;/tt&amp;gt;. This causes the specified command to replace the current program (i.e. the Python script), so &amp;lt;tt&amp;gt;exec_command()&amp;lt;/tt&amp;gt; never returns. Similar to bash's &amp;quot;exec&amp;quot; command. This can be useful if the script is a &amp;quot;wrapper&amp;quot; around a single command, where you construct the command line and execute the command as the final step. Notes: exec_command() is rarely appropriate. You probably want run_command() instead. On Windows, exec_command() will probably require the &amp;quot;.exe&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
If you have any other questions, you might want to look at the code ({{src|lib/python/core.py}}). Most of these functions are only a few lines long.&lt;br /&gt;
&lt;br /&gt;
=== Hints for parse_command() ===&lt;br /&gt;
&lt;br /&gt;
To turn this command&lt;br /&gt;
        g.rename rast=old_name,new_name&lt;br /&gt;
into a g.parse_command() call, you need to consider that it is a function call with three arguments:&lt;br /&gt;
# &amp;quot;g.rename&amp;quot;&lt;br /&gt;
# rast=old_name&lt;br /&gt;
# new_name&lt;br /&gt;
&lt;br /&gt;
The second argument is a keyword argument, the first and third are&lt;br /&gt;
positional (non-keyword) arguments. Python doesn't allow positional&lt;br /&gt;
arguments to follow keyword arguments; positional arguments come&lt;br /&gt;
first, keyword arguments last.&lt;br /&gt;
&lt;br /&gt;
Given the context, it's safe to assume that you want to pass a pair of&lt;br /&gt;
map names as the value to the rast= option. This requires explicit&lt;br /&gt;
parentheses so that the comma is treated as forming a tuple rather&lt;br /&gt;
than as an argument separator:&lt;br /&gt;
&lt;br /&gt;
        g.parse_command(&amp;quot;g.rename&amp;quot;, rast=(old_name,new_name))&lt;br /&gt;
&lt;br /&gt;
The parentheses in a tuple value can only be omitted if it doesn't&lt;br /&gt;
result in the comma being ambiguous (as is the case in a function&lt;br /&gt;
call).&lt;br /&gt;
&lt;br /&gt;
== Interfacing ==&lt;br /&gt;
&lt;br /&gt;
=== Interfacing with NumPy ===&lt;br /&gt;
&lt;br /&gt;
The {{pyapi|script|script.array|array}} module defines a &amp;lt;code&amp;gt;class array&amp;lt;/code&amp;gt; which is a subclass of [http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html numpy.memmap] with &amp;lt;code&amp;gt;.read()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.write()&amp;lt;/code&amp;gt; methods to read/write the underlying file via {{cmd|r.out.bin}}/{{cmd|r.in.bin}}. Metadata can be read with {{pyapi|script|script.raster|raster_info}}:&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.array as garray&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    map = &amp;quot;elevation.dem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # read map&lt;br /&gt;
    a = garray.array()&lt;br /&gt;
    a.read(map)&lt;br /&gt;
&lt;br /&gt;
    # get raster map info&lt;br /&gt;
    print grass.raster_info(map)['datatype']&lt;br /&gt;
    i = grass.raster_info(map)&lt;br /&gt;
    &lt;br /&gt;
    # get computational region info&lt;br /&gt;
    c = grass.region()&lt;br /&gt;
    print &amp;quot;rows: %d&amp;quot; % c['rows']&lt;br /&gt;
    print &amp;quot;cols: %d&amp;quot; % c['cols']&lt;br /&gt;
&lt;br /&gt;
    # new array for result&lt;br /&gt;
    b = garray.array()&lt;br /&gt;
    # calculate new map from input map and store as GRASS raster map&lt;br /&gt;
    b[...] = (a / 50).astype(int) * 50&lt;br /&gt;
    b.write(&amp;quot;elev.50m&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The size of the array is taken from the current region ([[computational region]]).&lt;br /&gt;
&lt;br /&gt;
The main drawback of using numpy is that you're limited by available&lt;br /&gt;
memory. Using a subclass of &amp;lt;code&amp;gt;numpy.memmap&amp;lt;/code&amp;gt; lets you use files which may&lt;br /&gt;
be much larger, but processing the entire array in one go is likely to&lt;br /&gt;
produce in-memory results of a similar size.&lt;br /&gt;
&lt;br /&gt;
'''NULL (no data) management:'''&lt;br /&gt;
&lt;br /&gt;
For integer maps, the NULL value is -2^31 = -2147483648. For floating-point maps, the NULL value is NaN. Note that the null= parameter for read() and write() specifies the value in the numpy array which is mapped to/from null values in the GRASS raster map.&lt;br /&gt;
&lt;br /&gt;
If you're using floating-point numpy arrays, then use (Note: This assumes that atof() and sscanf(&amp;quot;%lf&amp;quot;) recognise &amp;quot;nan&amp;quot;; this is the case on Linux, but doesn't appear to work on Windows)&lt;br /&gt;
 null=numpy.nan&lt;br /&gt;
&lt;br /&gt;
For integer arrays, using&lt;br /&gt;
 null=-2147483648&lt;br /&gt;
will ensure that valid values don't collide with NYLLs.&lt;br /&gt;
&lt;br /&gt;
'''MASK support:'''&lt;br /&gt;
&lt;br /&gt;
The function grass.script.array.read() and ...write() use r.out.bin and r.in.bin respectively. r.out.bin respects the MASK.&lt;br /&gt;
&lt;br /&gt;
=== Interfacing with NumPy and SciPy  ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.scipy.org/doc/scipy/reference/index.html SciPy] offers simple access to complex calculations. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from scipy import stats&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
import grass.script.array as garray&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    map = &amp;quot;elevation.dem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    x = garray.array()&lt;br /&gt;
    x.read(map)&lt;br /&gt;
&lt;br /&gt;
    # Descriptive Statistics:&lt;br /&gt;
    print &amp;quot;max, min, mean, var:&amp;quot;&lt;br /&gt;
    print x.max(), x.min(), x.mean(), x.var()&lt;br /&gt;
    print &amp;quot;Skewness test: z-score and 2-sided p-value:&amp;quot;&lt;br /&gt;
    print stats.skewtest(stats.skew(x))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interfacing with NumPy, SciPy and Matlab ===&lt;br /&gt;
&lt;br /&gt;
One may also use the SciPy - Matlab interface:&lt;br /&gt;
    &lt;br /&gt;
    r.out.mat input=elevation output=elev.mat&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    ### PY ###&lt;br /&gt;
    import scipy.io as sio&lt;br /&gt;
    # load data&lt;br /&gt;
    elev = sio.loadmat('elev.mat')&lt;br /&gt;
    # retrive the actual array. the data set contains also the spatial reference&lt;br /&gt;
    elev.get('map_data')&lt;br /&gt;
    data = elev.get('map_data')&lt;br /&gt;
    # a first simple plot&lt;br /&gt;
    import pylab&lt;br /&gt;
    pylab.plot(data)&lt;br /&gt;
    pylab.show()&lt;br /&gt;
    # the contour plot&lt;br /&gt;
    pylab.contour(data)&lt;br /&gt;
    # obviously data needs to ne reversed&lt;br /&gt;
    import numpy as np&lt;br /&gt;
    data_rev = data[::-1]&lt;br /&gt;
    pylab.contour(data_rev)&lt;br /&gt;
    # =&amp;gt; this is a quick plot. basemap mapping may provide a nicer map!&lt;br /&gt;
    #######&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Display example ===&lt;br /&gt;
Example of Python script, which is processed by {{cmd|g.parser}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#&lt;br /&gt;
############################################################################&lt;br /&gt;
#&lt;br /&gt;
# MODULE:      d.shadedmap&lt;br /&gt;
# AUTHOR(S):   Unknown; updated to GRASS 5.7 by Michael Barton&lt;br /&gt;
#              Converted to Python by Glynn Clements&lt;br /&gt;
# PURPOSE:     Uses d.his to drape a color raster over a shaded relief map&lt;br /&gt;
# COPYRIGHT:   (C) 2004,2008,2009 by the GRASS Development Team&lt;br /&gt;
#&lt;br /&gt;
#              This program is free software under the GNU General Public&lt;br /&gt;
#              License (&amp;gt;=v2). Read the file COPYING that comes with GRASS&lt;br /&gt;
#              for details.&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
&lt;br /&gt;
#%Module&lt;br /&gt;
#% description: Drapes a color raster over a shaded relief map using d.his&lt;br /&gt;
#% keyword: display&lt;br /&gt;
#% keyword: raster&lt;br /&gt;
#%End&lt;br /&gt;
#%option&lt;br /&gt;
#% key: reliefmap&lt;br /&gt;
#% type: string&lt;br /&gt;
#% gisprompt: old,cell,raster&lt;br /&gt;
#% description: Name of shaded relief or aspect map&lt;br /&gt;
#% required : yes&lt;br /&gt;
#%end&lt;br /&gt;
#%option&lt;br /&gt;
#% key: drapemap&lt;br /&gt;
#% type: string&lt;br /&gt;
#% gisprompt: old,cell,raster&lt;br /&gt;
#% description: Name of raster to drape over relief map&lt;br /&gt;
#% required : yes&lt;br /&gt;
#%end&lt;br /&gt;
#%option&lt;br /&gt;
#% key: brighten&lt;br /&gt;
#% type: integer&lt;br /&gt;
#% description: Percent to brighten&lt;br /&gt;
#% options: -99-99&lt;br /&gt;
#% answer: 0&lt;br /&gt;
#%end&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
from grass.script import core as grass&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    drape_map = options['drapemap']&lt;br /&gt;
    relief_map = options['reliefmap']&lt;br /&gt;
    brighten = options['brighten']&lt;br /&gt;
    ret = grass.run_command(&amp;quot;d.his&amp;quot;, h_map = drape_map,  i_map = relief_map, brighten = brighten)&lt;br /&gt;
    sys.exit(ret)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    options, flags = grass.parser()&lt;br /&gt;
    main()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Parsing the options and flags  ===&lt;br /&gt;
&lt;br /&gt;
{{pyapi|script|script.core|parser}} is an interface to {{cmd|g.parser}}, and allows to parse the ''options'' and ''flags'' passed to your script on the command line. It is to be called at the top-level:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    options, flags = grass.parser()&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Global variables &amp;quot;options&amp;quot; and &amp;quot;flags&amp;quot; are Python dictionaries containing the options/flags values, keyed by lower-case option/flag names. The values in &amp;quot;options&amp;quot; are strings, those in &amp;quot;flags&amp;quot; are Python booleans. All those variables have to be previously declared in the header of your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; options, flags = grass.parser()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; options&lt;br /&gt;
{'input': 'my_map', 'output': 'map_out', 'option1': '21.472', 'option2': ''}&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; flags&lt;br /&gt;
{'c': True, 'm': False}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Passing several floats to a single option:'''&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python my.module.py input=input output=output myoption=0.1,0.2,0.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The values in the &amp;quot;options&amp;quot; dictionary returned from the parser()&lt;br /&gt;
function are always strings. You can parse the string with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
        myoption = map(float, options['myoption'].split(','))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The option definition in the script should have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
        #% type: double&lt;br /&gt;
        #% multiple: yes&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows g.parser to validate the option syntax, so you can rely&lt;br /&gt;
upon the string being in the correct format. If the values have a&lt;br /&gt;
fixed range, you can use e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
        #% options: 0.0-1.0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to have the parser check that the values fall within the range.&lt;br /&gt;
&lt;br /&gt;
For more information on option definitions, see:&lt;br /&gt;
&lt;br /&gt;
http://grass.osgeo.org/programming7/gislib.html#Complete_Structure_Members_Table&lt;br /&gt;
&lt;br /&gt;
=== Example for embedding r.mapcalc (map algebra) ===&lt;br /&gt;
&lt;br /&gt;
{{pyapi|script|script.raster|mapcalc}} accepts a template string followed by keyword&lt;br /&gt;
arguments for the substitutions, e.g. (code snippets):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
grass.mapcalc(&amp;quot;${out} = ${rast1} + ${rast2}&amp;quot;,&lt;br /&gt;
              out = options['output'],&lt;br /&gt;
              rast1 = options['raster1'],&lt;br /&gt;
              rast2 = options['raster2'])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Best practice'': first copy all of the options[] into separate variables at the beginning of main(), i.e.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def main():&lt;br /&gt;
    output = options['output']&lt;br /&gt;
    raster1 = options['raster1']&lt;br /&gt;
    raster2 = options['raster2']&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    grass.mapcalc(&amp;quot;${out} = ${rast1} + ${rast2}&amp;quot;,&lt;br /&gt;
                  out = output,&lt;br /&gt;
                  rast1 = raster1,&lt;br /&gt;
                  rast2 = raster2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Performing multiple computations using &amp;lt;tt&amp;gt;grass.script.raster.mapcalc()&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
expr = &amp;quot;;&amp;quot;.join([&lt;br /&gt;
        &amp;quot;$out.r = r#$first * $frac + (1.0 - $frac) * r#$second&amp;quot;,&lt;br /&gt;
        &amp;quot;$out.g = g#$first * $frac + (1.0 - $frac) * g#$second&amp;quot;,&lt;br /&gt;
        &amp;quot;$out.b = b#$first * $frac + (1.0 - $frac) * b#$second&amp;quot;])&lt;br /&gt;
grass.mapcalc(expr, out=out, first=first, second=second, frac=percent/100.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hint: multi-line strings can be separated by using a semicolon instead of a newline.&lt;br /&gt;
&lt;br /&gt;
=== Looping over file names stored in an ASCII file ===&lt;br /&gt;
&lt;br /&gt;
When looping over file names stored in an ASCII file and getting the error&lt;br /&gt;
&lt;br /&gt;
   WARNING: Illegal filename &amp;lt;map.f1jan.05216.something&lt;br /&gt;
          &amp;gt;. Character &amp;lt;&lt;br /&gt;
          &amp;gt; not allowed.&lt;br /&gt;
&lt;br /&gt;
then the line terminators may be the reason.&lt;br /&gt;
When you iterate over a file, the strings include the line terminators (e.g. '\n' or '\r\n'). Use e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    for line in gl:&lt;br /&gt;
        renamed = line.rstrip().replace('.','_')&lt;br /&gt;
        ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to remove any trailing whitespace (including newlines) from each line.&lt;br /&gt;
&lt;br /&gt;
=== Example for parsing raster category labels ===&lt;br /&gt;
&lt;br /&gt;
How to obtain the text labels&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    # dump cats to file to avoid &amp;quot;too many argument&amp;quot; problem:&lt;br /&gt;
    p = grass.pipe_command('r.category', map = rastertmp, separator = ';', quiet = True)&lt;br /&gt;
    cats = []&lt;br /&gt;
    for line in p.stdout:&lt;br /&gt;
        cats.append(line.rstrip('\r\n').split(';')[0])&lt;br /&gt;
    p.wait()&lt;br /&gt;
&lt;br /&gt;
    number = len(cats)&lt;br /&gt;
    if number &amp;lt; 1:&lt;br /&gt;
        grass.fatal(_(&amp;quot;No categories found in raster map&amp;quot;))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example for parsing category numbers ===&lt;br /&gt;
&lt;br /&gt;
'''Q:''' How to obtain the number of cells of a certain category?&lt;br /&gt;
&lt;br /&gt;
'''A:''' It is recommended to use {{pyapi|script|script.core|pipe_command}} and parse the output, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       p = grass.pipe_command('r.stats',flags='c',input='map')&lt;br /&gt;
       result = {}&lt;br /&gt;
       for line in p.stdout:&lt;br /&gt;
           val,count = line.strip().split()&lt;br /&gt;
           result[int(val)] = int(count)&lt;br /&gt;
       p.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example for getting the region's number of rows and columns ===&lt;br /&gt;
&lt;br /&gt;
'''Q:''' How to obtain the number of rows and columns of the current region?&lt;br /&gt;
&lt;br /&gt;
'''A:''' It is recommended to use the {{pyapi|script|script.core|region}} function which will create a dictionary with values for extents and resolution, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#-*- coding:utf-8 -*-&lt;br /&gt;
#&lt;br /&gt;
############################################################################&lt;br /&gt;
#&lt;br /&gt;
# MODULE:       g.region.resolution&lt;br /&gt;
# AUTHOR(S):    based on a post at GRASS-USER mailing list [1]               &lt;br /&gt;
# PURPOSE:	Parses &amp;quot;g.region -g&amp;quot;, prints out number of rows, cols&lt;br /&gt;
# COPYLEFT:     ;-)&lt;br /&gt;
# COMMENT:      ...a lot of comments to be easy-to-read for/by beginners&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
#%Module&lt;br /&gt;
#% description: Print number of rows, cols of current geographic region&lt;br /&gt;
#% keyword: region&lt;br /&gt;
#%end&lt;br /&gt;
&lt;br /&gt;
# importing required modules&lt;br /&gt;
import sys # the sys module [2]&lt;br /&gt;
from grass.script import core as grass # the core module [3]&lt;br /&gt;
&lt;br /&gt;
# information about imported modules can be obtained using the dir() function&lt;br /&gt;
# e.g.: dir(sys)&lt;br /&gt;
&lt;br /&gt;
# define the &amp;quot;main&amp;quot; function: get number of rows, cols of region&lt;br /&gt;
def main():&lt;br /&gt;
    &lt;br /&gt;
    # #######################################################################&lt;br /&gt;
    # the following commented code works but is kept only for learning purposes&lt;br /&gt;
     &lt;br /&gt;
    ## assigning the output of the command &amp;quot;g.region -g&amp;quot; in a string called &amp;quot;return_rows_x_cols&amp;quot;&lt;br /&gt;
    # return_rows_x_cols = grass.read_command('g.region', flags = 'g')&lt;br /&gt;
    &lt;br /&gt;
    ## parsing arguments of interest (rows, cols) in a dictionary named &amp;quot;rows_x_cols&amp;quot;&lt;br /&gt;
    # rows_x_cols = grass.parse_key_val(return_rows_x_cols)&lt;br /&gt;
    &lt;br /&gt;
    ## selectively print rows, cols from the dictionary &amp;quot;rows_x_cols&amp;quot;&lt;br /&gt;
    # print 'rows=%d \ncols=%d' % (int(rows_x_cols['rows']), int(rows_x_cols['cols']))&lt;br /&gt;
    &lt;br /&gt;
    # #######################################################################&lt;br /&gt;
    &lt;br /&gt;
    # faster/ easier way: use of the &amp;quot;grass.region()&amp;quot; function&lt;br /&gt;
    gregion = grass.region()&lt;br /&gt;
    rows = gregion['rows']&lt;br /&gt;
    cols = gregion['cols']&lt;br /&gt;
    &lt;br /&gt;
    # print rows, cols properly formated &lt;br /&gt;
    print 'rows=%d \ncols=%d' % (rows, cols)&lt;br /&gt;
&lt;br /&gt;
# this &amp;quot;if&amp;quot; condition instructs execution of code contained in this script, *only* if the script is being executed directly &lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;: # this allows the script to be used as a module in other scripts or as a standalone script&lt;br /&gt;
    options, flags = grass.parser() #&lt;br /&gt;
    sys.exit(main()) #&lt;br /&gt;
&lt;br /&gt;
# Links&lt;br /&gt;
# [1] http://n2.nabble.com/Getting-rows-cols-of-a-region-in-a-script-tp2787474p2787509.html&lt;br /&gt;
# [2] http://www.python.org/doc/2.5.2/lib/module-sys.html&lt;br /&gt;
# [3] http://grass.osgeo.org/grass71/manuals/libpython&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Managing mapsets ===&lt;br /&gt;
&lt;br /&gt;
To check if a certain mapset exists in the active location, use {{pyapi|script|script.core|mapsets}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.mapsets(False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... returns a list of mapsets in the current location.&lt;br /&gt;
&lt;br /&gt;
=== r.mapcalc example ===&lt;br /&gt;
&lt;br /&gt;
Example of Python script, which is processed by {{cmd|g.parser}}:&lt;br /&gt;
&lt;br /&gt;
The shell script line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  r.mapcalc &amp;quot;MASK = if(($cloudResampName &amp;lt; 0.01000),1,null())&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would be written like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
       ...&lt;br /&gt;
&lt;br /&gt;
       grass.mapcalc(&amp;quot;MASK=if(($cloudResampName &amp;lt; 0.01000),1,null())&amp;quot;,&lt;br /&gt;
                     cloudResampName = cloudResampName)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first argument to the mapcalc function is a template (see the Python library documentation for [http://docs.python.org/library/string.html string.Template]). Any keyword arguments (other than &amp;lt;tt&amp;gt;quiet&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;verbose&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;overwrite&amp;lt;/tt&amp;gt;) specify substitutions.&lt;br /&gt;
&lt;br /&gt;
=== r.mapcalc example: defining a moving window ===&lt;br /&gt;
&lt;br /&gt;
Moving window of 4 cell in every 8 direction and do a boolean comparison. Boolean value (e.g. the result of a comparison) is an integer, with 1 for true, 0 for false.&lt;br /&gt;
Then do a r.mapcalc calculation with the moving window.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
           &lt;br /&gt;
       # define a moving window of 4 cell in every 8 direction&lt;br /&gt;
       #&lt;br /&gt;
       # map[4,4]                                    map[4,0]                                    map[4,-4]		&lt;br /&gt;
       # 	    map[3,3]                         map[3,0]                         map[3,-3]			&lt;br /&gt;
       # 		       map[2,2]              map[2,0]              map[2,-2]				&lt;br /&gt;
       #                                  map[1,1]   map[1,0]   map[1,-1]	 				&lt;br /&gt;
       # map[0,4]   map[0,3]   map[0,2]   map[0,1]       x      map[0,-1]  map[0,-2]  map[0,-3]  map[0,-4]&lt;br /&gt;
       #                                  map[-1,1]  map[-1,0]  map[-1,-1]					&lt;br /&gt;
       #                       map[-2,2]             map[-2,0]             map[-2,-2]				&lt;br /&gt;
       #            map[-3,3]                        map[-3,0]                        map[-3,-3]			&lt;br /&gt;
       # map[-4,4]                                   map[-4,0]                                   map[-4,-4]&lt;br /&gt;
       &lt;br /&gt;
       # define the offet duplets&lt;br /&gt;
       &lt;br /&gt;
       offsets = [d&lt;br /&gt;
           for j in xrange(1,4+1)&lt;br /&gt;
           for i in [j,-j]&lt;br /&gt;
           for d in [(i,0),(0,i),(i,i),(i,-i)]]&lt;br /&gt;
       	&lt;br /&gt;
       # &amp;gt;&amp;gt;&amp;gt;offsets&lt;br /&gt;
       # [(1, 0), (0, 1), (1, 1), (1, -1), (-1, 0), (0, -1), (-1, -1), (-1, 1), (2, 0), (0, 2), (2, 2), (2, -2), (-2, 0), (0, -2), \&lt;br /&gt;
       # (-2, -2), (-2, 2), (3, 0), (0, 3), (3, 3), (3, -3), (-3, 0), (0, -3), (-3, -3), (-3, 3), (4, 0), (0, 4), (4, 4), (4, -4), \&lt;br /&gt;
       # (-4, 0), (0, -4), (-4, -4), (-4, 4)]&lt;br /&gt;
       &lt;br /&gt;
       # define the calculation term&lt;br /&gt;
       &lt;br /&gt;
       terms = [&amp;quot;(myelevnc[%d,%d] &amp;lt; myelevnc)&amp;quot; % d&lt;br /&gt;
                for d in offsets]&lt;br /&gt;
       &lt;br /&gt;
       # &amp;gt;&amp;gt;&amp;gt;terms&lt;br /&gt;
       # ['(myelevnc[1,0] &amp;lt; myelevnc)', '(myelevnc[0,1] &amp;lt; myelevnc)', '(myelevnc[1,1] &amp;lt; myelevnc)', '(myelevnc[1,-1] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-1,0] &amp;lt; myelevnc)', '(myelevnc[0,-1] &amp;lt; myelevnc)', '(myelevnc[-1,-1] &amp;lt; myelevnc)', '(myelevnc[-1,1] &amp;lt; myelevnc)',\&lt;br /&gt;
       # '(myelevnc[2,0] &amp;lt; myelevnc)', '(myelevnc[0,2] &amp;lt; myelevnc)', '(myelevnc[2,2] &amp;lt; myelevnc)', '(myelevnc[2,-2] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-2,0] &amp;lt; myelevnc)', '(myelevnc[0,-2] &amp;lt; myelevnc)', '(myelevnc[-2,-2] &amp;lt; myelevnc)', '(myelevnc[-2,2] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[3,0] &amp;lt; myelevnc)', '(myelevnc[0,3] &amp;lt; myelevnc)', '(myelevnc[3,3] &amp;lt; myelevnc)', '(myelevnc[3,-3] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-3,0] &amp;lt; myelevnc)', '(myelevnc[0,-3] &amp;lt; myelevnc)', '(myelevnc[-3,-3] &amp;lt; myelevnc)', '(myelevnc[-3,3] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[4,0] &amp;lt; myelevnc)', '(myelevnc[0,4] &amp;lt; myelevnc)', '(myelevnc[4,4] &amp;lt; myelevnc)', '(myelevnc[4,-4] &amp;lt; myelevnc)', \&lt;br /&gt;
       # '(myelevnc[-4,0] &amp;lt; myelevnc)', '(myelevnc[0,-4] &amp;lt; myelevnc)', '(myelevnc[-4,-4] &amp;lt; myelevnc)', '(myelevnc[-4,4] &amp;lt; myelevnc)']&lt;br /&gt;
       &lt;br /&gt;
       # define the calculation expression&lt;br /&gt;
       &lt;br /&gt;
       expr = &amp;quot;elevation_percentile4 = (100.0 / 48.0) * (%s)&amp;quot; % &amp;quot; + &amp;quot;.join(terms)&lt;br /&gt;
       &lt;br /&gt;
       # &amp;gt;&amp;gt;&amp;gt;expr&lt;br /&gt;
       #  elevation_percentile4 = (100.0 / 48.0) * ((myelevnc[1,0] &amp;lt; myelevnc) + (myelevnc[0,1] &amp;lt; myelevnc) + (myelevnc[1,1] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[1,-1] &amp;lt; myelevnc) + (myelevnc[-1,0] &amp;lt; myelevnc) + (myelevnc[0,-1] &amp;lt; myelevnc) + (myelevnc[-1,-1] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[-1,1] &amp;lt; myelevnc) + (myelevnc[2,0] &amp;lt; myelevnc) + (myelevnc[0,2] &amp;lt; myelevnc) + (myelevnc[2,2] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[2,-2] &amp;lt; myelevnc) + (myelevnc[-2,0] &amp;lt; myelevnc) + (myelevnc[0,-2] &amp;lt; myelevnc) + (myelevnc[-2,-2] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[-2,2] &amp;lt; myelevnc) + (myelevnc[3,0] &amp;lt; myelevnc) + (myelevnc[0,3] &amp;lt; myelevnc) + (myelevnc[3,3] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[3,-3] &amp;lt; myelevnc) + (myelevnc[-3,0] &amp;lt; myelevnc) + (myelevnc[0,-3] &amp;lt; myelevnc) + (myelevnc[-3,-3] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[-3,3] &amp;lt; myelevnc) + (myelevnc[4,0] &amp;lt; myelevnc) + (myelevnc[0,4] &amp;lt; myelevnc) + (myelevnc[4,4] &amp;lt; myelevnc) + \&lt;br /&gt;
       # (myelevnc[4,-4] &amp;lt; myelevnc) + (myelevnc[-4,0] &amp;lt; myelevnc) + (myelevnc[0,-4] &amp;lt; myelevnc) + (myelevnc[-4,-4] &amp;lt; myelevnc)\&lt;br /&gt;
       #  + (myelevnc[-4,4] &amp;lt; myelevnc))&lt;br /&gt;
       &lt;br /&gt;
       # do the r.mapcalc calculation with the moving window&lt;br /&gt;
       &lt;br /&gt;
       grass.mapcalc( expr )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using output from GRASS modules in the script ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you need to use the output of a module for the next step. There are dedicated functions to obtain the result of, for example, a statistical analysis.&lt;br /&gt;
&lt;br /&gt;
Example: get the range of a raster map and use it in {{cmd|r.mapcalc}}. Here you can use {{pyapi|script|script.raster|raster_info}}, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
       max = grass.raster_info(inmap)['max']&lt;br /&gt;
       grass.mapcalc(&amp;quot;$outmap = $inmap / $max&amp;quot;,&lt;br /&gt;
                     inmap = inmap, outmap = outmap, max = max)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using output from r.what ===&lt;br /&gt;
&lt;br /&gt;
''Q: How does one return attribute values from a call to the 'r.what' module running in a python script?''&lt;br /&gt;
&lt;br /&gt;
A: If you use &amp;lt;tt&amp;gt;grass.script.raster_what()&amp;lt;/tt&amp;gt;, it returns a list of dictionaries.&lt;br /&gt;
&lt;br /&gt;
PyGRASS which requires you to add &amp;lt;tt&amp;gt;stdout_=PIPE&amp;lt;/tt&amp;gt;, then you can get the output as a string from &amp;lt;tt&amp;gt;module.outputs.stdout&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Or using directly the C API through python with (North Carolina dataset example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.vector import VectorTopo&lt;br /&gt;
from grass.pygrass.raster import RasterRow&lt;br /&gt;
from grass.pygrass.gis.region import Region&lt;br /&gt;
&lt;br /&gt;
with RasterRow('elevation', mode='r') as rast:&lt;br /&gt;
    with VectorTopo('hospitals', mode='r') as hospitals:&lt;br /&gt;
        region = Region()&lt;br /&gt;
        for hosp in hospitals:&lt;br /&gt;
            value = rast.get_value(hosp, region)&lt;br /&gt;
            if value is not None:&lt;br /&gt;
                print(hosp.cat, value)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling a GRASS module in Python ===&lt;br /&gt;
&lt;br /&gt;
Imagine, you wanted to execute this command in Python:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  r.profile -g input=mymap output=newfile profile=12244.256,-295112.597,12128.012,-295293.77&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All arguments except the first (which is a flag) are keyword arguments, i.e. &amp;lt;tt&amp;gt;arg = val&amp;lt;/tt&amp;gt;. For the flag, use &amp;lt;tt&amp;gt;flags = 'g'&amp;lt;/tt&amp;gt; (note that &amp;quot;-g&amp;quot; would be the negative of a Python variable named &amp;quot;g&amp;quot;!). So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('r.profile',&lt;br /&gt;
               input = input_map,&lt;br /&gt;
               output = output_file,&lt;br /&gt;
               profile = [12244.256,-295112.597,12128.012,-295293.77]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
               profile = [(12244.256,-295112.597),(12128.012,-295293.77)]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i.e. you need to provide the keyword, and the argument must be a valid Python expression. Function &amp;lt;code&amp;gt;run_command()&amp;lt;/code&amp;gt; etc accept lists and tuples.&lt;br /&gt;
&lt;br /&gt;
'''What is the proper way to include keyword-arguments tuples?'''&lt;br /&gt;
&lt;br /&gt;
For example, &amp;quot;g.list -f type=rast,vect&amp;quot; translates into:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&amp;quot;g.list&amp;quot;, flags=&amp;quot;f&amp;quot;, type=&amp;quot;rast,vect&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&amp;quot;g.list&amp;quot;, flags=&amp;quot;f&amp;quot;, type=[&amp;quot;rast&amp;quot;,&amp;quot;vect&amp;quot;])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The various *_command() functions accept arbitrary keyword arguments. Any keywords which don't have a specific meaning to either the *_command() function or the Popen constructor are treated as arguments to the GRASS module.&lt;br /&gt;
&lt;br /&gt;
'''What is the proper way to use multiple flags?'''&lt;br /&gt;
&lt;br /&gt;
How can I call a module with multiple flags set (e.g., -a and -b) in GRASS-Python?&lt;br /&gt;
&lt;br /&gt;
  flags = &amp;quot;ab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command(&amp;quot;r.info&amp;quot;, flags=&amp;quot;eg&amp;quot;, map=[&amp;quot;elevation&amp;quot;])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Differences between ''run_command()'' and ''read_command()'':'''&lt;br /&gt;
&lt;br /&gt;
* {{pyapi|script|script.core|run_command}} executes the command and waits for it to terminate; it doesn't redirect any of the standard streams.&lt;br /&gt;
* {{pyapi|script|script.core|read_command}} executes the command with stdout redirected to a pipe, and reads everything written to it. Once the command terminates, it returns the data written to stdout as a string.&lt;br /&gt;
&lt;br /&gt;
'''How to retrieve error messages from ''read_command()'':'''&lt;br /&gt;
&lt;br /&gt;
None of the existing *_command functions redirect stderr. You can do so with e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def read2_command(*args, **kwargs):&lt;br /&gt;
   kwargs['stdout'] = grass.PIPE&lt;br /&gt;
   kwargs['stderr'] = grass.PIPE&lt;br /&gt;
   ps = grass.start_command(*args, **kwargs)&lt;br /&gt;
   return ps.communicate()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This behaves like &amp;lt;tt&amp;gt;read_command()&amp;lt;/tt&amp;gt; except that it returns a tuple of (stdout, stderr) rather than just stdout.&lt;br /&gt;
&lt;br /&gt;
=== Interface to copying maps (g.copy) ===&lt;br /&gt;
&lt;br /&gt;
Copy a raster map (for vector, replace &amp;quot;rast&amp;quot; with &amp;quot;vect&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('g.copy', rast = (input, output))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To generalize it, &amp;quot;datatype&amp;quot; is the form of grass data to copy (eg, rast, vect, etc)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('g.copy', **{datatype: (input, output)})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface to listing maps (g.list) ===&lt;br /&gt;
&lt;br /&gt;
You may use the functions in [http://grass.osgeo.org/programming7/namespacepython_1_1script_1_1core.html python.script.core.mlist_grouped()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
list_grouped('raster')['PERMANENT']&lt;br /&gt;
[..., 'lakes', ..., 'slope', ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
mlist_grouped('vector', pattern='*roads*')['PERMANENT']&lt;br /&gt;
['railroads', 'roadsmajor']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Python/pygrass#Sample_PyGRASS_scripts|Sample PyGRASS scripts]] for an alternative solution.&lt;br /&gt;
&lt;br /&gt;
=== i.group with patterns as name for input ===&lt;br /&gt;
&lt;br /&gt;
Imagery groups can be populated like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from grass.pygrass.gis import Mapset&lt;br /&gt;
&lt;br /&gt;
run_command(&amp;quot;i.group&amp;quot;, group=&amp;quot;mygroup&amp;quot;, input=mset.glist(&amp;quot;raster&amp;quot;, pattern=&amp;quot;mypattern_*&amp;quot;))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Percentage output for progress of computation ===&lt;br /&gt;
&lt;br /&gt;
A) Within a Python script, the {{pyapi|script|script.core|percent}} module method wraps the &amp;lt;tt&amp;gt;g.message -p&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
B) If you call a GRASS command within the Python code, you have to parse the output by setting &amp;lt;tt&amp;gt;GRASS_MESSAGE_FORMAT=gui&amp;lt;/tt&amp;gt; in the environment when running the command and read from the command's stderr; e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
       env = os.environ.copy()&lt;br /&gt;
       env['GRASS_MESSAGE_FORMAT'] = 'gui'&lt;br /&gt;
       p = grass.start_command(..., stderr = grass.PIPE, env = env)&lt;br /&gt;
       # read from p.stderr&lt;br /&gt;
       p.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need to capture both stdout and stderr, you need to use threads, select, or non-blocking I/O to consume data from both streams as it is generated in order to avoid deadlock.&lt;br /&gt;
&lt;br /&gt;
ALTERNATIVE:&lt;br /&gt;
&lt;br /&gt;
Redirect both stdout and stderr to the same pipe (and hope that the normal output doesn't include anything which will be mistaken for progress/error/etc messages):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       p = grass.start_command(..., stdout = grass.PIPE, stderr = grass.STDOUT, env = env)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NULL data management ===&lt;br /&gt;
&lt;br /&gt;
How to analyse if there are only NULL cells in a map:&lt;br /&gt;
&lt;br /&gt;
If a map contains only null cells, its minimum and maximum will be &amp;quot;NULL&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
       $ r.mapcalc 'foo = null()'&lt;br /&gt;
       $ r.info -r foo&lt;br /&gt;
       min=NULL&lt;br /&gt;
       max=NULL&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the Python API, The 'min' and 'max' values in the result of the {{pyapi|script|script.raster|raster_info}} function will be &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Counting cells ===&lt;br /&gt;
&lt;br /&gt;
Counting cells is far more expensive than simply determining whether&lt;br /&gt;
there are any non-null cells. Counting cells requires reading the&lt;br /&gt;
entire map, while the {{cmd|r.info}} approach only needs to read the metadata&lt;br /&gt;
files.&lt;br /&gt;
&lt;br /&gt;
If you do need to count cells, {{cmd|r.stats}} is likely to be more efficient than {{cmd|r.univar}}.&lt;br /&gt;
&lt;br /&gt;
A count loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       while grass.raster_info(inmap)['max'] is not None:&lt;br /&gt;
           ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Display: overlayed map display with labels ===&lt;br /&gt;
&lt;br /&gt;
Example: display a vector map and overlay its labels on top of the map.&lt;br /&gt;
&lt;br /&gt;
If the environment contains the setting GRASS_PNG_READ=TRUE, d.* commands should overlay their output on an existing image (otherwise the first command creates the file map.png but the second command overwrites the file with only the labels). So the following should work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('d.vect', map='my_shape')&lt;br /&gt;
       env = os.environ.copy()&lt;br /&gt;
       env['GRASS_PNG_READ'] = 'TRUE'&lt;br /&gt;
       grass.run_command('d.labels', labels='my_shape_labels', env = env)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Path to GISDBASE ===&lt;br /&gt;
In order to a avoid hardcoded paths to GRASS mapset files like the SQLite DB file, you can get the GISDBASE variable from the environment:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
       import os.path&lt;br /&gt;
&lt;br /&gt;
       env = grass.gisenv()&lt;br /&gt;
&lt;br /&gt;
       gisdbase = env['GISDBASE']&lt;br /&gt;
       location = env['LOCATION_NAME']&lt;br /&gt;
       mapset = env['MAPSET']&lt;br /&gt;
&lt;br /&gt;
       path = os.path.join(gisdbase, location, mapset, 'sqlite.db')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Creating a new location ===&lt;br /&gt;
&lt;br /&gt;
Use {{pyapi|script|script.core|create_location}} to create a new location.&lt;br /&gt;
&lt;br /&gt;
=== Use Python reserved keyword ===&lt;br /&gt;
&lt;br /&gt;
'''Q:''' ''r.resamp.bspline'' uses 'lambda' as a command line parameter name, but when you try to use it with {{pyapi|script|script.core|run_command}} or {{pyapi|script|script.core|start_command}} you get an error as lambda is a python reserved keyword. How to work around that?&lt;br /&gt;
&lt;br /&gt;
'''A:''' Append an underscore to the name, i.e.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       grass.run_command('r.resamp.bspline', lambda_ = ...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this follows Python [http://legacy.python.org/dev/peps/pep-0008/#descriptive-naming-styles PEP8] style guide. In GRASS GIS version 6, you have to prepend the underscore.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the PNG display driver ===&lt;br /&gt;
&lt;br /&gt;
Code fragment to control the {{cmd|pngdriver}} in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
from grass.script import core as grass&lt;br /&gt;
def main():&lt;br /&gt;
       os.environ['GRASS_PNGFILE'] = filename&lt;br /&gt;
       os.environ['GRASS_WIDTH'] = str(width)&lt;br /&gt;
       os.environ['GRASS_HEIGHT'] = str(height)&lt;br /&gt;
       grass.run_command('d.his', i='elevation_shade', h='elevation')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sophisticated cleanup procedure ===&lt;br /&gt;
&lt;br /&gt;
Scripts which create several temporary files need a more sophisticated cleanup procedure which deletes all the tmp maps which have been created. This procedure should also work if the script stops (e.g due to an error).&lt;br /&gt;
&lt;br /&gt;
Solution: Define a list of map names which starts out empty and has names appended to it as the names are generated. Code fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
       import atexit, sys&lt;br /&gt;
       import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
       tmp_rast = []&lt;br /&gt;
&lt;br /&gt;
       def cleanup():&lt;br /&gt;
           for rast in tmp_rast:&lt;br /&gt;
               grass.run_command(&amp;quot;g.remove&amp;quot;,&lt;br /&gt;
                                 rast = rast,&lt;br /&gt;
                                 quiet = True)&lt;br /&gt;
&lt;br /&gt;
       def main():&lt;br /&gt;
           ...&lt;br /&gt;
           while ...:&lt;br /&gt;
               next_rast = ...&lt;br /&gt;
               tmp_rast.append(next_rast)&lt;br /&gt;
               ...&lt;br /&gt;
&lt;br /&gt;
       if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
           options, flags = grass.parser()&lt;br /&gt;
           atexit.register(cleanup)&lt;br /&gt;
           sys.exit(main())&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using temporary region for computations ===&lt;br /&gt;
&lt;br /&gt;
There are two possible ways how to define temporary region for raster-based computations within your scripts. First method uses environmental variable WIND_OVERRIDE, the second GRASS_REGION, see {{cmd|variables|desc=GRASS variables}} for more info. The key point is to recover the current region when the script is finished or terminated.&lt;br /&gt;
&lt;br /&gt;
* ''First method'' (WIND_OVERRIDE) is implemented as {{pyapi|script|script.core|use_temp_region}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
# store the current region settings and installs an atexit&lt;br /&gt;
# handler to recover the current region on script termination&lt;br /&gt;
grass.use_temp_region()&lt;br /&gt;
&lt;br /&gt;
grass.run_command('g.region', region='detail')&lt;br /&gt;
&lt;br /&gt;
grass.mapcalc('map = 1', overwrite=True)&lt;br /&gt;
&lt;br /&gt;
# to unset the temporary WIND_OVERRIDE file and remove any &lt;br /&gt;
# region named by it, use:&lt;br /&gt;
grass.del_temp_region():&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Second method'' (GRASS_REGION) doesn't store current region settings to any temporary region, it just defines GRASS_REGION which forces GIS Library to use this settings for raster-based computations instead of the settings stored in WIND file (ie. current region). See {{pyapi|script|script.core|region_env}}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import grass.script as grass&lt;br /&gt;
&lt;br /&gt;
# copy environment and define GRASS_REGION environmental variable&lt;br /&gt;
# same as `g.region region=detail`&lt;br /&gt;
env = os.environ.copy()&lt;br /&gt;
env['GRASS_REGION'] = grass.region_env(region='detail')&lt;br /&gt;
 &lt;br /&gt;
grass.mapcalc('map = 1', overwrite=True, env=env)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Direct Access from wxGUI ==&lt;br /&gt;
&lt;br /&gt;
[[wxGUI]] Layer Manager in GRASS GIS comes with &amp;quot;Python shell&amp;quot; which enables users to type and execute python commands directly in wxGUI environment.&lt;br /&gt;
&lt;br /&gt;
[[Image:wxgui-pyshell.png|center|400px|Embedded interactive Python Shell in wxGUI Layer Manager]]&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[GRASS GIS Jupyter notebooks]]&lt;br /&gt;
* [[Working with GRASS without starting it explicitly‎]]&lt;br /&gt;
* Many more tutorials under [[:Category:Python]]&lt;/div&gt;</summary>
		<author><name>⚠️BernardoBrenoPacas</name></author>
	</entry>
</feed>