Reconstruction#

lauelab.reconstruct provides an in-process Reconstructor and supported subprocess wrappers. The CPU executable, reconstructN_cpu, ships with the package. The CUDA executable, reconstructN_gpu, requires a separate CUDA build and must be available on PATH unless you pass its path explicitly.

See Reconstruct a wire scan for usage and Depth reconstruction for the calculation.

All paths return a ReconstructionResult. Runtime failures are recorded in that result. Invalid arguments and setup failures that occur before processing raise exceptions. The native path does not support the executable’s -F parameter-file option or distortion maps.

The subprocess environment defaults OPENBLAS_NUM_THREADS to 1. The reconstruction programs link OpenBLAS through GSL but do not call BLAS, so extra OpenBLAS workers only consume CPU time. An existing caller setting is preserved. The num_threads argument independently controls the CPU program’s OpenMP reconstruction threads. The executable’s image_range (-f/-l) options apply only to scans stored as one file per image; multi-image HDF5 input used by Reconstructor has no file range.

Behaviour changes in this release#

The reconstructN_cpu option -n <tag> previously had no effect because the normalization-vector length was taken from an HDF5 status code. It now scales each scan frame by entry1/<tag>, falling back to <tag> at the file root, divided by 102 for mA and 88100 for cnt3. The in-process path applies the same divisors but reads only entry1/<tag>, and it raises InputError when that vector is missing or shorter than the scan. The executable silently skips normalization in the same case. This asymmetry is deliberate: the in-process path reports a request it cannot honour.

A wire axis exactly parallel to the positioner x axis, with a zero wire rotation vector, now uses the identity transformation in both reconstruction paths. Earlier reconstructN_cpu releases produced non-finite values for this valid zero-rotation geometry.

class lauelab.reconstruct.Reconstructor(geometry, detector, *, depth_range, resolution=1.0, wire_edge='leading', percent_brightest=100.0, normalization=None, norm_exponent=None, norm_threshold=None, cosmic_filter=False, output_pixel_type=None, num_threads=None, rows_per_stripe=None, memory_limit_mb=8192)[source]#

Reusable in-process wire-scan reconstructor.

Parameters:
  • geometry (Geometry or pathlib.Path) – Parsed geometry or path to a geometry XML file. The geometry must contain a complete wire section.

  • detector (int) – Active detector slot in geometry. This is a physical geometry slot, not an ordinal position among active detectors.

  • depth_range (tuple of float) – Inclusive (start, end) sample depths in µm along the incident beam, relative to the Si origin in geometry. Values must be finite and nondecreasing. Equal endpoints request one depth.

  • resolution (float) – Distance between reconstructed depths in µm. The default is 1.0. The value must be positive and finite.

  • wire_edge (str) – Wire edge or edges used for reconstruction: "leading", "trailing", or "both". The default is "leading". "both" defaults file output to pixel-type code 1 when output_pixel_type is omitted.

  • percent_brightest (float) – Percentage of the brightest intensity-map pixels retained by the reconstruction mask. The default is 100.0. The value must be greater than 0 and at most 100.

  • normalization (str or None) – HDF5 vector below entry1 used to scale file-input frames. The default is None. "mA" values are divided by 102 and "cnt3" values by 88100; other tags have no fixed divisor. A missing or short vector raises InputError. This parameter does not apply to reconstruct_array(); pass its scale argument instead.

  • norm_exponent (float or None) – Exponent normalization applied from the intensity map. The default is None. Values must be greater than 0 and at most 5. This normalization applies to file and array input.

  • norm_threshold (float or None) – Positive intensity threshold for exponent normalization. The default is None; in that case, the threshold is the mean plus five standard deviations of the lowest half of the intensity-map pixels.

  • cosmic_filter (bool) – Apply the executable-compatible cosmic-ray filter before reconstruction. The default is False.

  • output_pixel_type (int or None) – Output-file pixel type. The default is None. Code 0 is numpy.float32, 1 is numpy.int32, 2 is numpy.int16, 3 is numpy.uint16, 5 is numpy.float64, 6 is numpy.int8, and 7 is numpy.uint8. File input defaults to the input type when it has a corresponding code, otherwise to code 5; wire_edge="both" defaults to code 1. This parameter does not alter arrays returned by reconstruct_array().

  • num_threads (int or None) – Positive OpenMP thread count for each reconstruction call. The default is None, which estimates physical cores from Linux SMT topology and otherwise uses the logical CPU count.

  • rows_per_stripe (int or None) – Positive number of image rows processed per stripe. The default is None, which uses at most 256 rows and may use fewer to satisfy memory_limit_mb.

  • memory_limit_mb (int) – Positive stripe-buffer limit in MiB. The default is 8192. It does not include retained result images or HDF5 library buffers.

