The goal of hlsmanager is to simplify to work with the HLS dataset from NASA. When downloaded from NASA AppEEARS; all the bands get saved as on tiff-file and the user has to merge them based on their filename.
This package offers:
- an overview about the data you downloaded
- merge them based on the default filename
- cloud mask them
- Reduce data to temporal means/median/sd.
The data can be downloaded from: https://appeears.earthdatacloud.nasa.gov/?_ga=2.43130661.1417310973.1723470150-437277444.1719598629 All the steps are consecutive and can be considered the first part of your analysis workflow. The package is based on the naming convention of NASAAppears, its crucial to not rename the files. In case of unexpected error, dont use filepaths that include underscores. The package never loads all data into RAM, so it can be used to process a large number of scenes.
Possible hlsmanager workflow:
library(hlsmanager)
summary_df <- hlsmanager::auto_df("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded", calculate_non_na_pixels = T) # HLS data as downloaded
#> [1] "dataframe with, 15 was created."
head(summary_df)
#> year doy band
#> 1 2025 218 B04
#> 2 2025 228 B04
#> 3 2025 233 B04
#> 4 2025 235 B04
#> 5 2025 243 B04
#> 6 2025 218 B08
#> filepath
#> 1 C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded/HLSS30.020_B04_doy2025218_aid0001_32N.tif
#> 2 C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded/HLSS30.020_B04_doy2025228_aid0001_32N.tif
#> 3 C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded/HLSS30.020_B04_doy2025233_aid0001_32N.tif
#> 4 C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded/HLSS30.020_B04_doy2025235_aid0001_32N.tif
#> 5 C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded/HLSS30.020_B04_doy2025243_aid0001_32N.tif
#> 6 C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded/HLSS30.020_B08_doy2025218_aid0001_32N.tif
#> filename satellite_typ non_na_pixels
#> 1 HLSS30.020_B04_doy2025218_aid0001_32N.tif sentinel 0.9593137
#> 2 HLSS30.020_B04_doy2025228_aid0001_32N.tif sentinel 0.9593137
#> 3 HLSS30.020_B04_doy2025233_aid0001_32N.tif sentinel 0.9593137
#> 4 HLSS30.020_B04_doy2025235_aid0001_32N.tif sentinel 0.9593137
#> 5 HLSS30.020_B04_doy2025243_aid0001_32N.tif sentinel 0.9593137
#> 6 HLSS30.020_B08_doy2025218_aid0001_32N.tif sentinel 0.9593137hlsmanager::auto_group("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded", "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/grouped")
#> [1] "dataframe with, 15 was created."
#> [1] "2025_218-stack was saved."
#> [1] "2025_228-stack was saved."
#> [1] "2025_233-stack was saved."
#> [1] "2025_235-stack was saved."
#> [1] "2025_243-stack was saved."
#> [1] "All rasterstacks seems to have the same amount of bands. The data should be complete."
#> [1] "5 RASTERSTACKS WERE SAVED."
print(paste("Number of files downloaded",length(list.files("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded"))))
#> [1] "Number of files downloaded 15"
print(paste("Number of files grouped",length(list.files("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/grouped"))))
#> [1] "Number of files grouped 5"
# The data consists of 5 scenes with 3 bands each, including the FMask-layer. With this function, all the bands where grouped
# into the five scenes.
terra::plot(terra::rast(list.files("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/grouped", full.names=T)[1])[[1:2]])# In case some files are missing, the function give a warning and an overview of the bands.
hlsmanager::auto_group("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/tiffsasdownloaded_missing", "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/grouped_missing")
#> [1] "dataframe with, 14 was created."
#> [1] "2025_218-stack was saved."
#> [1] "2025_228-stack was saved."
#> [1] "2025_233-stack was saved."
#> [1] "2025_235-stack was saved."
#> [1] "2025_243-stack was saved."
#> [1] "Not all the rasterstacks have the same amount of bands. Here you can see the statistics of the rasterstacks and the number of bands. The Fmask is counted as a band as well. You can still use the data, its just not complete."
#> year doy number_of_bands
#> 1 2025 218 3
#> 2 2025 228 3
#> 3 2025 233 3
#> 4 2025 235 3
#> 5 2025 243 2
#> [1] "5 RASTERSTACKS WERE SAVED."
# In this case, the scene from 2025 doy 228 has only 2 bands and is therefore missing one. hlsmanager::auto_mask("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/grouped", "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked", filterClouds = TRUE, filterAdjacent = TRUE, filterCloudshadow = TRUE, filterSnowice = FALSE, filterWater = FALSE, filterAerosol_climatology = FALSE, filterAerosol_low = FALSE, filterAerosol_moderate = FALSE, filterAerosol_high = FALSE)
#> [1] "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked/MASKED_HLS_STACK_2025_218_B04-B08-Fmask.tif was filtered and saved."
#> [1] "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked/MASKED_HLS_STACK_2025_228_B04-B08-Fmask.tif was filtered and saved."
#> [1] "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked/MASKED_HLS_STACK_2025_233_B04-B08-Fmask.tif was filtered and saved."
#> [1] "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked/MASKED_HLS_STACK_2025_235_B04-B08-Fmask.tif was filtered and saved."
#> [1] "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked/MASKED_HLS_STACK_2025_243_B04-B08-Fmask.tif was filtered and saved."
#> [1] "MASKING FINISHED."
terra::plot(terra::rast(list.files("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked", full.names=T)[3])[[1:2]])# With this command we compute the means from doy 215 to doy 280 in steps of five days.
# Most of the intervalls will be empty and we will get an error message for that.
# computation is still carried out with the non-empty intervalls.
# All the reducer_modes ignore NAs.
reducer(215, 280, 10, reducer = "mean", "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/masked", "C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/mean")
#> The time intervall from to 215 in the year 2025 has no scenes. The next step is computed instead.
#>
#> [1] "Raster from 215 to 225 was calculated."
#> [1] "Raster from 225 to 235 was calculated."
#> [1] "Raster from 235 to 245 was calculated."
#> The time intervall from 245 to 255 in the year 2025 has no scenes. The next step is computed instead.
#>
#> The time intervall from 255 to 265 in the year 2025 has no scenes. The next step is computed instead.
#>
#> The time intervall from 265 to 275 in the year 2025 has no scenes. The next step is computed instead.
#>
#> THE YEAR 2025 IS FINISHED.
#>
#> [1] "FUNCTION ENDED SUCCESFULLY.\n\n"
terra::plot(terra::rast(list.files("C:/Users/miles/OneDrive/Dokumente/EAGLE/karlakolumna/mean", full.names = T)[2]))# In this case, we don´t see a difference to the plotted SpatRaster in 4., but only because the other SpatRaster consist only of clouds and therefore NAs. 



