tutorials:analyse-structure
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorials:analyse-structure [2025/06/27 15:58] – t | tutorials:analyse-structure [2025/06/30 16:51] (current) – t | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== |
- | 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' | + | Sometimes, |
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 6: | Line 6: | ||
Note that there are also the [[tutorials: | Note that there are also the [[tutorials: | ||
- | There are two typical data origins for structures that people want to analyze: Manually measured FASTRAK data and plants generated in GroIMP. This article covers | + | There are three typical data origins for structures that people want to analyze: Manually measured FASTRAK |
===== Requirements ===== | ===== Requirements ===== | ||
- | * GroIMP " | + | * GroIMP " |
* GroIMP " | * GroIMP " | ||
* Some recent version of R | * Some recent version of R | ||
Line 15: | Line 15: | ||
===== GroIMP import & export===== | ===== GroIMP import & export===== | ||
+ | As always in GroIMP, you can import your file using Object -> Insert File / Insert File to RGG. The difference is that if you insert to RGG, the file will be imported under the RGG Root instead of under Node.0. For our example here, always use " | ||
==== Import: FASTRAK ==== | ==== Import: FASTRAK ==== | ||
- | + | Importing | |
- | When using FASTRAK data, you can open a new RGG project and simply import your file using Object -> Insert File / Insert File to RGG. This requires the fastrakReader plugin. | + | Note that your data might be scaled in an unexpected way relative to your GroIMP project. In the picture below is an example of FASTRAK data inserted in a New RGG project, note the size of the FASTRAK tree relative to the " |
{{: | {{: | ||
Line 40: | Line 41: | ||
]} | ]} | ||
</ | </ | ||
+ | |||
+ | === 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. | ||
+ | |||
+ | 1. Open the 2D Graph and select the edge connecting Node.0 with the first node of your Fastrak structure: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | 2. In the attribute editor, change the edge type from branch to successor: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | That's it! | ||
+ | |||
+ | ==== Import: DTD ==== | ||
+ | DTD files can be imported in exactly the same way as FASTRAK files, but no special plugin is required. | ||
==== Import: QSM ==== | ==== Import: QSM ==== | ||
Line 48: | Line 65: | ||
==== Export ==== | ==== Export ==== | ||
Export from GroIMP as .qsm is provided by the qsm plugin. Under View -> Export -> complete scene you need to specify a file name and select text/qsm as filetype. The resulting file is simply a comma separated table which contains information for every cylinder in your scene: | Export from GroIMP as .qsm is provided by the qsm plugin. Under View -> Export -> complete scene you need to specify a file name and select text/qsm as filetype. The resulting file is simply a comma separated table which contains information for every cylinder in your scene: | ||
- | {{: | + | {{: |
+ | You can also export to .qsm from RGG using: | ||
+ | <code java> | ||
+ | export3DScene(getWD() + my_name + " | ||
+ | </ | ||
+ | ===== Import in R ===== | ||
+ | Please take a quick look the rTwig documentation to get an idea what is possible with this library and how it works in general. The main point here is that we can import our .qsm file using the reconstruct_qsm() function: | ||
+ | <code sas> | ||
+ | library(rTwig) | ||
+ | qsm <- reconstruct_qsm( | ||
+ | cylinder = read.csv(" | ||
+ | id = " | ||
+ | branch_order = " | ||
+ | start_x = " | ||
+ | end_x = " | ||
+ | ) | ||
+ | plot_qsm(qsm, | ||
+ | </ | ||
+ | {{: | ||
+ | ===== Analysis in R ===== | ||
+ | The most useful rTwig functions are probably the plot_qsm() function you already saw (it has diverse coloring options and can also be used for point clouds) and the tree_metrics() function. Besides this, you can always just use the qsm cylinder data to come up with your own analysis. tree_metrics() is somewhat similar to the GROGRA functions, it outputs a whole range of overall descriptors and distributions for various aspects of your tree's morphology. Pleas reference the rTwig documentation for further details. | ||
+ | <code sas> | ||
+ | metrics <- tree_metrics(qsm) | ||
+ | plot(metrics$stem_taper$height_m, | ||
+ | xlab = " | ||
+ | ylab = " | ||
+ | lines(metrics$stem_taper$height_m, | ||
+ | </ | ||
+ | {{: | ||
+ | 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). 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 <- " | ||
+ | file_list <- list.files(path = folder_path, | ||
+ | qsm_list <- list() | ||
+ | for (file in file_list) { | ||
+ | cyl_data <- read.csv(file) | ||
+ | tree_id <- tools:: | ||
+ | qsm <- reconstruct_qsm( | ||
+ | cylinder = cyl_data, | ||
+ | id = " | ||
+ | branch_order = " | ||
+ | start_x = " | ||
+ | end_x = " | ||
+ | mutate(tree_id = tree_id) | ||
+ | qsm_list[[tree_id]] <- qsm | ||
+ | } | ||
+ | |||
+ | stem_list <- lapply(qsm_list, | ||
+ | qsm %> | ||
+ | filter(branch_order == 0) %>% | ||
+ | arrange(base_distance) %> | ||
+ | mutate(year = 1: | ||
+ | |||
+ | 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 = " | ||
+ | ggtitle(" | ||
+ | xlab(" | ||
+ | scale_x_continuous(breaks = all_years) + | ||
+ | theme_minimal() | ||
+ | </ | ||
+ | {{: | ||
tutorials/analyse-structure.1751032696.txt.gz · Last modified: 2025/06/27 15:58 by t