Notes

Invalid arguments and failures before stripe processing raise an exception. After processing starts, an expected reconstruction or I/O failure returns a ReconstructionResult with success=False and partial progress.

reconstruct(path, output_base=None, *, return_images=False)[source]#

Reconstruct one HDF5 point, optionally writing per-depth files.

Parameters:
  • path (pathlib.Path or str) – Input 34-ID-E multi-image HDF5 file.

  • output_base (pathlib.Path, str, or None) – Output filename prefix. The default is None. When supplied, one HDF5 file is written per depth plus <output_base>summary.txt. Existing output files are replaced.

  • return_images (bool) – Retain the unscaled reconstructed images in memory. The default is False. This is independent of writing output files.

Returns:

ReconstructionResult – Reconstruction status, output paths, depth coordinates, intensity totals, timings, and optional images.

Raises:
  • InputError – If the input path, file metadata, geometry, or options are invalid, or setup fails before stripe processing begins.

  • MemoryError – If allocation fails before stripe processing begins.

Return type:

ReconstructionResult

reconstruct_array(images, wire_xyz, *, intensity_map=None, positioner='none', image_geometry=None, scale=None)[source]#

Reconstruct aligned in-memory images and raw wire positions.

Parameters:
  • images (numpy.ndarray) – Numeric array with shape (N, rows, columns). numpy.uint16 input remains uint16; every other numeric dtype is converted to contiguous numpy.float64 storage.

  • wire_xyz (numpy.ndarray) – Raw wire positions with shape (N + 1, 3) in the acquisition coordinate system. No file-format bookkeeping offset is applied.

  • intensity_map (numpy.ndarray or None) – Intensity map with shape (rows, columns) used for the bright-pixel mask and exponent normalization. The default is None, which uses the first image.

  • positioner (str) – Historical correction applied to wire_xyz: "none", "pm500", or "alio". The default is "none".

  • image_geometry (ImageGeometry or None) – Full-detector dimensions and ROI mapping. The default is None, which describes an unbinned, zero-based full frame whose detector size is exactly (columns, rows). Binned images and detector ROIs require an explicit geometry; start and group use unbinned pixels.

  • scale (numpy.ndarray or None) – Per-image dimensionless scale factors with shape (N,). The default is None. This is the array-path equivalent of the constructor’s HDF5 normalization vector.

Returns:

ReconstructionResult – A result whose images field is an unscaled numpy.float64 array. Array reconstruction does not write files.

Return type:

ReconstructionResult

Notes

The constructor’s normalization and output_pixel_type parameters do not apply on this path. norm_exponent still applies through intensity_map.

Raises:
  • InputError – If an array shape, dtype, positioner, geometry, or scale is invalid, or setup fails before stripe processing begins.

  • MemoryError – If allocation fails before stripe processing begins.

class lauelab.reconstruct.ImageGeometry(nx_full, ny_full, start=(0, 0), group=(1, 1), n_rows=None, n_cols=None)[source]#

Detector ROI geometry in unbinned-pixel coordinates.

Parameters:
  • nx_full (int) – Full detector width in unbinned pixels.

  • ny_full (int) – Full detector height in unbinned pixels.

  • start (tuple of int) – Zero-based (x, y) coordinate of the ROI origin in unbinned pixels. The default is (0, 0).

  • group (tuple of int) – (x, y) detector binning factors. The default is (1, 1).

  • n_rows (int or None) – Binned image height. The default is None, which uses ny_full // group[1].

  • n_cols (int or None) – Binned image width. The default is None, which uses nx_full // group[0].

property shape: tuple[int, int]#

Binned image shape as (rows, columns).

class lauelab.reconstruct.StripeTiming(row_start, row_stop, read_seconds, compute_seconds, write_seconds)[source]#

Elapsed I/O and native compute time for one row stripe.

row_start#

Zero-based first image row in the stripe.

Type:

int

row_stop#

Exclusive image-row stop index.

Type:

int

read_seconds#

Input read time in seconds.

Type:

float

compute_seconds#

Native reconstruction time in seconds.

Type:

float

write_seconds#

Output write time in seconds, or 0 when no files are written.

Type:

float

class lauelab.reconstruct.ReconstructionResult(success, output_files, log, error=None, command='', return_code=0, images=None, depth_um=None, depth_intensity=None, timings=None, last_completed_stripe=None)[source]#

Result from subprocess or in-process wire-scan reconstruction.

