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.
Use reconstruct_scan() to reconstruct points in local worker processes. It writes one HDF5 file per point and a shared scan.h5 catalog, then returns a ScanResult.
For an external scheduler, call prepare_scan() to get a PreparedScan coordinator and serializable PointTask objects. Workers execute tasks with reconstruct_point() and return a PointOutcome. You can also call reconstruct_point directly to write a standalone point.
To index a depth image, select it with ScanFrame, also importable from this module. To produce per-depth files for other tools, use export_per_depth(). Reconstruction scan format specifies the layouts, statuses, and pixel values.
Every other path returns 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 ingeometry. 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 whenoutput_pixel_typeis 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
entry1used to scale file-input frames. The default isNone."mA"values are divided by 102 and"cnt3"values by 88100; other tags have no fixed divisor. A missing or short vector raisesInputError. This parameter does not apply toreconstruct_array(); pass itsscaleargument 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 isnumpy.float32, 1 isnumpy.int32, 2 isnumpy.int16, 3 isnumpy.uint16, 5 isnumpy.float64, 6 isnumpy.int8, and 7 isnumpy.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 byreconstruct_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 satisfymemory_limit_mb. An explicit size must also fit the limit.memory_limit_mb (int) – Positive stripe-buffer limit in MiB. The default is
8192. It includes scan-output conversion and stripe-reduction buffers. It does not include retained result images, frame-sized maps/references, native per-thread scratch, or HDF5 library buffers; it is not an RSS limit. A budget too small for one row raisesInputError.
Notes
Invalid arguments and failures before stripe processing raise an exception. After processing starts, an expected reconstruction or I/O failure returns a
ReconstructionResultwithsuccess=Falseand 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:
- 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.uint16input remainsuint16; every other numeric dtype is converted to contiguousnumpy.float64storage.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 isNone, 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;startandgroupuse unbinned pixels.scale (numpy.ndarray or None) – Per-image dimensionless scale factors with shape
(N,). The default isNone. This is the array-path equivalent of the constructor’s HDF5normalizationvector.
- Returns:
ReconstructionResult – A result whose
imagesfield is an unscalednumpy.float64array. Array reconstruction does not write files.- Return type:
Notes
The constructor’s
normalizationandoutput_pixel_typeparameters do not apply on this path.norm_exponentstill applies throughintensity_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 usesny_full // group[1].n_cols (int or None) – Binned image width. The default is
None, which usesnx_full // group[0].
- 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.
- 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
Noneon the subprocess path.- success#
Truewhen reconstruction completed. Invalid arguments and setup failures raise instead of returning a result. Failures after native stripe processing starts set this field toFalseand preserve available partial progress.- Type:
- 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.
- log#
Standard output captured from a subprocess. The in-process path returns an empty string.
- Type:
- error#
Standard error from an unsuccessful subprocess or the in-process runtime error message.
Noneindicates no reported error.- Type:
str or None
- return_code#
Subprocess exit status. The in-process path returns 0 on success and -1 for a runtime failure represented by this result.
- Type:
- images#
Retained reconstructed images with shape
(n_depths, rows, columns)and dtypenumpy.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 dtypenumpy.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 dtypenumpy.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
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 bythreads_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 requireddepth_range. Do not passnum_threads; usethreads_per_workerinstead.
- Returns:
list of ReconstructionResult – One result per input path, in input order. An expected input, memory, or I/O failure sets
success=Falsefor that point without stopping the remaining points.- Raises:
ValueError – If a worker or thread count is invalid, or
num_threadsis passed.InputError – If the shared reconstructor configuration is invalid.
- lauelab.reconstruct.prepare_scan(paths, directory, *, geometry, detector, point_ids=None, compression=None, **reconstructor_kwargs)[source]#
Inspect scan inputs, publish the initial catalog, and return a coordinator.
- Parameters:
paths (Sequence[str | PathLike]) – Input 34-ID-E multi-image HDF5 point files, in manifest order. Each is made absolute against the current directory.
directory (pathlib.Path or str) – Scan directory. It must not exist or must be empty; it receives
scan.h5andpoints/<input stem>.h5for each input.geometry (Geometry, pathlib.Path, or str) – Parsed geometry or path to a geometry XML file with a wire section. Its text is embedded in the catalog and in every task.
detector (int) – Active physical detector slot in
geometry.point_ids (Sequence[str] | None) – Sequence of unique, non-empty strings corresponding to
paths, orNone, which uses the input stems. IDs are independent of the point filenames.compression (str or None) –
"gzip"compresses the stored frames losslessly; the default isNone.**reconstructor_kwargs – Keyword arguments for
Reconstructor, including the requireddepth_range, exceptnum_threads.
- Returns:
PreparedScan – The coordinator of the scan.
scan.h5already lists every input; a point whose input cannot be read is recorded as failed and has no task.- Raises:
InputError – If there are no inputs; the shared configuration,
point_ids, orcompressionis invalid;num_threadsis passed; or an input stem is unsafe or two inputs would write the same point file.FileExistsError – If
directoryexists and is not an empty directory.OSError – If the scan directory or catalog cannot be written.
- Return type:
Notes
All shared settings and destinations are checked before writing. Input inspection reads metadata without loading frames.
- class lauelab.reconstruct.PreparedScan(directory, tasks, run_values, catalog)[source]#
Track point outcomes and publish the scan catalog.
Created by
prepare_scan(). The coordinator is the only writer ofscan.h5: it holds the catalog in memory and batches changes into snapshots at most once every five seconds. Workers publish their own point files. Preparation and finalization publish immediately. Use it as a context manager in the process that prepared it; it cannot be sent to another process. Send its tasks instead.An external scheduler uses it in this order:
record_dispatch()when a task is handed to a worker,record()with the worker’s outcome, andfinish()after recording an outcome for every dispatched task. Assign each task once. If a worker is lost, record a failed outcome for its task; the coordinator does not retry it.- directory#
Absolute scan directory.
- Type:
- tasks#
Tasks of the points whose inputs passed inspection, in manifest order. Points that failed inspection are recorded in the catalog and have no task.
- snapshot(*, force=False)[source]#
Publish pending changes when five seconds have elapsed since publication.
Dispatch and outcome recording call this automatically. An external scheduler should also call it in its polling loop while waiting for workers, so pending changes become visible during long-running points. No background thread writes the catalog.
reconstruct_scanhandles this polling itself.Set
force=Trueto publish pending changes immediately. An unchanged catalog is never rewritten. Return whether a snapshot was published. Publication errors propagate; the previous snapshot remains available and pending changes remain in memory.
- record_dispatch(task)[source]#
Record that
taskwas handed to a worker, publishing a snapshot if due.The point’s status becomes
"writing"until its outcome is recorded.- Raises:
InputError – If the task is not one of this scan’s tasks, was already dispatched or recorded, or the run is no longer running.
OSError – If the catalog cannot be published.
- record(outcome)[source]#
Record the outcome of one task, publishing a snapshot if due.
A complete outcome is accepted only when its point file is published at the task’s output path and records the task’s identity, output description, scientific settings, geometry, source path, input selection, and acquisition metadata. Pixel values are not read. Outcomes can be recorded in any order.
- Raises:
InputError – If the outcome matches no task of this scan, the point was already recorded, the run is no longer running, or the outcome is neither complete nor failed with an error.
InvalidScanFile – If the point file of a complete outcome is invalid or disagrees with its task.
OSError – If the point file cannot be opened or the catalog cannot be published. The previous catalog snapshot is kept.
- finish(*, cancelled=False)[source]#
Record the end of the run, publish the final catalog, and return the result.
- Parameters:
cancelled (bool) –
Truewhen the run stopped before every task was dispatched. Points that were never dispatched become"unattempted".- Raises:
InputError – If a dispatched task has no recorded outcome; if points were never dispatched and
cancelledis false; or if the run already ended.OSError – If the catalog cannot be published.
- close()[source]#
Mark an unfinished run as failed and publish its final catalog.
Dispatched points without an outcome become
"interrupted"and points never dispatched become"unattempted". Safe to call more than once; it does nothing afterfinish(). Leaving the context never reports a successful run.
- class lauelab.reconstruct.PointTask(point_id, index, source, output, detector, settings, geometry_path, geometry_xml, compression, image_shape, n_depths, depth_bounds_um, pixel_type, raw_slices, scan_number, sample_position, energy_kev)[source]#
Serializable inputs and settings for reconstructing one point.
Tasks contain strings, numbers, and plain containers, so they can be pickled for a process pool or MPI. To serialize as JSON, first convert with
dataclasses.asdict(); rebuild withPointTask(**values). Each worker opens its own input and creates its own native state. Open files, native handles, and callbacks are never included in a task.- settings#
Reconstructorkeyword arguments other thannum_threads, validated and normalized. Treat as read-only.- Type:
- geometry_xml#
Complete geometry XML captured during preparation and used for every point, even if the original geometry file changes later.
- Type:
Notes
Before reconstruction, the worker checks that the output description, input selection, and acquisition metadata still match the prepared task. Raw pixel content is not verified.
- lauelab.reconstruct.reconstruct_point(task, output=None, *, num_threads=None, **parameters)[source]#
Reconstruct one point in the calling process and publish its point file.
Call it with a
PointTaskfromprepare_scan(), or with an input file, an output path, and the parameters of a standalone point. No worker process is started.- Parameters:
task (PointTask, pathlib.Path, or str) – A prepared task, or the input 34-ID-E multi-image HDF5 file of a standalone point.
output (pathlib.Path, str, or None) – Point file to write for a standalone point. It must not exist; its directory is created when needed. Omit it with a task, which carries its own output path.
num_threads (int or None) – Positive OpenMP thread count. The default is
None, which estimates the physical cores.**parameters – For a standalone point only:
geometry,detector, optionalpoint_id(default: the input stem) andcompression, and theReconstructorkeyword arguments, including the requireddepth_range.
- Returns:
PointOutcome –
"complete"with the published path, or"failed"with the error of an expected input or reconstruction failure. A failed point publishes nothing. Pixels are not returned; read them withPointReader.- Raises:
InputError – If the arguments are inconsistent or the parameters of a standalone point are invalid, or its input cannot be read.
ReconstructionError – If the point file cannot be created, written, validated, or published, including when the output or another worker’s private file already exists. The private file is removed; a published file is never replaced.
- Return type:
Notes
The point file is written to
<output>.partialbeside the final path, closed, validated, and published. The input is refused as a failed point if its output description, selected raw-slice range, or acquisition metadata differ from the task. Raw pixel content is not verified.
- lauelab.reconstruct.reconstruct_scan(paths, directory, *, geometry, detector, point_ids=None, compression=None, workers=1, threads_per_worker=None, progress=None, should_stop=None, **reconstructor_kwargs)[source]#
Reconstruct wire-scan points into a scan directory with local worker processes.
The scan is prepared with
prepare_scan(), each point is reconstructed byreconstruct_point()in one ofworkersspawned processes, and the coordinator records outcomes in memory as they arrive. Pending catalog changes are published at five-second intervals and immediately at the end of the run. Completed point files can be read while the scan runs. Pixels stay in the worker that computed them.- Parameters:
paths (Sequence[str | PathLike]) – As for
prepare_scan().directory (str | PathLike) – As for
prepare_scan().geometry – As for
prepare_scan().detector (int) – As for
prepare_scan().point_ids (Sequence[str] | None) – As for
prepare_scan().compression (str | None) – As for
prepare_scan().workers (int) – Number of worker processes, at least 1. Each worker reconstructs one point at a time and holds that point’s stripe buffers, so memory demand grows with
workers.threads_per_worker (int or None) – OpenMP threads of each worker. The default is
None, which divides the estimated physical cores among the workers. Storage conversion can overlap reconstruction, soworkers * threads_per_workeris not a strict limit on runnable threads.progress (Callable[[PointOutcome], None] | None) – Callable or
None. It is called in the calling process with thePointOutcomeof each point when it is recorded, including points whose input failed inspection.should_stop (Callable[[], bool] | None) – Callable or
None, polled in the calling process between outcomes. When it returnsTrue, no further point starts, points that have not started are withdrawn, and running points finish.**reconstructor_kwargs –
Reconstructorkeyword arguments, including the requireddepth_range, exceptnum_threads.
- Returns:
ScanResult –
scan.h5and one outcome per point in manifest order. An expected failure of one point’s input or reconstruction is recorded for that point and does not stop the run. A stopped run iscancelledand its remaining points are"unattempted". Check every outcome.- Raises:
InputError – If the shared configuration,
workers,threads_per_worker, or a callback is invalid, or asprepare_scan()raises.FileExistsError – If
directoryexists and is not empty.ReconstructionError – If a point file cannot be written or published, or a worker process ends unexpectedly. No new point starts; completed point files are kept, and the catalog records the run as failed.
OSError – If the catalog cannot be published. The last valid snapshot is kept.
- Return type:
Notes
A first interrupt (Ctrl-C, or a notebook kernel interrupt) acts like
should_stop: the run reports that running points are finishing, and returns a cancelled result once they have. A second interrupt terminates the workers and raisesKeyboardInterrupt; their points are recorded as interrupted and their private files may remain. In the main thread, Python’s default SIGINT handler is temporarily replaced and then restored. A handler installed by the caller is left in place.
- class lauelab.reconstruct.ScanResult(path, cancelled, outcomes)[source]#
Result of a reconstruction scan.
- path#
Path to the
scan.h5catalog.- Type:
- outcomes#
One outcome for each manifest entry, in manifest order, including points whose input failed inspection.
- Type:
- class lauelab.reconstruct.PointOutcome(index, point_id, status, error=None, seconds=0.0, output=None)[source]#
Status and output of one point.
- status#
"complete"or"failed"fromreconstruct_point(). A scan result also reports"interrupted"and"unattempted"points.- Type:
- class lauelab.reconstruct.ScanReader(path)[source]#
Read the catalog of a reconstruction scan.
On creation, the reader loads a snapshot of
scan.h5and closes the catalog file. Create a new reader to see later updates. You can list points and their metadata without opening any point files.- Parameters:
path (pathlib.Path or str) –
scan.h5of a directory written byprepare_scan().
- path#
- Type:
- directory#
Directory containing
scan.h5; point paths are relative to it.- Type:
- points#
Catalog in manifest order.
- Type:
tuple of PointEntry
- Raises:
OSError – If the file cannot be opened as HDF5.
InvalidScanFile – If the file is not a valid catalog of a supported version, including a file in the retired single-file layout.
- point_path(point_id)[source]#
Return the point file of
point_id, resolved againstdirectory.The path is assigned during preparation; the file may not yet exist.
- Raises:
KeyError – If the scan has no point with this ID.
- point(point_id)[source]#
Open the point file of a complete point.
Only this point’s file is opened. The returned reader belongs to the caller, who may close it; closing this
ScanReaderalso closes it.- Raises:
KeyError – If the scan has no point with this ID.
InputError – If the catalog snapshot does not list the point as complete.
InvalidScanFile – If the point file is invalid or its metadata disagrees with the catalog.
- class lauelab.reconstruct.PointReader(path)[source]#
Read frames, regions, and metadata from a reconstructed point file.
Open the reader in the process that will use it, and close it with a context manager or
close(). The open reader cannot be sent to another process. All required metadata is in the point file, so you can read it without the catalog, raw input, or original geometry file. Image reads load only the requested frames or region and return arrays that remain usable after the reader closes.- Parameters:
path (pathlib.Path or str) – A point file, for example
points/Twin2_wire_1.h5of a scan.
- path#
- Type:
- manifest_index#
Zero-based position in the scan the point was prepared in, or
Nonefor a standalone point.- Type:
int or None
- dtype#
Stored pixel dtype.
- Type:
- depth_um#
Physical depth of each frame in µm along the incident beam relative to the geometry’s Si origin, shape
(n_depths,).- Type:
- start, group
Zero-based
(x, y)frame origin in unbinned pixels and(x, y)binning factors, aslauelab.indexing.Indexer.index()takes them.
- sample_position#
Sample
(x, y, z)in µm in the acquisition coordinate system. Missing components are NaN.
- settings#
Requested reconstruction settings by name, such as
"depth_range"and"wire_edge", and"geometry_path". A setting that was not given isNone.- Type:
- Raises:
OSError – If the file cannot be opened as HDF5.
InvalidScanFile – If the file is not a complete point file of a supported version, including a scan catalog or a file in the retired single-file layout.
- frame(depth_index)[source]#
Return the stored frame at zero-based
depth_index, shape(rows, columns).
- region(bounds, depths=None)[source]#
Return stored pixels in half-open
boundsthrough a range of depths.- Parameters:
- Returns:
numpy.ndarray – Shape
(n_selected_depths, y1 - y0, x1 - x0)in the stored dtype.- Return type:
- iter_blocks(max_bytes)[source]#
Yield
(first_depth_index, frames)blocks of at mostmax_bytes.Blocks cover every depth in order.
max_bytesmust hold at least one frame.
- reference(name)[source]#
Return reference image
"first_raw","sum_raw", or"sum_reconstructed".The raw images hold detector counts before filtering and normalization.
"sum_reconstructed"is the sum of the stored frames.
- depth_intensity()[source]#
Return the sum of the stored pixels of each frame, shape
(n_depths,).The dtype is
numpy.int64for integer pixels andnumpy.float64otherwise.
- computed_depth_intensity()[source]#
Return the sum of each computed frame before scaling and conversion.
These
numpy.float64values equalReconstructionResult. depth_intensity. They differ fromdepth_intensity()whenever storage changed a pixel.
- class lauelab.reconstruct.PerDepthReader(paths, point_id='per-depth')[source]#
Inspect one point stored as individual reconstructed HDF5 frames.
- Parameters:
paths – Iterable of per-depth HDF5 paths from
Reconstructor,reconstruct, orexport_per_depth. Supply only one point’s files, without its summary text file. Files are ordered by their embedded physical depth, not their filename. Depths must be finite and unique; frame shape, dtype, detector mapping and normalization must agree.point_id (str) – Caller-assigned point identity; default
"per-depth".
Notes
Use as a context manager. Metadata inspection reads no pixels, and each data operation opens and closes at most one file at a time. Closing the reader prevents further reads. Treat the source files as immutable while using it. Every returned array is owned by the caller.
shapeis(depth, y, x);dtypedescribes stored pixels, anddepth_umholds physical depths in µm.detector_size,startandgroupuse the same unbinned(x, y)convention asPointReader.norm_rescaleandnorm_thresholddescribe the stored conversion; reading never applies it again. Only the reconstructed sum reference is available. Raw references raiseInputError.- region(bounds, depths=None)[source]#
Return a region through depth, as
PointReader.region()does.
- class lauelab.reconstruct.PointEntry(index, point_id, status, error, path, source_path, scan_number, sample_position, energy_kev, shape, depth_bounds_um, dtype)[source]#
Metadata for one point from the scan catalog, loaded without reading pixels.
- status#
"pending","writing","complete","failed","interrupted", or"unattempted". The catalog makes a point available for reading once its status is"complete".- Type:
- path#
Location of the point file relative to the directory of
scan.h5, with/separators. Assigned during preparation, including for points that later fail.- Type:
- sample_position#
Sample
(x, y, z)in µm in the acquisition coordinate system. Missing components are NaN.
- shape#
(n_depths, rows, columns); all zero for a point whose input could not be read.
- dtype#
Stored pixel dtype.
- Type:
numpy.dtype or None
- lauelab.reconstruct.validate_scan_file(path)[source]#
Check the structure of a closed
scan.h5with bounded reads.- Parameters:
path (pathlib.Path or str) – Catalog to check. Its writer must have closed it.
- Returns:
ScanFileSummary – Run status and point counts. Structural validity does not mean that every point is complete; check
ScanFileSummary.complete.- Raises:
OSError – If the file cannot be opened as HDF5.
InvalidScanFile – If the format marker or version is wrong, including the retired single-file layout; a dataset is missing or has the wrong dtype or shape; catalog rows disagree in length; a status code is unknown, or a finished or cancelled run has a pending or writing point; point IDs or point paths are empty, unsafe, or repeat; or a catalog row is inconsistent.
- Return type:
Notes
The check reads
scan.h5only. Point files are not opened, and the file remains unchanged.
- lauelab.reconstruct.export_per_depth(path, output_base)[source]#
Write a point file as LaueGo-compatible per-depth files.
Output follows the
Reconstructor.reconstruct()naming convention:<output_base><i>.h5for depth indexiand<output_base>summary.txt. Pixels are copied from the point file in their stored dtype without conversion or rescaling. The export also copies physical depths, detector metadata, and normalization provenance. All data comes from the point file; reconstruction is not repeated.- Parameters:
path (pathlib.Path or str) – A point file, such as
points/<input stem>.h5of a scan directory.output_base (pathlib.Path or str) – Output filename prefix, not a directory. Existing files are replaced.
- Returns:
list of str – The per-depth paths in depth order followed by the summary path.
- Raises:
InvalidScanFile – If
pathis not a complete point file.OSError – If the point file cannot be opened or an output cannot be written. Files already written are left in place, and the point file is unchanged.
- Return type:
Notes
The summary reports
$executionTimeas zero, because the export did not run reconstruction.$rows_at_one_timeis the stripe height used during reconstruction.
- class lauelab.reconstruct.ScanFileSummary(run_status, n_points, n_pending, n_writing, n_complete, n_failed, n_interrupted, n_unattempted, lauelab_version)[source]#
Run status and point counts returned by
validate_scan_file().- n_points, n_pending, n_writing, n_complete, n_failed, n_interrupted, n_unattempted
Point counts by status.
- Type:
- 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:
output_file (str | Path) – Base path for output files, without an extension.
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
0through3. The default is1.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 thenPATH.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
0through7.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_rangeorwire_edgeis invalid.
- Return type:
- 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, ornorm_threshold. Usereconstruct()when you need those options.- Parameters:
output_file (str | Path) – Base path for output files, without an extension.
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
0through3. The default is1.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 thenPATH.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
0through7.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_rangeorwire_edgeis invalid.
- Return type:
- lauelab.reconstruct.find_executable()[source]#
Find the native CPU reconstruction executable.
- Returns:
str – Path to
reconstructN_cpuin the installed package or onPATH.- Raises:
FileNotFoundError – If the executable cannot be found.
- Return type:
- lauelab.reconstruct.find_gpu_executable()[source]#
Find the native CUDA reconstruction executable.
- Returns:
str – Path to
reconstructN_gpuin the installed package or onPATH.- Raises:
FileNotFoundError – If the executable cannot be found.
- Return type:
- lauelab.reconstruct.gpu_available()[source]#
Report whether the native CUDA reconstruction executable is usable.
- Returns:
bool –
TrueifreconstructN_gpuis available and passes validation.- Return type:
Wire metadata used by reconstruction is documented as
lauelab.indexing.WireGeometry.
Inspection#
lauelab.reconstruct.inspection provides square ROI placement, depth traces, normalization, positive-sample selection for logarithmic axes, and reference images. See Inspect a reconstructed point for examples. These functions operate independently of the plotting library. Every returned array is a new, read-only array that the caller owns. ROI bounds are half-open (y0, y1, x0, x1) in stored-image pixels.
- lauelab.reconstruct.inspection.square_bounds(size, x, y, image_shape)[source]#
Place a square ROI of
sizepixels at a click and return its bounds.- Parameters:
size (int) – Side of the square in stored-image pixels; a positive integer.
x (float) – Click position in zero-based stored-image pixel coordinates, where an integer is a pixel centre and pixel
(x, y)coversx - 0.5tox + 0.5.y (float) – Click position in zero-based stored-image pixel coordinates, where an integer is a pixel centre and pixel
(x, y)coversx - 0.5tox + 0.5.image_shape (tuple of int) –
(rows, columns)of the stored image.
- Returns:
tuple of int – Half-open
(y0, y1, x0, x1)selectingimage[y0:y1, x0:x1], which holds exactlysize * sizepixels.- Raises:
InputError – If
sizeis not a positive integer, the click is not finite, or the square would extend outside the image.- Return type:
Notes
The square’s centre is the legal centre nearest the click: an integer for an odd size and a half-integer for an even size. A click at equal distance from two legal centres takes the lower coordinate. On each axis the first pixel is
ceil(click - size / 2).
- lauelab.reconstruct.inspection.bounds_center(bounds)[source]#
Return the
(x, y)centre of half-open(y0, y1, x0, x1)bounds.
- lauelab.reconstruct.inspection.depth_trace(point, bounds=None, *, label=None, max_bytes=67108864)[source]#
Return the stored intensity of a region through depth.
- Parameters:
point (PointReader, PerDepthReader, or ArrayPoint)
bounds (tuple of int or None) – Half-open
(y0, y1, x0, x1)in stored-image pixels, or None for the full frame. A scan point uses its embedded reduction without reading pixels; per-depth files and arrays are reduced on demand. An ROI reads only its selected pixels in bounded depth blocks.label (str or None) – Name for the trace. The default names the full frame or the bounds.
max_bytes (int) – Maximum pixel bytes read at once for an ROI; default 64 MiB. Must hold at least one depth plane of the ROI. The returned 1D trace and storage-library buffers are additional. Ignored for the full-frame trace, which uses the reader’s reduction.
- Raises:
InputError – If the bounds are not four integers selecting at least one pixel inside the image.
- lauelab.reconstruct.inspection.roi_traces(point, rois, *, max_bytes=67108864)[source]#
Return one
DepthTraceper named region, in the given order.roismaps a caller-chosen name to half-open bounds. An empty mapping returns an empty dict and is not an error.max_bytesbounds each ROI’s pixel reads as indepth_trace(); ROIs are reduced in sequence.
- lauelab.reconstruct.inspection.reference_image(point, kind='sum_reconstructed')[source]#
Return a reference image with its source kind and pixel-value convention.
- Parameters:
point (PointReader, PerDepthReader, or ArrayPoint)
kind (str) –
"sum_reconstructed"(the default),"first_raw", or"sum_raw".
- Raises:
InputError – If
kindis unknown or the point does not hold that image.
- class lauelab.reconstruct.inspection.DepthTrace(values, depth_um, point_id, bounds, label)[source]#
Intensity of one region through the reconstructed depths of a point.
- values#
Sum of the stored pixels in the region at each depth, shape
(n_depths,).numpy.int64for an integer stored dtype andnumpy.float64otherwise; exact in the integer case. Values are signed, and a sum can be zero or negative.- Type:
- depth_um#
Physical depth of each sample in µm, shape
(n_depths,).- Type:
- bounds#
Half-open
(y0, y1, x0, x1)of the region, or None for the full frame.
- property depth_index: numpy.ndarray#
Zero-based depth index of each sample, the alternative x axis.
- normalized()[source]#
Divide the trace by its own maximum. See
NormalizedTrace.
- log_samples()[source]#
Select the samples a logarithmic axis can show. See
LogSamples.
- class lauelab.reconstruct.inspection.NormalizedTrace(values, reason)[source]#
Normalized trace and an explanation when normalization is unavailable.
- values#
trace / max(trace)asnumpy.float64, with the sign of each sample preserved and the maximum equal to 1. None when the maximum is zero or negative.- Type:
numpy.ndarray or None
- class lauelab.reconstruct.inspection.LogSamples(kept, n_omitted)[source]#
Positive-sample indices and the count of omitted nonpositive samples.
- kept#
Indices of the samples that are positive, in order.
- Type:
- class lauelab.reconstruct.inspection.ReferenceImage(image, kind, values, point_id, label)[source]#
Reference image with its source kind and pixel-value convention.
- image#
(rows, columns)array the caller owns.- Type:
- values#
"raw"for detector counts before filtering and normalization, or"stored"for a sum of the stored reconstructed frames.- Type:
- class lauelab.reconstruct.inspection.ArrayPoint(images, depth_um, point_id='array')[source]#
The point-access interface over an in-memory
(depth, y, x)stack.Use it to inspect
ReconstructionResult.imagesor any stack the same way as a point in a scan file. Inspection uses the array’s existing dtype and values.- Parameters:
images (numpy.ndarray) – Numeric array with shape
(n_depths, rows, columns).depth_um (numpy.ndarray) – Physical depth of each frame in µm, shape
(n_depths,).point_id (str) – Name for the point in prepared data. The default is
"array".
Notes
The available reference image is
"sum_reconstructed". Requests for raw reference images raiseInputError.