# ---------------------------------------------------------------------
# name: internal_select_sub
# description: These functions do the temporal selection of SAR (sentinel-1) records.
# They create a temporary tile id for each record, according to which they can be
# selected. As they are cloud-free no further spatial selection is necessary. These
# records are thus only selected according to their tile and temporal characteristics.
# This can be done in accordance with previously selected optical records. The sub-periods
# selected for optical records are handed over to the SAR selection. Selection of optical
# records has priority due to cloud cover constraints. SAR selection is hence temporally
# guided by the optical selection in case there is one. Otherwise, SAR selection is
# conducted independently.
# author: Henrik Fisser, 2019
# ---------------------------------------------------------------------
#' select timestamps for SAR data according to num_timestamps, min_distance and max_sub_period.
#' @param records data.frame.
#' @param period_new_all list of character vectors of two dates, one vector for each timestamp.
#' @param min_distance numeric the minimum number of days between two used acquisitions for distinguished timestamps.
#' @param num_timestamps numeric the number of timestamps the timeseries shall cover.
#' @param max_sub_period numeric maximum length of sub-period.
#' @param params list holding everything inserted into this parameter list in the calling select function.
#' @return \code{SAR_selected} list of [[ids]] character vector of selected ids per timestamp, [[period]] character vector
#' of two dates and [[sub-period]] numeric the sub-period number
#' character vector of two dates (start and end date of SAR sub-period)
#' @keywords internal
#' @noRd
.select_SAR <- function(records, period_new_all = NULL,
max_sub_period, min_distance, num_timestamps, params) {
out(sep(), msg=F)
out("Selecting SAR records", msg = T)
.select_SAR_start()
ids <- c()
period <- c()
sensor_name <- name_product_sentinel1()
subperiods <- unique(records$sub_period)
s_match <- which(records[[name_product()]] == sensor_name)
# if the length of the current sub-period is longer than max_sub_period grade all dates in sub_period
# according to the number of the given records for each date and calculate the distance of each record
# from this date. Exclude records consecutively until max_sub_period is reached
selected_SAR <- list() # to be filled with the selected lists of selected ids and sub-periods
for (timestamp in 1:max(subperiods)) {
# sensor_match are all sentinel-1 records of this sub-period
sensor_match <- intersect(s_match, which(records$sub_period == timestamp))
records_in_s <- records[sensor_match,]
if (NROW(records_in_s) > 0) {
if (inherits(records_in_s, TRY_ERROR())) out("Failed to create tile id", 3)
period_new <- period_new_all[[timestamp]]
previous <- timestamp - 1
if (timestamp > 1) {
# enforce min_distance
# combined period of period_new from optical records (if not NULL because has_SAR == 100) and previous SAR period
previous_period <- .identify_period(c(period_new_all[[previous]], selected_SAR[[previous]]$period))
period_initial <- .identify_period(records_in_s[[params$date_col]])
# earliest date of next sub-period adjusted
first_date <- .select_force_distance(previous_period, min_distance)
period_s <- .select_handle_next_sub(first_date, period_initial,
min_distance, max_sub_period)
records_in_s <- .select_within_period(records_in_s, period_s, params$date_col) # subset to records within period_s
}
dates_s <- sapply(records_in_s[[params$date_col]], as.Date)
if (!is.null(period_new)) {
period_new_dates <- sapply(period_new, as.Date)
dates_combined <- unlist(c(dates_s, period_new_dates))
dates_s <- min(dates_combined, max(dates_combined))
}
min_dates_s <- min(dates_s)
max_dates_s <- max(dates_s)
sub_period_le <- max_dates_s-min_dates_s
# grade dates and exclude consecutively
if (sub_period_le > max_sub_period) {
dates_seq <- min_dates_s:max_dates_s
date_grade <- sapply(dates_seq, function(date) {
records_match <- which(dates_s == date)
# include one record per tile for the grading as for SAR several records on one date = no benefit
grade <- length(unique(records[records_match, params$tileid_col]))
})
# calculate best_period based on date_grade, in combination with period_new
# and while ensuring max_sub_period
best_period <- .select_best_period(date_grade=date_grade,
dates_seq=dates_seq,
min_date=min(dates_seq),
max_date=max(dates_seq),
period_new=period_new,
max_sub_period=max_sub_period)
if (!is.na(best_period)) {
incl <- .select_subset_to_best_period(dates_s, best_period)
ids <- records_in_s[incl,params$identifier] # ids of selected records in updated sub-period
}
} else {
ids <- records_in_s[[params$identifier]] # all ids of records in sub-period
}
if (!.is_empty_array(ids)) {
selected_tile_ids <- records_in_s[which(ids %in% records_in_s[[params$identifier]]), name_tile_id()]
ids_subset <- sapply(unique(selected_tile_ids), function(tile) {
return(which(selected_tile_ids == tile)[1]) # take one available record of tile id
})
ids <- ids[ids_subset]
}
dates_sel <- records_in_s[which(ids %in% records[[params$identifier]]), params$date_col]
period <- .identify_period(dates_sel)
}
no_SAR_period <- is.null(period)
if (no_SAR_period && is.null(period_new_all[[timestamp]])) {
period <- .calc_default_sub_period(params$period, num_timestamps, timestamp)
}
selected_SAR[[timestamp]] <- list("ids"=ids,
"period"=period,
"timestamp"=timestamp)
.select_SAR_timestamp_status(timestamp, selected_SAR[[timestamp]], length(ids))
}
return(selected_SAR)
}
#' selection process when only SAR given in records
#' @param records data.frame.
#' @param max_sub_period numeric max_sub_period.
#' @param min_distance numeric min_distance.
#' @param num_timestamps numeric num_timestamps.
#' @param params list par.
#' @return records data.frame ready for return to user
#' @keywords internal
#' @noRd
.select_all_SAR <- function(records, max_sub_period,
min_distance, num_timestamps,
params) {
selected_SAR <- .select_SAR(records, period_new_all = NULL,
max_sub_period,min_distance,
num_timestamps,params)
records <- .select_finish_SAR(records, selected_SAR, num_timestamps, params)
return(records)
}
#' selection process for SAR when some SAR given in records
#' @param records data.frame.
#' @param selected list selected.
#' @param max_sub_period numeric max_sub_period.
#' @param min_distance numeric min_distance.
#' @param num_timestamps numeric num_timestamps.
#' @param params list par.
#' @return selected list of lists where each list is a selected list of one timestamp
#' @keywords internal
#' @noRd
.select_some_SAR <- function(records, selected, max_sub_period,
min_distance, num_timestamps, params) {
period <- "period"
ids <- "ids"
# SAR records shall be searched within max_sub_period combined
# with the periods selected for optical
period_new_all <- lapply(selected,function(x) return(x[[period]]))
selected_SAR <- .select_SAR(records, period_new_all, max_sub_period, min_distance,
num_timestamps,params)
# add selected ids to selected list of optical records
for (ts in 1:length(selected_SAR)) {
ts_SAR <- selected_SAR[[ts]]
optical_ids <- selected[[ts]][[ids]]
selected[[ts]][[ids]] <- append(optical_ids, ts_SAR[[ids]])
selected[[ts]][[period]] <- .identify_period(c(selected[[ts]]$period,ts_SAR[[period]]))
.select_completed_statement(ts)
}
return(selected)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.