Source code for ess.reduce.nexus.json_generator
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024 Scipp contributors (https://github.com/scipp)
"""Generators for "JSON" data from a NeXus file, for the purpose of testing."""
from collections.abc import Generator
from typing import Any
import scipp as sc
def _as_str_attr(value: Any, name: str) -> dict:
val = str(value)
return {"string_size": len(val), "type": "string", "name": name, "values": val}
def _variable_to_json(var: sc.Variable, name: str):
attrs = []
if var.dtype == sc.DType.datetime64:
offset = var.min()
attrs.append(_as_str_attr(offset.value, "offset"))
var = var - offset
if var.unit is not None:
attrs.append(_as_str_attr(var.unit, "units"))
return {
"module": "dataset",
"config": {
"name": name,
"values": var.values,
"size": list(var.shape),
"type": str(var.dtype),
},
"attributes": attrs,
}
_event_index_0 = sc.array(dims=('dummy',), values=[0], unit=None)
def _event_data_pulse_to_json(pulse: sc.DataArray) -> dict:
content = pulse.value.coords
event_time_zero = sc.concat([pulse.coords['event_time_zero']], 'dummy')
event_time_offset = content['event_time_offset']
event_id = content.get('event_id')
# I think we always have a pixel_id in the flatbuffer, so monitors just get ones?
if event_id is None:
event_id = sc.ones(sizes=event_time_offset.sizes, dtype='int32', unit=None)
children = [
_variable_to_json(event_time_zero, name='event_time_zero'),
_variable_to_json(event_time_offset, name='event_time_offset'),
_variable_to_json(event_id, name='event_id'),
_variable_to_json(_event_index_0, name='event_index'),
]
group = {
"type": "group",
"name": "events_0",
"children": children,
"attributes": [_as_str_attr("NXevent_data", name="NX_class")],
}
return group
[docs]
def event_data_generator(data: sc.DataArray) -> Generator[dict, None, None]:
"""
Generate JSON data for event data from a NeXus file.
Parameters
----------
data:
A data array with event data, equivalent to what ScippNexus would load from an
NXevent_data group in a NeXus file.
Yields
------
:
A dict of data for a single event data pulse that can be wrapped in a
:py:class:`ess.reduce.nexus.json_nexus.JSONGroup`.
"""
for pulse in data:
yield _event_data_pulse_to_json(pulse)