A C++ implementation of the Arner et al. 2001 forest typing algorithm.
This library is largely translated from the FVS codebase (stkval.f and fortyp.f) but also references the Arner documents.
Variable names were kept the same as the FVS FORTRAN code. There are a number of unused variables in the original code that are included but commented out.
The library provides a function forest_type(treelist, false)
which uses DBH, species (using FIA numeric codes), and TPA expansion values and returns the forest type classification. Due to some implementation details, there is a second bool
parameter to simulate southern variant specific logic.
There are also convenience lookup tables to convert between forest type, forest type group, and their text names.
fortyp_name()
returns the string name of a given forest type code
fortypgroup()
returns the forest type group int of a given forest type
fortypgroup_name()
returns the string name of a given forest type group code
If the forest type code is not found, it will just return a null string.
A library libfortyp
can be built using CMake
and supports out-of-source builds.
git clone
cd fortyp
mkdir build #or whatever you want to call it
cd build
cmake .. #add -DBUILD_SHARED_LIBS=ON for shared library, otherwise will be static
make
There is a small demo with some example data included in the demo
folder. To compile the demo replace the cmake
statement above with:
cmake -DBUILD_DEMO=ON ..
which can then be executed by running the ./demo_stocking
executable.
from ctypes import *
fortyplib = cdll.LoadLibrary("./path/to/libfortyp.so")
#convert a forest type to forest type group
fortyplib.fortypgroup.restype = c_int
fortyplib.fortypgroup.argtypes = [c_int]
fortyplib.fortypgroup(101) #100
#get the name of a forest type group
fortyplib.fortypgroup_name.restype = c_char_p
fortyplib.fortypgroup_name.argtypes = [c_int]
fortyplib.fortypgroup_name(200).decode("utf-8") #"Douglas-fir"
#get the name of a forest type
fortyplib.fortyp_name.restype = c_char_p
fortyplib.fortyp_name.argtypes = [c_int]
fortyplib.fortyp_name(201).decode("utf-8") #"Douglas-fir"
using Libdl
lib = Libdl.dlopen("./build2/lib/libfortyp.so")
ccall(Libdl.dlsym(lib, :fortypgroup), Int32, (
Ref{Cint},
), Ptr{Cint}(201))
x1 = ccall(Libdl.dlsym(lib, :fortypgroup_name), Ptr{UInt8}, (
Ref{Cint},
), Ptr{Cint}(200))
unsafe_string(x1)
x2 = ccall(Libdl.dlsym(lib, :fortyp_name), Ptr{UInt8}, (
Ref{Cint},
), Ptr{Cint}(201))
unsafe_string(x2)
TO DO?:
- generalize and clean up input structure
- add some error handling to map lookups
- cleaner way to handle variant logic?
- add
python
/R
interop examples
PRs/issues welcome