[GRASS-dev] r.mapcal and python

Hi all,
I'm a python newbie so have some patience :slight_smile:

I'm trying to use r.mapcal with the grass.py function 'run_command' in this way:

e = "%s=%s-%s" % (out, dsm, dtm)
grass.run_command('r.mapcalc', expression = e)

However, the new raster in "%out" doesn't appear, and a new raster called 'expression' is created instead.

I also tried with:

grass.run_command('r.mapcalc', expression = "%s=%s-%s" % (out, dsm, dtm))

with the same result. And also with:

grass.run_command('r.mapcalc', %s = "%s-%s" % (out, dsm, dtm))

which threw at me an execution error.

Any suggestion?

Thanks in advanced,
Roberto.

Ciao Roberto,
try with this solution:

output='yourmap'
map1='yourmap1'
map2='yourmap2'
cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)

It works for me :wink:
Massimiliano

Roberto Antolí­n wrote:

Hi all,
I'm a python newbie so have some patience :slight_smile:

I'm trying to use r.mapcal with the grass.py function 'run_command' in this way:

e = "%s=%s-%s" % (out, dsm, dtm)
grass.run_command('r.mapcalc', expression = e)

However, the new raster in "%out" doesn't appear, and a new raster called 'expression' is created instead.

I also tried with:

grass.run_command('r.mapcalc', expression = "%s=%s-%s" % (out, dsm, dtm))

with the same result. And also with:

grass.run_command('r.mapcalc', %s = "%s-%s" % (out, dsm, dtm))

which threw at me an execution error.

Any suggestion?

Thanks in advanced,
Roberto.

_______________________________________________
grass-dev mailing list
grass-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-dev

--
-----------------------------------------------------
Dr. Massimiliano Cannata
Environmental & Geomatic Engineer

Institute of Earth Sciences - SUPSI
Trevano, C.P. 72, CH-6952 Canobbio, SWITZERLAND

Tel: +41 (0)58 / 666 62 14 Fax: +41 (0)58 / 666 62 09
E-mail: massimiliano.cannata@supsi.ch

Web: http://www.ist.supsi.ch
http://istgis.ist.supsi.ch:8001/geomatica/
-------------------------------------------------------

On 10/11/08 15:36, Roberto Antolí­n wrote:

Hi all,
I'm a python newbie so have some patience :slight_smile:

I'm trying to use r.mapcal with the grass.py function 'run_command' in this way:

e = "%s=%s-%s" % (out, dsm, dtm)
grass.run_command('r.mapcalc', expression = e)

However, the new raster in "%out" doesn't appear, and a new raster called 'expression' is created instead.

I also tried with:

grass.run_command('r.mapcalc', expression = "%s=%s-%s" % (out, dsm, dtm))

The expression= parameter only exists in GRASS7, but not in grass6.x.

So, r.mapcalc expression=k=1

will give you

in GRASS6.x: a map called 'expression' with the value 1

in GRASS7: a map called 'k' with the value 1

So everything depends on the version of GRASS you are running.

with the same result. And also with:

grass.run_command('r.mapcalc', %s = "%s-%s" % (out, dsm, dtm))

No expert, but shouldn't this be:

grass.run_command('r.mapcalc', "%s = %s-%s" % (out, dsm, dtm))

[note the changed location of the opening quote]

Moritz

Ciao Maxi,
Nice to hear from you! Everything's ok?

Massimiliano Cannata escribió:

Ciao Roberto,
try with this solution:

output='yourmap'
map1='yourmap1'
map2='yourmap2'
cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)

Thank you, Maxi! It works perfectly well. I think I'll use this solution rather than the grass.py library for 'r.mapcalc'.

Regards,
Roberto.

Hi all, Moritz,

Moritz Lennert escribió:

grass.run_command('r.mapcalc', expression = "%s=%s-%s" % (out, dsm, dtm))

The expression= parameter only exists in GRASS7, but not in grass6.x.

So, r.mapcalc expression=k=1

will give you

in GRASS6.x: a map called 'expression' with the value 1

That was exactly what I obtained: a map called 'expression' with the difference between dtm and dsm.

grass.run_command('r.mapcalc', %s = "%s-%s" % (out, dsm, dtm))

No expert, but shouldn't this be:

grass.run_command('r.mapcalc', "%s = %s-%s" % (out, dsm, dtm))

In fact that was the first thing I tried, but I got this error:

syntax error, unexpected '-', expecting NAME or STRING
Parse error

Regards,
Roberto.

Moritz Lennert wrote:

> I'm a python newbie so have some patience :slight_smile:
>
> I'm trying to use r.mapcal with the grass.py function 'run_command' in
> this way:
>
> e = "%s=%s-%s" % (out, dsm, dtm)
> grass.run_command('r.mapcalc', expression = e)
>
> However, the new raster in "%out" doesn't appear, and a new raster
> called 'expression' is created instead.
>
> I also tried with:
>
> grass.run_command('r.mapcalc', expression = "%s=%s-%s" % (out, dsm, dtm))

The expression= parameter only exists in GRASS7, but not in grass6.x.

So, r.mapcalc expression=k=1

will give you

in GRASS6.x: a map called 'expression' with the value 1

in GRASS7: a map called 'k' with the value 1

So everything depends on the version of GRASS you are running.

> with the same result. And also with:
>
> grass.run_command('r.mapcalc', %s = "%s-%s" % (out, dsm, dtm))

No expert, but shouldn't this be:

grass.run_command('r.mapcalc', "%s = %s-%s" % (out, dsm, dtm))

