Skip to content

Commit

Permalink
Merge pull request #2913 from ericpre/metadata_setter
Browse files Browse the repository at this point in the history
Deprecate setting `metadata` and `original_metadata` attributes
  • Loading branch information
jlaehne committed Mar 30, 2022
2 parents 2fac7e8 + f06b534 commit a1b206b
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 67 deletions.
5 changes: 3 additions & 2 deletions hyperspy/_signals/complex_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,9 @@ def argand_diagram(self, size=[256, 256], range=None):
raise ValueError('display_range should be array_like, shape(2,2) or shape(2,).')

argand_diagram, real_edges, imag_edges = np.histogram2d(re, im, bins=size, range=range)
argand_diagram = Signal2D(argand_diagram.T)
argand_diagram.metadata = self.metadata.deepcopy()
argand_diagram = Signal2D(argand_diagram.T,
metadata=self.metadata.as_dictionary(),
)
argand_diagram.metadata.General.title = f'Argand diagram of {self.metadata.General.title}'

if self.real.metadata.Signal.has_item('quantity'):
Expand Down
2 changes: 1 addition & 1 deletion hyperspy/_signals/eds_sem.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def get_calibration_from(self, ref, nb_pix=1):
"""

self.original_metadata = ref.original_metadata.deepcopy()
self._original_metadata = ref.original_metadata.deepcopy()
# Setup the axes_manager
ax_m = self.axes_manager.signal_axes[0]
ax_ref = ref.axes_manager.signal_axes[0]
Expand Down
2 changes: 1 addition & 1 deletion hyperspy/_signals/eds_tem.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def get_calibration_from(self, ref, nb_pix=1):
"""

