diff --git a/dascore/core/coords.py b/dascore/core/coords.py index d120013a..c720fc86 100644 --- a/dascore/core/coords.py +++ b/dascore/core/coords.py @@ -1024,6 +1024,18 @@ def _check_inputs(data, start, stop, step): msg = "When data is not defined, start, stop, and step must be." raise CoordError(msg) + def _get_new_max(data, min, step): + """Get the new length to use""" + + # for int based data types we need to modify the end time + # otherwise this will just go nuts + dtype = getattr(min, "dtype", None) + if dtype_time_like(dtype) or np.issubdtype(dtype, np.integer): + max = min + (len(data) - 1) * step + else: + max = data[-1] + return max + def _maybe_get_start_stop_step(data): """Get start, stop, step, is_monotonic.""" data = np.array(data) @@ -1036,9 +1048,10 @@ def _maybe_get_start_stop_step(data): unique_diff = np.unique(diffs) if len(unique_diff) == 1 or all_diffs_close_enough(unique_diff): _min = data[0] - _max = data[-1] # this is a poor man's median that preserves dtype - _step = np.sort(diffs)[len(diffs) // 2] + sorted_diffs = np.sort(diffs) + _step = sorted_diffs[len(sorted_diffs) // 2] + _max = _get_new_max(data, _min, _step) return _min, _max + _step, _step, is_monotonic return None, None, None, is_monotonic diff --git a/dascore/examples.py b/dascore/examples.py index b9f19710..db541201 100644 --- a/dascore/examples.py +++ b/dascore/examples.py @@ -15,7 +15,7 @@ from dascore.utils.downloader import fetch from dascore.utils.misc import register_func from dascore.utils.patch import get_default_patch_name -from dascore.utils.time import to_datetime64, to_timedelta64 +from dascore.utils.time import to_timedelta64 EXAMPLE_PATCHES = {} EXAMPLE_SPOOLS = {} @@ -139,13 +139,6 @@ def _sin_wave_patch( data=data, coords={"time": time, "distance": distance}, dims=("time", "distance"), - attrs={ - "time_min": to_datetime64(time_min), - "time_step": 1 / sample_rate, - "distance_min": 1, - "distance_step": 1, - "distance_max": 3, - }, ) return patch diff --git a/tests/test_core/test_coords.py b/tests/test_core/test_coords.py index 1a9d800b..95b60a16 100644 --- a/tests/test_core/test_coords.py +++ b/tests/test_core/test_coords.py @@ -285,6 +285,7 @@ def test_convert_offset_units(self): f_array = array * (9 / 5) + 32.0 coord = get_coord(values=array, units="degC") out = coord.convert_units("degF") + assert out.shape == f_array.shape assert np.allclose(f_array, out.values) def test_unit_str(self, evenly_sampled_coord): @@ -820,6 +821,16 @@ def test_arrange_equiv(self): coord = get_coord(start=start, stop=stop, step=step) assert coord.shape == ar.shape + def test_unchanged_len(self): + """Ensure an array converted to Coord range has same len. See #229.""" + t_array = np.linspace(0.0, 1, 44100) + t_coord = get_coord(values=t_array) + assert t_array.shape == t_coord.shape + # now test datetime + time = dc.to_timedelta64(t_array) + np.datetime64("2020-01-01") + time_coord = get_coord(values=time) + assert len(time) == len(time_coord) + class TestMonotonicCoord: """Tests for monotonic array coords.""" diff --git a/tests/test_examples.py b/tests/test_examples.py index 39eb7ef5..51de49c1 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -25,6 +25,11 @@ def test_example_1(self): out = dc.get_example_patch("example_event_1") assert isinstance(out, dc.Patch) + def test_sin_wav(self): + """Ensure the sin wave example can be loaded. See issee 229.""" + out = dc.get_example_patch("sin_wav") + assert isinstance(out, dc.Patch) + class TestGetExampleSpool: """Test suite for `get_example_spool`."""