[note the changed location of the opening quote]

In terms of Python syntax, the latter is correct.

However, grass.run_command() is intended for modules which use
G_parser(). In particular, you can only pass arguments which have the
form "name=value".

You can fudge it for the 6.x version of r.mapcalc with:

  grass.run_command('r.mapcalc', **{out: "%s-%s" % (dsm, dtm)})

But I would suggest either using subprocess.call():

  subprocess.call(['r.mapcalc', '%s = %s-%s' % (out, dsm, dtm)])

or passing the expression via stdin using grass.write_command():

  grass.write_command('r.mapcalc', stdin = '%s = %s-%s' % (out, dsm, dtm))

--
Glynn Clements <glynn@gclements.plus.com>

Roberto Antolí­n wrote:

> Ciao Roberto,
> try with this solution:
>
> output='yourmap'
> map1='yourmap1'
> map2='yourmap2'
> cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
> os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)

Thank you, Maxi! It works perfectly well. I think I'll use this solution
rather than the grass.py library for 'r.mapcalc'.

Don't use the os.spawn* functions; they have been superseded by
subprocess.Popen() and subprocess.call().

--
Glynn Clements <glynn@gclements.plus.com>

Hi Glynn and all,

Glynn Clements escribió:

cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)

Don't use the os.spawn* functions; they have been superseded by
subprocess.Popen() and subprocess.call().

After your (all) messages I searched for some information about subprocess.* and saw that os.spawn* were replaced by them.

Thank you for pointing me this! It confirms my doubts. In fact, subprocess.* are currently being used in grass.py library, aren't they? Using subprocess.* will give some kind of homogeneity.

Cheers,
Roberto.

Roberto Antolí­n wrote:

After your (all) messages I searched for some information
about subprocess.* and saw that os.spawn* were replaced by
them.

Thank you for pointing me this! It confirms my doubts. In
fact, subprocess.* are currently being used in grass.py
library, aren't they? Using subprocess.* will give some
kind of homogeneity.

I was about to suggest that the wiki Python page be checked, but
"GRASS-Wiki has a problem" :frowning: (hopefully temporary).

Hamish

Glynn Clements wrote:

Roberto Antolí­n wrote:

Ciao Roberto,
try with this solution:

output='yourmap'
map1='yourmap1'
map2='yourmap2'
cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)
      

Thank you, Maxi! It works perfectly well. I think I'll use this solution rather than the grass.py library for 'r.mapcalc'.
    
Don't use the os.spawn* functions; they have been superseded by
subprocess.Popen() and subprocess.call().

Yes, replace spawn* with popen or call. It is the right direction.

P.s.: Only call can handle the P_WAIT mode?

Maxi

--
-----------------------------------------------------
Dr. Massimiliano Cannata
Environmental & Geomatic Engineer

Institute of Earth Sciences - SUPSI
Trevano, C.P. 72, CH-6952 Canobbio, SWITZERLAND

Tel: +41 (0)58 / 666 62 14 Fax: +41 (0)58 / 666 62 09
E-mail: massimiliano.cannata@supsi.ch

Web: http://www.ist.supsi.ch
http://istgis.ist.supsi.ch:8001/geomatica/
-------------------------------------------------------

Roberto Antolí­n wrote:

>>> cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
>>> os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)
>
> Don't use the os.spawn* functions; they have been superseded by
> subprocess.Popen() and subprocess.call().

After your (all) messages I searched for some information about
subprocess.* and saw that os.spawn* were replaced by them.

Thank you for pointing me this! It confirms my doubts. In fact,
subprocess.* are currently being used in grass.py library, aren't they?
Using subprocess.* will give some kind of homogeneity.

Yes, the various grass.*_command() functions are all implemented on
top of subprocess.Popen().

The grass module provides wrappers for subprocess.Popen() and
subprocess.call(). The only difference between these wrappers and the
versions in the subprocess module is that the GRASS versions set
shell=True on Windows (this is so that it will execute scripts as well
as binary executables).

The most basic process creation function is grass.start_command(),
which uses grass.make_command() to construct the argument list, then
passes it to grass.Popen(). All of the other functions are based upon
grass.start_command().

--
Glynn Clements <glynn@gclements.plus.com>

Massimiliano Cannata wrote:

>>> Ciao Roberto,
>>> try with this solution:
>>>
>>> output='yourmap'
>>> map1='yourmap1'
>>> map2='yourmap2'
>>> cmdargs2=["%s=if(%s>%s,10000,0)"%(output,map1,map2)]
>>> os.spawnvp(os.P_WAIT,"r.mapcalc", ["r.mapcalc"] + cmdargs2)
>>>
>> Thank you, Maxi! It works perfectly well. I think I'll use this solution
>> rather than the grass.py library for 'r.mapcalc'.
>>
>
> Don't use the os.spawn* functions; they have been superseded by
> subprocess.Popen() and subprocess.call().
>
>
Yes, replace spawn* with popen or call. It is the right direction.

P.s.: Only call can handle the P_WAIT mode?

subprocess.call() waits for the process to terminate, and returns its
exit code. It is defined as:

  def call(*popenargs, **kwargs):
      return Popen(*popenargs, **kwargs).wait()

[plus a documentation string, which has been omitted above for
brevity.]

Examples of how to obtain equivalent behaviour to the os.* functions
are given in:

http://docs.python.org/library/subprocess.html#replacing-older-functions-with-the-subprocess-module

The only common case which the subprocess module doesn't replace is
the os.exec* functions.

--
Glynn Clements <glynn@gclements.plus.com>