Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP DXTBX compatibility with numpy 2.0 #751

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .azure-pipelines/ci-conda-env.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ conda-forge::hdf5
conda-forge::matplotlib-base
conda-forge::mrcfile
conda-forge::natsort
conda-forge::numpy<2
conda-forge::numpy
conda-forge::nxmx
conda-forge::orderedset
conda-forge::pillow>=5.4.1
Expand Down
48 changes: 24 additions & 24 deletions src/dxtbx/format/FormatHDF5EigerNearlyNexus.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def find_entries(nx_file):
if "entry" in nx_file:
entry = nx_file["entry"]
if "NX_class" in entry.attrs:
if entry.attrs["NX_class"] == np.string_("NXentry"):
if entry.attrs["NX_class"] == np.bytes_("NXentry"):
if "definition" not in entry:
return entry
return None
Expand All @@ -49,7 +49,7 @@ def is_eiger_nearly_nexus_file(filename):
if entry is not None:
try:
return (
np.string_("dectris eiger")
np.bytes_("dectris eiger")
in entry["instrument"]["detector"]["description"][()].lower()
)
except KeyError:
Expand All @@ -76,7 +76,7 @@ def create_scalar(handle, path, dtype, value):
dataset[()] = value

# Add NXmx definition
create_scalar(handle["entry"], "definition", "S4", np.string_("NXmx"))
create_scalar(handle["entry"], "definition", "S4", np.bytes_("NXmx"))

# Add saturation value
try:
Expand All @@ -100,7 +100,7 @@ def create_scalar(handle, path, dtype, value):

# Add detector type
create_scalar(
handle["entry/instrument/detector"], "type", "S5", np.string_("PIXEL")
handle["entry/instrument/detector"], "type", "S5", np.bytes_("PIXEL")
)

# Move the beam
Expand All @@ -111,7 +111,7 @@ def create_scalar(handle, path, dtype, value):
module_path = "/entry/instrument/detector/module"
# print "Creating detector module %s" % (module_path)
group = handle.create_group(module_path)
group.attrs["NX_class"] = np.string_("NXdetector_module")
group.attrs["NX_class"] = np.bytes_("NXdetector_module")

# Add a module index
create_scalar(group, "module_index", "int64", 0)
Expand Down Expand Up @@ -174,13 +174,13 @@ def create_scalar(handle, path, dtype, value):
"float32",
handle["/entry/instrument/detector/x_pixel_size"][()],
)
group["fast_pixel_direction"].attrs["transformation_type"] = np.string_(
group["fast_pixel_direction"].attrs["transformation_type"] = np.bytes_(
"translation"
)
group["fast_pixel_direction"].attrs["vector"] = fast_axis
group["fast_pixel_direction"].attrs["offset"] = (0, 0, 0)
group["fast_pixel_direction"].attrs["units"] = np.string_("m")
group["fast_pixel_direction"].attrs["depends_on"] = np.string_(depends_on)
group["fast_pixel_direction"].attrs["units"] = np.bytes_("m")
group["fast_pixel_direction"].attrs["depends_on"] = np.bytes_(depends_on)

# Add slow_pixel_size dataset
create_scalar(
Expand All @@ -189,29 +189,29 @@ def create_scalar(handle, path, dtype, value):
"float32",
handle["/entry/instrument/detector/y_pixel_size"][()],
)
group["slow_pixel_direction"].attrs["transformation_type"] = np.string_(
group["slow_pixel_direction"].attrs["transformation_type"] = np.bytes_(
"translation"
)
group["slow_pixel_direction"].attrs["vector"] = slow_axis
group["slow_pixel_direction"].attrs["offset"] = (0, 0, 0)
group["slow_pixel_direction"].attrs["units"] = np.string_("m")
group["slow_pixel_direction"].attrs["depends_on"] = np.string_(depends_on)
group["slow_pixel_direction"].attrs["units"] = np.bytes_("m")
group["slow_pixel_direction"].attrs["depends_on"] = np.bytes_(depends_on)

# Add module offset dataset
# print "Set module offset to be zero relative to detector"
create_scalar(group, "module_offset", "float32", 0)
group["module_offset"].attrs["transformation_type"] = np.string_("translation")
group["module_offset"].attrs["transformation_type"] = np.bytes_("translation")
group["module_offset"].attrs["vector"] = (0, 0, 0)
group["module_offset"].attrs["offset"] = (0, 0, 0)
group["module_offset"].attrs["units"] = np.string_("m")
group["module_offset"].attrs["depends_on"] = np.string_(depends_on)
group["module_offset"].attrs["units"] = np.bytes_("m")
group["module_offset"].attrs["depends_on"] = np.bytes_(depends_on)

# Create detector depends_on
create_scalar(
handle["/entry/instrument/detector"],
"depends_on",
"S%d" % len(depends_on),
np.string_(depends_on),
np.bytes_(depends_on),
)

# Add detector position
Expand All @@ -228,22 +228,22 @@ def create_scalar(handle, path, dtype, value):
)
)
group = handle.create_group("/entry/instrument/detector/transformations")
group.attrs["NX_class"] = np.string_("NXtransformations")
group.attrs["NX_class"] = np.bytes_("NXtransformations")
create_scalar(group, "translation", "float32", detector_offset_vector.length())
group["translation"].attrs["transformation_type"] = np.string_("translation")
group["translation"].attrs["transformation_type"] = np.bytes_("translation")
if detector_offset_vector.length() > 0:
group["translation"].attrs["vector"] = detector_offset_vector.normalize()
else:
group["translation"].attrs["vector"] = detector_offset_vector
group["translation"].attrs["offset"] = 0
group["translation"].attrs["units"] = np.string_("m")
group["translation"].attrs["depends_on"] = np.string_(".")
group["translation"].attrs["units"] = np.bytes_("m")
group["translation"].attrs["depends_on"] = np.bytes_(".")

