Results#

FrameResult contains Python copies of native indexing output. A result with no identified patterns is valid and can contain detected peaks and frame statistics.

Results files#

See Results files for writing, loading, and converting.

class lauelab.indexing.ResultsWriter(path, *, crystal, geometry, peak_params, index_params, detector_index, detector_id, cosmic_filter, overwrite=False, compression=None, program='liblaue')[source]#

Write indexing results incrementally to one HDF5 file.

Notes

Every append() checks the result type and the frame identity before touching the file. If a write then raises, for any reason including malformed result content, the file is left with a partially appended frame and the writer is marked failed: failed becomes True, error holds the exception, and further appends are refused. There is no transactional recovery; the file is not a valid results file and the run must be rewritten from the start. validate_results_file() detects such a file.

program names the code that produced the results; it is stored in the program attribute of /run. The default is the in-process indexer.

property failed: bool#

Whether a write raised, leaving the file unusable.

property count: int#

Frames appended so far.

append(result, frame_id=None)[source]#

Append one frame result and its ragged peaks and patterns.

Parameters:
  • result (FrameResult) – The frame result to store.

  • frame_id – Unique string or integer identity; defaults to the zero-based append position. All identities in one file share one kind.

Raises:
  • RuntimeError – If the writer is not open or has failed earlier.

  • TypeError, ValueError – If result is not a FrameResult or frame_id is not a unique identity of the file’s kind. These are raised before anything is written, so the writer remains usable.

  • Exception – Any error raised while writing, including one caused by malformed result content such as a sample position of the wrong length, marks the writer failed and propagates.

class lauelab.indexing.XmlResultsWriter(path, *, overwrite=False)[source]#

Write frame results to one LaueGo AllSteps XML document incrementally.

Parameters:
  • path (str | Path) – Destination XML file.

  • overwrite (bool) – Replace an existing file. The default refuses with FileExistsError.

count#

Steps written so far.

Type:

int

failed#

True once a write to the file raised. The document may then be truncated or malformed; further appends are refused.

Type:

bool

error#

The exception that set failed.

Type:

Exception or None

Notes

Output is byte-identical to write_combined_xml for the same steps, and each step is serialized, written, and flushed when it arrives, so memory use does not grow with the number of frames. Use the writer as a context manager; leaving the block writes the closing tag and closes the file even when the body raised. After a failed write, close() first truncates the file back to the end of the last completely written step, so the document stays well formed up to that step whenever the filesystem still accepts the closing tag.

This is the auxiliary output of an indexing run. A caller that also writes an HDF5 results file should treat a failure here as a warning about the XML alone; the HDF5 file is unaffected.

append(item)[source]#

Append one FrameResult or LaueGo Step.

Raises:
  • RuntimeError – If the writer is not open, has already failed, or the result has no XML snapshot.

  • TypeError – If item is neither a FrameResult nor a Step.

  • OSError – If writing fails. The writer is then marked failed.

close()[source]#

Write the closing tag and close the file. Safe to call twice.

After a failed append the file is truncated to the end of the last complete step and the closing tag is still attempted, so that the document ends properly whenever the filesystem allows; a second failure is recorded in error and not raised again.

lauelab.indexing.validate_results_file(path, *, frame_ids=None, n_frames=None)[source]#

Check the structure of a closed indexing-results file with bounded reads.

Parameters:
  • path – Results file to check. It must be closed by its writer.

  • frame_ids (Iterable[Hashable] | None) – Optional expected identities in order, such as a run manifest. The file’s frames/frame_ids must equal this sequence exactly.

  • n_frames (int | None) – Optional expected frame count.

Returns:

ResultsFileSummary – Counts and provenance read during the check.

Raises:
  • OSError – If the file cannot be opened as HDF5.

  • InvalidResultsFile – If the format marker or version is wrong; a group or dataset is missing or has the wrong dtype or trailing shape; per-frame, per-peak, per-pattern, or per-assignment datasets disagree in length; an offsets dataset does not start at zero, increase monotonically, and end at its group’s row count; n_peaks, n_patterns, or n_indexed disagree with the offsets; pattern ranks do not restart at zero within each frame; an assignment refers outside its owning frame; frame identities repeat; or the file does not match frame_ids or n_frames.

