Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre-release 1.4.2-1 #1033

Merged
merged 15 commits into from
Nov 2, 2023
Merged
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: sits
Type: Package
Version: 1.4.2
Version: 1.4.2-1
Title: Satellite Image Time Series Analysis for Earth Observation Data Cubes
Authors@R: c(person('Rolf', 'Simoes', role = c('aut'), email = 'rolf.simoes@inpe.br'),
person('Gilberto', 'Camara', role = c('aut', 'cre'), email = 'gilberto.camara.inpe@gmail.com'),
Expand Down Expand Up @@ -36,7 +36,7 @@ Description: An end-to-end toolkit for land use and land cover classification
Minimum recommended requirements: 16 GB RAM and 4 CPU dual-core.
Encoding: UTF-8
Language: en-US
Depends: R (>= 4.1.0)
Depends: R (>= 4.0.0)
URL: https://github.com/e-sensing/sits/, https://e-sensing.github.io/sitsbook/
BugReports: https://github.com/e-sensing/sits/issues
License: GPL-2
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

# What's new in SITS version 1.4

### Hotfix version 1.4.2-1
* Fix crs bug in `sits_apply()`
* Update file name in clean feature
* Fix time series extraction bug with segments
* Fix examples

### New features in SITS version 1.4.2
* Support for vector data cubes, including visualisation
* Object-based time series analysis using spatio-temporal segmentation
Expand Down
22 changes: 4 additions & 18 deletions R/api_clean.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,9 @@
output_dir,
version) {
# Output file
out_file <- .file_clean_name(
tile = tile, band = band,
version = version, output_dir = output_dir
out_file <- .file_derived_name(
tile = tile, band = band, version = version, output_dir = output_dir
)
# Resume asset
if (.raster_is_valid(out_file, output_dir = output_dir)) {
# recovery message
.check_recovery(out_file)
# Create tile based on template
tile <- .tile_derived_from_file(
file = out_file, band = band,
base_tile = tile, derived_class = .tile_derived_class(tile),
labels = .tile_labels(tile),
update_bbox = FALSE
)
return(tile)
}
# Remove remaining incomplete files
unlink(out_file)
# Create chunks as jobs
chunks <- .tile_chunks_create(
tile = tile, overlap = overlap, block = block
Expand Down Expand Up @@ -88,6 +72,8 @@
# Returned block files for each fraction
block_files
})
# Remove raster without clean
unlink(.tile_path(tile))
# Merge blocks into a new class_cube tile
band_tile <- .tile_derived_merge_blocks(
file = out_file,
Expand Down
16 changes: 0 additions & 16 deletions R/api_file.R
Original file line number Diff line number Diff line change
Expand Up @@ -119,22 +119,6 @@
)
}

#' @title Build a file path for a cleaned map (used in sits_clean)
#' @noRd
#' @param tile Tile of data cube
#' @param band Spectral band
#' @param version Version name
#' @param output_dir Directory where file will be saved
#' @returns File path for derived cleaned map
.file_clean_name <- function(tile, band, version, output_dir) {
.file_path(
tile[["satellite"]], tile[["sensor"]], .tile_name(tile),
.tile_start_date(tile), .tile_end_date(tile), band,
paste(version, "clean", sep = "-"),
ext = "tif", output_dir = output_dir
)
}

