Repository: wright-group/WrightTools

Issue:
wt.data.join claims method = 'sum' is a valid choice in docstring, but method = 'sum' not implemented
If there is a potential use case for 'sum', we should implement. Else we should remove from documentation.


Discussion:
http://wright.tools/en/stable/auto_examples/join.html

It seems to be implemented
The way join works, _all_ of the data are added together, but the methods besides "sum" zero out the overlap regions.

We could do more validation on the inputs, but actually any input other than one of the accepted strings would end up doing sum
I agree that 'sum' (or any other string not in {first, last, max, min, mean}) sums the channels, but it also sums the (non-axis) variables, an undesirable behavior. Should I close this and open that as a separate issue? 
I mean, I don't think there is any action to take... they have to be combined _somehow_, and not super interested adding the level of complexity needed for "some arrays do x others do y" I mean, if you want to take a crack at it, be my guest, just the API design is rather challenging there to get expected results.

Resolving patch:
diff --git a/WrightTools/data/_join.py b/WrightTools/data/_join.py
--- a/WrightTools/data/_join.py
+++ b/WrightTools/data/_join.py
@@ -62,7 +62,7 @@ def join(
         The name for the data object which is created. Default is 'join'.
     parent : WrightTools.Collection (optional)
         The location to place the joined data object. Default is new temp file at root.
-    method : {'first', 'last', 'min', 'max', 'sum', 'mean'}
+    method : {'first', 'last', 'min', 'max', 'mean'}
         Mode to use for merged points in the joined space.
         Default is 'first'.
     verbose : bool (optional)
@@ -76,6 +76,11 @@ def join(
     warnings.warn("join", category=wt_exceptions.EntireDatasetInMemoryWarning)
     if isinstance(datas, Collection):
         datas = datas.values()
+    valid_methods = ["first", "last", "min", "max", "mean"]
+    if method not in valid_methods:
+        if method == "sum":
+            raise ValueError(f"method 'sum' is deprecated; consider 'mean' instead.")
+        raise ValueError(f"invalid method {method!r}: expected {valid_methods}")
     datas = list(datas)
     if not isinstance(atol, collections.abc.Iterable):
         atol = [atol] * len(datas[0].axes)
@@ -177,7 +182,7 @@ def get_shape(out, datas, item_name):
         out.create_channel(
             shape=get_shape(out, datas, channel_name),
             **datas[0][channel_name].attrs,
-            dtype=datas[0][channel_name].dtype
+            dtype=datas[0][channel_name].dtype,
         )
         count[channel_name] = np.zeros_like(out[channel_name], dtype=int)
     for variable_name in variable_names:
@@ -186,7 +191,7 @@ def get_shape(out, datas, item_name):
             out.create_variable(
                 shape=get_shape(out, datas, variable_name),
                 **datas[0][variable_name].attrs,
-                dtype=datas[0][variable_name].dtype
+                dtype=datas[0][variable_name].dtype,
             )
             count[variable_name] = np.zeros_like(out[variable_name], dtype=int)
 
diff --git a/examples/join.py b/examples/join.py
--- a/examples/join.py
+++ b/examples/join.py
@@ -25,12 +25,11 @@
 last = wt.data.join([a, b], method="last", name="last")
 min = wt.data.join([a, b], method="min", name="min")
 max = wt.data.join([a, b], method="max", name="max")
-sum = wt.data.join([a, b], method="sum", name="sum")
 mean = wt.data.join([a, b], method="mean", name="mean")
 
 # Plot the splits in columns
 fig, gs = wt.artists.create_figure(nrows=4, cols=[1, 1])
-for i, da in enumerate([a, b, first, last, min, max, sum, mean]):
+for i, da in enumerate([a, b, first, last, min, max, mean]):
     ax = plt.subplot(gs[i])
     ax.pcolor(da, vmin=0, vmax=6)
     wt.artists.corner_text(da.natural_name, ax=ax)


Test patch:
diff --git a/tests/data/join.py b/tests/data/join.py
--- a/tests/data/join.py
+++ b/tests/data/join.py
@@ -515,30 +515,6 @@ def test_overlap_last():
     joined.close()
 
 
-def test_overlap_sum():
-    a = wt.Data()
-    b = wt.Data()
-
-    a.create_variable("x", np.linspace(0, 10, 11))
-    b.create_variable("x", np.linspace(5, 15, 11))
-    a.transform("x")
-    b.transform("x")
-    a.create_channel("y", np.ones_like(a.x[:]))
-    b.create_channel("y", np.ones_like(b.x[:]) * 2)
-
-    joined = wt.data.join([a, b], method="sum")
-
-    assert joined.shape == (16,)
-    assert np.allclose(joined.x.points, np.linspace(0, 15, 16))
-    assert np.isclose(joined.y[0], 1.0)
-    assert np.isclose(joined.y[10], 3.0)
-    assert np.isclose(joined.y[-1], 2.0)
-
-    a.close()
-    b.close()
-    joined.close()
-
-
 def test_overlap_max():
     a = wt.Data()
     b = wt.Data()