Giter Club home page Giter Club logo

modistools's Introduction

MODISTools

R build status codecov Status rOpenSci Peer Review Downloads

Programmatic interface to the ‘MODIS Land Products Subsets’ web services. Allows for easy downloads of ‘MODIS’ time series directly to your R workspace or your computer. When using the package please cite the manuscript as referenced below. Keep in mind that the original manuscript describes versions prior to release 1.0 of the package. Functions described in this manuscript do not exist in the current package, please consult the documentation to find matching functionality.

Installation

stable release

To install the current stable release use a CRAN repository:

install.packages("MODISTools")
library("MODISTools")

development release

To install the development releases of the package run the following commands:

if(!require(devtools)){install.package("devtools")}
devtools::install_github("khufkens/MODISTools")
library("MODISTools")

Vignettes are not rendered by default, if you want to include additional documentation please use:

if(!require(devtools)){install.package("devtools")}
devtools::install_github("khufkens/MODISTools", build_vignettes = TRUE)
library("MODISTools")

Use

Downloading MODIS time series

To extract a time series of modis data for a given location and its direct environment use the mt_subset() function.

detailed parameter description (click to expand)

Parameter Description
product a MODIS product
band a MODIS product band (if NULL all bands are downloaded)
lat latitude of the site
lon longitude of the site
start start year of the time series (data start in 1980)
end end year of the time series (current year - 2 years, use force = TRUE to override)
internal logical, TRUE or FALSE, if true data is imported into R workspace otherwise it is downloaded into the current working directory
out_dir path where to store the data when not used internally, defaults to tempdir()
km_lr force “out of temporal range” downloads (integer)
km_ab suppress the verbose output (integer)
site_name a site identifier
site_id a site_id for predefined locations (not required)
progress logical, TRUE or FALSE (show download progress)

# load the library
library(MODISTools)

# download data
subset <- mt_subset(product = "MOD11A2",
                    lat = 40,
                    lon = -110,
                    band = "LST_Day_1km",
                    start = "2004-01-01",
                    end = "2004-02-01",
                    km_lr = 1,
                    km_ab = 1,
                    site_name = "testsite",
                    internal = TRUE,
                    progress = FALSE)
print(str(subset))
#> 'data.frame':    36 obs. of  21 variables:
#>  $ xllcorner    : chr  "-9370963.05" "-9370963.05" "-9370963.05" "-9370963.05" ...
#>  $ yllcorner    : chr  "4445948.79" "4445948.79" "4445948.79" "4445948.79" ...
#>  $ cellsize     : chr  "926.625433055834" "926.625433055834" "926.625433055834" "926.625433055834" ...
#>  $ nrows        : int  3 3 3 3 3 3 3 3 3 3 ...
#>  $ ncols        : int  3 3 3 3 3 3 3 3 3 3 ...
#>  $ band         : chr  "LST_Day_1km" "LST_Day_1km" "LST_Day_1km" "LST_Day_1km" ...
#>  $ units        : chr  "Kelvin" "Kelvin" "Kelvin" "Kelvin" ...
#>  $ scale        : chr  "0.02" "0.02" "0.02" "0.02" ...
#>  $ latitude     : num  40 40 40 40 40 40 40 40 40 40 ...
#>  $ longitude    : num  -110 -110 -110 -110 -110 -110 -110 -110 -110 -110 ...
#>  $ site         : chr  "testsite" "testsite" "testsite" "testsite" ...
#>  $ product      : chr  "MOD11A2" "MOD11A2" "MOD11A2" "MOD11A2" ...
#>  $ start        : chr  "2004-01-01" "2004-01-01" "2004-01-01" "2004-01-01" ...
#>  $ end          : chr  "2004-02-01" "2004-02-01" "2004-02-01" "2004-02-01" ...
#>  $ complete     : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...
#>  $ modis_date   : chr  "A2004001" "A2004009" "A2004017" "A2004025" ...
#>  $ calendar_date: chr  "2004-01-01" "2004-01-09" "2004-01-17" "2004-01-25" ...
#>  $ tile         : chr  "h09v05" "h09v05" "h09v05" "h09v05" ...
#>  $ proc_date    : chr  "2020168005635" "2020168010833" "2020168012220" "2020168013617" ...
#>  $ pixel        : int  1 1 1 1 2 2 2 2 3 3 ...
#>  $ value        : int  13148 13160 13398 13412 13153 13140 13370 13388 13131 13096 ...
#> NULL

The output format is a tidy data frame, as shown above. When witten to a csv with the parameter internal = FALSE this will result in a flat file on disk.

Note that when a a region is defined using km_lr and km_ab multiple pixels might be returned. These are indexed using the pixel column in the data frame containing the time series data. The remote sensing values are listed in the value column. When no band is specified all bands of a given product are returned, be mindful of the fact that different bands might require different multipliers to represent their true values. To list all available products, bands for particular products and temporal coverage see function descriptions below.

Batch downloading MODIS time series

When a large selection of locations is needed you might benefit from using the batch download function mt_batch_subset(), which provides a wrapper around the mt_subset() function in order to speed up large download batches. This function has a similar syntax to mt_subset() but requires a data frame defining site names (site_name) and locations (lat / lon) (or a comma delimited file with the same structure) to specify a list of download locations.

