Files
uLib/docs/python/usage.md
2026-03-06 10:45:33 +00:00

8.2 KiB
Raw Permalink Blame History

Python API Usage

The uLib Python package is split into two sub-modules mirroring the C++ library:

Sub-module Contents
uLib.Core Low-level utilities: Object, Timer, Options, TypeRegister
uLib.Math Geometry, grids, voxel images, ray-tracing, image filters
import uLib
# Sub-modules are accessible as attributes
uLib.Core   # core utilities
uLib.Math   # mathematical structures

uLib.Core

Object

Base class for uLib objects; exposed to Python for type-hierarchy purposes.

obj = uLib.Core.Object()
copy = obj.DeepCopy()

Timer

Precision wall-clock timer.

import time
timer = uLib.Core.Timer()
timer.Start()
time.sleep(0.5)
elapsed = timer.StopWatch()   # returns elapsed seconds as float
print(f"Elapsed: {elapsed:.3f} s")

Options

Wraps Boost.ProgramOptions for INI-style configuration files.

opt = uLib.Core.Options("My Program")
opt.parse_config_file("config.ini")   # load settings
n = opt.count("my_key")               # check if key exists
opt.save_config_file("out.ini")

uLib.Math Linear Algebra

The math module exposes Eigen3 vectors and matrices as well-typed Python objects with NumPy interoperability.

Fixed-size Vectors

import numpy as np
import uLib

# Construct from list
v3 = uLib.Math.Vector3f([1.0, 2.0, 3.0])
print(v3[0], v3[1], v3[2])   # 1.0 2.0 3.0

# Construct from NumPy array
arr = np.array([4.0, 5.0, 6.0], dtype=np.float32)
v3b = uLib.Math.Vector3f(arr)

# Zero-initialise
v4d = uLib.Math.Vector4d()    # all zeros

# Available types
# Vector1f / 2f / 3f / 4f  (float32)
# Vector1d / 2d / 3d / 4d  (float64)
# Vector1i / 2i / 3i / 4i  (int32)

Fixed-size Matrices

# 2-by-2 float matrix
m2f = uLib.Math.Matrix2f()
m2f[0, 0] = 1;  m2f[0, 1] = 2
m2f[1, 0] = 3;  m2f[1, 1] = 4

# From list (row-major)
m4f = uLib.Math.Matrix4f([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1])

# From NumPy (2-D array)
mat = np.eye(3, dtype=np.float32)
m3f = uLib.Math.Matrix3f(mat)

# Dynamic matrices
mXf = uLib.Math.MatrixXf(4, 4)   # 4×4 float, zeros

Homogeneous Types

# HPoint3f  a 3-D point in homogeneous coordinates (w = 1)
p = uLib.Math.HPoint3f(1.0, 2.0, 3.0)

# HVector3f  a free vector (w = 0)
v = uLib.Math.HVector3f(0.0, 1.0, 0.0)

# HLine3f  a parametric ray
line = uLib.Math.HLine3f()
line.origin    = uLib.Math.HPoint3f(0, 0, 0)
line.direction = uLib.Math.HVector3f(0, 0, 1)

uLib.Math Transforms and Geometry

AffineTransform

A rigid-body / affine transform stored as a 4×4 matrix.

tf = uLib.Math.AffineTransform()

tf.SetPosition([1.0, 0.0, 0.0])   # translate
tf.Translate([0.0, 1.0, 0.0])     # cumulative translate
tf.Scale([2.0, 2.0, 2.0])         # uniform scale
tf.Rotate(uLib.Math.Vector3f([0, 0, 3.14159]))  # Euler angles (rad)

mat4 = tf.GetWorldMatrix()   # 4×4 matrix
pos  = tf.GetPosition()      # Vector3f

Geometry

Inherits AffineTransform; converts points between world and local frames.

geo = uLib.Math.Geometry()
geo.SetPosition([1.0, 1.0, 1.0])

world_pt = uLib.Math.Vector4f([2.0, 3.0, 2.0, 1.0])
local_pt = geo.GetLocalPoint(world_pt)
back     = geo.GetWorldPoint(local_pt)
# back ≈ [2, 3, 2, 1]

ContainerBox

An axis-aligned bounding box with an associated transform.

box = uLib.Math.ContainerBox()
box.SetOrigin([-1.0, -1.0, -1.0])
box.SetSize([2.0, 2.0, 2.0])
print(box.GetSize())    # [2, 2, 2]

uLib.Math Structured Grids

StructuredGrid (3-D)

A 3-D voxel grid (origin, spacing, and integer dimensions).

dims = uLib.Math.Vector3i([10, 10, 10])
grid = uLib.Math.StructuredGrid(dims)
grid.SetSpacing([1.0, 1.0, 1.0])
grid.SetOrigin([0.0, 0.0, 0.0])

print(grid.GetSpacing())          # [1, 1, 1]
print(grid.IsInsideBounds([5, 5, 5, 1]))  # True
idx = grid.Find([2.5, 2.5, 2.5]) # returns grid cell index

