Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
if: runner.os == 'macOS'
run: |
brew update
brew install libzip eigen googletest ninja lcov
brew install libzip eigen googletest ninja lcov zlib

- name: Install dependencies (Windows)
if: runner.os == 'Windows'
Expand All @@ -45,6 +45,7 @@ jobs:
libzip `
eigen3 `
gtest `
zlib `
--triplet x64-windows

- name: Setup MSVC environment (Windows)
Expand All @@ -60,6 +61,7 @@ jobs:
-DTRX_USE_CONAN=OFF \
-DTRX_BUILD_TESTS=ON \
-DTRX_BUILD_EXAMPLES=ON \
-DTRX_ENABLE_NIFTI=ON \
-DCMAKE_PREFIX_PATH="${BREW_PREFIX}" \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_FLAGS="--coverage" \
Expand All @@ -72,6 +74,7 @@ jobs:
-G Ninja
-DTRX_USE_CONAN=OFF
-DTRX_BUILD_TESTS=ON
-DTRX_ENABLE_NIFTI=ON
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/trx-cpp-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
-G Ninja \
-DTRX_BUILD_TESTS=ON \
-DTRX_BUILD_EXAMPLES=ON \
-DTRX_ENABLE_NIFTI=ON \
-DGTest_DIR=${GITHUB_WORKSPACE}/deps/googletest/install/lib/cmake/GTest \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_FLAGS="--coverage" \
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ tests/data
test_package/build/
test_package/CMakeUserPresets.json
syntax.log
docs/_build/
docs/api/

test_package/build
test_package/CMakeUserPresets.json
29 changes: 29 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: 2

build:
os: ubuntu-22.04
tools:
python: "3.11"
apt_packages:
- cmake
- g++
- pkg-config
- zlib1g-dev
- libeigen3-dev
- libzip-dev
- ninja-build
- zipcmp
- zipmerge
- ziptool

jobs:
pre_build:
- cmake -S . -B build -DTRX_BUILD_DOCS=ON
- cmake --build build --target docs

python:
install:
- requirements: docs/requirements.txt

sphinx:
configuration: docs/conf.py
42 changes: 42 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ project(trx VERSION 0.1.0)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(FetchContent)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

set(TRX_IS_TOP_LEVEL OFF)
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
Expand All @@ -25,6 +26,8 @@ option(TRX_BUILD_TESTS "Build trx tests" OFF)
option(TRX_BUILD_EXAMPLES "Build trx example commandline programs" ON)
option(TRX_ENABLE_CLANG_TIDY "Run clang-tidy during builds" OFF)
option(TRX_ENABLE_INSTALL "Install trx-cpp targets" ${TRX_IS_TOP_LEVEL})
option(TRX_BUILD_DOCS "Build API documentation with Doxygen/Sphinx" OFF)
option(TRX_ENABLE_NIFTI "Enable optional NIfTI header utilities" ${TRX_BUILD_EXAMPLES})

if(TRX_ENABLE_CLANG_TIDY)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand Down Expand Up @@ -84,6 +87,7 @@ endif()