Below an example is provided on how to batch download data for a data frame of given site names and locations (lat / lon).

# create data frame with a site_name, lat and lon column
# holding the respective names of sites and their location
df <- data.frame("site_name" = paste("test",1:2))
df$lat <- 40
df$lon <- -110
  
# test batch download
subsets <- mt_batch_subset(df = df,
                     product = "MOD11A2",
                     band = "LST_Day_1km",
                     internal = TRUE,
                     start = "2004-01-01",
                     end = "2004-02-01")

print(str(subsets))
#> 'data.frame':    8 obs. of  21 variables:
#>  $ xllcorner    : chr  "-9370036.35" "-9370036.35" "-9370036.35" "-9370036.35" ...
#>  $ yllcorner    : chr  "4446875.49" "4446875.49" "4446875.49" "4446875.49" ...
#>  $ cellsize     : chr  "926.625433055834" "926.625433055834" "926.625433055834" "926.625433055834" ...
#>  $ nrows        : int  1 1 1 1 1 1 1 1
#>  $ ncols        : int  1 1 1 1 1 1 1 1
#>  $ band         : chr  "LST_Day_1km" "LST_Day_1km" "LST_Day_1km" "LST_Day_1km" ...
#>  $ units        : chr  "Kelvin" "Kelvin" "Kelvin" "Kelvin" ...
#>  $ scale        : chr  "0.02" "0.02" "0.02" "0.02" ...
#>  $ latitude     : num  40 40 40 40 40 40 40 40
#>  $ longitude    : num  -110 -110 -110 -110 -110 -110 -110 -110
#>  $ site         : chr  "test 1" "test 1" "test 1" "test 1" ...
#>  $ product      : chr  "MOD11A2" "MOD11A2" "MOD11A2" "MOD11A2" ...
#>  $ start        : chr  "2004-01-01" "2004-01-01" "2004-01-01" "2004-01-01" ...
#>  $ end          : chr  "2004-02-01" "2004-02-01" "2004-02-01" "2004-02-01" ...
#>  $ complete     : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...
#>  $ modis_date   : chr  "A2004001" "A2004009" "A2004017" "A2004025" ...
#>  $ calendar_date: chr  "2004-01-01" "2004-01-09" "2004-01-17" "2004-01-25" ...
#>  $ tile         : chr  "h09v05" "h09v05" "h09v05" "h09v05" ...
#>  $ proc_date    : chr  "2020168005635" "2020168010833" "2020168012220" "2020168013617" ...
#>  $ pixel        : int  1 1 1 1 1 1 1 1
#>  $ value        : int  13129 13102 13343 13364 13129 13102 13343 13364
#> NULL

Listing products

To list all available products use the mt_products() function.

products <- mt_products()
head(products)
#>        product
#> 1       Daymet
#> 2 ECO4ESIPTJPL
#> 3      ECO4WUE
#> 4       GEDI03
#> 5     GEDI04_B
#> 6      MCD12Q1
#>                                                                          description
#> 1 Daily Surface Weather Data (Daymet) on a 1-km Grid for North America, Version 4 R1
#> 2               ECOSTRESS Evaporative Stress Index PT-JPL (ESI) Daily L4 Global 70 m
#> 3                          ECOSTRESS Water Use Efficiency (WUE) Daily L4 Global 70 m
#> 4                GEDI Gridded Land Surface Metrics (LSM) L3 1km EASE-Grid, Version 2
#> 5       GEDI Gridded Aboveground Biomass Density (AGBD) L4B 1km EASE-Grid, Version 2
#> 6              MODIS/Terra+Aqua Land Cover Type (LC) Yearly L3 Global 500 m SIN Grid
#>   frequency resolution_meters
#> 1     1 day              1000
#> 2    Varies                70
#> 3    Varies                70
#> 4  One time              1000
#> 5  One time              1000
#> 6    1 year               500

Listing bands

To list all available bands for a given product use the mt_bands() function.

bands <- mt_bands(product = "MOD11A2")
head(bands)
#>               band                          description valid_range fill_value
#> 1   Clear_sky_days               Day clear-sky coverage    1 to 255          0
#> 2 Clear_sky_nights             Night clear-sky coverage    1 to 255          0
#> 3    Day_view_angl View zenith angle of day observation    0 to 130        255
#> 4    Day_view_time        Local time of day observation    0 to 240        255
#> 5          Emis_31                   Band 31 emissivity    1 to 255          0
#> 6          Emis_32                   Band 32 emissivity    1 to 255          0
#>    units scale_factor add_offset
#> 1   <NA>         <NA>       <NA>
#> 2   <NA>         <NA>       <NA>
#> 3 degree            1        -65
#> 4    hrs          0.1          0
#> 5   <NA>        0.002       0.49
#> 6   <NA>        0.002       0.49

listing dates

To list all available dates (temporal coverage) for a given product and location use the mt_dates() function.

dates <- mt_dates(product = "MOD11A2", lat = 42, lon = -110)
head(dates)
#>   modis_date calendar_date
#> 1   A2000049    2000-02-18
#> 2   A2000057    2000-02-26
#> 3   A2000065    2000-03-05
#> 4   A2000073    2000-03-13
#> 5   A2000081    2000-03-21
#> 6   A2000089    2000-03-29

References

