Skip to content

title: API โ€” the object model description: pardesline.object: Object and its subclasses PointCloud, Mesh, Volume, LabelMap, RawArray, Transform, Image; Frame; conversions and sidecars.


Objects

pardesline.object.Object

Object(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

A local file (or DICOM folder), typed by its extension.

is_raw_array property

is_raw_array: bool

True for .npy / .npz / .bin / .raw files: data that only a layout can read.

layout property

layout: dict[str, Any] | None

How a raw array is to be read (dtype, shape, columns, key...), when declared.

registration_sidecar property

registration_sidecar: dict[str, Any] | None

The <name>.json written next to the file by registration ops.

transform property

transform: dict[str, Any] | None

The estimated transform of a registration output, when present.

with_layout

with_layout(**layout: Any) -> Object

A copy that declares the array layout, e.g. with_layout(dtype="float32", shape="(N,4)", columns=["x","y","z","reflectance"]).

with_frame

with_frame(axes: str | None = None, units: str | None = None, **more: Any) -> Object

A copy that states the frame (source="user"). Does not override what the file header itself says.

info

info() -> dict[str, Any]

Header-level facts (size, spacing, counts...) read lazily and cached.

methods

methods() -> list[str]

Qualified names of every catalog method that accepts this file type.

run

run(method: str, /, *, moving: Object | str | PathLike | None = None, output: str | PathLike | None = None, timeout: float | None = None, on_log: Callable[[str], None] | None = None, on_progress: Callable[[int], None] | None = None, **params: Any) -> Object

Run a catalog method on this object; the result is a new Object that inherits the frame and licence and records the step.

downsample

downsample(**params: Any) -> Object

Voxel downsampling (voxel_size).

remove_outliers

remove_outliers(**params: Any) -> Object

Statistical outlier removal (nb_neighbors, std_ratio).

normals

normals(**params: Any) -> Object

Normal estimation.

poisson

poisson(**params: Any) -> Object

Poisson surface reconstruction (depth, density_quantile).

icp

icp(moving: Object | str | PathLike, **params: Any) -> Object

ICP refinement: align moving onto this (fixed) cloud.

ransac

ransac(moving: Object | str | PathLike, **params: Any) -> Object

RANSAC global registration (FPFH features).

decimate

decimate(**params: Any) -> Object

Mesh decimation (target_reduction).

smooth

smooth(**params: Any) -> Object

Laplacian smoothing (n_iterations).

to_points

to_points(**params: Any) -> Object

Sample a mesh into a point cloud (Poisson-disk, num_points).

register

register(moving: Object | str | PathLike, **params: Any) -> Object

Rigid volume registration (SimpleITK): align moving onto this volume.

segment

segment(**params: Any) -> Object

Otsu threshold segmentation of a volume.

save

save(dest: str | PathLike, *, sidecar: bool = True) -> Path

Copy the file (plus its registration sidecar and .raw sibling for .mhd) to dest - a directory keeps the current name - and write <dest>.pardesline.json with frame, labels, licence and provenance. Returns the new path.

to_open3d

to_open3d()

Load as an Open3D geometry (PointCloud or TriangleMesh).

to_pyvista

to_pyvista()

Load with pyvista.read.

to_sitk

to_sitk()

Load a volume as a SimpleITK.Image (DICOM folders accepted).

to_numpy

to_numpy()

Points (N,3) for clouds, vertices for meshes, voxels (z,y,x) for volumes.

pardesline.object.PointCloud

PointCloud(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Object

to_mesh

to_mesh(**params: Any) -> Mesh

A surface from the points (Poisson, density-trimmed). Lossy and parametric - depth, density_quantile - the step records them.

align

align(moving: Object | str | PathLike, **params: Any) -> PointCloud

Coarse-to-fine rigid alignment of moving onto this cloud (RANSAC on FPFH features, then ICP). Returns the moved cloud; the transform is in .transform.

clean

clean(**params: Any) -> PointCloud

Statistical outlier removal.

segment

segment(**params: Any) -> PointCloud

DBSCAN clustering (eps, min_points); clusters are colours.

pardesline.object.Mesh

Mesh(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Object

to_points

to_points(**params: Any) -> PointCloud

Sample the surface into points (Poisson-disk, num_points).

clean

clean(**params: Any) -> Mesh

Merge duplicate points, drop degenerate cells.

pardesline.object.Volume

Volume(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Object

to_mesh

to_mesh(*, isovalue: float | None = None, label: int | None = None, output=None) -> Mesh

Isosurface in world coordinates. label=k is exact for a label map; isovalue=v is the level set of a grey-level volume. One of the two is required.

align

align(moving: Object | str | PathLike, **params: Any) -> Volume

Rigid registration of moving onto this volume (SimpleITK, GEOMETRY initialisation). The transform is in .transform.

segment

segment(*, lower: float | None = None, upper: float | None = None, **params: Any) -> LabelMap

Threshold segmentation: Otsu when no bounds are given, otherwise lower/upper in intensity units. Returns a LabelMap with label 1.

as_labels

as_labels(labels: dict[int, str] | None = None) -> LabelMap

Declare this volume a label map (voxel value = class id).

pardesline.object.LabelMap

LabelMap(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Volume

A volume whose voxel values are class ids. labels names them.

to_mesh

to_mesh(label: int | None = None, *, isovalue: float | None = None, output=None) -> Mesh

Exact boundary of one label. With a single named label it is the default.

pardesline.object.RawArray

RawArray(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Object

A .npy / .npz / .bin file: numbers without meaning until a layout says what they are. as_points(...) or as_volume(...) turn it into a typed object; a manifest role does the same for a dataset.

as_points

as_points(**layout: Any) -> PointCloud

Declare the array as points: as_points(dtype="float32", shape="(N,4)", columns=["x","y","z","reflectance"]).

as_volume

as_volume(labels: dict[int, str] | None = None, **layout: Any) -> Volume

Declare the array as a dense grid: as_volume(key="occ_label", shape="(200,200,16)", spacing=[0.4,0.4,0.4]); with labels it is a LabelMap.

pardesline.object.Transform

Transform(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Object

pardesline.object.Image

Image(path: str | PathLike, *, frame: Frame | None = None, labels: dict[int, str] | None = None, license: License | None = None, provenance: list[dict[str, Any]] | None = None, role: str | None = None, meta: dict[str, Any] | None = None, layout: Any = None, read_sidecar: bool = True)

Bases: Object

pardesline.object.frame.Frame dataclass

Frame(axes: str | None = None, units: str | None = None, affine: tuple[tuple[float, float, float, float], ...] | None = None, crs: str | None = None, source: str | None = None)

Where the coordinates of an object live.

axes: axis convention ("LPS" for DICOM/ITK volumes, "RAS" for NIfTI headers, "Y-up" for glTF, "sensor" for a LiDAR sweep...). units: length unit of one coordinate step. affine: 4x4 row-major matrix from index/local space to the world frame, when the file has one (volumes). crs: geographic reference for survey data. source: who stated it - "file" (read from the header), "format" (fixed by the specification), "manifest" or "user".

merged

merged(other: Frame | None) -> Frame

other fills what is unknown here; it never silently overrides a value the file itself stated.

pardesline.object.load_object

load_object(path: str | PathLike) -> Object

Open a file as the right :class:Object subclass, reading its sidecar when present.

Same as pl.load for a file.

pardesline.object.kind_of

kind_of(path: str | PathLike) -> str

The object kind a path maps to by extension.

One of pointcloud, mesh, volume, labels, array...; file when unknown.

pardesline.object.arrays

Raw arrays (.npy, .npz, .bin) read through a declared layout.

A raw array says nothing about what its numbers mean: KITTI's .bin is float32 (N,4) x, y, z, reflectance; a KITTI-360 chunk is coord.npy (N,3); an occupancy grid is (L,W,H) class ids. The layout comes from the manifest (or from the caller); nothing here guesses it. Decoded data is materialised in a standard file (PLY for points, MetaImage for grids) so the catalog ops - which read files - run unchanged.

load_array

load_array(path: str | PathLike, layout: Layout | dict[str, Any] | None) -> np.ndarray

Read the array exactly as the layout says. .npy/.npz carry their own dtype and shape (checked against the layout); .bin/.raw need dtype and a shape whose last dimensions are fixed.

decode_points

decode_points(path: str | PathLike, layout: Layout | dict[str, Any] | None) -> tuple[np.ndarray, dict[str, np.ndarray]]

(xyz float64 (N,3), attributes) from a points array. Columns are taken from the layout; without columns the first three are x, y, z and the rest are kept as col_<i>.

write_ply

write_ply(path: str | PathLike, xyz: ndarray, attrs: dict[str, ndarray] | None = None) -> Path

Binary little-endian PLY with x y z (double), optional colours (uchar red green blue), normals (nx ny nz) and one float property per other attribute. No dependency: pure NumPy.

array_to_points

array_to_points(path: str | PathLike, layout: Layout | dict[str, Any] | None, out_path: str | PathLike) -> dict[str, Any]

Materialise a points array as PLY. Returns a provenance step.

array_to_volume

array_to_volume(path: str | PathLike, layout: Layout | dict[str, Any] | None, out_path: str | PathLike) -> dict[str, Any]

Materialise a dense grid as MetaImage (.mha). The layout's spacing / origin (in the role's units) set the geometry; without them the grid gets unit spacing at the origin and the caller is told so.