Skip to content

Commit dbfb402

Browse files
committed
Changes
1 parent 33f3d26 commit dbfb402

File tree

13 files changed

+89
-114
lines changed

13 files changed

+89
-114
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
repos:
22
# This should be before any formatting hooks like isort
33
- repo: https://github.com/astral-sh/ruff-pre-commit
4-
rev: "v0.7.1"
4+
rev: "v0.7.2"
55
hooks:
66
- id: ruff
77
args: ["--fix"]

.ruff.toml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ extend-ignore = [
4444
"NPY002", # TODO: migrate from np.random.rand to np.random.Generator
4545
# upgrades
4646
"UP038", # Use | in isinstance - not compatible with models and is slower
47-
# pytest (PT)
47+
# pytest
4848
"PT001", # Always use pytest.fixture()
4949
"PT004", # Fixtures which don't return anything should have leading _
5050
"PT011", # except(ValueRaises) is too broad
5151
"PT012", # except statement is too lengthy
5252
"PT023", # Always use () on pytest decorators
5353
"PT023", # Always use () on pytest decorators
54-
# flake8-pie
54+
# flake8-use-pathlib
5555
"PIE808", # Disallow passing 0 as the first argument to range
5656
# flake8-use-pathlib
5757
"PTH123", # open() should be replaced by Path.open()
@@ -67,22 +67,22 @@ extend-ignore = [
6767
"setup.py" = ["INP001"]
6868
"conftest.py" = ["INP001"]
6969
"docs/conf.py" = [
70+
"INP001", # Implicit namespace package
7071
"E402" # Module imports not at top of file
7172
]
72-
"docs/*.py" = [
73-
"INP001", # Implicit-namespace-package. The examples are not a package.
74-
]
7573
"examples/*.py" = [
7674
"T201", # We need print in our examples
77-
"E501", # Line too long
78-
"INP001", # implicit namespace package
75+
"INP001", # Implicit namespace package
76+
]
77+
"__init__.py" = [
78+
"E402", # Module level import not at top of cell
79+
"F401", # Unused import
80+
"F403", # from {name} import * used; unable to detect undefined names
81+
"F405", # {name} may be undefined, or defined from star imports
7982
]
80-
"ndcube/*.py" = [
81-
"T201", # allow use of print in examples
82-
"INP001", # File is part of an implicit namespace package.
83+
"test_*.py" = [
84+
"E402", # Module level import not at top of cell
8385
]
84-
"__init__.py" = ["E402", "F401", "F403"]
85-
"test_*.py" = ["B011", "D", "E402", "PGH001", "S101"]
8686

8787
[lint.pydocstyle]
8888
convention = "numpy"

ndcube/__init__.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""
2+
======
23
ndcube
34
======
45
5-
A base package for multi-dimensional contiguous and non-contiguous coordinate-aware arrays.
6+
A package for multi-dimensional contiguous and non-contiguous coordinate-aware arrays.
67
78
* Homepage: https://github.com/sunpy/ndcube
89
* Documentation: https://docs.sunpy.org/projects/ndcube/
@@ -14,13 +15,16 @@
1415
from .ndcube_sequence import NDCubeSequence, NDCubeSequenceBase
1516
from .version import version as __version__
1617

17-
__all__ = ['NDCube',
18-
'NDCubeSequence',
19-
"NDCollection",
20-
"ExtraCoords",
21-
"GlobalCoords",
22-
"ExtraCoordsABC",
23-
"GlobalCoordsABC",
24-
"NDCubeBase",
25-
"NDCubeSequenceBase",
26-
"__version__"]
18+
19+
__all__ = [
20+
'NDCube',
21+
'NDCubeSequence',
22+
"NDCollection",
23+
"ExtraCoords",
24+
"GlobalCoords",
25+
"ExtraCoordsABC",
26+
"GlobalCoordsABC",
27+
"NDCubeBase",
28+
"NDCubeSequenceBase",
29+
"__version__",
30+
]

ndcube/_dev/scm_version.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Try to use setuptools_scm to get the current version; this is only used
22
# in development installations from the git repository.
3-
43
from pathlib import Path
54

65
try:

ndcube/extra_coords/table_coord.py

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import gwcs
77
import gwcs.coordinate_frames as cf
88
import numpy as np
9+
import scipy.interpolate
910

1011
import astropy.units as u
1112
from astropy.coordinates import SkyCoord
@@ -15,16 +16,13 @@
1516
from astropy.time import Time
1617
from astropy.wcs.wcsapi.wrappers.sliced_wcs import combine_slices, sanitize_slices
1718

18-
try:
19-
import scipy.interpolate
20-
except ImportError:
21-
pass
22-
23-
__all__ = ['TimeTableCoordinate',
24-
'SkyCoordTableCoordinate',
25-
'QuantityTableCoordinate',
26-
'BaseTableCoordinate',
27-
'MultipleTableCoordinate']
19+
__all__ = [
20+
'TimeTableCoordinate',
21+
'SkyCoordTableCoordinate',
22+
'QuantityTableCoordinate',
23+
'BaseTableCoordinate',
24+
'MultipleTableCoordinate',
25+
]
2826

2927

3028
class Length1Tabular(_Tabular):
@@ -140,7 +138,7 @@ def _generate_tabular(lookup_table, interpolation='linear', points_unit=u.pix, *
140138
raise TypeError("lookup_table must be a Quantity.") # pragma: no cover
141139

142140
ndim = lookup_table.ndim
143-
tabular_nd = tabular_model(ndim, name=f"Tabular{ndim}D")
141+
TabularND = tabular_model(ndim, name=f"Tabular{ndim}D")
144142

145143
# The integer location is at the centre of the pixel.
146144
points = [(np.arange(size) - 0) * points_unit for size in lookup_table.shape]
@@ -155,7 +153,7 @@ def _generate_tabular(lookup_table, interpolation='linear', points_unit=u.pix, *
155153
if len(lookup_table) == 1:
156154
t = Length1Tabular(points, lookup_table, **kwargs)
157155
else:
158-
t = tabular_nd(points, lookup_table, **kwargs)
156+
t = TabularND(points, lookup_table, **kwargs)
159157

160158
# TODO: Remove this when there is a new gWCS release
161159
# Work around https://github.com/spacetelescope/gwcs/pull/331
@@ -352,10 +350,7 @@ def _slice_table(self, i, table, item, new_components, whole_slice):
352350
dwd["world_axis_physical_types"].append(self.frame.axis_physical_types[i])
353351
dwd["world_axis_units"].append(table.unit.to_string())
354352
dwd["world_axis_object_components"].append((f"quantity{i}", 0, "value"))
355-
dwd["world_axis_object_classes"].update({f"quantity{i}": (u.Quantity,
356-
(),
357-
{"unit", table.unit.to_string()})})
358-
return
353+
dwd["world_axis_object_classes"].update({f"quantity{i}": (u.Quantity, (), {"unit", table.unit.to_string()})})
359354

360355
new_components["tables"].append(table[item])
361356
if self.names:
@@ -923,16 +918,11 @@ def dropped_world_dimensions(self):
923918

924919
dropped_multi_table = MultipleTableCoordinate(*self._dropped_coords)
925920

926-
dropped_world_dimensions["world_axis_names"] += [name or None for name in
927-
dropped_multi_table.frame.axes_names]
928-
dropped_world_dimensions["world_axis_physical_types"] += (
929-
list(dropped_multi_table.frame.axis_physical_types))
930-
dropped_world_dimensions["world_axis_units"] += [u.to_string() for u in
931-
dropped_multi_table.frame.unit]
932-
dropped_world_dimensions["world_axis_object_components"] += \
933-
dropped_multi_table.frame._world_axis_object_components
934-
dropped_world_dimensions["world_axis_object_classes"].update(
935-
dropped_multi_table.frame._world_axis_object_classes)
921+
dropped_world_dimensions["world_axis_names"] += [name or None for name in dropped_multi_table.frame.axes_names]
922+
dropped_world_dimensions["world_axis_physical_types"] += list(dropped_multi_table.frame.axis_physical_types)
923+
dropped_world_dimensions["world_axis_units"] += [u.to_string() for u in dropped_multi_table.frame.unit]
924+
dropped_world_dimensions["world_axis_object_components"] += dropped_multi_table.frame._world_axis_object_components
925+
dropped_world_dimensions["world_axis_object_classes"].update(dropped_multi_table.frame._world_axis_object_classes)
936926

937927
for dropped in self._dropped_coords:
938928
# If the table is a tuple (QuantityTableCoordinate) then we need to

ndcube/tests/helpers.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,26 @@
2020

2121
from ndcube import NDCube, NDCubeSequence
2222

23-
__all__ = ['figure_test',
24-
'get_hash_library_name',
25-
'assert_extra_coords_equal',
26-
'assert_metas_equal',
27-
'assert_cubes_equal',
28-
'assert_cubesequences_equal',
29-
'assert_wcs_are_equal']
23+
__all__ = [
24+
'figure_test',
25+
'get_hash_library_name',
26+
'assert_extra_coords_equal',
27+
'assert_metas_equal',
28+
'assert_cubes_equal',
29+
'assert_cubesequences_equal',
30+
'assert_wcs_are_equal',
31+
]
3032

3133

3234
def get_hash_library_name():
3335
"""
3436
Generate the hash library name for this env.
3537
"""
3638
ft2_version = f"{mpl.ft2font.__freetype_version__.replace('.', '')}"
37-
animators_version = "dev" if (("dev" in mpl_animators.__version__)
38-
or ("rc" in mpl_animators.__version__))\
39-
else mpl_animators.__version__.replace('.', '')
40-
mpl_version = "dev" if (("dev" in mpl.__version__)
41-
or ("rc" in mpl.__version__)) \
42-
else mpl.__version__.replace('.', '')
43-
astropy_version = "dev" if (("dev" in astropy.__version__)
44-
or ("rc" in astropy.__version__)) \
45-
else astropy.__version__.replace('.', '')
46-
return (f"figure_hashes_mpl_{mpl_version}_ft_{ft2_version}"
47-
f"_astropy_{astropy_version}_animators_{animators_version}.json")
39+
animators_version = "dev" if (("dev" in mpl_animators.__version__) or ("rc" in mpl_animators.__version__)) else mpl_animators.__version__.replace('.', '')
40+
mpl_version = "dev" if (("dev" in mpl.__version__) or ("rc" in mpl.__version__)) else mpl.__version__.replace('.', '')
41+
astropy_version = "dev" if (("dev" in astropy.__version__) or ("rc" in astropy.__version__)) else astropy.__version__.replace('.', '')
42+
return f"figure_hashes_mpl_{mpl_version}_ft_{ft2_version}_astropy_{astropy_version}_animators_{animators_version}.json"
4843

4944

5045
def figure_test(test_function):
@@ -155,8 +150,7 @@ def assert_wcs_are_equal(wcs1, wcs2):
155150
# SlicedLowLevelWCS vs BaseHighLevelWCS don't have the same pixel_to_world method
156151
low_level_wcs1 = wcs1.low_level_wcs if isinstance(wcs1, BaseHighLevelWCS) else wcs1
157152
low_level_wcs2 = wcs2.low_level_wcs if isinstance(wcs2, BaseHighLevelWCS) else wcs2
158-
np.testing.assert_array_equal(low_level_wcs1.pixel_to_world_values(*random_idx.T),
159-
low_level_wcs2.pixel_to_world_values(*random_idx.T))
153+
np.testing.assert_array_equal(low_level_wcs1.pixel_to_world_values(*random_idx.T), low_level_wcs2.pixel_to_world_values(*random_idx.T))
160154

161155
def create_sliced_wcs(wcs, item, dim):
162156
"""

ndcube/tests/test_ndcube.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ def test_axis_world_coords_empty_ec(ndcube_3d_l_ln_lt_ectime):
203203
assert awc == ()
204204

205205

206-
207206
@pytest.mark.xfail(reason=">1D Tables not supported")
208207
def test_axis_world_coords_complex_ec(ndcube_4d_ln_lt_l_t):
209208
cube = ndcube_4d_ln_lt_l_t
@@ -818,11 +817,11 @@ def test_rebin(ndcube_3d_l_ln_lt_ectime, bin_shape):
818817
expected_uncertainty = None
819818
expected_unit = cube.unit
820819
expected_meta = cube.meta
821-
expected_tx = np.array([[9.99999999, 19.99999994, 29.99999979, 39.9999995,
820+
expected_Tx = np.array([[9.99999999, 19.99999994, 29.99999979, 39.9999995,
822821
49.99999902, 59.99999831, 69.99999731, 79.99999599],
823822
[9.99999999, 19.99999994, 29.99999979, 39.9999995,
824823
49.99999902, 59.99999831, 69.99999731, 79.99999599]]) * u.arcsec
825-
expected_ty = np.array([[-14.99999996, -14.9999999, -14.99999981, -14.99999969,
824+
expected_Ty = np.array([[-14.99999996, -14.9999999, -14.99999981, -14.99999969,
826825
-14.99999953, -14.99999934, -14.99999911, -14.99999885],
827826
[-4.99999999, -4.99999998, -4.99999995, -4.9999999,
828827
-4.99999985, -4.99999979, -4.99999971, -4.99999962]]) * u.arcsec
@@ -837,8 +836,8 @@ def test_rebin(ndcube_3d_l_ln_lt_ectime, bin_shape):
837836
assert output.uncertainty == expected_uncertainty
838837
assert output.unit == expected_unit
839838
assert output.meta == expected_meta
840-
assert u.allclose(output_sc.Tx, expected_tx)
841-
assert u.allclose(output_sc.Ty, expected_ty)
839+
assert u.allclose(output_sc.Tx, expected_Tx)
840+
assert u.allclose(output_sc.Ty, expected_Ty)
842841
assert u.allclose(output_spec, expected_spec)
843842
assert output_time.scale == expected_time.scale
844843
assert output_time.format == expected_time.format
@@ -956,15 +955,13 @@ def test_rebin_no_propagate(ndcube_2d_ln_lt_mask_uncert):
956955
bin_shape = (2, 4)
957956

958957
cube._mask[:] = True
959-
with pytest.warns(NDCubeUserWarning, match="Uncertainties cannot be propagated as all values "
960-
"are masked and operation_ignores_mask is False."):
958+
with pytest.warns(NDCubeUserWarning, match="Uncertainties cannot be propagated as all values are masked and operation_ignores_mask is False."):
961959
output = cube.rebin(bin_shape, operation=np.sum, propagate_uncertainties=True,
962960
operation_ignores_mask=False)
963961
assert output.uncertainty is None
964962

965963
cube._mask = True
966-
with pytest.warns(NDCubeUserWarning, match="Uncertainties cannot be propagated as all values "
967-
"are masked and operation_ignores_mask is False."):
964+
with pytest.warns(NDCubeUserWarning, match="Uncertainties cannot be propagated as all values are masked and operation_ignores_mask is False."):
968965
output = cube.rebin(bin_shape, operation=np.sum, propagate_uncertainties=True,
969966
operation_ignores_mask=False)
970967
assert output.uncertainty is None
@@ -1149,8 +1146,7 @@ def test_cube_arithmetic_rdivide(ndcube_2d_ln_lt_units, value):
11491146
@pytest.mark.parametrize('value', [1, 2, -1])
11501147
def test_cube_arithmetic_rdivide_uncertainty(ndcube_4d_unit_uncertainty, value):
11511148
cube_quantity = u.Quantity(ndcube_4d_unit_uncertainty.data, ndcube_4d_unit_uncertainty.unit)
1152-
with pytest.warns(NDCubeUserWarning, match="UnknownUncertainty does not support uncertainty "
1153-
"propagation with correlation. Setting uncertainties to None."):
1149+
with pytest.warns(NDCubeUserWarning, match="UnknownUncertainty does not support uncertainty propagation with correlation. Setting uncertainties to None."):
11541150
with np.errstate(divide='ignore'):
11551151
new_cube = value / ndcube_4d_unit_uncertainty
11561152
check_arithmetic_value_and_units(new_cube, value / cube_quantity)
@@ -1189,8 +1185,7 @@ def test_cube_arithmetic_power(ndcube_2d_ln_lt, power):
11891185
@pytest.mark.parametrize('power', [2, -2, 10, 0.5])
11901186
def test_cube_arithmetic_power_unknown_uncertainty(ndcube_4d_unit_uncertainty, power):
11911187
cube_quantity = u.Quantity(ndcube_4d_unit_uncertainty.data, ndcube_4d_unit_uncertainty.unit)
1192-
with pytest.warns(NDCubeUserWarning, match="UnknownUncertainty does not support uncertainty propagation "
1193-
"with correlation. Setting uncertainties to None."):
1188+
with pytest.warns(NDCubeUserWarning, match="UnknownUncertainty does not support uncertainty propagation with correlation. Setting uncertainties to None."):
11941189
with np.errstate(divide='ignore'):
11951190
new_cube = ndcube_4d_unit_uncertainty ** power
11961191
check_arithmetic_value_and_units(new_cube, cube_quantity**power)
@@ -1199,9 +1194,7 @@ def test_cube_arithmetic_power_unknown_uncertainty(ndcube_4d_unit_uncertainty, p
11991194
@pytest.mark.parametrize('power', [2, -2, 10, 0.5])
12001195
def test_cube_arithmetic_power_std_uncertainty(ndcube_2d_ln_lt_uncert, power):
12011196
cube_quantity = u.Quantity(ndcube_2d_ln_lt_uncert.data, ndcube_2d_ln_lt_uncert.unit)
1202-
with pytest.warns(NDCubeUserWarning, match=r"<class 'astropy.nddata.nduncertainty.StdDevUncertainty'> "
1203-
r"does not support propagation of uncertainties for power. "
1204-
r"Setting uncertainties to None."):
1197+
with pytest.warns(NDCubeUserWarning, match=r"<class 'astropy.nddata.nduncertainty.StdDevUncertainty'> does not support propagation of uncertainties for power. Setting uncertainties to None."):
12051198
with np.errstate(divide='ignore'):
12061199
new_cube = ndcube_2d_ln_lt_uncert ** power
12071200
check_arithmetic_value_and_units(new_cube, cube_quantity**power)
@@ -1235,11 +1228,9 @@ def test_squeeze(ndcube_4d_ln_l_t_lt):
12351228

12361229
def test_squeeze_error(ndcube_4d_ln_l_t_lt):
12371230
same = ndcube_4d_ln_l_t_lt.squeeze()[0:1,:,:,:]
1238-
with pytest.raises(ValueError, match="Cannot select any axis to squeeze out, "
1239-
"as none of them has size equal to one."):
1231+
with pytest.raises(ValueError, match="Cannot select any axis to squeeze out, as none of them has size equal to one."):
12401232
same.squeeze([0,1])
1241-
with pytest.raises(ValueError, match="All axes are of length 1, therefore we will not squeeze NDCube to become "
1242-
"a scalar. Use `axis=` keyword to specify a subset of axes to squeeze."):
1233+
with pytest.raises(ValueError, match="All axes are of length 1, therefore we will not squeeze NDCube to become a scalar. Use `axis=` keyword to specify a subset of axes to squeeze."):
12431234
same[0:1,0:1,0:1,0:1].squeeze()
12441235

12451236

ndcube/utils/collection.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,5 @@ def assert_aligned_axes_compatible(data_dimensions1, data_dimensions2, data_axes
159159
if len(data_axes1) != len(data_axes2):
160160
raise ValueError(f"Number of aligned axes must be equal: {len(data_axes1)} != {len(data_axes2)}")
161161
# Confirm dimension lengths of each aligned axis is the same.
162-
if not all(np.array(data_dimensions1)[np.array(data_axes1)] ==
163-
np.array(data_dimensions2)[np.array(data_axes2)]):
162+
if not all(np.array(data_dimensions1)[np.array(data_axes1)] == np.array(data_dimensions2)[np.array(data_axes2)]):
164163
raise ValueError("All corresponding aligned axes between cubes must be of same length.")

ndcube/visualization/mpl_plotter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ def plot(self, axes=None, plot_axes=None, axes_coordinates=None,
7979
with warnings.catch_warnings():
8080
warnings.simplefilter('ignore', AstropyUserWarning)
8181
if naxis == 1:
82-
ax = self._plot_1d_cube(plot_wcs, axes, axes_coordinates,
82+
ax = self._plot_1D_cube(plot_wcs, axes, axes_coordinates,
8383
axes_units, data_unit, **kwargs)
8484

8585
elif naxis == 2 and 'y' in plot_axes:
86-
ax = self._plot_2d_cube(plot_wcs, axes, plot_axes, axes_coordinates,
86+
ax = self._plot_2D_cube(plot_wcs, axes, plot_axes, axes_coordinates,
8787
axes_units, data_unit, **kwargs)
8888
else:
8989
ax = self._animate_cube(plot_wcs, plot_axes=plot_axes,
@@ -107,7 +107,7 @@ def _apply_axes_coordinates(self, axes, axes_coordinates):
107107
axes.coords[coord_index].set_ticks_visible(False)
108108
axes.coords[coord_index].set_ticklabel_visible(False)
109109

110-
def _plot_1d_cube(self, wcs, axes=None, axes_coordinates=None, axes_units=None,
110+
def _plot_1D_cube(self, wcs, axes=None, axes_coordinates=None, axes_units=None,
111111
data_unit=None, **kwargs):
112112
if axes is None:
113113
axes = plt.subplot(projection=wcs)
@@ -153,7 +153,7 @@ def _plot_1d_cube(self, wcs, axes=None, axes_coordinates=None, axes_units=None,
153153

154154
return axes
155155

156-
def _plot_2d_cube(self, wcs, axes=None, plot_axes=None, axes_coordinates=None,
156+
def _plot_2D_cube(self, wcs, axes=None, plot_axes=None, axes_coordinates=None,
157157
axes_units=None, data_unit=None, **kwargs):
158158
if axes is None:
159159
axes = plt.subplot(projection=wcs, slices=plot_axes)

ndcube/visualization/mpl_sequence_plotter.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ def animate(self, sequence_axis_coords=None, sequence_axis_unit=None, **kwargs):
5454
The unit in which the sequence_axis_coordinates should be displayed.
5555
If None, the default unit will be used.
5656
"""
57-
return SequenceAnimator(self._ndcube,
58-
sequence_axis_coords=sequence_axis_coords,
59-
sequence_axis_unit=sequence_axis_unit,
60-
**kwargs)
57+
return SequenceAnimator(self._ndcube, sequence_axis_coords=sequence_axis_coords, sequence_axis_unit=sequence_axis_unit, **kwargs)
6158

6259

6360
class SequenceAnimator(ArrayAnimatorWCS):

0 commit comments

Comments
 (0)