[GRASS-user] raster MASKs; was [GRASS-dev] interferring ovewrite flags

Michael Barton wrote:

How can you make a mask additive with r.mapcalc? This could be useful
sometime.

"additive" in a processing sense, not mathematical. (still 0|NULL,1)

for example: (spearfish)

r.mapcalc MASK='if(isnull(roads))'
r.mapcalc MASK=fields
d.rast elevation.dem

shows elevation where there is fields but no roads, as fields is read
in with a mask in place.

Hamish

Right. I understand, even if I didn't phrase it that way. Does this happen
for any r.mapcalc processing using the same procedures or just ones in which
MASK is the result? Also, is it always an "and" or can you also get the
effects of an "or"? Definitely a 'gotcha' to watch out for. I'm concerned
especially because we are doing a lot of iterative r.mapcalc processing in
scripts and this could be a problem.

Michael
__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

From: Hamish <hamish_nospam@yahoo.com>
Date: Mon, 2 Oct 2006 17:18:18 +1300
To: Michael Barton <michael.barton@asu.edu>
Cc: grass list <grassuser@grass.itc.it>
Subject: raster MASKs; was [GRASS-dev] interferring ovewrite flags

Michael Barton wrote:

How can you make a mask additive with r.mapcalc? This could be useful
sometime.

"additive" in a processing sense, not mathematical. (still 0|NULL,1)

for example: (spearfish)

r.mapcalc MASK='if(isnull(roads))'
r.mapcalc MASK=fields
d.rast elevation.dem

shows elevation where there is fields but no roads, as fields is read
in with a mask in place.

Hamish

Michael Barton wrote:

Right. I understand, even if I didn't phrase it that way. Does this
happen for any r.mapcalc processing using the same procedures or just
ones in which MASK is the result? Also, is it always an "and" or can
you also get the effects of an "or"? Definitely a 'gotcha' to watch
out for. I'm concerned especially because we are doing a lot of
iterative r.mapcalc processing in scripts and this could be a problem.

The MASK is generally applied when a row of input data is read from the
disk.

A module scan specifically ask to ignore the MASK, but the vast vast
majority of raster modules process data by row (to save memory), and use
G_get_raster_row() to do that.

G_get_raster_row_nomask() is the non-masking version. Things that use it:
  display/d.rast.edit/mk_tmp_file.c
  imagery/i.rectify/perform.c
  imagery/i.ortho.photo/photo.rectify/perform.c
  raster/r.compress/main.c
  raster/r.le/r.le.patch/driver.c
  raster/r.le/r.le.patch/trace.c
  raster/r.le/r.le.pixel/cellclip.c
  raster/r.le/r.le.pixel/driver.c
* raster/r.null/null.c

So:

r.mapcalc MASK='if(isnull(roads))'
r.mapcalc MASK=fields
d.rast elevation.dem # displays with holes
r.mapcalc one=1 # full coverage once MASK is removed
r.mapcalc two=elevation.dem # holes once MASK is removed
g.remove MASK
d.rast one
d.rast two

the numeric mapcalc cmd hasn't read a map from the disk, so in fact it
is a solid block. The "two" map has read, so in fact contains holes.
If the "one" map is displayed with a MASK in place, it appears to have
holes in it, but these are introduced when d.rast loads the map to
display it.

clear?

Hamish

OK. Thanks. It took a bit of re-reading this to get it all--and to connect
the dots with your initial post. I think the r.mask script does not have
these issues because it uses r.reclass (like the original GRASS 5 r.mask
did), but it is a good reason for caution when using r.mapcalc to create a
MASK. Just to make sure I've got it, could you check my comments below?

Thanks
Michael
__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

From: Hamish <hamish_nospam@yahoo.com>
Date: Mon, 2 Oct 2006 20:37:36 +1300
To: Michael Barton <michael.barton@asu.edu>
Cc: <grassuser@grass.itc.it>
Subject: Re: raster MASKs; was [GRASS-dev] interferring ovewrite flags

Michael Barton wrote:

Right. I understand, even if I didn't phrase it that way. Does this
happen for any r.mapcalc processing using the same procedures or just
ones in which MASK is the result? Also, is it always an "and" or can
you also get the effects of an "or"? Definitely a 'gotcha' to watch
out for. I'm concerned especially because we are doing a lot of
iterative r.mapcalc processing in scripts and this could be a problem.

The MASK is generally applied when a row of input data is read from the
disk.

A module scan specifically ask to ignore the MASK, but the vast vast
majority of raster modules process data by row (to save memory), and use
G_get_raster_row() to do that.

