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

Remove legacy mode from write attributes #289

Merged
merged 6 commits into from
Feb 4, 2024
Merged
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
5 changes: 5 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
coverage:
status:
project:
default:
threshold: 1%
4 changes: 2 additions & 2 deletions kwave/kWaveSimulation_helper/save_to_disk_func.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from kwave.options.simulation_options import SimulationOptions
from kwave.utils.data import scale_time
from kwave.utils.dotdictionary import dotdict
from kwave.utils.io import write_attributes, write_matrix
from kwave.utils.io import write_attributes_typed, write_matrix
from kwave.utils.matrix import num_dim2
from kwave.utils.tictoc import TicToc

Expand Down Expand Up @@ -488,7 +488,7 @@ def save_h5_file(filepath, integer_variables, float_variables, hdf_compression_l
del value

# set additional file attributes
write_attributes(filepath, legacy=True) # TODO: update to currently breaking code after references are updated
write_attributes_typed(filepath)


def save_mat_file(filepath, integer_variables, float_variables):
Expand Down
64 changes: 6 additions & 58 deletions kwave/utils/io.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import logging
import os
import platform
import socket
from datetime import datetime
from typing import Optional

import cv2
import h5py
import numpy as np

import kwave
from .conversion import cast_to_type
from .data import get_date_string
from .dotdictionary import dotdict
Expand Down Expand Up @@ -200,37 +197,6 @@ def write_matrix(filename, matrix: np.ndarray, matrix_name: str, compression_lev


def write_attributes_typed(filename, file_description=None):
# get literals
h5_literals = get_h5_literals()

# get computer infor
comp_info = dotdict({
'date': datetime.now().strftime("%d-%b-%Y"),
'computer_name': socket.gethostname(),
'operating_system_type': platform.system(),
'operating_system': platform.system() + " " + platform.release() + " " + platform.version(),
'user_name': os.environ.get('USERNAME'),
'matlab_version': 'N/A',
'kwave_version': '1.3',
'kwave_path': 'N/A',
})

# set file description if not provided by user
if file_description is None:
file_description = f'Input data created by {comp_info.user_name} running MATLAB ' \
f'{comp_info.matlab_version} on {comp_info.operating_system_type}'

# set additional file attributes
with h5py.File(filename, "a") as f:
f[h5_literals.FILE_MAJOR_VER_ATT_NAME] = h5_literals.HDF_FILE_MAJOR_VERSION
f[h5_literals.FILE_MINOR_VER_ATT_NAME] = h5_literals.HDF_FILE_MINOR_VERSION
f[h5_literals.CREATED_BY_ATT_NAME] = 'k-Wave 1.3'
f[h5_literals.FILE_DESCR_ATT_NAME] = file_description
f[h5_literals.FILE_TYPE_ATT_NAME] = h5_literals.HDF_INPUT_FILE
f[h5_literals.FILE_CREATION_DATE_ATT_NAME] = get_date_string()


def write_attributes(filename: str, file_description: Optional[str] = None, legacy: bool = False) -> None:
"""
Write attributes to a HDF5 file.

Expand All @@ -242,19 +208,7 @@ def write_attributes(filename: str, file_description: Optional[str] = None, lega
filename: The name of the HDF5 file.
file_description: The description of the file. If not provided, a default description
will be used.
legacy: If set to True, the function will use the deprecated legacy method to write attributes.
If set to False, the function will use the new typed method. Defaults to False.

Raises:
DeprecationWarning: If legacy is set to True, a DeprecationWarning will be raised.

"""

if not legacy:
write_attributes_typed(filename, file_description)
return

logging.log(logging.WARN, f'{DeprecationWarning.__name__}: Attributes will soon be typed when saved and not saved ')
# get literals
h5_literals = get_h5_literals()

Expand All @@ -277,18 +231,12 @@ def write_attributes(filename: str, file_description: Optional[str] = None, lega

# set additional file attributes
with h5py.File(filename, "a") as f:
# create a dictionary of attributes
attributes = {
h5_literals.FILE_MAJOR_VER_ATT_NAME: h5_literals.HDF_FILE_MAJOR_VERSION,
h5_literals.FILE_MINOR_VER_ATT_NAME: h5_literals.HDF_FILE_MINOR_VERSION,
h5_literals.CREATED_BY_ATT_NAME: f'k-Wave {kwave.VERSION}',
h5_literals.FILE_DESCR_ATT_NAME: file_description,
h5_literals.FILE_TYPE_ATT_NAME: h5_literals.HDF_INPUT_FILE,
h5_literals.FILE_CREATION_DATE_ATT_NAME: get_date_string(),
}
# loop through the attributes dictionary and assign each attribute to the file
for key, value in attributes.items():
assign_str_attr(f.attrs, key, value)
f[h5_literals.FILE_MAJOR_VER_ATT_NAME] = h5_literals.HDF_FILE_MAJOR_VERSION
f[h5_literals.FILE_MINOR_VER_ATT_NAME] = h5_literals.HDF_FILE_MINOR_VERSION
f[h5_literals.CREATED_BY_ATT_NAME] = 'k-Wave 1.3'
f[h5_literals.FILE_DESCR_ATT_NAME] = file_description
f[h5_literals.FILE_TYPE_ATT_NAME] = h5_literals.HDF_INPUT_FILE
f[h5_literals.FILE_CREATION_DATE_ATT_NAME] = get_date_string()


def write_flags(filename):
Expand Down
34 changes: 23 additions & 11 deletions tests/h5_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,30 @@ def from_h5(h5_path):
data = {}

def extract_summary(name, obj):
np_obj = np.array(obj)
if obj.dtype != 'O':
py_obj = np.array(obj)
else:
# obj is a string with reference dtype ('|O')
py_obj = obj[()].decode("utf-8")

hashes = {}
for sd in range(6, 17, 2):
# why to have " + 0" here?
# because in NumPy, there could be 0 & -0
# while hashing we only want single type of zero
# therefore we add 0 to have only non-negative zero
if isinstance(py_obj, str):
hash = sha256(py_obj.encode()).hexdigest()
else:
hash = sha256(py_obj.round(sd) + 0).hexdigest()

hashes[str(sd)] = hash

data[name] = {
'dtype': str(obj.dtype),
'attrs': H5Summary._convert_attrs(obj.attrs),
'shape': list(obj.shape),
'checksums': {
# why to have " + 0" here?
# because in NumPy, there could be 0 & -0
# while hashing we only want single type of zero
# therefore we add 0 to have only non-negative zero
str(sd): sha256(np_obj.round(sd) + 0).hexdigest() for sd in range(6, 17, 2)
}
'checksums': hashes
}

with h5py.File(h5_path, 'r') as hf:
Expand Down Expand Up @@ -68,9 +80,9 @@ def _convert_attrs(attrs):
def get_diff(self, other, eps=1e-8, precision=8):
assert isinstance(other, H5Summary)
excluded = [
"root['root']['attrs']['created_by']",
"root['root']['attrs']['creation_date']",
"root['root']['attrs']['file_description']",
"root['created_by']",
"root['creation_date']",
"root['file_description']",
"root['Nt']" # Skip Nt after updating kgrid logic
]
own_summary = self._strip_checksums(precision)
Expand Down
4 changes: 2 additions & 2 deletions tests/matlab_test_data_collectors/python_testers/h5io_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import h5py
import numpy as np

from kwave.utils.io import write_matrix, write_attributes, write_grid, write_flags
from kwave.utils.io import write_matrix, write_attributes_typed, write_grid, write_flags


def compare_h5_attributes(local_h5_path, ref_path):
Expand Down Expand Up @@ -62,7 +62,7 @@ def test_write_attributes(tmp_path_factory):
matrix = np.single(10.0 * np.ones([1, 1]))
ref_path = os.path.join(Path(__file__).parent, f"collectedValues/writeAttributes/{idx}.h5")
write_matrix(tmp_path, matrix, matrix_name)
write_attributes(tmp_path)
write_attributes_typed(tmp_path)
compare_h5_attributes(tmp_path, ref_path)
idx = idx + 1
pass
Expand Down
87 changes: 79 additions & 8 deletions tests/reference_outputs/out_cpp_io_in_parts.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,32 @@
"16": "e4771988ad7747ce3ab562f13a2728280589e3c138f178d4bcf9c882dc7d78ad"
}
},
"created_by": {
"dtype": "object",
"attrs": {},
"shape": [],
"checksums": {
"6": "6640fe2857501271816938cd9541df3696cfa0470377c804a18d87ea1592d693",
"8": "6640fe2857501271816938cd9541df3696cfa0470377c804a18d87ea1592d693",
"10": "6640fe2857501271816938cd9541df3696cfa0470377c804a18d87ea1592d693",
"12": "6640fe2857501271816938cd9541df3696cfa0470377c804a18d87ea1592d693",
"14": "6640fe2857501271816938cd9541df3696cfa0470377c804a18d87ea1592d693",
"16": "6640fe2857501271816938cd9541df3696cfa0470377c804a18d87ea1592d693"
}
},
"creation_date": {
"dtype": "object",
"attrs": {},
"shape": [],
"checksums": {
"6": "ddabdc65b10c644161b859b40696f295ea200d08560165cb9df1d167536bef45",
"8": "ddabdc65b10c644161b859b40696f295ea200d08560165cb9df1d167536bef45",
"10": "ddabdc65b10c644161b859b40696f295ea200d08560165cb9df1d167536bef45",
"12": "ddabdc65b10c644161b859b40696f295ea200d08560165cb9df1d167536bef45",
"14": "ddabdc65b10c644161b859b40696f295ea200d08560165cb9df1d167536bef45",
"16": "ddabdc65b10c644161b859b40696f295ea200d08560165cb9df1d167536bef45"
}
},
"dt": {
"dtype": "float32",
"attrs": {
Expand Down Expand Up @@ -299,6 +325,58 @@
"16": "af5570f5a1810b7af78caf4bc70a660f0df51e42baf91d4de5b2328de0e83dfc"
}
},
"file_description": {
"dtype": "object",
"attrs": {},
"shape": [],
"checksums": {
"6": "97273e0f179b26e2428e2d35eec3e92f1280acf86c194d9bf58d5a7d59efaea7",
"8": "97273e0f179b26e2428e2d35eec3e92f1280acf86c194d9bf58d5a7d59efaea7",
"10": "97273e0f179b26e2428e2d35eec3e92f1280acf86c194d9bf58d5a7d59efaea7",
"12": "97273e0f179b26e2428e2d35eec3e92f1280acf86c194d9bf58d5a7d59efaea7",
"14": "97273e0f179b26e2428e2d35eec3e92f1280acf86c194d9bf58d5a7d59efaea7",
"16": "97273e0f179b26e2428e2d35eec3e92f1280acf86c194d9bf58d5a7d59efaea7"
}
},
"file_type": {
"dtype": "object",
"attrs": {},
"shape": [],
"checksums": {
"6": "c96c6d5be8d08a12e7b5cdc1b207fa6b2430974c86803d8891675e76fd992c20",
"8": "c96c6d5be8d08a12e7b5cdc1b207fa6b2430974c86803d8891675e76fd992c20",
"10": "c96c6d5be8d08a12e7b5cdc1b207fa6b2430974c86803d8891675e76fd992c20",
"12": "c96c6d5be8d08a12e7b5cdc1b207fa6b2430974c86803d8891675e76fd992c20",
"14": "c96c6d5be8d08a12e7b5cdc1b207fa6b2430974c86803d8891675e76fd992c20",
"16": "c96c6d5be8d08a12e7b5cdc1b207fa6b2430974c86803d8891675e76fd992c20"
}
},
"major_version": {
"dtype": "object",
"attrs": {},
"shape": [],
"checksums": {
"6": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
"8": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
"10": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
"12": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
"14": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
"16": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b"
}
},
"minor_version": {
"dtype": "object",
"attrs": {},
"shape": [],
"checksums": {
"6": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
"8": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
"10": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
"12": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
"14": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
"16": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"
}
},
"nonlinear_flag": {
"dtype": "uint64",
"attrs": {
Expand Down Expand Up @@ -900,13 +978,6 @@
}
},
"root": {
"attrs": {
"created_by": "b'k-Wave 1.3'",
"creation_date": "b'16-Apr-2021-00-02-50'",
"file_description": "b'Input data created by faridyagubbayli running MATLAB 9.7 (R2019b) on MACI64'",
"file_type": "b'input'",
"major_version": "b'1'",
"minor_version": "b'2'"
}
"attrs": {}
}
}
Loading
Loading