0

I'm trying to use GRASS on python 2.7, but I'm having some problems at setting my script on IDLE, then I'm getting an error at parser() function:

Here is my script:

import os
import sys

gisbase = os.environ['GISBASE'] = 'C:\Program Files (x86)\GRASS GIS 7.0.1RC1'
gisrc = 'C:\grassdata'
gisdbase = 'C:\grassdata'
location = 'newLocation'
mapset = 'TC'
LD_LIBRARY_PATH = 'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\lib'
PATH = 'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\etc';'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\etc\python';'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\lib';'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\bin';'C:\Python27';'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\Python27';'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\msys'
PYTHONLIB = 'C:\Python27'
PYTHONPATH = 'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\etc\python'


sys.path.append(os.path.join(os.environ['GISBASE'], 'etc', 'python'))

import grass.script as grass

grass.parser() #I'M STUCKING HERE

I'm getting an error inside subprocess.py :

p = subprocess.Popen([prog, '-n'] + argv, stdout=subprocess.PIPE)

The full error:

Traceback (most recent call last):
  File "C:\Users\Ciro\Desktop\teste_grass.py", line 19, in <module>
    grass.parser()
  File "C:\Program Files (x86)\GRASS GIS 7.0.1RC1\etc\python\grass\script\core.py", line 680, in parser
    p = subprocess.Popen([prog, '-n'] + argv, stdout=subprocess.PIPE)
  File "C:\Python27\ArcGIS10.1\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python27\ArcGIS10.1\lib\subprocess.py", line 893, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

What am I missing?

  • Perhaps the paths should be written with double backslashes? – Anna Feb 7 '16 at 20:49
2

You are using parser() function to bring up a your GRASS module interface, but you are also setting up environment to run GRASS modules without starting GRASS explicitly. Although it is possible to use both, usually you do only one depending on what you want to achieve.

In case you want to write a script which would run in GRASS environment as a module (which is the ideal and simple way), you need to use template like this (simplified from GRASS Python doc):

#%module
#% description: Multiply by three
#% keyword: raster
#% keyword: algebra
#% keyword: multiply
#%end
#%option G_OPT_R_INPUT
#% key: input
#% description: Name of input raster A in an expression A + B
#%end
#%option G_OPT_R_OUTPUT
#%end

import sys
import grass.script as gscript

def main():
    options, flags = gscript.parser()
    input_ = options['input']
    output = options['output']
    gscript.mapcalc('{r} = {a} + {b}'.format(r=output, a=input_, b=braster))
    return 0

if __name__ == "__main__":
    sys.exit(main())

In case you want to use GRASS modules without starting GRASS session, you need to set up the environment first. Your code has several issues:

  • the line with PATH is a valid Python syntax but it likely does something else than you meant since the semicolons are outside of strings
  • paths on MS Windows are using backslashes (\), as backslash is escaping character, you need to write \\ to get one backslash, alternatively, use raw strings, e.g. r'some\path'
  • the variables you are setting are Python global variables for a module (file), but what you want to set are system environmental variables

Here is an example how to setup the environment (simplified from GRASS Python doc):

import os
import sys
import subprocess

grass7bin = r'C:\Program Files (x86)\GRASS GIS 7.0.1RC1\grass70.bat'
startcmd = [grass7bin, '--config', 'path']
try:
    p = subprocess.Popen(startcmd, shell=False,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()
except OSError as error:
    sys.exit("ERROR: Cannot find GRASS GIS start script"
             " {cmd}: {error}".format(cmd=startcmd[0], error=error))
if p.returncode != 0:
    sys.exit("ERROR: Issues running GRASS GIS start script"
             " {cmd}: {error}"
             .format(cmd=' '.join(startcmd), error=err))
gisbase = out.strip(os.linesep)

os.environ['GISBASE'] = gisbase
grass_pydir = os.path.join(gisbase, "etc", "python")
sys.path.append(grass_pydir)

import grass.script.setup as gsetup

gisdb = os.path.join(os.path.expanduser("~"), "Documents/grassdata")
location = "nc_spm_08"
mapset = "user1"

rcfile = gsetup.init(gisbase, gisdb, location, mapset)

# use grass functions here

os.remove(rcfile)

Now you put your GRASS module calls and GRASS Python API function calls to the place where # use grass functions here is.

However, if you just start GRASS GIS and run your script from there, your script can be as simple as this:

import grass.script as gscript

gscript.run_command('g.region', s=10, n=50, w=30, e=60, res=2)
gscript.mapcalc('test1 = sin(col() + row())')
print gscript.read_command('r.info', map='test1', flags='g')
print gscript.parse_command('r.univar', map='test1', flags='g')

To run the script, use File > Launch script in the GUI or type python yourscript.py to the command line. The second method works well on Linux as you don't have to figure out full path to Python there. On MS Windows, you usually need to figure out full path to Python installed with GRASS GIS. Alternatively, if you want to use Python interactive shell, you can use the one in GRASS GIS GUI and just type whatever you need there or use execfile() function to execute your script (you need to pass a full path to the script or correct relative path).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.