I am trying to raster::mosaic bunch of .tif files extracted from hdf4 MODIS files. My script is working fine but I am puzzled by the range of raster values (min, max) before and after data processing. The original hdf4 rasters are 8 bits integer raster ranged between 0-255 for every individual raster files before mosaicing. However, when I do a raster mosaic then the resulting raster is ranged between 0-25. My question is why?

I tried to reproduce this through a reproducible example but the problem doesn't apply to any example data such as below:

rx1 <- raster(nrows=2400, ncols=2400, vals = floor(runif(5760000, min=0, max=256)) )
extent(rx1) <- c(11119505, 12231456, -4447802, -3335852)
rx2 <-  raster(nrows=2400, ncols=2400, vals = floor(runif(5760000, min=0, max=256)) )
extent(rx2) <- c(12231456, 13343406, -4447802, -3335852)

lr.1 <- list()
lr.1[[1]] <- rx1
lr.1[[2]] <- rx2

lr.1$fun <- mean
rast.mosaic1 <- do.call(mosaic,lr.1)

#class       : RasterLayer 
#dimensions  : 2400, 4800, 11520000  (nrow, ncol, ncell)
#resolution  : 463.3129, 463.3125  (x, y)
#extent      : 11119505, 13343407, -4447802, -3335852  (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
#data source : in memory
#names       : layer 
#values      : 0, 255  (min, max)

If the same line of codes is applied to this data, then the result is:

lr.2 <- list()
lr.2[[1]] <- r[[1]]
lr.2[[2]] <- r[[3]]

lr.2$fun <- mean
rast.mosaic2 <- do.call(mosaic,lr.2)

#class       : RasterLayer 
#dimensions  : 2400, 4800, 11520000  (nrow, ncol, ncell)
#resolution  : 463.3127, 463.3127  (x, y)
#extent      : 11119505, 13343406, -4447802, -3335852  (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs 
#data source : in memory
#names       : layer 
#values      : 0, 25.4  (min, max)

When read into R the data has values from 0 to 25.4:

> r1 = raster("./Lai_500m1.tif")
> r2 = raster("./Lai_500m3.tif")
> range(r1[],na.rm=TRUE)
[1]  0.0 25.4
> range(r2[], na.rm=TRUE)
[1]  0.0 25.4

So this is happening before the mosaic. The mosaic is not relevant here.

255 is the "missing data" value. From the raster metadata:

Band 1 Block=2400x3 Type=Byte, ColorInterp=Gray
  Description = MOD15A2H MODIS/Terra Gridded 500M Leaf Area Index LAI (8-day composite)
  NoData Value=255
  Unit Type: m^2/m^2
  Offset: 0,   Scale:0.1

and there are:

> table(is.na(r1[]))

5759987      13 

13 out of 6 million in the first and 105 out of 6 million in the second file. You won't see them when plotting.

The metadata seems to define a lot of special values:

255 = _Fillvalue, assigned when:
    * the MOD09GA suf. reflectance for channel VIS, NIR was assigned its _Fillvalue, or
    * land cover pixel itself was assigned _Fillvalus 255 or 254.
254 = land cover assigned as perennial salt or inland fresh water.
253 = land cover assigned as barren, sparse vegetation (rock, tundra, desert.)
252 = land cover assigned as perennial snow, ice.
251 = land cover assigned as "permanent" wetlands/inundated marshlands.
250 = land cover assigned as urban/built-up.
249 = land cover assigned as "unclassified" or not able to determine.
248 = no standard deviation available, pixel produced using backup method.

and I think these are (apart from 255 which maps to NA in R) scaled by 0.1 because of that scaling factor in the previous metadata block. Hence in r1 there's a few pixels that are 25.4 (perennial salt or inland fresh water), 25.3 (barren, sparse vegetation) and 25.0 (urban/built-up). The rest are all between 0 and 7.

Anyway, that's not relevant to understanding why your mosaic was between 0 and 25.4 That was because your data was truly between 0 and 25.4, and 25.5 is the missing data value, and R reads it as NA.

  • That is well explained! Yes, the results are between 0 and 7 actually and 25 is NA. Was a bit confusing but not anymore. – Majid May 3 at 3:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.