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

374 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |
```python
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.
```python
obj = uLib.Core.Object()
copy = obj.DeepCopy()
```
### Timer
Precision wall-clock timer.
```python
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.
```python
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
```python
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
```python
# 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
```python
# 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.
```python
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.
```python
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.
```python
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).
```python
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
```python
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`).
```python
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)
```python
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.
```python
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()`.
```python
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
```python
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.
```python
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.
```python
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.
```python
filt = uLib.Math.VoxFilterAlgorithmThreshold(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetThreshold(0.5)
filt.Run()
```
### Median Filter
```python
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.
```python
# 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.
```python
# 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 …
```