#' @title Build a file path for a mosaic
#' @noRd
#' @param tile Tile of data cube
Expand Down
5 changes: 4 additions & 1 deletion R/api_file_info.R
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ NULL
#' @param xmax largest X coordinate
#' @param ymin smallest Y coordinate
#' @param ymax largest Y coordinate
#' @param crs coordinate reference system
#' @param path location of the data
#' @returns eo_cube tibble
.fi_eo <- function(fid, band, date, ncols, nrows, xres, yres, xmin, xmax,
ymin, ymax, path) {
ymin, ymax, crs, path) {
# Create a new eo file_info
tibble::tibble(
fid = fid,
Expand All @@ -74,6 +75,7 @@ NULL
xmax = xmax,
ymin = ymin,
ymax = ymax,
crs = crs,
path = path
)
}
Expand All @@ -99,6 +101,7 @@ NULL
xmax = .raster_xmax(r_obj),
ymin = .raster_ymin(r_obj),
ymax = .raster_ymax(r_obj),
crs = .raster_crs(r_obj),
path = files
)
}
Expand Down
13 changes: 0 additions & 13 deletions R/api_label_class.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,6 @@
out_file <- .file_derived_name(
tile = tile, band = band, version = version, output_dir = output_dir
)
# Resume feature
if (file.exists(out_file)) {
.check_recovery(tile[["tile"]])
class_tile <- .tile_derived_from_file(
file = out_file,
band = band,
base_tile = tile,
derived_class = "class_cube",
labels = .tile_labels(tile),
update_bbox = FALSE
)
return(class_tile)
}
# Create chunks as jobs
chunks <- .tile_chunks_create(tile = tile, overlap = 0)
# Process jobs in parallel
Expand Down
19 changes: 13 additions & 6 deletions R/api_segments.R
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,13 @@
time_series = c("Index", dplyr::all_of(bands)))
# include the ids of the polygons
ts_bands[["polygon_id"]] <- pol_id
# we do the unnest again because we do not know the polygon id index
ts_bands <- tidyr::unnest(ts_bands, "time_series")
# remove pixels where all timeline was NA
ts_bands <- tidyr::drop_na(ts_bands)
# nest the values by bands
ts_bands <- tidyr::nest(ts_bands,
time_series = c("Index", dplyr::all_of(bands)))
# nest the values by sample_id and time_series
ts_bands <- tidyr::nest(ts_bands, points = c("sample_id", "time_series"))
# retrieve the segments
Expand Down Expand Up @@ -418,12 +425,12 @@
output_dir = output_dir)
samples <- purrr::map(seg_tile_bands_lst, function(seg_tile_bands){
samples_part <- .segments_extract_data(seg_tile_bands,
tile,
bands,
pol_id,
n_sam_pol,
multicores,
progress)
tile,
bands,
pol_id,
n_sam_pol,
multicores,
progress)
return(samples_part)
})
samples <- dplyr::bind_rows(samples)
Expand Down
2 changes: 1 addition & 1 deletion R/api_tile.R
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,7 @@ NULL
#' @param derived_class class of the derived tile
#' @param block_files files that host the blocks
#' @param multicores number of parallel processes
#' @param update_bbox should bbox be updated?
#' @param update_bbox should bbox be updated?
#' @return a new tile with files written
.tile_derived_merge_blocks <- function(file, band, labels, base_tile,
derived_class, block_files, multicores,
Expand Down
8 changes: 8 additions & 0 deletions R/sits_apply.R
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ sits_apply.raster_cube <- function(data, ...,
# Get output band expression
expr <- .apply_capture_expression(...)
out_band <- names(expr)
# Check if band already exists in cube
if (out_band %in% .cube_bands(data)) {
warning(
paste0("The provided band '", out_band, "' already exists in cube."),
call. = FALSE
)
return(data)
}
# Get all input bands in cube data
in_bands <- .apply_input_bands(data, expr = expr)

Expand Down
6 changes: 4 additions & 2 deletions R/sits_classify.R
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,16 @@
#' ml_model = rf_model,
#' output_dir = tempdir(),
#' n_sam_pol = 20,
#' multicores = 4
#' multicores = 4,
#' version = "segs_classify"
#' )
#' # Create a labelled vector cube
#' class_segs <- sits_label_classification(
#' cube = probs_segs,
#' output_dir = tempdir(),
#' multicores = 2,
#' memsize = 4
#' memsize = 4,
#' version = "segs_classify"
#' )
#' # plot class_segs
#' plot(class_segs)
Expand Down
21 changes: 18 additions & 3 deletions R/sits_label_classification.R
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,24 @@ sits_label_classification.probs_cube <- function(cube, ...,
label_fn <- .label_fn_majority()
# Process each tile sequentially
class_cube <- .cube_foreach_tile(cube, function(tile) {
# Output file
out_file <- .file_derived_name(
tile = tile, band = "class", version = version,
output_dir = output_dir
)
# Resume feature
if (file.exists(out_file)) {
.check_recovery(tile[["tile"]])
class_tile <- .tile_derived_from_file(
file = out_file,
band = "class",
base_tile = tile,
derived_class = "class_cube",
labels = .tile_labels(tile),
update_bbox = FALSE
)
return(class_tile)
}
# Label the data
class_tile <- .label_tile(
tile = tile,
Expand All @@ -129,7 +147,6 @@ sits_label_classification.probs_cube <- function(cube, ...,
version = version,
progress = progress
)
label_path <- .tile_path(class_tile)
if (clean) {
# Apply clean in data
class_tile <- .clean_tile(
Expand All @@ -141,8 +158,6 @@ sits_label_classification.probs_cube <- function(cube, ...,
output_dir = output_dir,
version = version
)
# Remove raster file without clean
unlink(label_path)
}
return(class_tile)
})
Expand Down
2 changes: 0 additions & 2 deletions R/sits_plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -1380,8 +1380,6 @@ plot.som_map <- function(x, y, ..., type = "codes", band = 1) {
#' xgb_model <- sits_train(samples_modis_ndvi,
#' ml_method = sits_xgboost()
#' )
#' # plot the model
#' plot(xgb_model)
#' }
#' @export
#'
Expand Down
4 changes: 3 additions & 1 deletion R/sits_sample_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ sits_reduce_imbalance <- function(samples,
)
new_samples <- dplyr::bind_rows(new_samples, samples_classes_ok)
}
# remove SOM additional columns
colnames_sits <- setdiff(colnames(new_samples), c("id_neuron", "id_sample"))
# return new sample set
return(new_samples)
return(new_samples[, colnames_sits])
}
9 changes: 6 additions & 3 deletions R/sits_segmentation.R
Original file line number Diff line number Diff line change
Expand Up @@ -209,20 +209,23 @@ sits_segment <- function(cube,
#' # segment the vector cube
#' segments <- sits_segment(
#' cube = cube,
#' output_dir = tempdir()
#' output_dir = tempdir(),
#' version = "slic-demo"
#' )
#' # create a classification model
#' rfor_model <- sits_train(samples_modis_ndvi, sits_rfor())
#' # classify the segments
#' seg_probs <- sits_classify(
#' data = segments,
#' ml_model = rfor_model,
#' output_dir = tempdir()
#' output_dir = tempdir(),
#' version = "slic-demo"
#' )
#' # label the probability segments
#' seg_label <- sits_label_classification(
#' cube = seg_probs,
#' output_dir = tempdir()
#' output_dir = tempdir(),
#' version = "slic-demo"
#' )
#' }
#' @export
Expand Down
22 changes: 16 additions & 6 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,16 @@ devtools::install_github("e-sensing/sits", dependencies = TRUE)
library(sits)
```

### Support for GPU

Classification using torch-based deep learning models in `sits` uses CUDA compatible NVIDIA GPUs if available, which provides up 10-fold speed-up compared to using CPUs only. Please see the [installation instructions](https://torch.mlverse.org/docs/articles/installation) for more information on how to install the required drivers.


## Building Earth Observation Data Cubes

### Image Collections Accessible by `sits`

The `sits` package allows users to created data cubes from analysis-ready data (ARD) image collections available in cloud services. The collections accessible in `sits` `r packageVersion("sits")` are:
Users create data cubes from analysis-ready data (ARD) image collections available in cloud services. The collections accessible in `sits` `r packageVersion("sits")` are:

1. Brazil Data Cube ([BDC](http://brazildatacube.org/en/home-page-2/#dataproducts)): Open data collections of Sentinel-2, Landsat-8 and CBERS-4 images.
2. Microsoft Planetary Computer ([MPC](https://planetarycomputer.microsoft.com/catalog)): Open data collection of Sentinel-2/2A and Landsat-8
Expand Down Expand Up @@ -273,7 +277,9 @@ plot(label_cube,

## Additional information

For more information, please see the on-line book ["SITS: Data analysis and machine learning for data cubes using satellite image time series"](https://e-sensing.github.io/sitsbook/).
Since version 1.4.2, `sits` support OBIA analysis of image time series, using an extension of R package `supercells`.

The package is described in detail in on-line book ["SITS: Data analysis and machine learning for data cubes using satellite image time series"](https://e-sensing.github.io/sitsbook/).


### References
Expand Down Expand Up @@ -314,11 +320,15 @@ We thank the authors of these papers for making their code available to be used

- [12] Maja Schneider, Marco Körner, "[Re] Satellite Image Time Series Classification with Pixel-Set Encoders and Temporal Self-Attention." ReScience C 7 (2), 2021. <doi:10.5281/zenodo.4835356>.

#### R packages used in sits
- [13] Jakub Nowosad, Tomasz Stepinski, "Extended SLIC superpixels algorithm for applications to non-imagery geospatial rasters". International Journal of Applied Earth Observation and Geoinformation, 112, 102935, 2022.

- [14] Martin Tennekes, “tmap: Thematic Maps in R.” Journal of Statistical Software, 84(6), 1–39, 2018.

### Acknowledgements for community support

The authors are thankful for the contributions of Marius Appel, Tim Appelhans, Henrik Bengtsson, Robert Hijmans, Edzer Pebesma, and Ron Wehrens, respectively chief developers of the packages `gdalcubes`, `leafem`, `data.table`, `terra/raster`, `sf`/`stars`, and `kohonen`. The `sits` package is also much indebted to the work of the RStudio team, including the `tidyverse`. We are indepted to Daniel Falbel for his and the `torch` packages. We thank Charlotte Pelletier and Hassan Fawaz for sharing the python code that has been reused for the TempCNN and ResNet machine learning models. We would like to thank Maja Schneider for sharing the python code that helped the implementation of the `sits_lighttae()` and `sits_tae()` model. We recognise the importance of the work by Chris Holmes and Mattias Mohr on the STAC specification and API.
The authors are thankful for the contributions of Edzer Pebesma, Jakub Novosad. Marius Appel, Martin Tennekes, Robert Hijmans, Ron Wehrens, and Tim Appelhans, respectively chief developers of the packages `sf`/`stars`, `supercells`, `gdalcubes`, `tmap`, `terra`, `kohonen`, and `leafem`. The `sits` package is also much indebted to the work of the RStudio team, including the `tidyverse`. We are indepted to Daniel Falbel for his great work in the `torch` and `luz` packages. We thank Charlotte Pelletier and Hassan Fawaz for sharing the python code that has been reused for the TempCNN and ResNet machine learning models. We would like to thank Maja Schneider for sharing the python code that helped the implementation of the `sits_lighttae()` and `sits_tae()` model. We recognise the importance of the work by Chris Holmes and Mattias Mohr on the STAC specification and API.

## Acknowledgements for Financial and Material Support
### Acknowledgements for Financial and Material Support

We acknowledge and thank the project funders that provided financial and material support:

Expand All @@ -336,7 +346,7 @@ We acknowledge and thank the project funders that provided financial and materia
funding from the European Union's Horizon Europe research and innovation programme
under [grant agreement No. 101059548](https://cordis.europa.eu/project/id/101059548).

## How to contribute
### How to contribute

The `sits` project is released with a [Contributor Code of Conduct](https://github.com/e-sensing/sits/blob/master/CODE_OF_CONDUCT.md).
By contributing to this project, you agree to abide by its terms.
Loading