Hufkens (2022). The MODISTools package: an interface to the MODIS Land Products Subsets Web Services https://github.com/ropensci/MODISTools

Acknowledgements

Original development was supported by the UK Natural Environment Research Council (NERC; grants NE/K500811/1 and NE/J011193/1), and the Hans Rausing Scholarship. Refactoring was supported through the Belgian Science Policy office COBECORE project (BELSPO; grant BR/175/A3/COBECORE). Logo design elements are taken from the FontAwesome library according to these terms, where the globe element was inverted and intersected. Continued support for MODISTools is provided by BlueGreen Labs.

ropensci_footer

modistools's People

Contributors

annnvv avatar etiennebr avatar jeroen avatar khufkens avatar maelle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

modistools's Issues

add in internal flag

allow for both internal storage or writing files to disk during subset download

Problems with 16-days NDVI

Dear all,

I am trying to use the MODISTools package to extract the 16 day NDVI average values (the product is MOD13Q1), in an area around some points that I am analyzing . However, the software keeps extracting fixed values (-3000) an I suspect is not really extracting 16-days average?

Find below an example. What is going wrong?

range(mt_dates(product = "MOD13Q1", lat = 11.906359, lon = 43.90075)$calendar_date)

ndvi.extraction <- mt_subset(product = "MOD13Q1",
                             lat = 11.906359,
                             lon = 43.90075,
                             km_lr=4,
                             km_ab=4,
                             band = "250m_16_days_NDVI",
                             start = "2015-05-01",
                             end = "2015-08-31",
                             progress = FALSE)

Best,

Jacopo

Reference MODISTools version described in Tuck et al. (2014) paper

The Tuck et al. (2014) paper that describes the MODISTools package, references functions that are no longer available or renamed in the current version of the package. Would it be possible to mention this in the README for users that discover the package via the paper? For example:

Tuck et al. (2014). MODISTools - downloading and processing MODIS remotely sensed data in R Ecology &
Evolution
, 4(24), 4658 - 4668.

The paper above describes version x of the package (available at ...). Since then, the maintenance of the package has been transferred and the package refactored. Use function() for MODISSubsets(), ...

Note: Old releases seem to be available at https://cran.r-project.org/src/contrib/Archive/MODISTools/ but not 0.94.3 that is listed in one of the scripts associated with the paper:

sessionInfo()
# MODISTools_0.94.3

Check formatting of dates

Check the format of the dates (YYYY-MM-DD) provided in a query. The API call will stall when faulty dates are provided.

mt_to_terra function

There is currently a function mt_to_raster() that creates a raster from the downloaded data. The raster package is getting deprecated, so it would be nice to either have a new function mt_to_terra() or a parameter to mt_to_raster() that provides a terra SpatRaster object.

Vignette fail - check workflow

Unsure why this happens as normally no external data is called for documentation might be idiosyncratic CRAN stuff.


Dear maintainer,

Please see the problems shown on
https://cran.r-project.org/web/checks/check_results_MODISTools.html.

Please correct before 2022-04-03 to safely retain your package on CRAN.

It seems we need to remind you of the CRAN policy:

'Packages which use Internet resources should fail gracefully with an informative message
if the resource is not available or has changed (and not give a check warning nor error).'

This needs correction whether or not the resource recovers.

The CRAN Team

Please remove dependencies on **rgdal**, **rgeos**, and/or **maptools**

