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)

Gallery generated by Sphinx-Gallery