Skip to content

Stem_diameter_profile() issue when detect_stem() outputs are written to disk first... #1

Description

@Robin-hartley

Kia ora Team,

just spotted this issue - as the detect_stem() can fail when running through a large list of individual tree point clouds, its best to write to disk. When the next phase is to derive profiles using stem_diameter_profile(), however, this relies on point clouds that have a "Stem" binary attribute, and the TreeLS package that is used in the background here doesn't natively write the Stem attribute as its not binary.

Here is an example:

list input clouds

itc_list <- list.files(file.path(getwd(), "Input_PCs"), pattern = ".laz$",
full.names = TRUE)

Sequential processing loop

results <- list()
error_log <- file.path(getwd(), "stem_errors_seq.txt")

Sequential processing loop

for (i in seq_along(itc_list )) {
file <- itc_list [i]
message("▶️ Processing file ", i, "/", length(itc_list ), ": ", basename(file))

tryCatch({
stem_las <- detect_stem(file, min_ht = 0.1, max_diameter = 0.8)

if (is.null(stem_las) || npoints(stem_las) == 0) {
  results[[file]] <- list(file = file, status = "empty", out_path = NA,
                          message = "No stem points")
} else {
  out_path <- file.path(out_path_stem,
                        paste0(tools::file_path_sans_ext(basename(file)), "_stem.laz"))
  lidR::writeLAS(stem_las, out_path)
  
  results[[file]] <- list(file = file, status = "ok", out_path = out_path, message = NA)
}

}, error = function(e) {
msg <- paste0("❌ Error with file: ", file, " | ", e$message, "\n")
cat(msg, file = error_log, append = TRUE)
results[[file]] <- list(file = file, status = "error", out_path = NA, message = e$message)
})
}

################# Diameter profiles #################

List all files.

pc_list <- list.files(file.path(getwd(), "Stem_PCs_treenotypR"),
pattern = ".laz$",
full.names = TRUE)

Sequential processing loop

results_2 <- list()
error_log2 <- file.path(getwd(), "seg_errors_seq.txt")

Sequential processing loop

for (i in seq_along(pc_list)) {
file <- pc_list[1]
message("▶️ Processing file ", i, "/", length(pc_list), ": ", basename(file))

tryCatch({
las <- lidR::readLAS(file)

profile <- stem_diameter_profile(las, 
                                 min_ht = 0.1, 
                                 max_diameter = 0.8,
                                 seg_ht = 0.2)

if (is.null(profile) || nrow(profile) == 0) {
  results_2[[las]] <- list(file = file, status = "empty", out_path = NA,
                            message = "No diameter profile generated")
} else {
  out_path_p <- file.path(out_path_profile,
                        paste0(tools::file_path_sans_ext(basename(file)), "_d_profile.csv"))
  
  write.csv(profile, out_path_p, row.names = FALSE)
  
  results_2[[file]] <- list(file = file, status = "ok", out_path = out_path_p, message = NA)
}

}, error = function(e) {
msg <- paste0("❌ Error with file: ", file, " | ", e$message, "\n")
cat(msg, file = error_log2, append = TRUE)
results_2[[file]] <- list(file = file, status = "error", out_path = NA, message = e$message)
})
}

De-bugging found the following error:

Error in validate_las(stem_las, required_cols = c("X", "Y", "Z", "Stem")) :
Invalid input: stem_las LAS object is missing required columns: Stem

I have some code to fix this up, so i will propse a change.

Cheers

RJLH

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions