Repository: wright-group/WrightTools

Issue:
chop does not propagate axis units
now that `chop` relies exclusively on `transform`, axis units are not propagated

simply need to explicitly propagate axis units


Discussion:

Resolving patch:
diff --git a/WrightTools/_group.py b/WrightTools/_group.py
--- a/WrightTools/_group.py
+++ b/WrightTools/_group.py
@@ -25,7 +25,14 @@
 # --- class ---------------------------------------------------------------------------------------
 
 
-class Group(h5py.Group):
+class MetaClass(type(h5py.Group)):
+
+    def __call__(cls, *args, **kwargs):
+        """Bypass normal construction."""
+        return cls.__new__(cls, *args, **kwargs)
+
+
+class Group(h5py.Group, metaclass=MetaClass):
     """Container of groups and datasets."""
 
     instances = {}
@@ -62,8 +69,9 @@ def __init__(self, filepath=None, parent=None, name=None, **kwargs):
                 self.attrs[key] = value
             except TypeError:
                 # some values have no native HDF5 equivalent
-                warnings.warn("'%s' not included in attrs because its Type (%s) cannot be represented" %
-                              (key, type(value)))
+                message = "'{}' not included in attrs because its Type ({}) cannot be represented"
+                message = message.format(key, type(value))
+                warnings.warn(message)
         # load from file
         self._update_natural_namespace()
         # the following are populated if not already recorded
@@ -287,7 +295,7 @@ def save(self, filepath=None, overwrite=False, verbose=True):
                 raise FileExistsError(filepath)
         # copy to new file
         h5py.File(filepath)
-        new = Group(filepath=filepath)
+        new = Group(filepath=filepath, edit_local=True)
         # attrs
         for k, v in self.attrs.items():
             new.attrs[k] = v
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -365,7 +365,11 @@ def chop(self, *args, at={}, parent=None, verbose=True):
                 kwargs['units'] = c.units
                 kwargs['label'] = c.label
                 data.create_channel(**kwargs)
-            data.transform([a.expression for a in kept_axes if a.expression not in at.keys()])
+            new_axes = [a.expression for a in kept_axes if a.expression not in at.keys()]
+            new_axis_units = [a.units for a in kept_axes if a.expression not in at.keys()]
+            data.transform(new_axes)
+            for j, units in enumerate(new_axis_units):
+                data.axes[j].convert(units)
             i += 1
         out.flush()
         # return


Test patch:
diff --git a/tests/data/chop.py b/tests/data/chop.py
--- a/tests/data/chop.py
+++ b/tests/data/chop.py
@@ -75,6 +75,21 @@ def test_3D_to_2D_at():
     chop.close()
 
 
+def test_3D_to_2D_units():
+    p = datasets.PyCMDS.wm_w2_w1_001
+    data = wt.data.from_PyCMDS(p)
+    data.convert('eV')
+    chop = data.chop('wm', 'w2')
+    assert len(chop) == 11
+    for d in chop.values():
+        assert d.wm.size == 29
+        assert d.w2.size == 11
+        assert d.axis_expressions == ('wm', 'w2',)
+        assert d.units == ('eV', 'eV')
+    data.close()
+    chop.close()
+
+
 def test_parent():
     p = datasets.PyCMDS.wm_w2_w1_001
     data = wt.data.from_PyCMDS(p)
@@ -89,3 +104,4 @@ def test_parent():
 if __name__ == "__main__":
     test_2D_to_1D()
     test_3D_to_1D()
+    test_3D_to_2D_units()