Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

management of number precision by terra: decimal raster values are modified when writing files

Raster values are modified when writing to external files, due to the classical problem of internal representation of numbers, I suppose:

library(terra)
r <- rast(ncol=2, nrow=2, vals=c(5.3, 7.1, 3, 1.2))
sprintf("%.8f",values(r))
# [1] "5.30000000" "7.10000000" "3.00000000" "1.20000000"
  
t <- writeRaster(r, "test.tif", overwrite=TRUE)

sprintf("%.8f",values(t))
#[1] "5.30000019" "7.09999990" "3.00000000" "1.20000005"

This can be highly problematic. What is the "best" adequate workaround? I tested rounding and writing in integer formats, and it worked:

r <- rast(ncol=2, nrow=2, vals=c(5.3, 7.1, 3, 1.2))
sprintf("%.8f",values(r))
#[1] "5.30000000" "7.10000000" "3.00000000" "1.20000000"
r=10*r
 
t <- writeRaster(r, "test.tif", overwrite=TRUE,wopt=list(datatype="INT4S"))
t=t/10
 
sprintf("%.8f",values(t))
#[1] "5.30000000" "7.10000000" "3.00000000" "1.20000000"

Is there a better workaround? In particular, is there any "precision" attribute in terra, which could be associated to each raster, allowing a simpler and more efficient management of these problems for the user?

like image 478
Jean-Luc Dupouey Avatar asked Sep 13 '25 13:09

Jean-Luc Dupouey


1 Answers

You can use double precision floats (FLT8S)

library(terra)
r <- rast(ncol=2, nrow=2, vals=c(5.3, 7.1, 3, 1.2))
t <- writeRaster(r, "test.tif", overwrite=TRUE, wopt=list(datatype="FLT8S"))
sprintf("%.8f",values(t))
#[1] "5.30000000" "7.10000000" "3.00000000" "1.20000000"

Is there any "precision" attribute in terra, which could be associated to each raster

No there is not. If there were one, that would require propagation rules? It may be easier just to set it when writing? One caveat is that some of the writing may go unnoticed, to temp files. To set the default to FLT8S, you can use terraOptions(datatype="FLT8S")

like image 169
Robert Hijmans Avatar answered Sep 16 '25 03:09

Robert Hijmans