Note
Go to the end to download the full example code.
Reading and Writing TRX Files#
This tutorial demonstrates how to read and write TRX files using trx-python. TRX is a tractography file format designed for efficient storage and access of brain fiber tract streamline data.
By the end of this tutorial, you will know how to:
Load a TRX file from disk
Inspect the contents of a TRX file
Access streamlines and metadata
Save a TRX file to disk
Create a TRX file from scratch
Loading a TRX file#
Let’s start by loading an existing TRX file. First, we need to download some test data.
import os
import tempfile
from trx.fetcher import fetch_data, get_home, get_testing_files_dict
from trx.trx_file_memmap import load, save
# Download test data
fetch_data(get_testing_files_dict(), keys="gold_standard.zip")
trx_home = get_home()
trx_path = os.path.join(trx_home, "gold_standard", "gs.trx")
# Load the TRX file
trx = load(trx_path)
print("TRX file loaded successfully!")
TRX file loaded successfully!
Inspecting TRX file contents#
The TrxFile object has several key attributes that you can inspect. Let’s look at what’s inside our loaded file.
# Print a summary of the TRX file
print(trx)
VOXEL_TO_RASMM:
[[3.969615 -0.245576 0.007596 12.082228]
[0.491151 1.969615 -0.122788 22.164438]
[0.030384 0.245576 0.992404 37.917774]
[0.000000 0.000000 0.000000 1.000000]]
DIMENSIONS: [ 5 10 20]
VOX_SIZES: [4.00 2.00 1.00]
VOX_ORDER: RAS
streamline_count: 13
vertex_count: 104
data_per_vertex keys: ['color_y', 'color_z', 'color_x']
data_per_streamline keys: ['random_coord']
groups keys: []
copy_safe: True
The header contains essential metadata about the tractogram:
print("Header information:")
print(f" Number of streamlines: {trx.header['NB_STREAMLINES']}")
print(f" Number of vertices: {trx.header['NB_VERTICES']}")
print(f" Image dimensions: {trx.header['DIMENSIONS']}")
print(f" Voxel to RASMM affine:\n{trx.header['VOXEL_TO_RASMM']}")
Header information:
Number of streamlines: 13
Number of vertices: 104
Image dimensions: [ 5 10 20]
Voxel to RASMM affine:
[[ 3.9696155e+00 -2.4557561e-01 7.5961235e-03 1.2082228e+01]
[ 4.9115121e-01 1.9696155e+00 -1.2278780e-01 2.2164438e+01]
[ 3.0384494e-02 2.4557561e-01 9.9240386e-01 3.7917774e+01]
[ 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00]]
Accessing streamlines#
Streamlines are the core data in a TRX file. Each streamline is a sequence of 3D points representing a fiber tract in the brain.
print(f"Number of streamlines: {len(trx)}")
print(f"Total number of vertices: {len(trx.streamlines._data)}")
# Access the first streamline
first_streamline = trx.streamlines[0]
print(f"\nFirst streamline has {len(first_streamline)} points")
print(f"First 3 points of the first streamline:\n{first_streamline[:3]}")
Number of streamlines: 13
Total number of vertices: 104
First streamline has 8 points
First 3 points of the first streamline:
[[11.149319 21.579943 37.600685]
[11.153116 21.518549 38.096886]
[11.02653 22.56475 37.723473]]
Accessing metadata#
TRX files can contain additional data per vertex (dpv) and per streamline (dps).
print("Data per vertex (dpv) keys:", list(trx.data_per_vertex.keys()))
print("Data per streamline (dps) keys:", list(trx.data_per_streamline.keys()))
print("Groups:", list(trx.groups.keys()))
Data per vertex (dpv) keys: ['color_y', 'color_z', 'color_x']
Data per streamline (dps) keys: ['random_coord']
Groups: []
Selecting a subset of streamlines#
You can easily select a subset of streamlines using indices or slicing.
# Select first 5 streamlines
subset = trx[:5]
print(f"Subset has {len(subset)} streamlines")
# Select specific streamlines by indices (ensure indices are valid)
max_idx = len(trx) - 1
indices = [0, min(2, max_idx), min(5, max_idx)]
selected = trx.select(indices)
print(f"Selected {len(selected)} streamlines")
Subset has 5 streamlines
WARNING:root:Keeping dpg despite affecting the group items.
Selected 3 streamlines
Saving a TRX file#
You can save a TRX file back to disk. The file can be saved as a compressed or uncompressed zip archive, or as a directory.
with tempfile.TemporaryDirectory() as tmpdir:
# Save as TRX file (zip archive)
output_path = os.path.join(tmpdir, "output.trx")
save(trx, output_path)
print(f"Saved TRX file to: {output_path}")
print(f"File size: {os.path.getsize(output_path)} bytes")
# Reload to verify
reloaded = load(output_path)
print(f"Reloaded TRX has {len(reloaded)} streamlines")
Saved TRX file to: /tmp/tmpyoezlpp6/output.trx
File size: 3881 bytes
Reloaded TRX has 13 streamlines
Creating a TRX file from an existing one#
A common workflow is to create a new TRX file based on an existing one, preserving the spatial reference information.
# Create a deepcopy of the loaded TRX file
trx_copy = trx.deepcopy()
print(f"Created copy with {len(trx_copy)} streamlines")
print(f"Header preserved: DIMENSIONS = {trx_copy.header['DIMENSIONS']}")
Created copy with 13 streamlines
Header preserved: DIMENSIONS = [ 5 10 20]
Summary#
In this tutorial, you learned how to:
Load TRX files using
load()Inspect header information and streamline data
Access data per vertex (dpv) and data per streamline (dps)
Select subsets of streamlines
Save TRX files using
save()Create copies of TRX files using
deepcopy()
The TRX format is designed for memory efficiency through memory-mapping, making it suitable for large tractography datasets.
Total running time of the script: (0 minutes 0.274 seconds)