[GRASS-user] Change GRASS region multiple times

Hello!

I’m working with pygrass, developing a new module for GRASS.

I need to create a new raster map during the execution. I’m using the commands:

from grass.pygrass import raster

newRasterMap = raster.RasterSegment(‘new’)
newRasterMap.open(‘w’, ‘CELL’)

I’ve noticed that new raster maps are created with the resolution of the current region in GRASS. I’ve noticed also that it is possible to change the current region during the execution of my new module using the script ‘g.region’. However, it looks like if I want to change the resolution again, the script ‘g.region’ does not have any effect. My conclusion: GRASS can change the current region just 1 time during the execution of a module. Is that correct?

I would like to know how can I develop a new module (using pygrass) where I could be able to create three new raster maps with different resolutions each?

Thank you all very much!

Dan

Dear Luna,

On Wed, Mar 2, 2016 at 10:40 PM, Luna, Daniel Eduardo <DEL47@pitt.edu> wrote:

I need to create a new raster map during the execution. I'm using the
commands:

        from grass.pygrass import raster

        newRasterMap = raster.RasterSegment('new')
        newRasterMap.open('w', 'CELL')

Do you really need RasterSegment? Do you need to write raster map not
in a sequential mode?

I've noticed that new raster maps are created with the resolution of the
current region in GRASS. I've noticed also that it is possible to change the
current region during the execution of my new module using the script
'g.region'. However, it looks like if I want to change the resolution again,
the script 'g.region' does not have any effect. My conclusion: GRASS can
change the current region just 1 time during the execution of a module. Is
that correct?

No, the region affect only the current process, using the g.region
module you are using an external process that should not have effect
on your process.

I would like to know how can I develop a new module (using pygrass) where I
could be able to create three new raster maps with different resolutions
each?

I wrote some code for testing
You can create a module that do your analysis, and then you can call
your module setting different regions (see function
test_different_regions1),
otherwise you can work only in the same process (see function
test_different_regions3).
I've also define a function (test_different_regions2) that mix ctypes
and external process, but If it is uncomment the
test_different_regions3 is not working any more... and I'm not able to
understand why... :slight_smile:

{{{
from grass.pygrass.modules import Module
from grass.pygrass.raster import RasterSegment
from grass.pygrass.gis.region import Region

def test_different_regions1(rinput, routput, method, *resamples):
    """Function using only external process, through GRASS modules"""
    for res in resamples:
        Module('g.region', raster=rinput, res=res, flags='ap')
        Module('r.resamp.stats', input=rinput,
               output=routput+'_{res}'.format(res=res),
               method=method, overwrite=True)

def write_raster(rinput, routput):
    """Function that work with input/output raster maps"""
    with RasterSegment(rinput, mode='r') as rin,
RasterSegment(routput, mode='w', mtype=rin.mtype, overwrite=True) as
rot:
        for irow, row in enumerate(rin):
            rot.put_row(irow, row * 2)
        print(rot.info.nsres, rot.info.ewres)

def test_different_regions2(rinput, routput, *resolutions):
    """Mixing external processes (g.region) with current"""
    for res in resolutions:
        Module('g.region', raster=rinput, res=res, flags='ap')
        write_raster(rinput, routput + '{res}'.format(res=res))
    #Module('g.region', raster=rinput, flags='a')

def test_different_regions3(rinput, routput, *resolutions):
    """Working only with current process"""
    reg = Region()
    for res in resolutions:
        reg.nsres, reg.ewres = res, res
        reg.write()
        reg.set_raster_region()
        print(reg)
        write_raster(rinput, routput + '{res}'.format(res=res))

print("\n\nOnly GRASS modules", "\n" + "=" * 30)
test_different_regions1('elevation', 'tmptest', 'average', 50, 100, 200)

# Uncomment to change behaviour of test_different_regions3
#print("\n\nGRASS modules and ctypes", "\n" + "=" * 30)
#test_different_regions2('elevation', 'tmptest', 50, 100, 200)

print("\n\nOnly ctypes", "\n" + "=" * 30)
test_different_regions3('elevation', 'tmptest', 50, 100, 200)
Module('g.remove', type='raster', pattern='tmptest' + '*', flags='f')

}}}

Happy coding

Pietro

Thank you very much for your response Pietro!

Unfortunately, I'm still having problems with this topic: During the execution of my module, the resolution can change just one time. Then. when I'm creating multiple raster maps, they all have the resolution of the first one. Even using the g.region module. Is this normal?

Using the "test_different_regions2" I'm obtaining all the maps with the first resolution in the list *resolutions. (Thank you very much for it anyway!!) Do you know what can be my problem?

