Results#
FrameResult contains the output and provenance for one processed frame. Native allocations are released before the object is returned. Peak and pattern data are copied into NumPy arrays.
Frame-level status#
Use these properties for a summary:
Property |
Meaning |
|---|---|
|
|
|
Number of detected peaks |
|
Total assignments across all patterns |
|
Number of identified patterns |
|
Sum of recorded peak-search and orientation-indexing times |
n_indexed counts assignments, not necessarily unique peaks. Use indexed_peak_indices when you need the unique set of peaks assigned to any pattern.
Peaks#
result.peaks is a one-dimensional structured array with one row per detected peak.
Field |
Shape |
Units |
Meaning |
|---|---|---|---|
|
scalar |
frame px |
Zero-based fitted x coordinate |
|
scalar |
frame px |
Zero-based fitted y coordinate |
|
scalar |
detector counts |
Fitted peak intensity |
|
scalar |
implementation-defined |
Integrated fitted intensity |
|
scalar |
px |
Fitted half-width along the x fit axis |
|
scalar |
px |
Fitted half-width along the y fit axis |
|
scalar |
deg |
Fitted peak tilt |
|
scalar |
dimensionless |
Normalized fit residual reported by peak search |
|
scalar |
detector counts |
Fitted background level |
|
|
dimensionless |
Unit scattering vector in the 34-ID-E laboratory convention |
Extract ordinary arrays by field name:
import numpy as np
xy = np.column_stack((result.peaks["fit_x"], result.peaks["fit_y"]))
qhat = result.peaks["qhat"]
intensity = result.peaks["intens"]
A frame coordinate (x, y) corresponds to NumPy access image[y, x]. Fitted coordinates are floating-point values and can lie between pixel centers.
Patterns#
Each Pattern represents one orientation returned by the native indexer.
Field |
Shape |
Units |
Meaning |
|---|---|---|---|
|
|
deg |
Euler-angle representation of the orientation |
|
|
dimensionless |
Orientation rotation matrix |
|
|
1/nm |
Reciprocal-lattice matrix, with |
|
scalar |
implementation-defined |
Native pattern goodness score |
|
scalar |
deg |
Root-mean-square angular indexing error |
|
|
Miller indices |
Assigned reflection indices |
|
|
array indices |
Zero-based indices into |
|
|
deg |
Angular error for each assignment |
|
|
keV |
Photon energy for each assignment |
|
|
implementation-defined |
Predicted intensity for each assignment |
pattern.n_indexed is len(pattern.pk_index). Rows in hkl, err_deg, energy_kev, and pred_intens correspond to the same assignments.
The reciprocal basis follows the native setDirectRecip convention. Its direct basis has c parallel to positive z, b in the yz plane, and a completing the right-handed basis. Reciprocal vectors include the 2*pi factor and are stored as rows in 1/nm, so q = hkl @ pattern.reciprocal.
Before constructing this basis, the native crystal model forces ideal metric constraints from the space group: cubic forces equal lengths and right angles; hexagonal forces a = b, alpha = beta = 90 deg, and gamma = 120 deg; tetragonal forces a = b and right angles; orthorhombic forces right angles; and monoclinic forces alpha = gamma = 90 deg. Trigonal cells use hexagonal axes when the supplied angles are already 90, 90, 120 deg within native tolerance; otherwise they use a rhombohedral cell with equal lengths and angles.
This convention also defines rotations reconstructed while loading XML. Compared with releases that used the JZT reference basis, XML-derived orientations for non-orthogonal cells change by the fixed rotation between those bases, including 30 degrees about c for hexagonal cells. Native live results and newly loaded XML now use the same basis. Prefer the full rotation matrix when exchanging orientations with other software, and confirm that software’s basis convention.
Indexed and unindexed peaks#
Pattern indices refer to result.peaks:
for pattern in result.patterns:
measured = result.peaks[pattern.pk_index]
assert len(measured) == pattern.n_indexed
result.indexed_peak_indices returns sorted, unique indices assigned to at least one pattern. result.unindexed_peak_indices returns the complement over all detected peaks.
indexed = result.peaks[result.indexed_peak_indices]
unindexed = result.peaks[result.unindexed_peak_indices]
These arrays are useful when a peak can appear in more than one pattern or when n_indexed must not be treated as a unique count.
Frame statistics and timing#
The result records:
threshold_usedtotal_sumsum_above_thresholdnum_above_thresholdthreshold_ratiopeak_minwidthpeak_maxwidthpeak_max_cent_to_fitpeak_boxsizepeaksearch_secondsindexing_seconds
total_sum, sum_above_threshold, and num_above_threshold exclude masked pixels and describe the raw input image. With PeakParams(smooth=True), smoothing applies to peak detection and fitting; an automatically derived threshold_used is then computed from the smoothed image (matching the LaueGo peaksearch program), while the sums above it still count raw pixels.
indexing_seconds measures the orientation-indexing section. It includes the negligible branch when no crystal is supplied or too few peaks are present. Pixel-to-q conversion is not included in either timing field. elapsed_seconds therefore does not measure complete call latency.
metadata contains supplied values and recognized HDF5 provenance. input_image is the HDF5 path for file input and None for an in-memory array. image_shape, start, group, and depth record the frame geometry used by the call.
Retained images#
index_frame() and Indexer.index() retain a contiguous uint16 image by default. A retained image can alias a C-contiguous array supplied by the caller. Native smoothing uses a separate working copy, so result.image remains the unsmoothed input. Set keep_image=False when downstream work only needs processed data.
Indexer.index_many() does not retain images by default. This avoids keeping one detector-sized array per result.
The FrameResult dataclass is frozen, but its arrays and metadata mapping can remain mutable. Copy them before modification when the unchanged result must remain available.
Write XML#
Write one result in the established Laue XML format:
result.write_xml("indexed-frame.xml")
Write several results in iteration order:
indexer.write_many_xml(results, "indexed-scan.xml")
Existing destination files are replaced. These methods serialize a snapshot captured when each result was created. Later mutations to result arrays do not update that snapshot.
Compatibility conversion#
result.to_step() returns a deep copy of the internal LaueGo XML model. This method is a compatibility bridge for code that must interact with that representation. It is not the preferred analysis model, and the serialization classes are not part of the curated public API.
Empty results#
No detected peaks is a valid result. The structured peak array is empty and no patterns are returned.
Detected peaks with no identified orientation is also valid. n_peaks is positive, patterns is empty, and indexed is False.
Exceptions represent invalid input, allocation failure, or failure inside a native stage. Do not convert a scientifically empty result into an exception unless your application requires that policy.