Structured2DGrid / Structured4DGrid

grid2d = uLib.Math.Structured2DGrid()
grid2d.SetDims([100, 100])
grid2d.SetPhysicalSpace([0, 0], [1, 1])
print(grid2d.GetSpacing())

uLib.Math VoxImage

VoxImage is a 3-D voxel volume where each cell stores a Voxel ( .Value + .Count).

dims = uLib.Math.Vector3i([20, 20, 20])
img  = uLib.Math.VoxImage(dims)
img.SetSpacing([0.5, 0.5, 0.5])

# Access by linear index
img.SetValue(0, 42.0)
print(img.GetValue(0))    # 42.0

# Access by 3-D index
img.SetValue(uLib.Math.Vector3i([1, 1, 1]), 7.5)
print(img.GetValue(uLib.Math.Vector3i([1, 1, 1])))  # 7.5

# Clipping / masking helpers
cropped = img.clipImage(uLib.Math.Vector3i([2, 2, 2]),
                        uLib.Math.Vector3i([18, 18, 18]))
masked  = img.maskImage(0.0, 100.0, 0.0)   # mask outside [0, 100]

# I/O
img.ExportToVti("output.vti")
img.ImportFromVti("output.vti")

Voxel (element type)

vox = uLib.Math.Voxel()
vox.Value = 1.5
vox.Count = 3

data = img.Data()        # returns the underlying Vector_Voxel
vox0 = data[0]
print(vox0.Value, vox0.Count)

uLib.Math VoxRaytracer

Performs ray-tracing through a StructuredGrid and returns per-voxel chord lengths.

import numpy as np
import uLib

grid = uLib.Math.StructuredGrid([10, 10, 10])
grid.SetSpacing([1.0, 1.0, 1.0])
grid.SetOrigin([0.0, 0.0, 0.0])

rt = uLib.Math.VoxRaytracer(grid)

# Trace a ray between two homogeneous points (x, y, z, w=1)
p1 = np.array([0.5, 0.5, -1.0, 1.0], dtype=np.float32)
p2 = np.array([0.5, 0.5, 11.0, 1.0], dtype=np.float32)
result = rt.TraceBetweenPoints(p1, p2)

print("Voxels crossed:", result.Count())
print("Total length  :", result.TotalLength())

elements = result.Data()
for i in range(result.Count()):
    print(f"  vox_id={elements[i].vox_id}  L={elements[i].L:.4f}")

uLib.Math Image Filters

All filters share the same interface: construct with a kernel size, attach a VoxImage, optionally set parameters, then call .Run().

import uLib

dims = uLib.Math.Vector3i([10, 10, 10])
img  = uLib.Math.VoxImage(dims)
for i in range(10**3):
    img.SetValue(i, float(i))

kernel_dims = uLib.Math.Vector3i([3, 3, 3])

Linear (Gaussian / Box) Filter

filt = uLib.Math.VoxFilterAlgorithmLinear(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)   # uniform box kernel, length = product of dims
filt.Run()

ABTrim Filter

Applies alpha-beta trimming to remove outliers before averaging.

filt = uLib.Math.VoxFilterAlgorithmAbtrim(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetABTrim(2, 2)    # trim 2 low and 2 high values
filt.Run()

Bilateral Filter

Edge-preserving smoothing controlled by a spatial sigma (from the kernel shape) and an intensity sigma.

filt = uLib.Math.VoxFilterAlgorithmBilateral(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetIntensitySigma(0.3)
filt.Run()

Threshold Filter

Zeros voxels below a threshold.

filt = uLib.Math.VoxFilterAlgorithmThreshold(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetThreshold(0.5)
filt.Run()

Median Filter

filt = uLib.Math.VoxFilterAlgorithmMedian(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.Run()

uLib.Math Accumulators

Accumulators collect scalar samples and return a summary statistic.

# Arithmetic mean
acc = uLib.Math.Accumulator_Mean_f()
acc(10.0)
acc(20.0)
mean = acc()       # 15.0

# Alpha-beta trimmed mean
acc2 = uLib.Math.Accumulator_ABTrim_f()
acc2.SetABTrim(0.1, 0.1)   # trim bottom 10 % and top 10 %
acc2 += 1.0
acc2 += 9999.0             # outlier
acc2 += 5.0
result = acc2()            # trimmed mean ≈ 3.0

Dynamic Vectors (uLib.Math.Vector_*)

Typed dynamic arrays backed by uLib::Vector<T> with optional CUDA memory management.

# Integer vector
vi = uLib.Math.Vector_i()
vi.append(1); vi.append(2); vi.append(3)
print(len(vi), vi[0])

# Float vector with CUDA management
vf = uLib.Math.Vector_f()
vf.append(1.5)
vf.MoveToVRAM()   # copy to GPU (no-op when CUDA is absent)
vf.MoveToRAM()    # copy back to CPU

# Other types: Vector_ui, Vector_l, Vector_ul, Vector_d
# Compound element types: Vector_Vector3f, Vector_Vector4f, Vector_Voxel …