# Create goniometer transformations if not found
if "/entry/sample/transformations" not in handle:
# print "Creating group /entry/sample/transformation"
group = handle.create_group("/entry/sample/transformations")
group.attrs["NX_class"] = np.string_("NXtransformations")
group.attrs["NX_class"] = np.bytes_("NXtransformations")
else:
group = handle["/entry/sample/transformations"]

Expand Down Expand Up @@ -274,11 +274,11 @@ def create_scalar(handle, path, dtype, value):
for name in sorted(handle["/entry/data"]):
num_images += handle_orig_entry_properties[name]["length"]
dataset = group.create_dataset("omega", (num_images,), dtype="float32")
dataset.attrs["units"] = np.string_("degree")
dataset.attrs["transformation_type"] = np.string_("rotation")
dataset.attrs["units"] = np.bytes_("degree")
dataset.attrs["transformation_type"] = np.bytes_("rotation")
dataset.attrs["vector"] = default_axis
dataset.attrs["offset"] = 0
dataset.attrs["depends_on"] = np.string_(".")
dataset.attrs["depends_on"] = np.bytes_(".")
omega_range_average = handle[
"/entry/sample/goniometer/omega_range_average"
][()]
Expand All @@ -295,7 +295,7 @@ def create_scalar(handle, path, dtype, value):
handle["/entry/sample"],
"depends_on",
"S%d" % len(dataset.name),
np.string_(dataset.name),
np.bytes_(dataset.name),
)

# Change relative paths to absolute paths
Expand Down
10 changes: 5 additions & 5 deletions src/dxtbx/format/FormatNexusJungfrauHack.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ def _setup_detector(self, detector, beam):
detector_material = clean_string(str(material))
material = {
"Si": "Si",
np.string_("Si"): "Si",
np.string_("Silicon"): "Si",
np.string_("Sillicon"): "Si",
np.string_("CdTe"): "CdTe",
np.string_("GaAs"): "GaAs",
np.bytes_("Si"): "Si",
np.bytes_("Silicon"): "Si",
np.bytes_("Sillicon"): "Si",
np.bytes_("CdTe"): "CdTe",
np.bytes_("GaAs"): "GaAs",
}.get(detector_material)
if not material:
raise RuntimeError("Unknown material: %s" % detector_material)
Expand Down
4 changes: 2 additions & 2 deletions src/dxtbx/format/FormatSER.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def read_emi(filename):


def _parseEntry_emi(value):
"""Auxiliary function to parse string entry to int, float or np.string_().
"""Auxiliary function to parse string entry to int, float or np.bytes_().
Parameters
----------
value : str
Expand All @@ -162,7 +162,7 @@ def _parseEntry_emi(value):
p = float(value)
except ValueError:
# if neither int nor float, stay with string
p = np.string_(str(value))
p = np.bytes_(str(value))

return p

Expand Down
8 changes: 4 additions & 4 deletions src/dxtbx/format/nexus.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@
NXNode = Union[h5py.File, h5py.Group]


def h5str(h5_value: str | numpy.string_ | bytes) -> str:
def h5str(h5_value: str | numpy.bytes_ | bytes) -> str:
"""
Convert a value returned an h5py attribute to str.

h5py can return either a bytes-like (numpy.string_) or str object
h5py can return either a bytes-like (numpy.bytes_) or str object
for attribute values depending on whether the value was written as
fixed or variable length. This function collapses the two to str.
"""
if isinstance(h5_value, (numpy.string_, bytes)):
if isinstance(h5_value, (numpy.bytes_, bytes)):
return h5_value.decode("utf-8")
return h5_value

