internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: wright-group/WrightTools

Issue:
axes attr not updated properly
for example, with `convert`

this manifests when saving or copying data


Discussion:

Resolving patch:
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -205,6 +205,9 @@ def variables(self):
     def _leaf(self):
         return '{0} {1}'.format(self.natural_name, self.shape)
 
+    def _on_axes_updated(self):
+        self.attrs['axes'] = [a.identity.encode() for a in self._axes]
+
     def _print_branch(self, prefix, level, depth, verbose):
 
         def print_leaves(prefix, lis, vline=True):
@@ -466,6 +469,7 @@ def convert(self, destination_units, *, convert_variables=False, verbose=True):
 
                     if verbose:
                         print('variable', var.natural_name, 'converted')
+        self._on_axes_updated()
 
     def create_channel(self, name, values=None, units=None, **kwargs):
         """Append a new channel.
@@ -592,7 +596,6 @@ def divide(self, divisor, channel=0, divisor_channel=0):
         self.transpose(transpose_order, verbose=False)
 
     def flush(self):
-        self.attrs['axes'] = [a.identity.encode() for a in self._axes]
         super().flush()
 
     def get_nadir(self, channel=0):
@@ -1448,6 +1451,7 @@ def transform(self, axes, verbose=True):
         # finish
         self.flush()
         self._update_natural_namespace()
+        self._on_axes_updated()
 
     def zoom(self, factor, order=1, verbose=True):
         """Zoom the data array using spline interpolation of the requested order.


Test patch:
diff --git a/tests/group/save.py b/tests/group/save.py
--- a/tests/group/save.py
+++ b/tests/group/save.py
@@ -121,6 +121,32 @@ def test_simple_save():
     os.remove(p)
 
 
+def test_propagate_units():
+    p = datasets.PyCMDS.wm_w2_w1_001
+    data = wt.data.from_PyCMDS(p)
+    data.convert('eV')
+    p = os.path.join(here, 'units')
+    p = data.save(p)
+    new = wt.open(p)
+    assert new.units == ('eV', 'eV', 'eV')
+    data.close()
+    new.close()
+    os.remove(p)
+
+
+def test_propagate_expressions():
+    p = datasets.PyCMDS.wm_w2_w1_001
+    data = wt.data.from_PyCMDS(p)
+    data.transform(['w1-wm', 'w2', 'w1'])
+    p = os.path.join(here, 'expressions')
+    p = data.save(p)
+    new = wt.open(p)
+    assert data.axis_expressions == new.axis_expressions
+    data.close()
+    new.close()
+    os.remove(p)
+
+
 # --- run -----------------------------------------------------------------------------------------
 
 
@@ -130,3 +156,5 @@ def test_simple_save():
     test_save_nested()
     test_simple_copy()
     test_simple_save()
+    test_propagate_units()
+    test_propagate_expressions()
Repository: wright-group/WrightTools

Issue:
print_tree depth kwarg is broken
seems to work when 1 or not given, but not for any other number


Discussion:

Resolving patch:
diff --git a/WrightTools/collection/_collection.py b/WrightTools/collection/_collection.py
--- a/WrightTools/collection/_collection.py
+++ b/WrightTools/collection/_collection.py
@@ -62,7 +62,7 @@ def __setitem__(self, key, value):
     def _leaf(self):
         return self.natural_name
 
-    def _print_branch(self, prefix, level, depth, verbose):
+    def _print_branch(self, prefix, depth, verbose):
         for i, name in enumerate(self.item_names):
             item = self[name]
             if i + 1 == len(self.item_names):
@@ -72,8 +72,8 @@ def _print_branch(self, prefix, level, depth, verbose):
                 s = prefix + '├── {0}: {1}'.format(i, item._leaf)
                 p = prefix + '│   '
             print(s)
-            if level + 1 < depth and hasattr(item, '_print_branch'):
-                item._print_branch(p, level, depth, verbose)
+            if depth > 1 and hasattr(item, '_print_branch'):
+                item._print_branch(p, depth=depth - 1, verbose=verbose)
 
     def create_collection(self, name='collection', position=None, **kwargs):
         """Create a new child colleciton.
@@ -149,7 +149,7 @@ def print_tree(self, depth=9, *, verbose=False):
             Toggle inclusion of extra information. Default is True.
         """
         print('{0} ({1})'.format(self.natural_name, self.filepath))
-        self._print_branch('', 0, depth, verbose=verbose)
+        self._print_branch('', depth=depth, verbose=verbose)
 
     def flush(self):
         """Ensure contents are written to file."""
diff --git a/WrightTools/data/_axis.py b/WrightTools/data/_axis.py
--- a/WrightTools/data/_axis.py
+++ b/WrightTools/data/_axis.py
@@ -69,7 +69,7 @@ def __repr__(self):
     def _leaf(self):
         out = self.expression
         if self.units is not None:
-            out += ' ({0})'.format(self.units)
+            out += ' ({0}) {1}'.format(self.units, self.shape)
         return out
 
     @property
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -223,7 +223,7 @@ def _on_axes_updated(self):
             setattr(self, key, a)
             self._current_axis_identities_in_natural_namespace.append(key)
 
-    def _print_branch(self, prefix, level, depth, verbose):
+    def _print_branch(self, prefix, depth, verbose):
 
         def print_leaves(prefix, lis, vline=True):
             for i, item in enumerate(lis):