Return type:

ResultsFileSummary

Notes

The check reads dataset shapes and dtypes, the per-frame and per-pattern bookkeeping arrays (identities, counts, ranks, offsets), and root attributes. Assignment peak indices are checked in bounded chunks. Peak values, reciprocal lattices, and other assignment arrays are not read. It establishes that the file is complete and self-consistent, not that the science in it is right; a valid file can describe an incomplete run.

lauelab.indexing.merge_results_files(paths, destination, *, frame_ids=None, overwrite=False)[source]#

Concatenate compatible HDF5 indexing files and validate before publication.

Parameters:
  • paths – Nonempty iterable of closed results files. Files must remain unchanged during the call. File order, followed by row order within each file, determines the output frame order. Empty files are allowed.

  • destination – New results file. It must differ from every input, even with overwrite.

  • frame_ids – Optional expected identities in the exact concatenated order. This checks selection and ordering; it does not reorder frames.

  • overwrite – Replace an existing destination only after a successful merge.

Returns:

ResultsFileSummary – Validated counts, identities, and provenance of the destination.

Raises:
  • InvalidResultsFile – An input or output is invalid; identities repeat across inputs or mix strings and integers; expected identities disagree; or run, geometry, crystal, column attributes, or supported columns are incompatible.

  • ValueError, TypeError – Input paths are empty, repeated, or alias the destination, or paths is a single path instead of an iterable.

  • FileExistsError – The destination exists and overwrite is false.

  • OSError – A file cannot be read, written, or published.

Return type:

ResultsFileSummary

Notes

Scientific arrays are copied in blocks of at most 65,536 rows. Only the three ragged-array offsets are rebased; assignment peak indices remain frame-local. No detector images are read and no indexing is repeated. Frame identities and validation bookkeeping require memory proportional to the frame and pattern counts. The output owns its data, with no links to the input files. Optional scan-source columns absent from older files receive their documented empty-string and -1 values.

Run, geometry, and crystal metadata must match exactly, including paths and units. Root attributes are copied from the first file, except that creation time and lauelab version describe this merge and source is removed. merged_sources records the input paths in order. A unique temporary file is removed on failure; an existing destination survives.

lauelab.indexing.merge_xml_files(paths, destination, *, n_steps=None, overwrite=False)[source]#

Concatenate LaueGo AllSteps documents, preserving step content as bytes.

Parameters:
  • paths – Nonempty iterable of closed UTF-8 or ASCII XML 1.0 files. Each must have an AllSteps root without attributes and only step element children. Files must remain unchanged during the call. Empty documents are allowed; file order and step order are preserved.

  • destination – Output XML document, distinct from all inputs.

  • n_steps – Optional expected total step count, a nonnegative integer.

  • overwrite – Replace an existing destination only after successful merging.

Returns:

int – Number of steps written.

Raises:
  • ValueError, TypeError – Invalid paths or step count; malformed or unsupported XML; or the total differs from n_steps. DTDs are refused.

  • FileExistsError – The destination exists and overwrite is false.

  • OSError – A file cannot be read, written, or published.

Return type:

int

Notes

Validation checks document structure and count, not scientific consistency or duplicate frame identities; use the HDF5 merge for those checks. Each source is parsed once, then its body is copied in 1 MiB blocks. No element tree or result objects are built. Numeric text, step attributes, and source paths are preserved. Memory use is independent of the number of steps. Publication uses a unique temporary file and preserves the destination on any failure, including an unexpected step count.

class lauelab.indexing.ResultsFileSummary(path, version, n_frames, n_peaks, n_patterns, n_assignments, frame_ids, has_crystal, has_geometry_text, created, lauelab_version, source=None)[source]#

Counts and provenance of a validated indexing-results file.

Parameters:
  • path (Path) – The validated file.

  • version (int) – Layout version.

  • n_frames (int) – Row counts of the four record groups.

  • n_peaks (int) – Row counts of the four record groups.

  • n_patterns (int) – Row counts of the four record groups.

  • n_assignments (int) – Row counts of the four record groups.

  • frame_ids (tuple) – Frame identities in file order, as strings or integers.

  • has_crystal (bool) – Whether the file carries a crystal group.

  • has_geometry_text (bool) – Whether the geometry XML text is embedded.

  • created (str) – Root attributes written by the producer.

  • lauelab_version (str) – Root attributes written by the producer.

  • source (str | None) – The XML document a converted file came from, or None.

