Skip to main content

OBAnalyser

OBAnalyser is a Python package for analysing open beam build data, with support for OBF and OBP workflows.

It can be used to:

  • extract build-level information such as layer timing, recoating data, and energy-related summaries
  • analyse OBP geometry and melt area information
  • rasterize full builds into per-layer image stacks
  • export JSON outputs that can be used in downstream processing pipelines

Installation

Install from PyPI:

pip install OBPAnalyser

For local development in a virtual environment:

python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt

Minimum example

import obanalyser.analyse_build as analyse_build
import obanalyser.plotters.plot_build_data as plot_build_data

path = r"tests\input\cubes_test\buildInfo.json"
build = analyse_build.analyse_build(path)
build.to_json(r"tests\output\build_info.json")

plot_build_data.plot_build_data(build)

This reads the build structure, analyses the layer content, writes a JSON summary, and plots the build data.

Export layer images

The package writes one grayscale PNG per layer directly into the output folder, named layer_0000.png, layer_0001.png, and so on:

  • Black (0): melted regions
  • Gray (190): sintered-only regions
  • Light gray (225): unscanned powder inside the build cylinder, when a radius is set
  • White (255): outside the cylinder (or empty space when no radius is set)

Melted regions stay black where scans overlap, regardless of scan order. No per-file images, subfolders, or metadata sidecars are generated. Each PNG embeds its pixel size, image dimensions in pixels and millimeters, physical bounds, zero-based layer index, Z step, cumulative Z height, and cylinder radius when supplied. Standard PNG physical resolution is also stored for image software that supports it.

from obanalyser.analyse_obf_geometry import write_obf_image_stack

build_path = r"tests\input\cubes_test\buildInfo.json"
output_dir = r"tests\output\layer_image_stack"

write_obf_image_stack(
    build_path,
    output_dir,
    pixel_um=200,
    close_gap_um=50,
    sinter_close_gap_um="auto",
    cylinder_radius_mm=50,
)

cylinder_radius_mm is optional and centers the cylinder at (0, 0) in build coordinates. The square image covers its diameter, rounded up to whole pixels; scans outside the circle are clipped. For example, a 50 mm radius with 200 µm pixels produces a 500 × 500 image covering 100 × 100 mm. Omitting the radius fits the image to the scanned regions as before.

Z context comes from layerFeed.buildPistonDistance in the build JSON, honoring layer defaults and per-layer overrides (or build.layerfeed.build_piston_distance in YAML). z_step_mm is the negative of the signed piston movement; z_height_mm accumulates these steps, with Z=0 before the first layer feed. For example, piston movements of -0.1 mm produce layer heights of 0.1, 0.2, 0.3 mm, etc. Zero steps and movements in the opposite direction retain their sign. These are planned relative build heights from the input, rather than measured absolute machine coordinates. Missing or invalid movement data stops export with an error instead of assigning an assumed height.

Sintered regions use automatic gap closing by default. The estimate uses the typical spacing between parallel preheat tracks (including rotated and reversed tracks), or nearest-neighbor spacing with a diagonal allowance for point scans, and the beam focus size. It includes a pixel-rounding allowance and caps the inferred spacing at four focus diameters to limit bridging between separate regions. Patterns with too few neighbors for an estimate retain their original coverage. This is a geometric representation of the sintered footprint, without an energy or thermal model.

Set sinter_close_gap_um to a number for manual control, 0 to disable sinter closing, or None to reuse close_gap_um. close_gap_um continues to control melt closing independently. Automatic closing can fill intentional gaps similar in size to the hatch spacing; use the manual override for those builds.

To read the embedded information with Pillow:

import json
from PIL import Image

with Image.open(r"tests\output\layer_image_stack\layer_0000.png") as image:
    info = json.loads(image.info["obanalyser"])
    print(info["pixel_size_um"], info["image_size_px"], info["image_size_mm"])
    print(info["layer_index"], info["z_step_mm"], info["z_height_mm"])

Example scripts

The repository includes runnable examples in the docs folder:

  • docs/examples.py
  • docs/example_create_image_stack.py

Notes

  • Spatial raster resolution for image stacks is controlled with pixel_um.
  • Melt gap closing is controlled with close_gap_um; sinter gap closing uses sinter_close_gap_um (default "auto").
  • write_obf_image_stack returns the image stack after saving the PNG files.
  • analyse_obf_geom returns a single-channel uint8 stack with shape [layer, row, col]; part colors and scan order do not affect pixel values.

Metadata

Release files for OBPAnalyser 0.0.14

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for OBPAnalyser 0.0.14
File Size Uploaded
obpanalyser-0.0.14.tar.gz 27.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for OBPAnalyser 0.0.14
File Interpreter ABI Platform
obpanalyser-0.0.14-py3-none-any.whl Python 3 none any Details

Total release size: 54.8 kB

Release files / obpanalyser-0.0.14.tar.gz

Download URL obpanalyser-0.0.14.tar.gz
Size 27.4 kB
Tags Source
SHA-256 checksum
How to use checksums
606ad2ba8319d573f26523cac92f2f472cc6190421c60e8f61d3a9195f53b2a3
BLAKE2b-256 checksum
How to use checksums
20c8cca7260f7cceb6bbc8150b28105fe48f4047b44e3d398fc60a9c44a20d63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.5

Release files / obpanalyser-0.0.14-py3-none-any.whl

Download URL obpanalyser-0.0.14-py3-none-any.whl
Size 27.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c2e4fd78847b978a036a68c768b8c2ca5883e1d6e84746848a8e9b937a48d31e
BLAKE2b-256 checksum
How to use checksums
ff6defc166174b9ca51d981af22017a40a40e93d6deb34f375111444aec78ed8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.5

Release history Release notifications | RSS feed

This release

0.0.14 This release

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.9

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page