add_library(trx
src/trx.cpp
src/detail/dtype_helpers.cpp
include/trx/trx.h
include/trx/trx.tpp
third_party/json11/json11.cpp
Expand Down Expand Up @@ -144,6 +148,25 @@ if(TRX_BUILD_TESTS)
endif()
endif()

if(TRX_ENABLE_NIFTI)
find_package(ZLIB REQUIRED)
add_library(trx-nifti
src/nifti_io.cpp
)
add_library(trx-cpp::trx-nifti ALIAS trx-nifti)
target_compile_features(trx-nifti PUBLIC cxx_std_17)
target_include_directories(trx-nifti
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_link_libraries(trx-nifti
PUBLIC
Eigen3::Eigen
ZLIB::ZLIB
)
endif()

if(TRX_BUILD_EXAMPLES)
FetchContent_Declare(
cxxopts
Expand All @@ -154,6 +177,25 @@ if(TRX_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()

if(TRX_BUILD_DOCS)
find_package(Doxygen QUIET)
find_program(TRX_SPHINX_BUILD_EXE NAMES sphinx-build)
if(DOXYGEN_FOUND AND TRX_SPHINX_BUILD_EXE)
add_custom_target(docs
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/docs/_build/doxygen
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile
COMMAND ${TRX_SPHINX_BUILD_EXE} -b html
${CMAKE_CURRENT_SOURCE_DIR}/docs
${CMAKE_CURRENT_SOURCE_DIR}/docs/_build/html
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs
COMMENT "Building Doxygen XML and Sphinx HTML docs"
VERBATIM
)
else()
message(STATUS "Docs disabled: Doxygen or sphinx-build not found.")
endif()
endif()

# Installation and package config
if(TRX_ENABLE_INSTALL)
set(TRX_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/trx-cpp")
Expand Down
162 changes: 11 additions & 151 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,22 @@
TRX-cpp is a C++11 library for reading, writing, and memory-mapping the TRX
tractography file format (zip archives or on-disk directories of memmaps).

## Dependencies
## Documentation

Required:
- C++11 compiler and CMake (>= 3.10)
- libzip
- Eigen3
Project documentation lives in `docs/` and includes build/usage instructions
plus the API reference. Build the site locally with the `docs` CMake target:

Optional:
- GTest (for building tests)

## Build and Install

### Quick build (no tests)

```
cmake -S . -B build
cmake --build build
```

### Build with tests

```
cmake -S . -B build \
-DTRX_BUILD_TESTS=ON \
-DGTest_DIR=/path/to/GTestConfig.cmake
cmake --build build
ctest --test-dir build --output-on-failure
```

## Style checks

This repo includes `.clang-tidy` and `.clang-format` at the root, plus
MRtrix-inspired helper scripts for formatting and style checks.

### Prerequisites

- `clang-format` available on `PATH`
- macOS (Homebrew): `brew install llvm` (or `llvm@17`) and ensure `clang-format` is on `PATH`
- Ubuntu: `sudo apt-get install clang-format`
- For `check_syntax` on macOS, GNU grep is required (`brew install grep`, then it will use `ggrep`).

### clang-format (bulk formatting)

Run the formatter across repo sources:

```
./clang-format-all
```

You can target a specific clang-format binary:

```
./clang-format-all --executable /path/to/clang-format
```

### check_syntax (style rules)

Run the MRtrix-style checks against the C++ sources:

```
./check_syntax
```

Results are written to `syntax.log` when issues are found.

### clang-tidy

Generate a build with compile commands, then run clang-tidy (matches CI):

```
cmake -S . -B build \
-DTRX_USE_CONAN=OFF \
-DTRX_BUILD_EXAMPLES=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
run-clang-tidy -p build $(git ls-files '*.cpp' '*.h' '*.hpp' '*.tpp' ':!third_party/**')
```
# Install prerequisites (Ubuntu example)
sudo apt-get install -y doxygen python3-pip
python3 -m pip install --user -r docs/requirements.txt

To run clang-tidy automatically during builds:

```
cmake -S . -B build -DTRX_ENABLE_CLANG_TIDY=ON
cmake --build build
# Configure once, then build the docs target
cmake -S . -B build
cmake --build build --target docs
```

If you have `run-clang-tidy` installed (LLVM extras), you can lint everything
tracked by the repo (excluding `third_party`), which matches CI.
Open `docs/_build/html/index.html` in a browser.


## Third-party notices
Expand All @@ -104,75 +34,5 @@ tracked by the repo (excluding `third_party`), which matches CI.

## Usage Examples

All examples assume:

```
#include <trx/trx.h>

using namespace trxmmap;
```

### Read a TRX zip and inspect data

```
TrxFile<half> *trx = load_from_zip<half>("tracks.trx");

// Access streamlines: vertices are stored as an Eigen matrix
const auto num_vertices = trx->streamlines->_data.size() / 3;
const auto num_streamlines = trx->streamlines->_offsets.size() - 1;

std::cout << "Vertices: " << num_vertices << "\n";
std::cout << "Streamlines: " << num_streamlines << "\n";
std::cout << "First vertex (x,y,z): "
<< trx->streamlines->_data(0, 0) << ","
<< trx->streamlines->_data(0, 1) << ","
<< trx->streamlines->_data(0, 2) << "\n";

// Data-per-streamline and data-per-vertex are stored in maps
for (const auto &kv : trx->data_per_streamline) {
std::cout << "DPS '" << kv.first << "' elements: "
<< kv.second->_matrix.size() << "\n";
}
for (const auto &kv : trx->data_per_vertex) {
std::cout << "DPV '" << kv.first << "' elements: "
<< kv.second->_data.size() << "\n";
}

trx->close(); // cleans up temporary on-disk data
delete trx;
```

### Read from an on-disk TRX directory

```
TrxFile<float> *trx = load_from_directory<float>("/path/to/trx_dir");
std::cout << "Header JSON:\n" << trx->header.dump() << "\n";
trx->close();
delete trx;
```

### Write a TRX file

You can modify a loaded `TrxFile` and save it to a new archive:

```
TrxFile<half> *trx = load_from_zip<half>("tracks.trx");

// Example: update header metadata
auto header_obj = trx->header.object_items();
header_obj["COMMENT"] = "saved by trx-cpp";
trx->header = json(header_obj);

// Save with no compression (ZIP_CM_STORE) or another libzip compression level
save(*trx, "tracks_copy.trx", ZIP_CM_STORE);

trx->close();
delete trx;
```

### Notes on memory mapping

`TrxFile` uses memory-mapped arrays under the hood for large datasets. The
`close()` method cleans up any temporary folders created during zip extraction.
If you skip `close()`, temporary directories may be left behind.
See the documentation in `docs/` for examples and API details.

19 changes: 19 additions & 0 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
PROJECT_NAME = "trx-cpp"
PROJECT_BRIEF = "C++ library for reading and writing the TRX format."

OUTPUT_DIRECTORY = _build/doxygen

GENERATE_HTML = NO
GENERATE_LATEX = NO
GENERATE_XML = YES
XML_OUTPUT = xml

INPUT = ../include ../src
RECURSIVE = YES
FILE_PATTERNS = *.h *.hpp *.tpp

EXTRACT_ALL = YES
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_NAMESPACES = YES
EXCLUDE_SYMBOLS = Eigen* trx::detail*
QUIET = YES
Loading
Loading