This package depends on (depends, imports or suggests) raster and one or more of the retiring packages rgdal, rgeos or maptools (https://r-spatial.org/r/2022/04/12/evolution.html, https://r-spatial.org/r/2022/12/14/evolution2.html). Since raster 3.6.3, all use of external FOSS library functionality has been transferred to terra, making the retiring packages very likely redundant. It would help greatly if you could remove dependencies on the retiring packages as soon as possible.

Archiving and/or transfer MODISTools on rOpenSci

Hi @maelle @karthik,

I've decided to hard fork, i.e. reclaim ownership, of {MODISTools} and this for a number or reasons. First and foremost, the platform removes much of the brand recognition I need to keep my consulting business going. Although a great resource for users, I don't think the same can be said for all code developers.

When promotion, community building, and maintenance remains largely the responsibility of "The Maintainer", while brand recognition and bolstering of a growing ecosystem of packages can only be leveraged at scale by rOpenSci itself I start to question the platform's business model. One can argue that this monetization through (academic) grant seeking, and removes any and all options for small businesses to do so themselves (as money always flows to the top).

I recognize that many contributors are academics for which the "potential" reduced overhead by handing things over to rOpenSci makes sense, as they have other sources of income. However, this equation changes dramatically if part of your income comes from brand recognition of your code work. This dynamic, IMO, does a disservice to small time developers of niche packages once stepping outside the academic sphere.

I'm willing to have an open discussion about this, and technically I would like a clean transfer of the current repository to https://github.com/bluegreen-labs. However, since I don't control this repository I've made sure to hard fork all my latest work beforehand.

I thank the rOpenSci team for early code review, and will consider returning if the platform allows for better visibility and business opportunities for independent consultants who depend on their code for a living.

Kind regards,
Koen

MODIS data over taiwan is incorrect

I've queried several NDVI and landcover products at all bands over the past few days using the central lat/lon of Taiwan. Every single one of the products is incorrect. They don't represent the outline of the country, and they make no logical sense. I'm not sure where the landsat images are coming from, but it isn't Taiwan.

Here is a working example:
library(MODIStools)
library(mapview)

NDVI <- mt_subset(product = "VNP13A1",
band = "500_m_16_days_NDVI",
lon = 121.1887,
lat = 23.8963,
km_lr = 20,
km_ab = 100,
start = "2019-01-01",
internal = TRUE,
progress = TRUE)

NDVI_r <- mt_to_raster(df = NDVI)

mapview(NDVI_r[[1]])

use memoise to speed up API calls

Cache results of mt_products(), mt_bands(), mt_sites() and mt_dates() in memory using memoise. This will result in only one call per session instead of multiple ones when running mt_subset().

HTTP Error 500 with mt_batch_subset

Hi,

I have tried to access mt_batch_subset(), but have been recieving the error message
"Error in open.connection(con,'"rb") : HTTP error 500
Error : $ operator is invalid for atomic vectors"

The same issue was observed even with mt_dates.

`df <- data.frame("site_name" = paste("test",1:2))
df$lat <- 40
df$lon <- -110

print(df)

subsets <- mt_batch_subset(df = df,
product = "MOD11A2",
band = "LST_Day_1km",
internal = TRUE,
start = "2004-01-01",
end = "2004-03-31")`

[Above code snippet from https://www.rdocumentation.org/packages/MODISTools/versions/1.1.1/topics/mt_batch_subset]
Can I please know when this issue will be resolved?

The current version of my R is R 4.1.0 and version of MODISTools is 1.1.1

Thank You.

URL issue

Hi!
When I am trying to download MODIS lai data from MODISTools and it seems the URL is broken and I got the following errors when I just use a build-in function:

MODISTools::mt_products()
Error in open.connection(con, "rb") : HTTP error 500.
Error in try(jsonlite::fromJSON(url))$products : 
  $ operator is invalid for atomic vectors

could you help me with that?
Best wishes,
Dongchen

Timeout was reached: [modis.ornl.gov] Connection timed out after 10000 milliseconds

Hi,

I am trying out MODISTools for the first time. Successfully installed from CRAN and added library.

But with MODISTools::mt_products() or MODISTools::mt_bands(), I get:

Error in open.connection(con, "rb") :
Timeout was reached: [modis.ornl.gov] Connection timed out after 10000 milliseconds
Error: $ operator is invalid for atomic vectors

What may be wrong?

I am not behind a VpN and below is my sessionInfo:

R version 4.1.0 (2021-05-18)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 10.16

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] MODISTools_1.1.1 forcats_0.5.1 stringr_1.4.0 dplyr_1.0.7 purrr_0.3.4
[6] readr_2.0.0 tidyr_1.1.3 tibble_3.1.2 ggplot2_3.3.5 tidyverse_1.3.1
[11] lubridate_1.7.10

loaded via a namespace (and not attached):
[1] Rcpp_1.0.7 lattice_0.20-44 assertthat_0.2.1 digest_0.6.27
[5] utf8_1.2.1 R6_2.5.0 cellranger_1.1.0 backports_1.2.1
[9] reprex_2.0.0 evaluate_0.14 httr_1.4.2 pillar_1.6.1
[13] rlang_0.4.11 curl_4.3.2 readxl_1.3.1 rstudioapi_0.13
[17] raster_3.4-13 rmarkdown_2.9 munsell_0.5.0 broom_0.7.8
[21] compiler_4.1.0 modelr_0.1.8 xfun_0.24 pkgconfig_2.0.3
[25] htmltools_0.5.1.1 tidyselect_1.1.1 codetools_0.2-18 fansi_0.5.0
[29] crayon_1.4.1 tzdb_0.1.2 dbplyr_2.1.1 withr_2.4.2
[33] grid_4.1.0 jsonlite_1.7.2 gtable_0.3.0 lifecycle_1.0.0
[37] DBI_1.1.1 pacman_0.5.1 magrittr_2.0.1 scales_1.1.1
[41] ncdf4_1.17 cli_3.0.1 stringi_1.6.2 cachem_1.0.6
[45] fs_1.5.0 sp_1.4-5 xml2_1.3.2 ellipsis_0.3.2
[49] generics_0.1.0 vctrs_0.3.8 tools_4.1.0 glue_1.4.2
[53] hms_1.1.0 fastmap_1.1.0 yaml_2.2.1 colorspace_2.0-1
[57] rvest_1.0.1 memoise_2.0.0 knitr_1.33 haven_2.4.1

I have also tried installing the package from a .tar file from CRAN on my MacOS.
install.packages("~/Downloads/MODISTools_1.1.1.tar")
but then I get:

Installing package into ‘/Users/rutuja/Library/R/x86_64/4.1/library’
(as ‘lib’ is unspecified)
Warning in install.packages :
package ‘~/Downloads/MODISTools_1.1.1.tar’ is not available for this version of R

A version of this package for your version of R might be available elsewhere,
see the ideas at
https://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Installing-packages

Thanks,
Rutuja

Check coordinates mt_to_raster()

Check if coordinates conversions are done properly, hunch that there is a re-projection error. Needs confirmation and checks.

create read_subset() and write_subset() functions

csv format:

# meta data: value
# meta data: value
# meta data: value
# meta data: value
# meta data: value
# 
col, col, col, ...
value, value, value, ...

data frame format:

subset
└─── header
	└─── latitude
	└─── longitude
	└─── ....
└─── subset
	└─── data frame with values

do not issue a stop on get_subset() failure

Corrupts batch downloads for all subsequent sites if in sequential mode.

solution:

  • raise a warning
  • return a NULL values for this 10 value chunk
  • report to header that download was incomplete
  • if all NULL return NULL

Installation issues of MODISTools

I've been trying to install MODISTools and I'm getting this error:

checking GDAL: checking whether PROJ is available fur running:... ERROR 1: PROJ: proj_create_from_database: cannot build geodeticCRS 4326: SQLite error on SELECT name, ellipsoid_auth_name, ellipsoid_code, prime_meridian_auth_name, prime_meridian_code, area_of_use_auth_name, area_of_use_code, publication_date, deprecated FROM geodetic_datum WHERE auth_name = ? AND code = ?: no such column: publication_date
ERROR 1: PROJ: proj_create_from_database: cannot build projectedCRS 3857: cannot build geodeticCRS 4326: SQLite error on SELECT name, ellipsoid_auth_name, ellipsoid_code, prime_meridian_auth_name, prime_meridian_code, area_of_use_auth_name, area_of_use_code, publication_date, deprecated FROM geodetic_datum WHERE auth_name = ? AND code = ?: no such column: publication_date
ERROR 1: PROJ: proj_create: unrecognized format / unknown name
ERROR 6: Cannot find coordinate operations from `' to `'
no
configure: error: OGRCoordinateTransformation() does not return a coord.trans: PROJ not available?
ERROR: configuration failed for package ‘sf’
* removing ‘/home/coralie/R/x86_64-pc-linux-gn

I've checked that I'm using the most up to date version of R and have been installing the package by using the tool inside RStudio. I've also tried opening RStudio in a new virtual environment to test installation without other packages installed.

Someone on Stack Overflow has suggested that this is due to the recent update to PROJ
I've tried to install an older version of PROJ (PROJ 5) but the error has not changed.

Can you help? Thanks!

mt_to_raster function

library(MODISTools)
library(raster)

# Download modis data
LC <- mt_subset(product = "MCD12Q1",
                lat = 48.383662,
                lon = 2.610250,
                band = "LC_Type1",
                start = "2005-01-01",
                end = "2005-12-30",
                km_lr = 10,
                km_ab = 10,
                site_name = "testsite",
                internal = TRUE,
                progress = FALSE)

VI <- mt_subset(product = "MOD13Q1",
                lat = 48.383662,
                lon = 2.610250,
                band = "250m_16_days_NDVI",
                start = "2005-01-01",
                end = "2005-12-31",
                km_lr = 10,
                km_ab = 10,
                site_name = "testsite",
                internal = TRUE,
                progress = FALSE)

QA <- mt_subset(product = "MOD13Q1",
                lat = 48.383662,
                lon = 2.610250,
                band = "250m_16_days_pixel_reliability",
                start = "2005-01-01",
                end = "2005-12-31",
                km_lr = 10,
                km_ab = 10,
                site_name = "testsite",
                internal = TRUE,
                progress = FALSE)

mt_to_raster <- function(df = subset){

  # find unique dates for which data should exist
  dates <- unique(df$calendar_date)

  # convert scale to 1 if not available
  # should not change the numeric value of a band
  df$scale[df$scale == "Not Available"] <- 1

  # loop over all dates, format rasters and return
  r <- do.call("stack",
    lapply(dates, function(date){

     # stuff values into raster
     m <- matrix(df$value[df$calendar_date == date] *
                   as.numeric(df$scale[df$calendar_date == date]),
                df$nrows[1],
                df$ncols[1],
                byrow = TRUE)

     # convert to raster and return
     return(raster(m))
    })
   )

  # get bounding box
  bb <- mt_bbox(
    xllcorner = df$xllcorner[1],
    yllcorner = df$yllcorner[1],
    cellsize = df$cellsize[1],
    nrows = df$nrows[1],
    ncols = df$ncols[1])

  # convert to Spatial object (easier to get extent)
  bb <- as(bb, 'Spatial')

  # assign extent + projection bb to raster
  extent(r) <- extent(bb)
  projection(r) <- projection(bb)
  names(r) <- as.character(dates)

  # return the data
  return(r)
}

# convert df to raster
VI_r <- mt_to_raster(df = VI)
QA_r <- mt_to_raster(df = QA)
LC_r <- mt_to_raster(df = LC)

# upsample due to lower resolution
LC_r_2x <- resample(LC_r, QA_r, method = "ngb")

# create mask on pixel reliability flag
m <- (QA_r < 0 | QA_r > 1 )

# create land cover mask
lc_m <- !(LC_r_2x == 4 | LC_r_2x == 5)

# combine both masks
VI_m <- mask(VI_r, m, maskvalue = 1)
VI_m <- mask(VI_r, lc_m, maskvalue = 1)

# plot masked data combining pixel quality
# and showing deciduous and mixed forest pixels
# only (for the Fontainbleau forest area)
par(oma= rep(4,4))
plot(VI_r, zlim = c(0,1))
plot(VI_m, zlim = c(0,1))

original data

Screenshot from 2019-03-13 14-34-15

masked values

Screenshot from 2019-03-13 15-36-50

Conversion from sinusoidal lower-left corner to lon lat

I suspect there is something wrong with the conversion from sinusoidal to angular. I'm not familiar with the sinusoidal projection, but I would suspect that the conversion using a constant is inacurate. https://github.com/khufkens/MODISTools/blob/1adc07bd8572454bf52ba629c7cf686c60e1398b/R/coordinate_conversion.R#L108

I think a safer approach would be to build the footprint from longitude latitude. Otherwise having a few tests with different locations across latitudes would convince me :)