@@ -984,6 +984,11 @@ def offset(self, points, offsets, along, offset_axis,
         # transpose out
         self.transpose(transpose_order, verbose=False)
 
+    def print_tree(self, *, verbose=True):
+        """Print a ascii-formatted tree representation of the data contents."""
+        print('{0} ({1})'.format(self.natural_name, self.filepath))
+        self._print_branch('', depth=0, verbose=verbose)
+
     def remove_channel(self, channel, *, verbose=True):
         """Remove channel from data.
 


Test patch:
Repository: wright-group/WrightTools

Issue:
add wt_exceptions.EntireDatasetInMemoryWarning to methods 
Methods that currently load entire dataset into memory:
- `smooth`

@ksunden @untzag please add to the list :)


Discussion:
`heal`

Resolving patch:
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -611,6 +611,7 @@ def heal(self, channel=0, method='linear', fill_value=np.nan,
 
 
         """
+        warnings.warn('heal', category=wt_exceptions.EntireDatasetInMemoryWarning)
         timer = wt_kit.Timer(verbose=False)
         with timer:
             # channel
@@ -1082,6 +1083,7 @@ def smooth(self, factors, channel=None, verbose=True):
         verbose : bool (optional)
             Toggle talkback. Default is True.
         """
+        warnings.warn('smooth', category=wt_exceptions.EntireDatasetInMemoryWarning)
         # get factors -----------------------------------------------------------------------------
 
         if isinstance(factors, list):
diff --git a/WrightTools/units.py b/WrightTools/units.py
--- a/WrightTools/units.py
+++ b/WrightTools/units.py
@@ -45,7 +45,7 @@
 
 # position units (native: mm)
 position = {'nm_p': ['x/1e6', '1e6/x', r'nm'],
-            'um': ['x/1000.', '1000/x.', r'um'],
+            'um': ['x/1000.', '1000.*x', r'um'],
             'mm': ['x', 'x', r'mm'],
             'cm': ['10.*x', 'x/10.', r'cm'],
             'in': ['x*0.039370', '0.039370*x', r'in']}


Test patch:
Repository: wright-group/WrightTools

Issue:
hide fit functionality



Discussion:

Resolving patch:
diff --git a/WrightTools/__init__.py b/WrightTools/__init__.py
--- a/WrightTools/__init__.py
+++ b/WrightTools/__init__.py
@@ -12,7 +12,6 @@
 from . import collection
 from . import data
 from . import diagrams
-from . import fit
 from . import kit
 from . import units
 from . import exceptions


Test patch:
Repository: wright-group/WrightTools

Issue:
apply_rcparams needs to tell matplotlib about amssymb
[Line #551](https://github.com/wright-group/WrightTools/blob/development/WrightTools/artists/_base.py#L551)
`matplotlib.rcParams['text.latex.preamble'] = '\\usepackage[cm]{sfmath}'`
should instead be:
`matplotlib.rcParams['text.latex.preamble'] = '\\usepackage[cm]{sfmath}\\usepackage{amssymb}'`


Discussion:

Resolving patch:
diff --git a/WrightTools/artists/_base.py b/WrightTools/artists/_base.py
--- a/WrightTools/artists/_base.py
+++ b/WrightTools/artists/_base.py
@@ -548,7 +548,8 @@ def apply_rcparams(kind='fast'):
     elif kind == 'publication':
         matplotlib.rcParams['text.usetex'] = True
         matplotlib.rcParams['text.latex.unicode'] = True
-        matplotlib.rcParams['text.latex.preamble'] = '\\usepackage[cm]{sfmath}'
+        preamble = '\\usepackage[cm]{sfmath}\\usepackage{amssymb}'
+        matplotlib.rcParams['text.latex.preamble'] = preamble
         matplotlib.rcParams['mathtext.fontset'] = 'cm'
         matplotlib.rcParams['font.family'] = 'sans-serif'
         matplotlib.rcParams['font.serif'] = 'cm'


Test patch:
Repository: wright-group/WrightTools

Issue:
wright.tools API does not render methods from _dataset or _group
http://wright.tools/en/master/api/WrightTools.datasets.html


Discussion:
OH, confusingly, this is the page for the distributed datasets we have as examples, not for the _dataset.py which is the h5py dataset subclass we use for channels and variables. We don't really have much by way of documentation for this, Though there is http://wright.tools/en/master/datasets.html, which provides a table listing all included such things
I propose adding `:inherited-members:` to the sphinx autodoc so that these methods show up for `Variable` and `Channel`

Resolving patch:
diff --git a/WrightTools/data/__init__.py b/WrightTools/data/__init__.py
--- a/WrightTools/data/__init__.py
+++ b/WrightTools/data/__init__.py
@@ -3,12 +3,14 @@
 
 
 from ._axis import *
-from ._brunold import *
 from ._channel import *
+from ._join import *
+from ._variable import *
+
+from ._brunold import *
 from ._colors import *
 from ._data import *
 from ._jasco import *
-from ._join import *
 from ._kent import *
 from ._ocean_optics import *
 from ._pycmds import *
@@ -21,6 +23,7 @@
            'join',
            'Axis',
            'Channel',
+           'Variable',
 
            # From methods in alphabetic order
            'from_BrunoldrRaman',
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -913,8 +913,8 @@ def remove_channel(self, channel, *, verbose=True):
 
         Parameters
         ----------
-        channel : int (index) or str (name)
-            Channel to remove.
+        channel : int or str
+            Channel index or name to remove.
         verbose : boolean (optional)
             Toggle talkback. Default is True.
         """
@@ -931,8 +931,8 @@ def remove_variable(self, variable, *, implied=True, verbose=True):
 
         Parameters
         ----------
-        variable : int (index) or str (name)
-            Variable to remove.
+        variable : int or str
+            Variable index or name to remove.
         implied : boolean (optional)
             Toggle deletion of other variables that start with the same
             name. Default is True.
diff --git a/WrightTools/kit/_list.py b/WrightTools/kit/_list.py
--- a/WrightTools/kit/_list.py
+++ b/WrightTools/kit/_list.py
@@ -58,7 +58,7 @@ def intersperse(lis, value):
     ----------
     lis : list
         List to intersperse.
-    value : value
+    value : object
         Value to insert.
 
     Returns


Test patch:
Repository: wright-group/WrightTools

Issue:
remove_nans_1D fails for list
```
>>> wt.kit.remove_nans_1D([np.nan, 1, 2, 2])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    wt.kit.remove_nans_1D([np.nan, 1, 2, 2])
  File "/home/kyle/wright/WrightTools/WrightTools/kit/_array.py", line 223, in rem
ove_nans_1D
    return tuple(a[goods] for a in args)
  File "/home/kyle/wright/WrightTools/WrightTools/kit/_array.py", line 223, in <ge
nexpr>
    return tuple(a[goods] for a in args)
TypeError: list indices must be integers or slices, not list
>>> wt.kit.remove_nans_1D(np.array([np.nan, 1, 2, 2]))
(array([1., 2., 2.]),)
```


Discussion:

Resolving patch:
diff --git a/WrightTools/kit/_array.py b/WrightTools/kit/_array.py
--- a/WrightTools/kit/_array.py
+++ b/WrightTools/kit/_array.py
@@ -210,17 +210,10 @@ def remove_nans_1D(*args):
     tuple
         Tuple of 1D arrays in same order as given, with nan indicies removed.
     """
-    # find all indicies to keep
-    bads = np.array([])
-    for arr in args:
-        bad = np.array(np.where(np.isnan(arr))).flatten()
-        bads = np.hstack((bad, bads))
-    if hasattr(args, 'shape') and len(args.shape) == 1:
-        goods = [i for i in np.arange(args.shape[0]) if i not in bads]
-    else:
-        goods = [i for i in np.arange(len(args[0])) if i not in bads]
-    # apply
-    return tuple(a[goods] for a in args)
+    vals = np.isnan(args[0])
+    for a in args:
+        vals |= np.isnan(a)
+    return tuple(np.array(a)[vals == False] for a in args)
 
 
 def share_nans(*arrs):


Test patch:
diff --git a/tests/kit/remove_nans_1D.py b/tests/kit/remove_nans_1D.py
old mode 100644
new mode 100755
--- a/tests/kit/remove_nans_1D.py
+++ b/tests/kit/remove_nans_1D.py
@@ -1,3 +1,4 @@
+#! /usr/bin/env python3
 """Test remove_nans_1D."""
 
 
@@ -18,10 +19,20 @@ def test_simple():
     assert wt.kit.remove_nans_1D(arr)[0].all() == np.arange(0, 6, dtype=float).all()
 
 
-def test_list():
+def test_multiple():
     arrs = [np.random.random(21) for _ in range(5)]
     arrs[0][0] = np.nan
     arrs[1][-1] = np.nan
     arrs = wt.kit.remove_nans_1D(*arrs)
     for arr in arrs:
         assert arr.size == 19
+
+
+def test_list():
+    assert np.all(wt.kit.remove_nans_1D([np.nan, 1, 2, 3])[0] == np.array([1, 2, 3]))
+
+
+if __name__ == "__main__":
+    test_simple()
+    test_multiple()
+    test_list()
Repository: wright-group/WrightTools

Issue:
multiplication doesn't seem to work in d.transform
`d.transform('w2+w2+w2', 'w1', 'd2')` works.

`d.transform('3*w2', 'w1', 'd2')` does not work (even with varying spacing around the multiplication operator)
Part of the error that is raised:
```
  File "/home/darien/source/WrightTools/WrightTools/data/_data.py", line 1306, in transform
    axis = current.get(expression, Axis(self, expression))

  File "/home/darien/source/WrightTools/WrightTools/data/_axis.py", line 53, in __init__
    self.units = self.variables[0].units

  File "/home/darien/source/WrightTools/WrightTools/data/_axis.py", line 152, in variables
    return self._variables

AttributeError: 'Axis' object has no attribute '_variables'
```


Discussion:
Further playing says that it is the _constant_ that is a problem and not the operation. For instance, `w1*w2` as an axis seems to work fine. 

Resolving patch:
diff --git a/WrightTools/data/_axis.py b/WrightTools/data/_axis.py
--- a/WrightTools/data/_axis.py
+++ b/WrightTools/data/_axis.py
@@ -106,7 +106,7 @@ def natural_name(self):
         name = self.expression.strip()
         for op in operators:
             name = name.replace(op, operator_to_identifier[op])
-        return name
+        return wt_kit.string2identifier(name)
 
     @property
     def ndim(self):
@@ -146,7 +146,10 @@ def variables(self):
         except (AssertionError, AttributeError):
             pattern = '|'.join(map(re.escape, operators))
             keys = re.split(pattern, self.expression)
-            indices = [self.parent.variable_names.index(key) for key in keys]
+            indices = []
+            for key in keys:
+                if key in self.parent.variable_names:
+                    indices.append(self.parent.variable_names.index(key))
             self._variables = [self.parent.variables[i] for i in indices]
         finally:
             return self._variables


Test patch:
diff --git a/tests/data/transform.py b/tests/data/transform.py
--- a/tests/data/transform.py
+++ b/tests/data/transform.py
@@ -4,6 +4,8 @@
 # --- import --------------------------------------------------------------------------------------
 
 
+import numpy as np
+
 import WrightTools as wt
 from WrightTools import datasets
 
@@ -18,3 +20,22 @@ def test_w2_w1():
     assert data.axis_names == ('w2', 'wm',)
     assert data.w2.shape == (81, 1)
     assert data.wm.shape == (81, 81)
+    data.close()
+
+
+def test_w2_w1_multiply():
+    p = datasets.PyCMDS.w2_w1_000
+    data = wt.data.from_PyCMDS(p)
+    data.transform('3*w2', '0.5*wm')
+    assert data.axis_names == ('_3__t__w2', '_0_5__t__wm',)
+    assert np.allclose(data._3__t__w2[:], data['w2'][:] * 3)
+    assert np.allclose(data._0_5__t__wm[:], data['wm'][:] * 0.5)
+    data.close()
+
+
+# --- run -----------------------------------------------------------------------------------------
+
+
+if __name__ == '__main__':
+    test_w2_w1()
+    test_w2_w1_multiply()
Repository: wright-group/WrightTools

Issue:
setter for null
Currently null is not settable on a channel

It can be worked around with `channel.attrs['null']`


Discussion:

Resolving patch:
diff --git a/WrightTools/data/_channel.py b/WrightTools/data/_channel.py
--- a/WrightTools/data/_channel.py
+++ b/WrightTools/data/_channel.py
@@ -93,6 +93,10 @@ def null(self):
             self.attrs['null'] = 0
         return self.attrs['null']
 
+    @null.setter
+    def null(self, value):
+        self.attrs['null'] = value
+
     @property
     def major_extent(self):
         """Maximum deviation from null."""


Test patch:
diff --git a/tests/data/channel/null.py b/tests/data/channel/null.py
new file mode 100644
--- /dev/null
+++ b/tests/data/channel/null.py
@@ -0,0 +1,28 @@
+"""Tests to do with null."""
+
+
+# --- import --------------------------------------------------------------------------------------
+
+
+import WrightTools as wt
+
+from WrightTools import datasets
+
+
+# --- test ----------------------------------------------------------------------------------------
+
+
+def test_setter():
+    p = datasets.BrunoldrRaman.LDS821_514nm_80mW
+    data = wt.data.from_BrunoldrRaman(p)
+    assert data.signal.null == 0
+    data.signal.null = 5
+    assert data.signal.null == 5
+    data.close()
+
+
+# --- run -----------------------------------------------------------------------------------------
+
+
+if __name__ == '__main__':
+    test_setter()
Repository: wright-group/WrightTools

Issue:
level only works for zeroth channel
[L663](https://github.com/wright-group/WrightTools/blob/development/WrightTools/data/_data.py#L663) is the culprit, I think. 
`channel = self.channels[0]`
should instead be
`channel = self.channels[channel_index]`


Discussion:

Resolving patch:
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -660,7 +660,7 @@ def level(self, channel, axis, npts, *, verbose=True):
         """
         warnings.warn('level', category=wt_exceptions.EntireDatasetInMemoryWarning)
         channel_index = wt_kit.get_index(self.channel_names, channel)
-        channel = self.channels[0]
+        channel = self.channels[channel_index]
         # verify npts not zero
         npts = int(npts)
         if npts == 0:


Test patch:
diff --git a/tests/data/level.py b/tests/data/level.py
--- a/tests/data/level.py
+++ b/tests/data/level.py
@@ -36,6 +36,20 @@ def test_3D():
     data.level('ai0', 1, 1)
     assert np.allclose(data.ai0[:, :1], [0.], atol=1e-3)
     data.close()
+    
+
+def test_channels():
+    p = datasets.PyCMDS.wm_w2_w1_001
+    data = wt.data.from_PyCMDS(p)
+    data_copy = data.copy()
+    data.bring_to_front(1)
+    data.level(0, 0, 4)
+    data_copy.level(1, 0, 4)
+    a = data.channels[0][:]
+    b = data_copy.channels[1][:]
+    assert np.allclose(a, b)
+    data.close()
+    data_copy.close()
 
 
 # --- run -----------------------------------------------------------------------------------------
@@ -45,3 +59,4 @@ def test_3D():
     test_1D()
     test_2D()
     test_3D()
+    test_channels()
Repository: wright-group/WrightTools

Issue:
remove_variable doesn't work if implied is False
https://github.com/wright-group/WrightTools/blob/7803e4ae618b670c4f4d5811eddac9746fa045dd/WrightTools/data/_data.py#L938-L948


Discussion:
to fix, the `remove` list needs to be populated in the `implied=False` case

Should also get a test case for this

Resolving patch:
diff --git a/WrightTools/data/_data.py b/WrightTools/data/_data.py
--- a/WrightTools/data/_data.py
+++ b/WrightTools/data/_data.py
@@ -940,6 +940,8 @@ def remove_variable(self, variable, *, implied=True, verbose=True):
             for n in self.variable_names:
                 if n.startswith(variable):
                     removed.append(n)
+        else:
+            removed = [variable]
         # check that axes will not be ruined
         for n in removed:
             for a in self._axes:


Test patch:
diff --git a/tests/data/remove_variable.py b/tests/data/remove_variable.py
--- a/tests/data/remove_variable.py
+++ b/tests/data/remove_variable.py
@@ -34,6 +34,19 @@ def test_implied():
     data.close()
 
 
+def test_not_implied():
+    p = datasets.PyCMDS.w2_w1_000
+    data = wt.data.from_PyCMDS(p)
+    names = data.variable_names
+    data.remove_variable('d0', implied=False)
+    for n in names:
+        if n != 'd0':
+            assert n in data.variable_names
+        else:
+            assert n not in data.variable_names
+    data.close()
+
+
 def test_index():
     p = datasets.KENT.LDS821_TRSF
     ignore = ['wm', 'd1', 'd2']
Repository: wright-group/WrightTools

Issue:
Change __version__ to match pep 440
Specifically, when a branch is specified, it should use a plus sign instead of minus

https://www.python.org/dev/peps/pep-0440/#local-version-identifiers

https://github.com/wright-group/WrightTools/blob/490a4a3d6fb6f016e7033d661b553b72c2d86fcb/WrightTools/__version__.py#L33


Discussion:

Resolving patch:
diff --git a/WrightTools/__version__.py b/WrightTools/__version__.py
--- a/WrightTools/__version__.py
+++ b/WrightTools/__version__.py
@@ -30,6 +30,6 @@
     with open(p) as f:
         __branch__ = f.readline().rstrip().split(r'/')[-1]
     if __branch__ != 'master':
-        __version__ += '-' + __branch__
+        __version__ += '+' + __branch__
 else:
     __branch__ = None


Test patch: