Skip to content

Commit 1a10b12

Browse files
Merge pull request #1166 from OldLipe/feat/dev-sits
Adjust base cube classification to extract time series using block strategy
2 parents 58f4bfe + 0d17250 commit 1a10b12

15 files changed

+147
-101
lines changed

NAMESPACE

-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ S3method(sits_apply,raster_cube)
325325
S3method(sits_apply,sits)
326326
S3method(sits_as_sf,raster_cube)
327327
S3method(sits_as_sf,sits)
328-
S3method(sits_bands,base_raster_cube)
329328
S3method(sits_bands,default)
330329
S3method(sits_bands,patterns)
331330
S3method(sits_bands,raster_cube)

R/api_check.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -1766,7 +1766,7 @@
17661766
n_bands <- length(.samples_bands.sits(samples))
17671767
n_times <- length(.samples_timeline(samples))
17681768
if(inherits(samples, "sits_base"))
1769-
n_bands_base <- length(.samples_bands_base(samples))
1769+
n_bands_base <- length(.samples_base_bands(samples))
17701770
else
17711771
n_bands_base <- 0
17721772
.check_that(ncol(pred) == 2 + n_bands * n_times + n_bands_base)

R/api_classify.R

+31-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#' in the classified images for each corresponding year.
1818
#'
1919
#' @param tile Single tile of a data cube.
20-
#' @param band Band to be produced.
20+
#' @param out_band Band to be produced.
21+
#' @param bands Bands to extract time series
22+
#' @param base_bands Base bands to extract values
2123
#' @param ml_model Model trained by \code{\link[sits]{sits_train}}.
2224
#' @param block Optimized block to be read into memory.
2325
#' @param roi Region of interest.
@@ -29,7 +31,9 @@
2931
#' @param progress Show progress bar?
3032
#' @return List of the classified raster layers.
3133
.classify_tile <- function(tile,
32-
band,
34+
out_band,
35+
bands,
36+
base_bands,
3337
ml_model,
3438
block,
3539
roi,
@@ -42,7 +46,7 @@
4246
# Output file
4347
out_file <- .file_derived_name(
4448
tile = tile,
45-
band = band,
49+
band = out_band,
4650
version = version,
4751
output_dir = output_dir
4852
)
@@ -53,7 +57,7 @@
5357
}
5458
probs_tile <- .tile_derived_from_file(
5559
file = out_file,
56-
band = band,
60+
band = out_band,
5761
base_tile = tile,
5862
labels = .ml_labels_code(ml_model),
5963
derived_class = "probs_cube",
@@ -105,7 +109,8 @@
105109
values <- .classify_data_read(
106110
tile = tile,
107111
block = block,
108-
bands = .ml_bands(ml_model),
112+
bands = bands,
113+
base_bands = base_bands,
109114
ml_model = ml_model,
110115
impute_fn = impute_fn,
111116
filter_fn = filter_fn
@@ -138,7 +143,7 @@
138143
# Prepare probability to be saved
139144
band_conf <- .conf_derived_band(
140145
derived_class = "probs_cube",
141-
band = band
146+
band = out_band
142147
)
143148
offset <- .offset(band_conf)
144149
if (.has(offset) && offset != 0) {
@@ -181,7 +186,7 @@
181186
# Merge blocks into a new probs_cube tile
182187
probs_tile <- .tile_derived_merge_blocks(
183188
file = out_file,
184-
band = band,
189+
band = out_band,
185190
labels = .ml_labels_code(ml_model),
186191
base_tile = tile,
187192
block_files = block_files,
@@ -374,11 +379,12 @@
374379
#' @param tile Input tile to read data.
375380
#' @param block Bounding box in (col, row, ncols, nrows).
376381
#' @param bands Bands to extract time series
382+
#' @param base_bands Base bands to extract values
377383
#' @param ml_model Model trained by \code{\link[sits]{sits_train}}.
378384
#' @param impute_fn Imputation function
379385
#' @param filter_fn Smoothing filter function to be applied to the data.
380386
#' @return A matrix with values for classification.
381-
.classify_data_read <- function(tile, block, bands,
387+
.classify_data_read <- function(tile, block, bands, base_bands,
382388
ml_model, impute_fn, filter_fn) {
383389
# For cubes that have a time limit to expire (MPC cubes only)
384390
tile <- .cube_token_generator(tile)
@@ -388,7 +394,7 @@
388394
tile = tile,
389395
block = block
390396
)
391-
# Read and preprocess values of each band
397+
# Read and preprocess values of each eo band
392398
values <- purrr::map(bands, function(band) {
393399
# Get band values (stops if band not found)
394400
values <- .tile_read_block(
@@ -436,9 +442,23 @@
436442
# Return values
437443
return(as.data.frame(values))
438444
})
445+
# Read and preprocess values of each base band
446+
values_base <- purrr::map(base_bands, function(band) {
447+
# Read and preprocess values of each base band
448+
values_base <- .tile_read_block(
449+
tile = .tile_base_info(tile),
450+
band = band,
451+
block = block
452+
)
453+
# Return values
454+
return(as.data.frame(values_base))
455+
})
456+
# Combine two lists
457+
values <- c(values, values_base)
439458
# collapse list to get data.frame
440-
values <- suppressMessages(purrr::list_cbind(values,
441-
name_repair = "universal"))
459+
values <- suppressMessages(
460+
purrr::list_cbind(values, name_repair = "universal")
461+
)
442462
# Compose final values
443463
values <- as.matrix(values)
444464
# Set values features name

R/api_cube.R

+32-3
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,29 @@ NULL
131131
}
132132
.cube_set_class(cube)
133133
}
134+
#' @title Identity function for data cubes
135+
#' @keywords internal
136+
#' @noRd
137+
#' @name .cube
138+
#' @param x cube
139+
#'
140+
#' @return data cube object.
134141
.cube <- function(x) {
135142
# return the cube
136143
x
137144
}
138-
#' @title Return areas of classes of a class_cue
145+
#' @title Get base info from a data cube
146+
#' @keywords internal
147+
#' @noRd
148+
#' @name .cube
149+
#' @param x cube
150+
#'
151+
#' @return data cube from base_info
152+
.cube_base_info <- function(x) {
153+
# return base info data cube
154+
dplyr::bind_rows(x[["base_info"]])
155+
}
156+
#' @title Return areas of classes of a class_cube
139157
#' @keywords internal
140158
#' @noRd
141159
#' @name .cube_class_areas
@@ -192,7 +210,7 @@ NULL
192210
class(cube) <- c("raster_cube", class(cube))
193211
bands <- .cube_bands(cube)
194212
} else {
195-
stop(.conf("messages", "cube_bands"))
213+
stop(.conf("messages", ".cube_bands"))
196214
}
197215
return(bands)
198216
}
@@ -203,7 +221,7 @@ NULL
203221
cube <- tibble::as_tibble(cube)
204222
bands <- .cube_bands(cube, add_cloud, dissolve)
205223
} else {
206-
stop(.conf("messages", "cube_bands"))
224+
stop(.conf("messages", ".cube_bands"))
207225
}
208226
return(bands)
209227
}
@@ -544,6 +562,17 @@ NULL
544562
}
545563
return(is_regular)
546564
}
565+
566+
#' @title Check that cube is a base cube
567+
#' @name .cube_is_base
568+
#' @keywords internal
569+
#' @noRd
570+
#' @param cube datacube
571+
#' @return Called for side effects.
572+
.cube_is_base <- function(cube) {
573+
inherits(cube, "base_raster_cube")
574+
}
575+
547576
#' @title Find out how many images are in cube during a period
548577
#' @noRd
549578
#' @param cube A data cube.

