Opened 11 years ago

Last modified 7 years ago

#1525 new defect

r.mask cannot use float maps

Reported by: pertusus Owned by: grass-dev@…
Priority: minor Milestone: 6.4.6
Component: Raster Version: svn-releasebranch64
Keywords: r.mask, r.reclass Cc:
CPU: x86-64 Platform: Linux

Description

In the r.mask documentation it is said

The mask is read as an integer map. If MASK is actually a floating-point map, the values will be converted to integers using the map's quantisation rules (this defaults to round-to-nearest, but can be changed with r.quant).

But if trying to do a mask with a float raster map, there is an error message:

echo "0|0|1" | r.in.xyz input=- output=seed
r.mask input=seed
ERROR: Raster map seed must be integer for maskcats parameter

Usint r.quant do not change anything (poking in the dark here, I don't really understand why r.quant do not need an output map).

r.quant -t seed
r.mask input=seed
ERROR: Raster map seed must be integer for maskcats parameter

A tarball is attached to reproduce the issue.

I had a look at r.mask and r.mask for 6.4.1, besides being a python script, the difference seems to be that in the svn version there is a test that the map is indeed a CELL map, which fails and give the error message, while there was no such test in the shell script. The code is along

      if grass.raster_info(input)['datatype'] != "CELL":
            grass.fatal(_("Raster map %s must be integer for maskcats parameter") % input)

I have tried without that check and things seems to work. I also attach a trivial patch that comment that code out. Maybe r.reclass does the magic float to integer quantification stuff? If it is the case, a comment in the code, like

# r.reclass takes care of float to integer translation

could be handy.

Maybe the problem is in the doc and really only integer raster map with type CELL may be used, but then the doc has to be changed and it would be nice to have a direction, the reference to r.quant not being very useful, in my opinion.

Attachments (2)

bug_grass_r_mask.tar.gz (1023 bytes ) - added by pertusus 11 years ago.
r.mask_no_check_of_CELL.diff (1.1 KB ) - added by pertusus 11 years ago.

Download all attachments as: .zip

Change History (13)

by pertusus, 11 years ago

Attachment: bug_grass_r_mask.tar.gz added

by pertusus, 11 years ago

comment:1 by pertusus, 11 years ago

In fact, the patch I propose leads to other issues down the line. I have found that r.mapcalc with a mask done with a FCELL raster type fails strangely later (I have a reproducer for that, in case it is not normal).

So forget about my patch.

comment:2 by pertusus, 11 years ago

Priority: normalminor

comment:3 by pertusus, 11 years ago

Well, seems that the issue with r.mapcalc also happens with CELL raster maps, and is very hard to reproduce... So my patch may still be relevant...

in reply to:  3 comment:4 by pertusus, 11 years ago

Replying to pertusus:

Well, seems that the issue with r.mapcalc also happens with CELL raster maps, and is very hard to reproduce... So my patch may still be relevant...

Sorry, this is wrong, the issue only happens with FCELL raster maps as r.mask...

in reply to:  description comment:5 by glynn, 11 years ago

Replying to pertusus:

I had a look at r.mask and r.mask for 6.4.1, besides being a python script, the difference seems to be that in the svn version there is a test that the map is indeed a CELL map, which fails and give the error message, while there was no such test in the shell script. The code is along

The test was added (incorrectly) in r46379. The CELL requirement should only apply if the maskcats= option was given. Fixed in r49997.

Maybe r.reclass does the magic float to integer quantification stuff?

The conversion is performed when the mask is used, not when it is set. It isn't necessary to use r.mask to create a mask; if a map named MASK exists in the current mapset, it is automatically used as a mask. The code which reads raster maps always reads the mask as CELL. The conversion from the stored type to the requested type (using quantisation rules in the case of FP->integer conversions) is built into libraster (libgis in versions before 7.0).

comment:6 by pertusus, 11 years ago

It does not solve my issue. I have printed the options, and indeed maskcats is not null, but *:

if __name__ == "__main__":
    options, flags = grass.parser()
    print options

r.mask input=seed {'input': 'seed', 'maskcats': '*'} ERREUR :Raster map seed must be integer for maskcats parameter

This is certainly because of the * below: #%option #% key: maskcats #% type: string #% description: Category values to use for mask (format: 1 2 3 thru 7 *) #% answer: * #% guisection: Create

in reply to:  6 comment:7 by pertusus, 11 years ago

Replying to pertusus:

It does not solve my issue. I have printed the options, and indeed maskcats is not null, but *:

if __name__ == "__main__":
    options, flags = grass.parser()
    print options

Correctly formatted:

r.mask input=seed
{'input': 'seed', 'maskcats': '*'}
ERREUR :Raster map seed must be integer for maskcats parameter

This is certainly because of the * below:

#%option
#% key: maskcats
#% type: string
#% description: Category values to use for mask (format: 1 2 3 thru 7 *)
#% answer: *
#% guisection: Create

in reply to:  6 comment:8 by glynn, 11 years ago

Replying to pertusus:

It does not solve my issue. I have printed the options, and indeed maskcats is not null, but *:

Oops; try r50019.

AFAICT, 6.x will have the same issue.

comment:9 by neteler, 11 years ago

Milestone: 7.0.06.4.2

comment:10 by hamish, 10 years ago

Keywords: r.mask r.reclass added
Milestone: 6.4.26.4.3

fix backported to devbr6 and relbr64 in r56123,4.

re. the error msg itself, r.reclass doesn't actually mind FP values and maps as input, that's where the quant rules come into effect.

there is some quant/rounding strangeness going on in r.reclass though:

# spearfish + 6.5svn

G65> g.region -d

G65> r.info -t fields
datatype=CELL

G65> r.mapcalc "seed = float(fields) + 0.55"
G65> r.info -r seed
min=1.55
max=63.55

G65> echo "30.45 thru 40.45 = 1" | r.reclass in=seed out=MASK
30.950000 rounded up to 30
40.950000 rounded up to 40
[Raster MASK present]

? "30.95 rounded up to 30", ... ?

(see scan_value() in r.reclass/parse.c)

Hamish

comment:11 by neteler, 7 years ago

Milestone: 6.4.36.4.6
Version: svn-trunksvn-releasebranch64
Note: See TracTickets for help on using tickets.