It would also be good to document the origin of the MODIS coordinate system parameters.
https://github.com/khufkens/MODISTools/blob/1adc07bd8572454bf52ba629c7cf686c60e1398b/R/coordinate_conversion.R#L36-L40

ropensci/software-review#246

There is no MODISSummaries() to use QA band

Hello, I want to use QA band to constraint pixel value. But no MODISSummaries() was found in MODISTools package, that was described in the paper of " MODISTools -- downloading and processing MODIS remotely sensed data in R". In addition, the mt_batch_subset() can not download two bands at the same time.
QQ截图20200909100301

Error using mt_bach_subset

Hello!

I'm trying to use the mt_bach_subset function, but I only got this error:
Error in checkForRemoteErrors(val) :
I installed the package in various R versions (3.5.3, 3.6.0, 4.05), but every time I run this function I get the same Error.
I think this error could be because of my R configuration, but I can't find the solution.

Cheers,
Bere

Interpreting QC

I didn't find much useful information for how to interpret the quality control information accessible through MODISTools downloads of respective bands. I wrote the following code (see also here for MOD13Q1 and here for MCD15A3H). I thought I post it here not as an actual "issue", and also not as an definite instruction for others, but rather as a call for others to point out possible errors or misinterpretations here. (I hard-coded a qc-flag-based filtering in the ingestr package, which provides yet another wrapper around MODISTools and more, see here).