R/api_data.R

+6-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
} else {
5050
cld_band <- NULL
5151
}
52+
if (.cube_is_base(cube)) {
53+
bands <- setdiff(bands, .cube_bands(.cube_base_info(cube)))
54+
}
55+
5256
# define parallelization strategy
5357
# find block size
5458
rast <- .raster_open_rast(.tile_path(cube))
@@ -81,9 +85,7 @@
8185
}
8286
if (.has(cube[["base_info"]])) {
8387
# get base info
84-
cube_base <- cube[["base_info"]]
85-
# bind all base info
86-
cube_base <- dplyr::bind_rows(cube_base)
88+
cube_base <- .cube_base_info(cube)
8789
# get bands
8890
bands_base <- .cube_bands(cube_base)
8991
# extract data
@@ -97,6 +99,7 @@
9799
)
98100
# save base data
99101
ts_tbl[["base_data"]] <- base_tbl[["time_series"]]
102+
# add base class
100103
class(ts_tbl) <- c("sits_base", class(ts_tbl))
101104
}
102105
return(ts_tbl)

R/api_plot_time_series.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
# how many time series are to be plotted?
7575
number <- nrow(data2)
7676
# what are the band names?
77-
bands <- .samples_bands(data2)
77+
bands <- .samples_bands(data2, include_base = FALSE)
7878
# what are the reference dates?
7979
ref_dates <- .samples_timeline(data2)
8080
# align all time series to the same dates