1. What do you mean with "writing the map in a sequential mode"?

(My case: I have a list of matrices, each one with the information I want to write in a different map. I know the East-West, North-South limits of each one, and depending on the number of rows/cols of each matrix, the resulting map resolution may vary. How can we do this?)

Thank you very much for your help!!
Daniel

________________________________________
From: Pietro <peter.zamb@gmail.com>
Sent: Friday, March 4, 2016 2:20
To: Luna, Daniel Eduardo
Cc: grass-user@lists.osgeo.org; Liang, Xu; Hernandez Cruz, Felipe
Subject: Re: [GRASS-user] Change GRASS region multiple times

Dear Luna,

On Wed, Mar 2, 2016 at 10:40 PM, Luna, Daniel Eduardo <DEL47@pitt.edu> wrote:

I need to create a new raster map during the execution. I'm using the
commands:

        from grass.pygrass import raster

        newRasterMap = raster.RasterSegment('new')
        newRasterMap.open('w', 'CELL')

Do you really need RasterSegment? Do you need to write raster map not
in a sequential mode?

I've noticed that new raster maps are created with the resolution of the
current region in GRASS. I've noticed also that it is possible to change the
current region during the execution of my new module using the script
'g.region'. However, it looks like if I want to change the resolution again,
the script 'g.region' does not have any effect. My conclusion: GRASS can
change the current region just 1 time during the execution of a module. Is
that correct?

No, the region affect only the current process, using the g.region
module you are using an external process that should not have effect
on your process.

I would like to know how can I develop a new module (using pygrass) where I
could be able to create three new raster maps with different resolutions
each?

I wrote some code for testing
You can create a module that do your analysis, and then you can call
your module setting different regions (see function
test_different_regions1),
otherwise you can work only in the same process (see function
test_different_regions3).
I've also define a function (test_different_regions2) that mix ctypes
and external process, but If it is uncomment the
test_different_regions3 is not working any more... and I'm not able to
understand why... :slight_smile:

{{{
from grass.pygrass.modules import Module
from grass.pygrass.raster import RasterSegment
from grass.pygrass.gis.region import Region

def test_different_regions1(rinput, routput, method, *resamples):
    """Function using only external process, through GRASS modules"""
    for res in resamples:
        Module('g.region', raster=rinput, res=res, flags='ap')
        Module('r.resamp.stats', input=rinput,
               output=routput+'_{res}'.format(res=res),
               method=method, overwrite=True)

def write_raster(rinput, routput):
    """Function that work with input/output raster maps"""
    with RasterSegment(rinput, mode='r') as rin,
RasterSegment(routput, mode='w', mtype=rin.mtype, overwrite=True) as
rot:
        for irow, row in enumerate(rin):
            rot.put_row(irow, row * 2)
        print(rot.info.nsres, rot.info.ewres)

def test_different_regions2(rinput, routput, *resolutions):
    """Mixing external processes (g.region) with current"""
    for res in resolutions:
        Module('g.region', raster=rinput, res=res, flags='ap')
        write_raster(rinput, routput + '{res}'.format(res=res))
    #Module('g.region', raster=rinput, flags='a')

def test_different_regions3(rinput, routput, *resolutions):
    """Working only with current process"""
    reg = Region()
    for res in resolutions:
        reg.nsres, reg.ewres = res, res
        reg.write()
        reg.set_raster_region()
        print(reg)
        write_raster(rinput, routput + '{res}'.format(res=res))

print("\n\nOnly GRASS modules", "\n" + "=" * 30)
test_different_regions1('elevation', 'tmptest', 'average', 50, 100, 200)

# Uncomment to change behaviour of test_different_regions3
#print("\n\nGRASS modules and ctypes", "\n" + "=" * 30)
#test_different_regions2('elevation', 'tmptest', 50, 100, 200)

print("\n\nOnly ctypes", "\n" + "=" * 30)
test_different_regions3('elevation', 'tmptest', 50, 100, 200)
Module('g.remove', type='raster', pattern='tmptest' + '*', flags='f')

}}}

Happy coding

Pietro

On 23/03/16 22:16, Luna, Daniel Eduardo wrote:

Thank you very much for your response Pietro!

Unfortunately, I'm still having problems with this topic: During the
execution of my module, the resolution can change just one time.
Then. when I'm creating multiple raster maps, they all have the
resolution of the first one. Even using the g.region module. Is this
normal?

Yes, just calling g.region is not enough as Pietro told you.

Check out [1] for hints on how to change region within your script. The first solution (use_temp_region()) generally works well for me.

Moritz

[1] https://grasswiki.osgeo.org/wiki/GRASS_Python_Scripting_Library#Using_temporary_region_for_computations