For MCD15A3H (band FparLai_QC) interpreted according to this document:

df <- df %>%

      ## separate into bits
      rowwise() %>%
      mutate(qc_bitname = intToBits( qc )[1:8] %>% rev() %>% as.character() %>% paste(collapse = "")) %>%

      ## MODLAND_QC bits
      ## 0: Good  quality (main algorithm with or without saturation)
      ## 1: Other quality (backup  algorithm or fill values)
      mutate(qc_bit0 = substr( qc_bitname, start=8, stop=8 )) %>%
      mutate(good_quality = ifelse( qc_bit0=="0", TRUE, FALSE )) %>%

      ## Sensor
      ## 0: Terra
      ## 1: Aqua
      mutate(qc_bit1 = substr( qc_bitname, start=7, stop=7 )) %>%
      mutate(terra = ifelse( qc_bit1=="0", TRUE, FALSE )) %>%

      ## Dead detector
      ## 0: Detectors apparently  fine  for up  to  50% of  channels  1,  2
      ## 1: Dead  detectors caused  >50%  adjacent  detector  retrieval
      mutate(qc_bit2 = substr( qc_bitname, start=6, stop=6 )) %>%
      mutate(dead_detector = ifelse( qc_bit2=="1", TRUE, FALSE )) %>%

      ## CloudState
      ## 00 0  Significant clouds  NOT present (clear)
      ## 01 1  Significant clouds  WERE  present
      ## 10 2  Mixed cloud present in  pixel
      ## 11 3  Cloud state not defined,  assumed clear
      mutate(qc_bit3 = substr( qc_bitname, start=4, stop=5 )) %>%
      mutate(CloudState = ifelse( qc_bit3=="00", 0, ifelse( qc_bit3=="01", 1, ifelse( qc_bit3=="10", 2, 3 ) ) )) %>%

      ## SCF_QC (five level confidence score)
      ## 000 0 Main (RT) method used, best result possible (no saturation)
      ## 001 1 Main (RT) method used with saturation. Good, very usable
      ## 010 2 Main (RT) method failed due to bad geometry, empirical algorithm used
      ## 011 3 Main (RT) method failed due to problems other than geometry, empirical algorithm used
      ## 100 4 Pixel not produced at all, value couldn???t be retrieved (possible reasons: bad L1B data, unusable MOD09GA data)
      mutate(qc_bit4 = substr( qc_bitname, start=1, stop=3 )) %>%
      mutate(SCF_QC = ifelse( qc_bit4=="000", 0, ifelse( qc_bit4=="001", 1, ifelse( qc_bit4=="010", 2, ifelse( qc_bit4=="011", 3, 4 ) ) ) ))

And for MOD13Q1 (band 250m_16_days_VI_Quality) based on this document:

