Extract time series from a Sentinel-2 data archive (created with the package sen2r) over spatial features (points or polygons). Quality flags can be added exploiting an additional extracted archive (see arguments scl_paths and cld_paths).

extract_s2ts(
  in_paths,
  in_sf,
  fun = "mean",
  in_sf_id,
  scl_paths,
  cld_paths,
  scl_w,
  fun_w = "mean"
)

Arguments

in_paths

Paths of the sen2r files (eventually obtained using read_in_cube(..., out_format = "path")).

in_sf

Object with polygonal or point geometries

fun

(optional) aggregation function (or function name) to be used in case of polygonal in_sf features. Default is mean. If scl_paths and/or cld_paths are defined:

  • the default mean is intended as weighted.mean() (where the computed quality flags are used as weights);

  • only the alternative value "best" is accepted (in this case, the pixel with the higher quality flag - or the average of pixels with the same higher quality flags - is considered).

in_sf_id

(optional) character vector corresponding to the name/names of the in_sf column with the features IDs. If missing, the row number is used.

scl_paths

(optional) Paths of the SCL files (they must correspond to in_paths); if provided, it is used to weight pixels during the aggregation and to provide an output quality flag. See details for the conversion between SCL and weights.

cld_paths

(optional) Paths of the CLD files (they must correspond to in_paths); see scl_paths. See details for the conversion between SCL and weights.

scl_w

(optional) weights to be used for each SCL class, which can be created using function scl_weights(). If missing, the default outputs of scl_weights() are used. See details for the conversion between SCL and weights.

fun_w

(optional) function to be used to aggregate quality flags in case of polygonal in_sf features. Default is mean.

Value

The output time series in s2ts format.

Details

To generate pixel weights, SCL and/or CLD layers can be used.

SCL are categorical layers (12 levels), so each level must be converted in a 0-1 numeric value. This is done by function scl_weights(). If the user provides only scl_paths, the layer of weights will be a 0-1 numeric layer in which each pixel value corresponds to the 0-1 value associated with the corresponding SCL class.

CLD are integer layers with the percentage (0-100) of cloud probability. Assumed that a CLD of 0% is associated to a weight of 1 and a CLD of 100% to a weight of 0, intermediate values are computed taking into account the output of scl_weights() for classes "cloud_high_probability", "cloud_medium_probability" and "unclassified" (this because CLD values are in the range 80-100 when associated to the SCL class "cloud_high_probability", in the range 20-80 when associated to "cloud_medium_probability" and in the range 20-80 when associated to "unclassified" or "thin_cirrus"). The two values "cloud_medium_probability" - "cloud_high_probability" and "unclassified" - "cloud_medium_probability" are taken as breaks to reclassify CLD. I.e., consider the default case: scl_weights()[c("cloud_high_probability", "cloud_medium_probability", "unclassified")] returns 0.0 0.1 0.5; so, breaks 0.05 and 0.35 are used, meaning that CLD values in the range 80-100% are rescaled to 0-0.05, CLD values in the range 20-80% are rescaled to 0.05-0.35 and CLD values in the range 80-100% are rescaled to 0.35-1. If the user provides only cld_paths, the layer of weights will be a 0-1 numeric layer with the above described values.

Finally, if the user provides both scl_paths and cld_paths, the two layers of weights are combined and the lowest quality flag is considered.

Author

Luigi Ranghetti, PhD (2020) luigi@ranghetti.info

Examples

# Load input data data("sampleroi") sen2r_ndvi_paths <- sample_paths("NDVI") sen2r_scl_paths <- sample_paths("SCL") # \donttest{ # Simple TS extraction from polygons (without quality flags) ts_raw_0 <- extract_s2ts(sen2r_ndvi_paths, sampleroi) print(ts_raw_0, topn = 5)
#> A raw s2ts time series with 60 dates and 2 IDs. #> Date Orbit Sensor 1   2   #> 1: 2020-01-04 022 2B 1161.33333 1733.06250 #> 2: 2020-01-09 022 2A 201.70833 223.52083 #> 3: 2020-01-14 022 2B -43.72917 150.77083 #> 4: 2020-01-19 022 2A 1163.68750 967.04167 #> 5: 2020-01-24 022 2B 1233.87500 1657.27083 #> --- #> 56: 2020-10-10 022 2B 572.33333 1018.64583 #> 57: 2020-10-15 022 2A -86.37500 -93.22917 #> 58: 2020-10-20 022 2B 571.81250 983.20833 #> 59: 2020-10-25 022 2A -385.56250 -677.97917 #> 60: 2020-10-30 022 2B 676.35417 783.27083
# } # TS extraction from polygons using a SCL archive for quality flags # (example used to produce the sample dataset "ts_raw") ts_raw <- extract_s2ts( sen2r_ndvi_paths, sampleroi, scl_paths = sen2r_scl_paths ) ts_raw$value <- ts_raw$value / 1E4 # reshape to standard NDVI range -1 to 1 print(ts_raw, topn = 5) # standard print
#> A raw s2ts time series with 60 dates and 2 IDs. #> Date Orbit Sensor 1   2   #> 1: 2020-01-04 022 2B 0.116133333 ○ 0.173306250 ○ #> 2: 2020-01-09 022 2A 0.020170833 ○ 0.022352083 ○ #> 3: 2020-01-14 022 2B -0.004372917 ○ 0.015077083 ○ #> 4: 2020-01-19 022 2A 0.116368750 ○ 0.096704167 ○ #> 5: 2020-01-24 022 2B 0.123387500 ○ 0.165727083 ○ #> --- #> 56: 2020-10-10 022 2B 0.057233333 ○ 0.104959233 ○ #> 57: 2020-10-15 022 2A -0.008637500 ○ -0.009322917 ○ #> 58: 2020-10-20 022 2B 0.057181250 ○ 0.098320833 ○ #> 59: 2020-10-25 022 2A -0.038556250 ○ -0.067797917 ○ #> 60: 2020-10-30 022 2B 0.067635417 ○ 0.078327083 ○ #> #> Quality flags: ● [1] ◕ [0.9,1) ◑ [0.75,0.9) ◔ [0.5,0.75) ○ [0,0.5)
head(as.data.frame(ts_raw)) # see content
#> id date orbit sensor value qa #> 1 1 2020-01-04 022 2B 0.116133333 0.33 #> 2 1 2020-01-09 022 2A 0.020170833 0.00 #> 3 1 2020-01-14 022 2B -0.004372917 0.00 #> 4 1 2020-01-19 022 2A 0.116368750 0.00 #> 5 1 2020-01-24 022 2B 0.123387500 0.33 #> 6 1 2020-01-29 022 2A 0.114379167 0.33
plot(ts_raw)
# \donttest{ # TS extraction from polygons using a different aggregation function ts_raw_2 <- extract_s2ts(sen2r_ndvi_paths, sampleroi, fun = "max") # TS extraction from points samplepts <- suppressWarnings(sf::st_centroid(sampleroi)) ts_raw_3 <- extract_s2ts(sen2r_ndvi_paths, samplepts) # }