R/api_plot_vector.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
# verifies if stars package is installed
8888
.check_require_packages("stars")
8989
# verifies if tmap package is installed
90-
.check_require_packages("plot")
90+
.check_require_packages("tmap")
9191
# precondition - check color palette
9292
.check_palette(palette)
9393
# revert the palette

R/api_predictors.R

+14-28
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919
# Get samples time series
2020
pred <- .ts(samples)
2121
# By default get bands as the same of first sample
22-
bands <- .samples_bands(samples)
22+
bands <- .samples_bands(samples, include_base = FALSE)
2323
# Preprocess time series
2424
if (.has(ml_model)) {
2525
# If a model is informed, get predictors from model bands
26-
bands <- .ml_bands(ml_model)
26+
bands <- intersect(.ml_bands(ml_model), bands)
27+
2728
# Normalize values for old version model classifiers that
2829
# do not normalize values itself
2930
# Models trained after version 1.2 do this automatically before
@@ -49,7 +50,7 @@
4950
})
5051
}
5152
}
52-
# Create predictors...
53+
# Create predictors
5354
pred <- pred[c(.pred_cols, bands)]
5455
# Add sequence 'index' column grouped by 'sample_id'
5556
pred <- pred |>
@@ -68,36 +69,22 @@
6869
}
6970
#' @export
7071
.predictors.sits_base <- function(samples, ml_model = NULL) {
71-
# Get predictors for time series
7272
# Prune samples time series
7373
samples <- .samples_prune(samples)
7474
# Get samples time series
75-
pred <- .ts(samples)
76-
# By default get bands as the same of first sample
77-
bands <- .samples_bands.sits(samples)
78-
# Create predictors...
79-
pred <- pred[c(.pred_cols, bands)]
80-
# Add sequence 'index' column grouped by 'sample_id'
81-
pred <- pred |>
82-
dplyr::select("sample_id", "label", dplyr::all_of(bands)) |>
83-
dplyr::group_by(.data[["sample_id"]]) |>
84-
dplyr::mutate(index = seq_len(dplyr::n())) |>
85-
dplyr::ungroup()
86-
# Rearrange data to create predictors
87-
pred <- tidyr::pivot_wider(
88-
data = pred, names_from = "index", values_from = dplyr::all_of(bands),
89-
names_prefix = if (length(bands) == 1) bands else "",
90-
names_sep = ""
91-
)
92-
# get predictors for base data
93-
base <- dplyr::bind_rows(samples$base_data)
94-
base <- base[,-1]
95-
# join time series predictors with base data predictors
96-
pred <- dplyr::bind_cols(pred, base)
75+
pred <- .predictors.sits(samples, ml_model)
76+
# Get predictors for base data
77+
pred_base <- samples |>
78+
dplyr::rename(
79+
"_" = "time_series", "time_series" = "base_data"
80+
) |>
81+
.predictors.sits() |>
82+
dplyr::select(-.data[["label"]])
83+
# Merge predictors
84+
pred <- dplyr::inner_join(pred, pred_base, by = "sample_id")
9785
# Return predictors
9886
pred
9987
}
100-
10188
#' @title Get predictors names with timeline
10289
#' @keywords internal
10390
#' @noRd
@@ -113,7 +100,6 @@
113100
USE.NAMES = FALSE
114101
))
115102
}
116-
117103
#' @title Get features from predictors
118104
#' @keywords internal
119105
#' @noRd

0 commit comments

Comments
 (0)