df <- df %>%

      ## separate into bits
      rowwise() %>%
      mutate(qc_bitname = intToBits( qc ) %>% as.character() %>% paste(collapse = "")) %>%

      ## Bits 0-1: VI Quality
      ##   00 VI produced with good quality
      ##   01 VI produced, but check other QA
      mutate(vi_quality = substr( qc_bitname, start=1, stop=2 )) %>%

      ## Bits 2-5: VI Usefulness
      ##   0000 Highest quality
      ##   0001 Lower quality
      ##   0010 Decreasing quality
      ##   0100 Decreasing quality
      ##   1000 Decreasing quality
      ##   1001 Decreasing quality
      ##   1010 Decreasing quality
      ##   1100 Lowest quality
      ##   1101 Quality so low that it is not useful
      ##   1110 L1B data faulty
      ##   1111 Not useful for any other reason/not processed
      mutate(vi_useful = substr( qc_bitname, start=3, stop=6 )) %>%

      ## Bits 6-7: Aerosol Quantity
      ##  00 Climatology
      ##  01 Low
      ##  10 Intermediate
      ##  11 High
      mutate(aerosol = substr( qc_bitname, start=7, stop=8 )) %>%

      ## Bit 8: Adjacent cloud detected
      ##  0 No
      ##  1 Yes
      mutate(adjcloud = substr( qc_bitname, start=9, stop=9 )) %>%

      ## Bits 9: Atmosphere BRDF Correction
      ##   0 No
      ##   1 Yes
      mutate(brdf_corr = substr( qc_bitname, start=10, stop=10 )) %>%

      ## Bits 10: Mixed Clouds
      ##   0 No
      ##   1 Yes
      mutate(mixcloud = substr( qc_bitname, start=11, stop=11 )) %>%

      ## Bits 11-13: Land/Water Mask
      ##  000 Shallow ocean
      ##  001 Land (Nothing else but land)
      ##  010 Ocean coastlines and lake shorelines
      ##  011 Shallow inland water
      ##  100 Ephemeral water
      ##  101 Deep inland water
      ##  110 Moderate or continental ocean
      ##  111 Deep ocean
      mutate(mask = substr( qc_bitname, start=12, stop=14 )) %>%

      ## Bits 14: Possible snow/ice
      ##  0 No
      ##  1 Yes
      mutate(snowice = substr( qc_bitname, start=15, stop=15 )) %>%

      ## Bits 15: Possible shadow
      ##  0 No
      ##  1 Yes
      mutate(shadow = substr( qc_bitname, start=16, stop=16 ))

Here df is a data frame with column qc containing integers downloaded as the respective QC band.

A little question, thanks for your review

m <- c(as.numeric(cellsize) * as.numeric(ncols),
as.numeric(cellsize) * as.numeric(nrows)) * trans +
c(as.numeric(xllcorner), as.numeric(yllcorner))
m <- matrix(m, 5, 2, byrow = TRUE)

     This is an amazing and novel design, while my question is this codes would product the boundary of the total data, and how can we get the specific boundary of each   block (or one little cell). 

Getting several NAs

Hi:

Thanks for your package. It is the most straightforward one related to MODIS (to my taste)
I am trying to get Land surface temperature data from Modis 11A2. I succeed, nevertheless, I am getting too many NAs. I leave an example model where the first week of temperatures is basically NAs. Is this a data issue, script issue, or package issue. I was hoping I could get your feedback . Best and thank you for your answer and time on this.

D.


library(MODISTools) # https://github.com/ropensci/MODISTools; https://mran.microsoft.com/snapshot/2014-11-17/web/packages/MODISTools/vignettes/UsingMODISTools.pdf
library(sf)
library(lubridate)
library(rgeos)

data.points=data.frame(lat=c(41,42), lon=c(-77, -75), date=c("2004-02-17", "2004-02-17"))

day.surface.temp.before.sampling=60 # gettin data from X days weeks before the sampling of mosquitoes

data.to.download="MOD11A2"

LST=vector(mode="list", length = nrow(data.points))