G_get_raster_row_nomask() is the non-masking version. Things that use it:
  display/d.rast.edit/mk_tmp_file.c
  imagery/i.rectify/perform.c
  imagery/i.ortho.photo/photo.rectify/perform.c
  raster/r.compress/main.c
  raster/r.le/r.le.patch/driver.c
  raster/r.le/r.le.patch/trace.c
  raster/r.le/r.le.pixel/cellclip.c
  raster/r.le/r.le.pixel/driver.c
* raster/r.null/null.c

These commands do NOT respect a MASK ???

So:

r.mapcalc MASK='if(isnull(roads))'
r.mapcalc MASK=fields
d.rast elevation.dem # displays with holes
r.mapcalc one=1 # full coverage once MASK is removed
r.mapcalc two=elevation.dem # holes once MASK is removed
g.remove MASK
d.rast one
d.rast two

r.mapcalc will respect a MASK ONLY if the formula to create a new map
includes an existing map (i.e., read from disk).

A new map created from a formula that does NOT include an existing map will
NOT respect a MASK, even though it may APPEAR to do so when you display it
using d.rast with a MASK in place--because d.rast DOES respect a MASK.

the numeric mapcalc cmd hasn't read a map from the disk, so in fact it
is a solid block. The "two" map has read, so in fact contains holes.
If the "one" map is displayed with a MASK in place, it appears to have
holes in it, but these are introduced when d.rast loads the map to
display it.

clear?

I think so.

...From earlier message

"additive" in a processing sense, not mathematical. (still 0|NULL,1)

for example: (spearfish)

r.mapcalc MASK='if(isnull(roads))'

MASK created with holes for roads

r.mapcalc MASK=fields

r.mapcalc reads map "fields", respecting MASK that leaves holes for roads,
and writes new MASK with fields but without roads.

d.rast elevation.dem

d.rast respects new MASK that is limited to fields without roads.

shows elevation where there is fields but no roads, as fields is read
in with a mask in place.

Michael Barton wrote:

> A module scan specifically ask to ignore the MASK, but the vast vast
> majority of raster modules process data by row (to save memory), and use
> G_get_raster_row() to do that.
>
> G_get_raster_row_nomask() is the non-masking version. Things that use it:
> display/d.rast.edit/mk_tmp_file.c
> imagery/i.rectify/perform.c
> imagery/i.ortho.photo/photo.rectify/perform.c
> raster/r.compress/main.c
> raster/r.le/r.le.patch/driver.c
> raster/r.le/r.le.patch/trace.c
> raster/r.le/r.le.pixel/cellclip.c
> raster/r.le/r.le.pixel/driver.c
> * raster/r.null/null.c

These commands do NOT respect a MASK ???

It depends.

E.g. r.compress and r.null simply ignore the mask (i.e. they read the
map using G_get_raster_row_nomask()). This makes sense, as these are
low-level utilities which operate directly upon the map, rather than a
"view" of it. Similarly, both of those modules set the region to the
map's region, ignoring the current region.

OTOH, r.le.patch/driver.c seems to handle the mask itself. The actual
map is read with G_get_raster_row(), but it also reads the MASK map
directly (using G_get_raster_row_nomask(); reading MASK with
G_get_raster_row() wouldn't make much sense).

i.ifft does something similar. i.ifft doesn't read any maps, it reads
the "raw" copy which i.fft creates. Not being a map, the mask doesn't
apply, so i.ifft applies the mask itself.

> r.mapcalc MASK='if(isnull(roads))'
> r.mapcalc MASK=fields
> d.rast elevation.dem # displays with holes
> r.mapcalc one=1 # full coverage once MASK is removed
> r.mapcalc two=elevation.dem # holes once MASK is removed
> g.remove MASK
> d.rast one
> d.rast two

r.mapcalc will respect a MASK ONLY if the formula to create a new map
includes an existing map (i.e., read from disk).

That's true of all modules. The mask is applied automatically to input
maps by libgis (unless the map is read using the _nomask versions of
the intput functions). It won't affect anything else unless the module
handles it explicitly (which very few do).

A new map created from a formula that does NOT include an existing map will
NOT respect a MASK, even though it may APPEAR to do so when you display it
using d.rast with a MASK in place--because d.rast DOES respect a MASK.

Yes. Anything which doesn't actually read a map will be unaffected by
the mask.

Also, note that if you use the neighbourhood modifier, e.g.:

  r.mapcalc 'out = in[10,10]'

the mask will be applied upon input, before the shift is applied.

Similarly, modules which switch regions between input and output (e.g.
r.resamp.interp, r.resamp.stats) will apply the mask at the input
resolution, not the output resolution. One consequence of this is that
r.resamp.stats may produce non-null cells where most other modules
would produce null cells due to the mask.

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