self.original_metadata = ref.original_metadata.deepcopy()
self._original_metadata = ref.original_metadata.deepcopy()
# Setup the axes_manager
ax_m = self.axes_manager.signal_axes[0]
ax_ref = ref.axes_manager.signal_axes[0]
Expand Down
2 changes: 1 addition & 1 deletion hyperspy/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ def load_with_reader(
if convert_units:
signal.axes_manager.convert_units()
if not load_original_metadata:
signal.original_metadata = type(signal.original_metadata)()
signal._original_metadata = type(signal.original_metadata)()
signal_list.append(signal)
else:
# it's a standalone model
Expand Down
7 changes: 0 additions & 7 deletions hyperspy/io_plugins/nexus.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import traits.api as t

from hyperspy.io_plugins.hspy import (get_signal_chunks, overwrite_dataset)
from hyperspy.misc.utils import DictionaryTreeBrowser
from hyperspy.exceptions import VisibleDeprecationWarning


Expand Down Expand Up @@ -1278,12 +1277,6 @@ def file_writer(filename,
nxentry = f.create_group("entry%d" % (i + 1))
nxentry.attrs["NX_class"] = _parse_to_file("NXentry")

if isinstance(sig.metadata, dict):
sig.metadata = DictionaryTreeBrowser(sig.metadata)
if isinstance(sig.original_metadata, dict):
sig.original_metadata = DictionaryTreeBrowser(
sig.original_metadata)

signal_name = sig.metadata.General.title \
if sig.metadata.General.title else 'unnamed__%d' % i
if "/" in signal_name:
Expand Down
49 changes: 25 additions & 24 deletions hyperspy/misc/date_time_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,30 +89,31 @@ def get_date_time_from_metadata(metadata, formatting='ISO'):


def update_date_time_in_metadata(dt, metadata):
""" Update the date and time in a metadata tree.
Parameters
----------
dt : date and time information: it can be a ISO 8601 string,
a datetime.datetime or a numpy.datetime64 object
metadata : metadata object to update
Return
----------
metadata object
Example
-------
>>> s = hs.load("example1.msa")
>>> dt = '2016-12-12T12:12:12-05:00'
>>> s.metadata = update_date_time_in_metadata(dt, s.metadata)
>>> s.metadata
├── General
│ ├── date = 2016-12-12
│ ├── original_filename = example1.msa
│ ├── time = 12:12:12
│ ├── time_zone = 'EST'
│ └── title = NIO EELS OK SHELL
"""
Update the date and time in a metadata tree.
Parameters
----------
dt : date and time information: it can be a ISO 8601 string,
a datetime.datetime or a numpy.datetime64 object
metadata : metadata object to update
Return
------
metadata object
Example
-------
>>> s = hs.load("example1.msa")
>>> dt = '2016-12-12T12:12:12-05:00'
>>> s.metadata = update_date_time_in_metadata(dt, s.metadata)
>>> s.metadata
├── General
│ ├── date = 2016-12-12
│ ├── original_filename = example1.msa
│ ├── time = 12:12:12
│ ├── time_zone = 'EST'
│ └── title = NIO EELS OK SHELL
"""
time_zone = None
if isinstance(dt, str):
Expand Down
5 changes: 3 additions & 2 deletions hyperspy/misc/eels/eelsdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,9 @@ def eelsdb(spectrum_type=None, title=None, author=None, element=None, formula=No
try:
s = dict2signal(parse_msa_string(msa_string)[0])
emsa = s.original_metadata
s.original_metadata = s.original_metadata.__class__(
{'json': json_spectrum})
s._original_metadata = type(s.original_metadata)(
{'json': json_spectrum}
)
s.original_metadata.emsa = emsa
spectra.append(s)

Expand Down
10 changes: 5 additions & 5 deletions hyperspy/misc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,8 +1198,8 @@ def stack(
signal.get_dimensions_from_data()
# Set the metadata, if an stack_metadata is an integer, the metadata
# will overwritten later
signal.metadata = first.metadata.deepcopy()
signal.metadata.General.title = f"Stack of {first.metadata.General.title}"
signal._metadata = first.metadata.deepcopy()
signal._metadata.General.title = f"Stack of {first.metadata.General.title}"

# Stack metadata
if isinstance(stack_metadata, bool):
Expand All @@ -1211,11 +1211,11 @@ def stack(
node.original_metadata = obj.original_metadata.deepcopy()
node.metadata = obj.metadata.deepcopy()
else:
signal.original_metadata = DictionaryTreeBrowser({})
signal._original_metadata = DictionaryTreeBrowser({})
elif isinstance(stack_metadata, int):
obj = signal_list[stack_metadata]
signal.metadata = obj.metadata.deepcopy()
signal.original_metadata = obj.original_metadata.deepcopy()
signal._metadata = obj.metadata.deepcopy()
signal._original_metadata = obj.original_metadata.deepcopy()
else:
raise ValueError("`stack_metadata` must a boolean or an integer.")

Expand Down
21 changes: 18 additions & 3 deletions hyperspy/samfire.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import logging
from multiprocessing import cpu_count
import warnings

import dill
import numpy as np
Expand All @@ -27,8 +28,7 @@
from hyperspy.misc.math_tools import check_random_state
from hyperspy.external.progressbar import progressbar
from hyperspy.signal import BaseSignal
from hyperspy.samfire_utils.strategy import (LocalStrategy,
GlobalStrategy)
from hyperspy.samfire_utils.strategy import LocalStrategy, GlobalStrategy
from hyperspy.samfire_utils.local_strategies import ReducedChiSquaredStrategy
from hyperspy.samfire_utils.global_strategies import HistogramStrategy

Expand Down Expand Up @@ -137,7 +137,7 @@ def __init__(self, model, workers=None, setup=True, random_state=None, **kwargs)
if workers is None:
workers = max(1, cpu_count() - 1)
self.model = model
self.metadata = DictionaryTreeBrowser()
self._metadata = DictionaryTreeBrowser()

self._scale = 1.0
# -1 -> done pixel, use
Expand Down Expand Up @@ -168,6 +168,21 @@ def __init__(self, model, workers=None, setup=True, random_state=None, **kwargs)
self.refresh_database()
self.random_state = check_random_state(random_state)

@property
def metadata(self):
return self._metadata

@metadata.setter
def metadata(self, d):
warnings.warn(
"Setting the `metadata` attribute is deprecated and will be removed "
"in HyperSpy 2.0. Use the `set_item` and `add_dictionary` methods "
"of the `metadata` attribute instead."
)
if isinstance(d, dict):
d = DictionaryTreeBrowser(d)
self._metadata = d

@property
def active_strategy(self):
return self.strategies[self._active_strategy_ind]
Expand Down
44 changes: 38 additions & 6 deletions hyperspy/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2204,7 +2204,7 @@ class for more details).
self._load_dictionary(kwds)

def _create_metadata(self):
self.metadata = DictionaryTreeBrowser()
self._metadata = DictionaryTreeBrowser()
mp = self.metadata
mp.add_node("_HyperSpy")
mp.add_node("General")
Expand All @@ -2215,7 +2215,7 @@ def _create_metadata(self):
folding.signal_unfolded = False
folding.original_shape = None
folding.original_axes_manager = None
self.original_metadata = DictionaryTreeBrowser()
self._original_metadata = DictionaryTreeBrowser()
self.tmp_parameters = DictionaryTreeBrowser()

def __repr__(self):
Expand Down Expand Up @@ -2414,6 +2414,38 @@ def data(self, value):
value = np.asanyarray(value)
self._data = np.atleast_1d(value)


@property
def metadata(self):
"""The metadata of the signal."""
return self._metadata

@metadata.setter
def metadata(self, d):
warnings.warn(
"Setting the `metadata` attribute is deprecated and will be removed "
"in HyperSpy 2.0. Use the `set_item` and `add_dictionary` methods "
"of the `metadata` attribute instead."
)
if isinstance(d, dict):
d = DictionaryTreeBrowser(d)
self._metadata = d

@property
def original_metadata(self):
"""The original metadata of the signal."""
return self._original_metadata

@original_metadata.setter
def original_metadata(self, d):
warnings.warn(
"Setting the `original_metadata` attribute is deprecated and will be removed "
"removed in HyperSpy 2.0. Use the `set_item` and `add_dictionary` "
"methods of the `original_metadata` attribute instead.")
if isinstance(d, dict):
d = DictionaryTreeBrowser(d)
self._original_metadata = d

@property
def ragged(self):
return self.axes_manager._ragged
Expand Down Expand Up @@ -3372,10 +3404,10 @@ def split(self,
self.original_metadata, 'stack_elements'):
for i, spectrum in enumerate(splitted):
se = self.original_metadata.stack_elements['element' + str(i)]
spectrum.metadata = copy.deepcopy(
se['metadata'])
spectrum.original_metadata = copy.deepcopy(
se['original_metadata'])
spectrum._metadata = copy.deepcopy(se['metadata'])
spectrum._original_metadata = copy.deepcopy(
se['original_metadata']
)
spectrum.metadata.General.title = se.metadata.General.title

return splitted
Expand Down
14 changes: 11 additions & 3 deletions hyperspy/tests/io/test_nexus_hdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
read_metadata_from_file, _getlink,
_check_search_keys, _parse_from_file,
_nexus_dataset_to_signal)
from hyperspy.misc.utils import DictionaryTreeBrowser
from hyperspy.signals import BaseSignal


dirpath = os.path.dirname(__file__)

file1 = os.path.join(dirpath, 'nexus_files', 'simple_signal.nxs')
Expand All @@ -45,7 +47,6 @@
file5 = os.path.join(dirpath, 'nexus_files', 'nexus_test_datakey.nxs')



my_path = os.path.dirname(__file__)


Expand Down Expand Up @@ -337,8 +338,15 @@ def test_save_metadata_as_dict(self, tmp_path):
s.original_metadata.set_item("testarray1", ["a", 2, "b", 4, 5])
s.original_metadata.set_item("testarray2", (1, 2, 3, 4, 5))
s.original_metadata.set_item("testarray3", np.array([1, 2, 3, 4, 5]))
s.original_metadata = s.original_metadata.as_dictionary()
s.metadata = s.metadata.as_dictionary()

with pytest.warns():
s.original_metadata = s.original_metadata.as_dictionary()
with pytest.warns():
s.metadata = s.metadata.as_dictionary()

assert isinstance(s.metadata, DictionaryTreeBrowser)
assert isinstance(s.original_metadata, DictionaryTreeBrowser)

fname = tmp_path / 'test.nxs'
s.save(fname)
lin = load(fname, nxdata_only=True)
Expand Down
2 changes: 1 addition & 1 deletion hyperspy/tests/io/test_tvips.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def test_main_header_from_signal(unit, expected_scale_factor, version, fheb,
sig, fake_signals, metadata, fake_metadatas):
signal = fake_signals[sig]
if metadata is not None:
signal.metadata = fake_metadatas[metadata]
signal._metadata = fake_metadatas[metadata]
signal.axes_manager[-1].units = unit
signal.axes_manager[-2].units = unit
original_scale_x = signal.axes_manager[-2].scale
Expand Down
17 changes: 10 additions & 7 deletions hyperspy/tests/misc/test_date_time_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,16 @@ def test_update_date_time_in_metadata():
assert_deep_almost_equal(md13.General.date, md2.General.date)
assert_deep_almost_equal(md13.General.time, md2.General.time)
assert_deep_almost_equal(md13.General.time_zone, '-05:00')
assert_deep_almost_equal(dtt.update_date_time_in_metadata(dt2, md.deepcopy()).as_dictionary(),
md2.as_dictionary())

assert_deep_almost_equal(dtt.update_date_time_in_metadata(iso3, md.deepcopy()).as_dictionary(),
md3.as_dictionary())
assert_deep_almost_equal(dtt.update_date_time_in_metadata(dt3, md.deepcopy()).as_dictionary(),
md3.as_dictionary())
assert_deep_almost_equal(
dtt.update_date_time_in_metadata(dt2, md.deepcopy()).as_dictionary(),
md2.as_dictionary())

assert_deep_almost_equal(
dtt.update_date_time_in_metadata(iso3, md.deepcopy()).as_dictionary(),
md3.as_dictionary())
assert_deep_almost_equal(
dtt.update_date_time_in_metadata(dt3, md.deepcopy()).as_dictionary(),
md3.as_dictionary())


def test_serial_date_to_ISO_format():
Expand Down
9 changes: 9 additions & 0 deletions hyperspy/tests/samfire/test_samfire.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ def test_samfire_init_metadata(self):
samf.stop()
del samf

def test_samfire_set_metadata_deprecation(self):
m = self.model
samf = m.create_samfire(workers=N_WORKERS, setup=False)
with pytest.warns():
samf.metadata = samf.metadata.as_dictionary()
assert isinstance(samf.metadata, DictionaryTreeBrowser)
samf.stop()
del samf

def test_samfire_init_strategy_list(self):
from hyperspy.samfire import StrategyList
m = self.model
Expand Down
7 changes: 3 additions & 4 deletions hyperspy/tests/utils/test_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
from hyperspy import utils
from hyperspy.signal import BaseSignal
from hyperspy.exceptions import VisibleDeprecationWarning
from hyperspy.misc.utils import DictionaryTreeBrowser



def test_stack_warning():
Expand All @@ -34,14 +32,15 @@ def test_stack_warning():
class TestUtilsStack:

def setup_method(self, method):
s = BaseSignal(np.random.random((3, 2, 5)))
s = BaseSignal(np.random.random((3, 2, 5)),
original_metadata={'om': 'some metadata'}
)
s.axes_manager.set_signal_dimension(1)
s.axes_manager[0].name = "x"
s.axes_manager[1].name = "y"
s.axes_manager[2].name = "E"
s.axes_manager[2].scale = 0.5
s.metadata.General.title = 'test'
s.original_metadata = DictionaryTreeBrowser({'om': 'some metadata'})
self.signal = s

@pytest.mark.parametrize('stack_metadata', [True, False, 0, 1])
Expand Down
4 changes: 4 additions & 0 deletions upcoming_changes/2913.api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Deprecate the ability to directly set ``metadata`` and ``original_metadata`` Signal
attributes in favor of using :py:meth:`~.misc.utils.DictionaryTreeBrowser.set_item`
and :py:meth:`~.misc.utils.DictionaryTreeBrowser.add_dictionary` methods or
specifying metadata when creating signals

0 comments on commit a1b206b

Please sign in to comment.