lauelab.is_results_file(path)[source]#

Return whether path carries the lauelab indexing-results format marker.

This reads only the root format attribute. It tells a results file apart from other HDF5 files such as detector frames; it does not check that the file is complete or consistent. Use lauelab.indexing.validate_results_file() for that.

lauelab.partial_path(final)[source]#

Return the in-progress name for final: the same name with .partial appended.

Parameters:

final (str | Path) – Destination the finished file will have.

Returns:

pathlib.Path – final with .partial added after its full name, in the same directory, so that publish_file() can rename it into place.

Return type:

Path

lauelab.publish_file(partial, final, *, overwrite=False)[source]#

Move a closed, validated file into its final name in the same directory.

Parameters:
  • partial (str | Path) – The finished file, normally from partial_path(). It must be closed; publish after every writer has released it.

  • final (str | Path) – Destination path in the same directory as partial.

  • overwrite (bool) – Replace an existing final. The default refuses to clobber: an existing destination raises FileExistsError and partial is left in place. The refusal is atomic with respect to another publisher on filesystems that support hard links.

Returns:

pathlib.Path – final.

Raises:
Return type:

Path

Notes

The rename is one filesystem operation, so a reader never observes a half-written final. This function does not validate content; call the format’s validator on partial first.

File layout#

Format lauelab-indexing-results, version 1. Root attributes are format, version, lauelab_version, created, and, for a converted file, source. The run group has no datasets; its attributes are program (the code that produced the results, liblaue for the in-process indexer), detector_index, detector_id, cosmic_filter, and one attribute per PeakParams and IndexParams field. The crystal group has name, space_group, setting, and source attributes and is absent when the run has no crystal. The geometry group has a path attribute.

A merged file has a merged_sources root attribute listing its input files in order. Its created and lauelab_version describe the merge, and it has no single-document source attribute.

A converted file contains only the run attributes present in its XML input: program, peak_program, cosmic_filter, max_rfactor, max_peaks, min_separation, peak_shape, mask_file, kev_max_calc, kev_max_test, angle_tolerance_deg, cone_deg, and hkl_prefer.

n is the row count of the group. Rows of peaks, patterns, and assignments are grouped by owner; the rows of owner i are offsets[i] to offsets[i + 1] of the matching offsets dataset, which has one more entry than there are owners. Absent values are NaN for floating-point datasets, -1 for scan_numbers, beam_bad, and light_on, and the empty string for string datasets. Coordinates in peaks are zero-based frame pixel (x, y) values.

Dataset

dtype

Shape

Units

Meaning

crystal/lattice_parameters

float64

(6,)

nm, deg

a, b, c, alpha, beta, gamma; attribute angle_units is deg

crystal/atom_symbols

string

(n,)

Element symbol per atom

crystal/atom_labels

string

(n,)

Site label per atom

crystal/atom_positions

float64

(n, 3)

fractional

Fractional coordinates

crystal/atom_occupancies

float32

(n,)

Site occupancy

geometry/xml

string

scalar

Geometry file text; present when the file was readable at write time

frames/frame_ids

int32 or string

(n,)

Frame identifier

frames/sample_positions

float64

(n, 3)

um

Sample (x, y, z) in the acquisition coordinate system

frames/depths

float64

(n,)

um

Sample depth passed to the geometry conversion

frames/scan_numbers

int32

(n,)

Scan number

frames/energies_kev

float32

(n,)

keV

Incident energy

frames/exposure_seconds

float32

(n,)

s

Detector exposure time

frames/beam_bad, light_on

int32

(n,)

Acquisition flags, -1 when absent

frames/hutch_temperature, sample_distance

float32

(n,)

unspecified

Acquisition values without an established unit; no conversion applied

frames/detector_ids

string

(n,)

Detector identifier

frames/input_images

string

(n,)

Source HDF5 path

frames/source_point_ids

string

(n,)

Point ID recorded in the point file at input_images, empty for ordinary frames; optional, and a file without it has no scan sources

frames/source_depth_indices

int32

(n,)