Expand All @@ -78,7 +78,7 @@ def dataset_as_flex(dataset, selection):
if dataset.dtype in [
numpy.half,
numpy.single,
numpy.float_,
numpy.float64,
numpy.float16,
numpy.float32,
]:
Expand Down
4 changes: 2 additions & 2 deletions src/dxtbx/format/nxmx_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def construct_entry(self):
entry["end_time_estimated"] = self.params.nexus_details.end_time_estimated

# --> definition
self._create_scalar(entry, "definition", "S4", np.string_("NXmx"))
self._create_scalar(entry, "definition", "S4", np.bytes_("NXmx"))

# --> sample
sample = self.handle["entry"].create_group("sample")
Expand Down Expand Up @@ -354,7 +354,7 @@ def recursive_setup_basis_dict(key, parent_name="", panel_id=0):
det_group.attrs["NX_class"] = "NXdetector_group"

det_group.create_dataset("group_index", data=list(range(1, 3)), dtype="i")
data = [np.string_("detector"), np.string_("detector")]
data = [np.bytes_("detector"), np.bytes_("detector")]
det_group.create_dataset("group_names", (2,), data=data, dtype="S12")
det_group.create_dataset("group_parent", (2,), data=[-1, 1], dtype="i")
det_group.create_dataset("group_type", (2,), data=[1, 2], dtype="i")
Expand Down
4 changes: 1 addition & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ def nxmx_example():

instrument = entry.create_group("instrument")
instrument.attrs["NX_class"] = "NXinstrument"
name = instrument.create_dataset(
"name", data=np.string_("DIAMOND BEAMLINE I03")
)
name = instrument.create_dataset("name", data=np.bytes_("DIAMOND BEAMLINE I03"))
name.attrs["short_name"] = "I03"

beam = instrument.create_group("beam")
Expand Down
20 changes: 9 additions & 11 deletions tests/format/test_FormatNXmxDLS16M.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ def test_understand(beamline, tmp_path):
with h5py.File(nxs, mode="w") as fh:
entry = fh.create_group("entry")
instrument = entry.create_group("instrument")
instrument.attrs["short_name"] = np.string_(f"DLS {beamline}")
instrument.attrs["short_name"] = np.bytes_(f"DLS {beamline}")
name = instrument.create_dataset(
"name", data=np.string_(f"DIAMOND BEAMLINE {beamline}")
"name", data=np.bytes_(f"DIAMOND BEAMLINE {beamline}")
)
name.attrs["short_name"] = np.string_(f"DLS {beamline}")
name.attrs["short_name"] = np.bytes_(f"DLS {beamline}")
assert FormatNXmxDLS16M.understand(nxs)
assert FormatNXmxDLS.understand(nxs)

Expand All @@ -216,9 +216,9 @@ def test_understand_legacy(beamline, tmp_path):
with h5py.File(nxs, mode="w") as fh:
entry = fh.create_group("entry")
instrument = entry.create_group("instrument")
instrument.attrs["short_name"] = np.string_(f"{beamline}")
name = instrument.create_dataset("name", data=np.string_(f"{beamline}"))
name.attrs["short_name"] = np.string_(f"{beamline}")
instrument.attrs["short_name"] = np.bytes_(f"{beamline}")
name = instrument.create_dataset("name", data=np.bytes_(f"{beamline}"))
name.attrs["short_name"] = np.bytes_(f"{beamline}")
assert FormatNXmxDLS16M.understand(nxs)
assert FormatNXmxDLS.understand(nxs)

Expand All @@ -236,9 +236,7 @@ def test_do_not_understand_i24(tmp_path):
with h5py.File(nxs, mode="w") as fh:
entry = fh.create_group("entry")
instrument = entry.create_group("instrument")
instrument.attrs["short_name"] = np.string_("DLS I24")
name = instrument.create_dataset(
"name", data=np.string_("DIAMOND BEAMLINE I24")
)
name.attrs["short_name"] = np.string_("DLS I24")
instrument.attrs["short_name"] = np.bytes_("DLS I24")
name = instrument.create_dataset("name", data=np.bytes_("DIAMOND BEAMLINE I24"))
name.attrs["short_name"] = np.bytes_("DLS I24")
assert not FormatNXmxDLS16M.understand(nxs)
2 changes: 1 addition & 1 deletion tests/nexus/test_build_dxtbx_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def test_dataset_as_flex_float():
def test_dataset_as_flex_double():
slices = ()
np_double_types = (
np.float_,
np.float64,
np.double,
np.float64,
)
Expand Down
Loading