User Tools

Site Tools


tutorials:analyse-structure

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorials:analyse-structure [2025/06/30 11:39] ttutorials:analyse-structure [2025/06/30 16:51] (current) t
Line 1: Line 1:
-====== A simple people's guide on structural data analysis integrating R ====== +====== Structural QSM-based data analysis integrating R ====== 
-There exists the rare case that you might want to conduct some statistical analysis on the structure of your simulated or measured plant outside of XL and GroIMP. GroIMP's query system is principally a very powerful tool for the data subsetting part of such analysis (finding parts of your structure that follow some topological relationships), but it can be hard to apply advanced statistical methods directly in GroIMP.+Sometimes, you might want to conduct some statistical analysis on the structure of your simulated or measured plant outside of XL and GroIMP. GroIMP's query system is principally a very powerful tool for the data subsetting part of such analysis (finding parts of your structure that follow some topological relationships), but it can be hard to apply advanced statistical methods directly in GroIMP.
  
 Here, we present an example on how to export structures from GroIMP and how to analyze them in R. There, the rTwig library allows for convenient analysis of QSM-like structures, which we will export from GroIMP. Here, we present an example on how to export structures from GroIMP and how to analyze them in R. There, the rTwig library allows for convenient analysis of QSM-like structures, which we will export from GroIMP.
Line 44: Line 44:
 === Correct FASTRAK Topology === === Correct FASTRAK Topology ===
 If you want to retain correct branch orders (0 = stem and so on) in the exported structure, you will need to manually correct the imported data. This is a workaround for a current issue with the QSM export, which will be resolved in the future. If you want to retain correct branch orders (0 = stem and so on) in the exported structure, you will need to manually correct the imported data. This is a workaround for a current issue with the QSM export, which will be resolved in the future.
 +
 1. Open the 2D Graph and select the edge connecting Node.0 with the first node of your Fastrak structure: 1. Open the 2D Graph and select the edge connecting Node.0 with the first node of your Fastrak structure:
 +
 {{:tutorials:fastrak-graph.png?400|}} {{:tutorials:fastrak-graph.png?400|}}
 +
 2. In the attribute editor, change the edge type from branch to successor: 2. In the attribute editor, change the edge type from branch to successor:
 +
 {{:tutorials:change-edge.png?400|}} {{:tutorials:change-edge.png?400|}}
  
Line 99: Line 103:
  
 tree_metrics() provides some useful aggregations that are similar to GroIMP queries, like for example the aggregation of individual cylinder segments into branches. tree_metrics() provides some useful aggregations that are similar to GroIMP queries, like for example the aggregation of individual cylinder segments into branches.
-The actual analysis to perform will however heavily depend on the type of your data source and how the data was collected (e.g. biologically meaningful shoot-based data vs. pure geometry acquisitions)+The actual analysis to perform will however heavily depend on the type of your data source and how the data was collected (e.g. biologically meaningful shoot-based data vs. pure geometry acquisitions). Supposing you have Fastrak data where every cylinder segment represents a yearly shoot, you could e.g. analyze the yearly apical growth of the stem on several spruce trees like this, just using the raw QSM data:
  
 +<code sas>
 +library(dplyr)
 +library(ggplot2)
 +
 +folder_path <- "D:/groimp/tiny_trees_analysis_example/f_qsms"
 +file_list <- list.files(path = folder_path, pattern = "\\.qsm$", full.names = TRUE)
 +qsm_list <- list()
 +for (file in file_list) {
 +  cyl_data <- read.csv(file)
 +  tree_id <- tools::file_path_sans_ext(basename(file))
 +  qsm <- reconstruct_qsm(
 +    cylinder = cyl_data,
 +    id = "id", parent = "parent", radius = "raw_radius",
 +    branch_order = "branch_order",
 +    start_x = "start_x", start_y = "start_y", start_z = "start_z",
 +    end_x = "end_x", end_y = "end_y", end_z = "end_z") %>
 +    mutate(tree_id = tree_id)
 +  qsm_list[[tree_id]] <- qsm
 +}
 +
 +stem_list <- lapply(qsm_list, function(qsm){
 +  qsm %>
 +    filter(branch_order == 0) %>%
 +    arrange(base_distance) %>
 +    mutate(year = 1:nrow(.))})
 +
 +all_stems <- bind_rows(stem_list)
 +all_years <- sort(unique(all_stems$year))
 +all_stems %>%  
 +  ggplot(., aes(x = year, y=length)) +
 +    geom_point(aes(color = tree_id)) + 
 +    geom_smooth(method = "lm") +
 +    ggtitle("Yearly apical shoot lengths") +
 +    xlab("Year") + ylab("Shoot length [m]") + 
 +    scale_x_continuous(breaks = all_years) +
 +    theme_minimal()
 +</code>
  
 +{{:tutorials:yearly_shoots_tiny_spruce.png?400|}}
  
tutorials/analyse-structure.1751276397.txt.gz · Last modified: 2025/06/30 11:39 by t