The first six fields preserve the positional constructor interface of the former named tuple. Native-only arrays and stripe timings are None on the subprocess path.

success#

True when reconstruction completed. Invalid arguments and setup failures raise instead of returning a result. Failures after native stripe processing starts set this field to False and preserve available partial progress.

Type:

bool

output_files#

Paths written by this call. For in-process file reconstruction these are the per-depth HDF5 files followed by the summary file. The list can contain partial output after a runtime failure.

Type:

list of str

log#

Standard output captured from a subprocess. The in-process path returns an empty string.

Type:

str

error#

Standard error from an unsuccessful subprocess or the in-process runtime error message. None indicates no reported error.

Type:

str or None

command#

Executed subprocess command. The in-process path returns "liblaue".

Type:

str

return_code#

Subprocess exit status. The in-process path returns 0 on success and -1 for a runtime failure represented by this result.

Type:

int

images#

Retained reconstructed images with shape (n_depths, rows, columns) and dtype numpy.float64. These values are not multiplied by the integer-output normalization rescale. They are present only when the in-process path retains images.

Type:

numpy.ndarray or None

depth_um#

Sample depths with shape (n_depths,) and dtype numpy.float64, in µm along the incident beam relative to the Si origin in the geometry file. This field is native-only.

Type:

numpy.ndarray or None

depth_intensity#

Sum of each unscaled reconstructed image, with shape (n_depths,) and dtype numpy.float64. This field is native-only.

Type:

numpy.ndarray or None

timings#

Per-stripe read, native compute, and write timings in seconds. This field is native-only.

Type:

list of StripeTiming or None

last_completed_stripe#

Zero-based index of the last stripe fully written to every output file, or the last stripe computed when no files are written. None means no stripe completed. This field is native-only.

Type:

int or None

ReconstructionResult is a dataclass with the same six leading fields as the former named tuple. Attribute access and positional construction are unchanged; tuple unpacking is not supported.

lauelab.reconstruct.reconstruct_points(paths, output_dir, *, geometry, detector, workers=None, threads_per_worker=16, **reconstructor_kwargs)[source]#

Reconstruct point files in spawn-based worker processes.

Each worker creates one reusable Reconstructor. Spawn avoids forking a process after the OpenMP runtime has initialized.

Parameters:
  • paths – Sequence of input 34-ID-E multi-image HDF5 point paths. Results preserve this order.

  • output_dir (pathlib.Path or str) – Directory for reconstructed files. Each point uses <stem>_ as its output filename prefix. The directory is created after options are validated.

  • geometry (Geometry, pathlib.Path, or str) – Parsed geometry or path to a geometry XML file.

  • detector (int) – Active physical detector slot in geometry.

  • workers (int or None) – Positive worker-process count. The default is None, which uses the physical-core estimate divided by threads_per_worker, with at least one worker.

  • threads_per_worker (int) – Positive OpenMP thread count used by each worker. The default is 16.

  • **reconstructor_kwargs – Keyword arguments for Reconstructor, including the required depth_range. Do not pass num_threads; use threads_per_worker instead.

Returns:

list of ReconstructionResult – One result per input path, in input order. An expected input, memory, or I/O failure sets success=False for that point without stopping the remaining points.

Raises:
  • ValueError – If a worker or thread count is invalid, or num_threads is passed.

  • InputError – If the shared reconstructor configuration is invalid.

lauelab.reconstruct.reconstruct(input_file, output_file, geometry, depth_range, resolution=1.0, *, image_range=None, verbose=1, percent_brightest=100.0, wire_edge='leading', memory_limit_mb=8192, executable=None, timeout=7200, normalization=None, output_pixel_type=None, distortion_map=None, detector_number=0, wire_depths_file=None, num_threads=None, rows_per_stripe=None, cosmic_filter=False, norm_exponent=None, norm_threshold=None)[source]#

Reconstruct wire-scan data with the native CPU executable.