for(i in nrow(data.points)){

# Download some test data. FAST
dat <- mt_subset(product = data.to.download,
                    lat = data.points$lat[i],
                    lon = data.points$lon[i],
                    band = "LST_Day_1km",
                    start = as.Date(data.points$date[i])-60, #"2004-01-01",
                    end = as.Date(data.points$date[i]),
                    km_lr = 10,
                    km_ab = 10,
                    progress = FALSE)  



# convert sinusoidal to lat / lon
lat_lon <- sin_to_ll(dat$xllcorner, dat$yllcorner)

# bind with the original dataframe
dat <- cbind(dat, lat_lon)

# convert to bounding box
bb <- apply(dat, 1, function(x){
  mt_bbox(xllcorner = x['xllcorner'],
          yllcorner = x['yllcorner'],
          cellsize = x['cellsize'],
          nrows = x['nrows'],
          ncols = x['ncols'])
})


# tile found correspond to this map.
#https://modis-land.gsfc.nasa.gov/MODLAND_grid.html
# unique(dat$tile)

# plot(PA)
# plot(spTransform(as_Spatial(bb[[1]]), CRSobj = crs(PA)), col="coral", add=T)


# Convert tidy MODISTools data to a raster (stack). Fast

#change NA values, in this case labelled with zero, to actually NA
dat$value[dat$value==0]<-NA

# fixing the vaues to become celcius
dat$value[!(is.na(dat$value))]=dat$value[!(is.na(dat$value))]*as.numeric(unique(dat$scale))-273.15

surf.temperature.raster.stack=mt_to_raster(dat, reproject = F)


#check point

# temp.spatial.point=SpatialPoints(data.points[1,2:1], proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs"))
# 
# plot(x=surf.temperature.raster.stack, y=3) # plot the first layer (first day of temperature)
# 
# plot(spTransform(temp.spatial.point, CRSobj = crs(surf.temperature.raster.stack)), add=T, col="red", cex=30)
# 
# plot(gBuffer(spgeom = spTransform(temp.spatial.point, CRSobj = crs(surf.temperature.raster.stack)), width = 1000), 
#      col="blue", add=T)     




# Finally extract the temp values 1 km around. 

temp.spatial.point=SpatialPoints(data.points[i,2:1], proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs"))

temp.buffer=gBuffer(spgeom = spTransform(temp.spatial.point, CRSobj = crs(surf.temperature.raster.stack)), width = 1000)


LST[[i]]=vector(mode = "list", length = dim(surf.temperature.raster.stack)[3])


for(y in 1:dim(surf.temperature.raster.stack)[3]){

LST[[i]][[y]]=raster::extract(subset(surf.temperature.raster.stack, y, drop=F),
                temp.buffer, weights=TRUE,  df=T)

}
}

progress = TRUE not showing progress bar

I have been using the package over the last week without much issue. However, after running a few queries today, the progress = TRUE argument in the mt_subset() function appears not to function. I get the red "loading" button, but no progress bar in the console.

Any idea what could be going on?

validate_key() function error

Hi all,
with the upgrade in MODISTools, and maybe in R 4.0.5 there appears to be an issue with MODISTools::mt_products()

The error appears to be related to the cachem package, but I am not sure. The real error is in relation to a function validate_key(), but I am not sure where that originates.

The error is:

products <- mt_products()
Warning: namespace ‘cachem’ is not available and has been replaced
by .GlobalEnv when processing object ‘’
Error in validate_key(key) : could not find function "validate_key"

I am running R 4.0.2 rather than 4.05, and I will test later if that might be the issue, but I would think that is far-fetched.

There is an unanswered stackoverflow question about this from 1 month ago: https://stackoverflow.com/questions/66852295/could-not-find-function-validate-key-using-modistools-in-r

sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)

Matrix products: default

Random number generation:
RNG: Mersenne-Twister
Normal: Inversion
Sample: Rounding

locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] MODISTools_1.1.1 lubridate_1.7.9 forcats_0.5.1 stringr_1.4.0
[5] dplyr_1.0.4 purrr_0.3.4 tidyr_1.1.2 tibble_3.1.0
[9] ggplot2_3.3.3 tidyverse_1.3.0 readr_1.4.0

loaded via a namespace (and not attached):
[1] tidyselect_1.1.0 xfun_0.21 lattice_0.20-41 haven_2.3.1
[5] colorspace_2.0-0 vctrs_0.3.6 generics_0.1.0 htmltools_0.5.1.1
[9] yaml_2.2.1 utf8_1.1.4 blob_1.2.1 rlang_0.4.10
[13] pillar_1.5.0 glue_1.4.2 withr_2.4.1 DBI_1.1.0
[17] sp_1.4-5 dbplyr_1.4.4 modelr_0.1.8 readxl_1.3.1
[21] lifecycle_1.0.0 munsell_0.5.0 gtable_0.3.0 cellranger_1.1.0
[25] raster_3.3-13 rvest_0.3.6 codetools_0.2-16 memoise_1.1.0
[29] evaluate_0.14 labeling_0.4.2 knitr_1.31 fastmap_1.0.1
[33] fansi_0.4.2 broom_0.7.5 Rcpp_1.0.6 scales_1.1.1
[37] backports_1.2.1 jsonlite_1.7.2 farver_2.1.0 fs_1.5.0
[41] hms_1.0.0 digest_0.6.27 stringi_1.5.3 grid_4.0.2
[45] cli_2.3.1 tools_4.0.2 magrittr_2.0.1 crayon_1.4.1
[49] pkgconfig_2.0.3 ellipsis_0.3.1 xml2_1.3.2 reprex_0.3.0
[53] assertthat_0.2.1 rmarkdown_2.3 httr_1.4.2 rstudioapi_0.13
[57] R6_2.5.0 compiler_4.0.2

mt_to_terra reproject does not work as expected

When using reproject = T, which transfers to 4326 the image is still slanted, with no square pixels as I would expect after a reproject.
I compared the results obtained by the former MRT tool (now HEG) and I guess it might by an issue with the underlying terra::project not recognising the sinusoidal projection correctly?

Cannot get data by using this library

Hi, I have problems by using this library. About one month ago, I can use this lib to get data, but today when I use this lib, I cannot get data, even use the example in the document. The function mt_products() and mt_bands() are ok, but the mt_subset() is not. I used the example in the document:
subset <- mt_subset(product = "MOD11A2", lat = 40, lon = -110, band = "LST_Day_1km", start = "2004-01-01", end = "2004-03-31", progress = FALSE)
I cannot get the response data. Can you help? Thanks.

Error in open.connection when running mt_subset

Error occurs when running code from documentation. Happens in both development version and cran version.

subset <- mt_subset(product = "MOD11A2",

  •                 lat = 40,
    
  •                 lon = -110,
    
  •                 band = "LST_Day_1km",
    
  •                 start = "2004-01-01",
    
  •                 end = "2004-03-31",
    
  •                 progress = FALSE)
    

Error in open.connection(con, "rb") : HTTP error 500.
Error: $ operator is invalid for atomic vectors

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.