Skip to content

Use scippnexus to save nexus files #131

@YooSunYoung

Description

@YooSunYoung

Currently we are using h5py in quite a few place.
We should probably use scippnexus for consistency.

essnmx/src/ess/nmx/nexus.py

Lines 361 to 362 in be53f9c

def _export_static_metadata_as_nxlauetof(
experiment_metadata: NMXExperimentMetadata,

essnmx/src/ess/nmx/nexus.py

Lines 398 to 399 in be53f9c

def _export_detector_metadata_as_nxlauetof(
*detector_metadatas: NMXDetectorMetadata,

Especially here we need compression for counts so that requires some update in scippnexus.

It can be useful for other instruments as well: #130 (review)

essnmx/src/ess/nmx/nexus.py

Lines 431 to 494 in be53f9c

def _export_reduced_data_as_nxlauetof(
dg: NMXReducedDataGroup,
output_file: str | pathlib.Path | io.BytesIO,
*,
append_mode: bool = True,
compress_counts: bool = True,
) -> None:
"""Export the reduced data to a NeXus file with the LAUE_TOF application definition.
Even though this function only exports
reduced data(detector counts and its coordinates),
the input should contain all the necessary metadata
for minimum sanity check.
Parameters
----------
dg:
Reduced data and metadata.
output_file:
Output file path.
append_mode:
If ``True``, the file is opened in append mode.
If ``False``, the file is opened in None-append mode.
> None-append mode is not supported for now.
> Only append mode is supported for now.
compress_counts:
If ``True``, the detector counts are compressed using bitshuffle.
It is because only the detector counts are expected to be large.
"""
if not append_mode:
raise NotImplementedError("Only append mode is supported for now.")
with h5py.File(output_file, "r+") as f:
nx_detector: h5py.Group = f[f"entry/instrument/{dg['detector_name'].value}"]
# Data - shape: [n_x_pixels, n_y_pixels, n_tof_bins]
# The actual application definition defines it as integer,
# but we keep the original data type for now
num_x, num_y = dg["detector_shape"].value # Probably better way to do this
if compress_counts:
data_dset = _create_compressed_dataset(
name="data",
root_entry=nx_detector,
var=sc.fold(
dg['counts'].data, dim='id', sizes={'x': num_x, 'y': num_y}
),
chunks=(num_x, num_y, 1),
dtype=np.uint,
)
else:
data_dset = _create_dataset_from_var(
name="data",
root_entry=nx_detector,
var=sc.fold(
dg['counts'].data, dim='id', sizes={'x': num_x, 'y': num_y}
),
dtype=np.uint,
)
data_dset.attrs["signal"] = 1
_create_dataset_from_var(
name='time_of_flight',
root_entry=nx_detector,
var=sc.midpoints(dg['counts'].coords['t'], dim='t'),
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions