-
Notifications
You must be signed in to change notification settings - Fork 0
Home
This project was created to analyze 3D MRI root data.
-
config.xml
contains meta-information about raw data files -
main.py
takes raw data, upsamples it and calculates vesselness measure -
wurzel/*
helper classes formain.py
andvis.py
-
dijkstra/grid.cpp
transforms raw data and vesselness measure to root tree -
dijkstra/treeinfo.cpp
print info about a root tree, translate to other formats
-
wurzel/viewer.py
defines some default views on 3D data for convenience -
vis.py
visualizes results of all other components, including c++ components usingviewer.py
For each raw data file, put a section like this in the config file:
<datafile read-dtype="float32">
<base-name>../data/GersteLA_96x96x410</base-name>
<read-shape x="410" y="96" z="96"/>
<shape x="436" y="96" z="96"/>
<stem-plane>5</stem-plane>
<stem-axis>0</stem-axis>
<has-rohr>false</has-rohr>
<scale>0.94</scale>
<noise-cutoff>0.02</noise-cutoff>
</datafile>
-
read-dtype
is the datatype of the elements -
base-name
is the basename (with prepended../
) as used lateron in BASE, which is used as a key -
read-shape
the size of the data as stored in the raw.dat
file -
shape
the size of the data after upsampling (should be isotropic then!) -
stem-plane
index of plane in which to look for stem -
stem-axis
number of axis the plane index refers to -
has-rohr
true/false, whether the dataset contains a measuring tube -
scale
how to get fromread-shape
resololution to millimeters (factor) -
noise-cutoff
average noise level after normalization
-
Makefile
contains targets to run all steps separately.make BASE=GersteLA_96x96x410_normal sato
upsamples
data/GersteLA_96x96x410_normal
and computes vesselnessmake BASE=GersteLA_96x96x410_normal grid
given vesselness and upsampled raw data from previous step, find the root tree (in the graph-theoretical sense ^^)
make BASE=GersteLA_96x96x410_normal treeinfo
output some stats about the found root tree
-
Makefile
has targets for running a dataset through the whole process, e.g.make BASE=GersteLA_96x96x410_normal
does all of the above steps.
-
Note that when running everything through
make
commands as suggested above, you need to adjust thedijkstra/grid
parameters in theMakefile
. -
vesselness measure: You can mainly configure the scales at which the measure is calculated. Have a look at
main.py
for that purpose. -
root tree extraction: The
grid
program is configurable using command line parameters. Try runninggrid --help
to find out more, e.g.Allowed options: --help produce help message --base the base name of the dataset -c [ --cfg ] arg (=config.xml) the config-file containing dataset descriptions (XML) --force force recomputation of dijkstra algorithm --stem-plane arg plane index in which to search for stem (read from config-file if not given) --stem-axis arg the axis of stem-plane (read from config-file if not given) -r [ --max-radius ] arg (=1.8) maximum root radius (in mm) -s [ --start-threshold ] arg (=0.1) minimum raw value to start tracking -t [ --total-len-thresh ] arg (=1000000000) maximal total length -d [ --dijkstra-stop-val ] arg (=1000000000) stop dijkstra when paths longer than this (decreases dijkstr runtime) -l [ --leaf-select-method ] arg (=median_raw) method for selecting leaf candidates [edge_detect,median_raw,subtree_weight] -f [ --min-flow-thresh ] arg (=0.0001) minimal flow fraction --no-gauss-fit save some time --no-subpix-pos save some time
-
Note to some of the parameters:
-
force
: after Dijkstra algorithm has been executed, the result is written to filesd_map.dat
andp_map.dat
. When you re-rungrid
, these files will be loaded instead of re-running Dijkstra. After changing scales in the vesselness measure ordijkstra-stop-val
, you have to use this parameter to ensure that the distance/predecessor maps are updated. -
dijskstra-stop-val
: Most of the MRI image volume does not belong to the root. You can avoid determining its connectivity (which takes a lot of time) by choosing a maximum distance from the root you want to explore. -
leaf-select-method
: a voxel is considered to be a leaf node if it is abovestart-threshold
and its distance to the root node is less thantotal-len-thresh
and-
edge_detect
is the method used in the VISAPP paper for maize. it is true if the upstream/downstream ratio is abovemin-flow-thresh
. -
subtree_weight
: In the subtree defined by the current node, the sum of the weights above threshold must be larger thanmin-flow-thresh
. -
median_raw
In a limited depth breadth first search towards the root, the median of the visited values must at least bemin-flow-thresh
.
-
-
All steps save intermediate outputs in the same directory as the original raw data. Subsequent runs will make use of (at least some) cached results:
- upsampling is not repeated if avoidable
- dijkstra is only run if no d_map/p_map file exists
- treeinfo is very fast and operates only on serialized root tree
If in doubt, delete intermediate files and re-run everything.
Care has been taken to parallelize as many operations as possible:
- Hessian computation of a single scale is parallelized with OpenMP using weave in Python. It will make use of all available cores.
- Optionally, you can distribute the Hessian computation of different scales
over multiple computers using a running ipcluster engine and the
-p
parameter tomain.py
- Dijkstra is not distributed, the parallel implementation for
dijkstra_shortest_path
algorithm is currently only available for adjacency list graphs, not the newgrid_graph
s. - Most loops over vertices in
grid.cpp
have been parallelized using Intel Thread Building blocks. It automatically makes use of all available cores. The side-effect free action objects are implemented using C++0X lambda functions, which are available ingcc
version >=4.5.