Zero-based depth index of that frame, -1 when none; optional, paired with source_point_ids

frames/titles, sample_names, user_names, beamlines, dates_exposed, ccd_shutters, mono_modes

string

(n,)

Acquisition metadata strings

frames/image_shapes

int32

(n, 2)

Frame shape as (rows, columns)

frames/roi_starts

int32

(n, 2)

Full-detector (x, y) origin of the frame

frames/roi_groups

int32

(n, 2)

Pixel grouping factors (x, y)

frames/n_peaks

int32

(n,)

Detected peaks

frames/n_patterns

int16

(n,)

Identified patterns

frames/threshold_used

float32

(n,)

Peak-search threshold

frames/threshold_ratio

float32

(n,)

Automatic-threshold ratio; NaN when inactive

frames/total_sum

float64

(n,)

Sum of unmasked pixel values

frames/sum_above_threshold

float64

(n,)

Sum of pixel values above the threshold

frames/num_above_threshold

int64

(n,)

Pixels above the threshold

frames/peak_minwidth, peak_maxwidth, peak_max_cent_to_fit

float32

(n,)

Effective peak-fit parameters

frames/peak_boxsize

int32

(n,)

Effective fit box size

frames/peaksearch_seconds, indexing_seconds

float32

(n,)

s

Stage timing

frames/peak_offsets

int64

(n + 1,)

Row range of each frame in peaks

frames/pattern_offsets

int64

(n + 1,)

Row range of each frame in patterns

peaks/fit_x, fit_y

float32

(n,)

pixel

Fitted peak coordinate

peaks/intens, integral, background

float32

(n,)

Fitted intensity, integral, and background

peaks/hwhm_x, hwhm_y

float32

(n,)

pixel

Fitted half-widths

peaks/tilt

float32

(n,)

deg

Fitted tilt

peaks/chisq

float32

(n,)

Normalized fit residual

peaks/qhat

float32

(n, 3)

Unit scattering vector

patterns/rank

int16

(n,)

Pattern index within its frame

patterns/reciprocal

float64

(n, 3, 3)

1/nm

Rows a*, b*, c* including the factor of two pi; attributes rows and includes_two_pi

patterns/goodness

float32

(n,)

Native goodness score

patterns/rms_error_deg

float32

(n,)

deg

Root-mean-square angular error

patterns/n_indexed

int32

(n,)

Assignments in the pattern

patterns/assignment_offsets

int64

(n + 1,)

Row range of each pattern in assignments

assignments/peak_index

int32

(n,)

Zero-based index into the owning frame’s peaks

assignments/hkl

int16

(n, 3)

Miller indices

assignments/error_deg

float32

(n,)

deg

Angular error

assignments/energy_kev

float32

(n,)

keV

Photon energy

assignments/pred_intens

float32

(n,)

Predicted intensity

Frame Result#

class lauelab.indexing.FrameResult(peaks, patterns, threshold_used, total_sum, sum_above_threshold, num_above_threshold, peaksearch_seconds, indexing_seconds, threshold_ratio=4.0, peak_minwidth=0.0, peak_maxwidth=0.0, peak_max_cent_to_fit=0.0, peak_boxsize=0, metadata={}, input_image=None, image_shape=(0, 0), start=(0, 0), group=(1, 1), depth=None, source=None, image=None)[source]#

Self-contained result of processing one diffraction frame.

Parameters:
  • peaks (numpy.ndarray) – Structured peak array with shape (n,). Fields are fit_x, fit_y, intens, integral, hwhm_x, hwhm_y, tilt, chisq, background, and the three-component qhat vector.

  • patterns (tuple[lauelab.indexing.indexer.Pattern, ...]) – Crystal orientations identified in the frame.

  • threshold_used (float) – Intensity threshold used by peak search. This is NaN when automatic thresholding receives no unmasked nonzero pixels.

  • total_sum (float) – Sum of unmasked raw frame pixel values.

  • sum_above_threshold (float) – Sum of pixel values above threshold_used.

  • num_above_threshold (int) – Number of pixels above threshold_used.

  • peak_minwidth (float) – Effective fitting parameters configured by the native peak search.

  • peak_maxwidth (float) – Effective fitting parameters configured by the native peak search.

  • peak_max_cent_to_fit (float) – Effective fitting parameters configured by the native peak search.

  • peak_boxsize (int) – Effective fitting parameters configured by the native peak search.

  • peaksearch_seconds (float) – Elapsed peak-search time in seconds.

  • indexing_seconds (float) – Elapsed orientation-indexing time in seconds. Pixel-to-q conversion is not included in either timing field.

  • threshold_ratio (float) – Resolved automatic-threshold ratio supplied to native peak search, or NaN when an absolute threshold made the ratio inactive.

  • metadata (Mapping[str, object]) – Experiment metadata copied into the result.

  • input_image (str | None) – Source HDF5 path, or None for an in-memory frame. For a ScanFrame this is the point file’s path; source holds the point and depth.

  • source (lauelab.indexing._frame.ScanFrame | None) – The ScanFrame that selected the frame, or None for an array or a per-frame HDF5 file.

  • image_shape (tuple[int, int]) – Frame shape as (rows, columns).

  • start (tuple[int, int]) – Zero-based detector (x, y) origin of the frame.

  • group (tuple[int, int]) – Detector-pixel grouping factors as (x, y).

  • depth (float | None) – Physical sample depth in micrometres used by the geometry conversion, or None when no depth applied. For HDF5 input this is the explicit argument when one was given, otherwise the file’s entry1/depth.

  • image (numpy.ndarray | None) – Retained contiguous frame in its input dtype, or None when image retention was disabled. This array can alias a contiguous array supplied by the caller. Native smoothing uses a separate working copy.

Notes

Native result memory is released before this object is returned. The dataclass is frozen, but contained arrays and the metadata mapping may remain mutable. A result with no patterns is valid and has indexed set to False.

property indexed: bool#

Whether at least one crystal pattern was identified.

property n_peaks: int#

Number of detected peaks.

property n_indexed: int#

Total peak assignments across all identified patterns.

property n_patterns: int#

Number of identified crystal patterns.

property elapsed_seconds: float#

Sum of the recorded peak-search and indexing times in seconds.

property indexed_peak_indices: numpy.ndarray#

Sorted unique peak indices assigned to any pattern.

Returns:

numpy.ndarray – One-dimensional array of zero-based indices into peaks.

property unindexed_peak_indices: numpy.ndarray#

Sorted peak indices not assigned to a pattern.

Returns:

numpy.ndarray – One-dimensional array of zero-based indices into peaks.

write_xml(path)[source]#

Write this result in the LaueGo XML format.

Parameters:

path (str | Path) – Destination XML file. An existing file is replaced.

Raises:
  • RuntimeError – If the result was constructed manually without an XML snapshot.

  • OSError – If the destination cannot be written.

Indexed Pattern#

See the results guide for the reciprocal-basis convention used by Pattern.reciprocal.

class lauelab.indexing.Pattern(euler_deg, rotation, reciprocal, goodness, rms_error_deg, hkl, pk_index, err_deg, energy_kev, pred_intens)[source]#

One crystal orientation identified in a diffraction frame.

Parameters:
  • euler_deg (numpy.ndarray) – Euler angles in degrees, with shape (3,).

  • rotation (numpy.ndarray) – Orientation rotation matrix with shape (3, 3).

  • reciprocal (numpy.ndarray) – Reciprocal-lattice matrix with shape (3, 3) in 1/nm. Rows are a*, b*, and c*; a Miller-index row maps to reciprocal space as q = hkl @ reciprocal.

  • goodness (float) – Native indexer’s goodness score for the pattern.

  • rms_error_deg (float) – Root-mean-square angular indexing error in degrees.

  • hkl (numpy.ndarray) – Integer Miller indices with shape (n, 3).

  • pk_index (numpy.ndarray) – Zero-based indices into the frame’s peak array, with shape (n,).

  • err_deg (numpy.ndarray) – Per-peak angular errors in degrees, with shape (n,).

  • energy_kev (numpy.ndarray) – Per-peak photon energies in keV, with shape (n,).

  • pred_intens (numpy.ndarray) – Per-peak predicted intensities, with shape (n,).

Notes

The dataclass is frozen, but its NumPy arrays remain mutable. Each pattern owns Python arrays copied from the native result.

property n_indexed: int#

Number of peaks assigned to this pattern.