Parameters:
  • input_file (str | Path) – Path to the input HDF5 file.

  • output_file (str | Path) – Base path for output files, without an extension.

  • geometry (str | Path) – Path to the geometry XML file.

  • depth_range (Tuple[float, float]) – Start and end depths in micrometres. The start must be less than the end.

  • resolution (float) – Depth resolution in micrometres. The default is 1.0.

  • image_range (Tuple[int, int] | None) – First and last image indices. By default, the executable processes its full input range.

  • verbose (int) – Native verbosity level from 0 through 3. The default is 1.

  • percent_brightest (float) – Percentage of the brightest pixels to process. The default is 100.0.

  • wire_edge (str) – Wire edge. Use "leading", "trailing", or "both". The corresponding short forms "l", "t", and "b" are also accepted.

  • memory_limit_mb (int) – Native memory limit in MB. The default is 8192.

  • executable (str | None) – Path to reconstructN_cpu. By default, the function searches the installed package and then PATH.

  • timeout (int) – Process timeout in seconds. The default is 7200.

  • normalization (str | None) – Native normalization tag.

  • output_pixel_type (int | None) – Native WinView output pixel type from 0 through 7.

  • distortion_map (str | None) – Path to a distortion-map file.

  • detector_number (int) – Detector number passed to the native executable. The default is 0.

  • wire_depths_file (str | None) – Path to a file that contains wire-depth corrections.

  • num_threads (int | None) – Number of OpenMP threads. By default, the executable selects the count.

  • rows_per_stripe (int | None) – Rows processed per stripe. By default, the executable uses its own value.

  • cosmic_filter (bool) – Enable native cosmic-ray filtering.

  • norm_exponent (float | None) – Exponent for image-intensity scaling.

  • norm_threshold (float | None) – Threshold for image-intensity scaling.

Returns:

ReconstructionResult – Process status, output paths, captured output, command, and return code.

Raises:
  • FileNotFoundError – If the CPU executable is not in the installed package or on PATH.

  • RuntimeError – If the executable does not produce the expected help output.

  • ValueError – If depth_range or wire_edge is invalid.

Return type:

ReconstructionResult

lauelab.reconstruct.reconstruct_gpu(input_file, output_file, geometry, depth_range, resolution=1.0, *, image_range=None, verbose=1, percent_brightest=100.0, wire_edge='leading', memory_limit_mb=8192, executable=None, timeout=7200, normalization=None, output_pixel_type=None, distortion_map=None, detector_number=0, wire_depths_file=None, cuda_rows=8)[source]#

Reconstruct wire-scan data with the native CUDA executable.

The CUDA program does not support cosmic-ray filtering, norm_exponent, or norm_threshold. Use reconstruct() when you need those options.

Parameters:
  • input_file (str | Path) – Path to the input HDF5 file.

  • output_file (str | Path) – Base path for output files, without an extension.

  • geometry (str | Path) – Path to the geometry XML file.

  • depth_range (Tuple[float, float]) – Start and end depths in micrometres. The start must be less than the end.

  • resolution (float) – Depth resolution in micrometres. The default is 1.0.

  • image_range (Tuple[int, int] | None) – First and last image indices. By default, the executable processes its full input range.

  • verbose (int) – Native verbosity level from 0 through 3. The default is 1.

  • percent_brightest (float) – Percentage of the brightest pixels to process. The default is 100.0.

  • wire_edge (str) – Wire edge. Use "leading", "trailing", or "both". The corresponding short forms "l", "t", and "b" are also accepted.

  • memory_limit_mb (int) – Native memory limit in MB. The default is 8192.

  • executable (str | None) – Path to reconstructN_gpu. By default, the function searches the installed package and then PATH.

  • timeout (int) – Process timeout in seconds. The default is 7200.

  • normalization (str | None) – Native normalization tag.

  • output_pixel_type (int | None) – Native WinView output pixel type from 0 through 7.

  • distortion_map (str | None) – Path to a distortion-map file.

  • detector_number (int) – Detector number passed to the native executable. The default is 0.

  • wire_depths_file (str | None) – Path to a file that contains wire-depth corrections for each pixel.

  • cuda_rows (int) – Number of CUDA rows to process. The default is 8.

Returns:

ReconstructionResult – Process status, output paths, captured output, command, and return code.

Raises:
  • FileNotFoundError – If the CUDA executable is not in the installed package or on PATH.

  • RuntimeError – If the executable does not produce the expected help output.

  • ValueError – If depth_range or wire_edge is invalid.

Return type:

ReconstructionResult

lauelab.reconstruct.find_executable()[source]#

Find the native CPU reconstruction executable.

Returns:

str – Path to reconstructN_cpu in the installed package or on PATH.

Raises:

FileNotFoundError – If the executable cannot be found.

Return type:

str

lauelab.reconstruct.find_gpu_executable()[source]#

Find the native CUDA reconstruction executable.

Returns:

str – Path to reconstructN_gpu in the installed package or on PATH.

Raises:

FileNotFoundError – If the executable cannot be found.

Return type:

str

lauelab.reconstruct.gpu_available()[source]#

Report whether the native CUDA reconstruction executable is usable.

Returns:

boolTrue if reconstructN_gpu is available and passes validation.

Return type:

bool

Wire metadata used by reconstruction is documented as {class}`lauelab.indexing.WireGeometry`.