diff --git a/.circleci/config.yml b/.circleci/config.yml index 73267989..dfc20562 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,7 +32,7 @@ jobs: jobname: type: string docker: - - image: circleci/python:3.8 + - image: cimg/python:3.9 environment: TOXENV=<< parameters.jobname >> steps: @@ -55,7 +55,7 @@ jobs: jobname: type: string docker: - - image: circleci/python:3.8 + - image: cimg/python:3.9 environment: TOXENV: << parameters.jobname >> GIT_SSH_COMMAND: ssh -i ~/.ssh/id_rsa_6464b6a8248237ca368fd4690777d921 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 98e856ec..0f676412 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,33 +1,38 @@ -ci: - autofix_prs: false repos: -- repo: https://github.com/psf/black - rev: 22.3.0 + - repo: https://github.com/myint/docformatter + rev: v1.4 hooks: - - id: black -- repo: https://github.com/myint/autoflake + - id: docformatter + args: [--in-place, --pre-summary-newline, --make-summary-multi] + - repo: https://github.com/myint/autoflake rev: v1.4 hooks: - id: autoflake args: ['--in-place', '--remove-all-unused-imports', '--remove-unused-variable'] exclude: ".*(.fits|.fts|.fit|.txt|tca.*|extern.*|.rst|.md|__init__.py|docs/conf.py)$" -- repo: https://github.com/PyCQA/isort - rev: 5.10.1 - hooks: + - repo: https://github.com/psf/black + rev: 22.3.0 + hooks: + - id: black + exclude: ".*(.fits|.fts|.fit|.txt|.csv)$" + - repo: https://github.com/PyCQA/isort + rev: 5.10.1 + hooks: - id: isort - args: ['--sp','setup.cfg'] - exclude: ".*(.fits|.fts|.fit|.txt|tca.*|extern.*|.rst|.md|docs/conf.py)$" -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 - hooks: + exclude: ".*(.fits|.fts|.fit|.txt|.csv)$" + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.2.0 + hooks: - id: check-ast - id: check-case-conflict - id: trailing-whitespace - exclude: ".*(.fits|.fts|.fit|.txt)$" + exclude: ".*(.fits|.fts|.fit|.txt|.csv)$" + - id: mixed-line-ending + exclude: ".*(.fits|.fts|.fit|.txt|.csv)$" + - id: end-of-file-fixer + exclude: ".*(.fits|.fts|.fit|.txt|.csv)$" - id: check-yaml - id: debug-statements - - id: check-added-large-files - - id: end-of-file-fixer - exclude: ".*(.fits|.fts|.fit|.txt|tca.*)$" - - id: mixed-line-ending - exclude: ".*(.fits|.fts|.fit|.txt|tca.*)$" + +ci: + autofix_prs: false diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cfb408ce..ebed79d9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,11 @@ +0.4.2 (2022-05-24) +================== + +Breaking Changes +---------------- + +- Minimum version of ``sunpy`` required is now 4.0.0 + 0.4.1 (2022-04-05) ================== diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0419fe02..d2cf9d33 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -58,15 +58,13 @@ stages: apt: - graphviz envs: - - macos: py37 - - windows: py38 + - macos: py38 + - windows: py39 - linux: build_docs posargs: " " pytest: false - linux: py39-online - - linux: py37-oldestdeps - - linux: py39-conda - libraries: {} + - linux: py38-oldestdeps - ${{ if or(eq(variables['Build.Reason'], 'Schedule'), eq(variables['Build.Reason'], 'Manual')) }}: - stage: CronTests @@ -81,6 +79,8 @@ stages: toxdeps: tox-pypi-filter envs: - linux: py310-devdeps + - linux: py39-conda + libraries: {} # On branches which aren't main, and not Pull Requests, build the wheels but only upload them on tags - ${{ if and(ne(variables['Build.Reason'], 'PullRequest'), or(ne(variables['Build.SourceBranchName'], 'main'), eq(variables['Build.Reason'], 'Schedule'), eq(variables['Build.Reason'], 'Manual'))) }}: diff --git a/docs/conf.py b/docs/conf.py index 73685829..db926b6d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,6 @@ """ Configuration file for the Sphinx documentation builder. + isort:skip_file """ # flake8: NOQA: E402 diff --git a/examples/tracing_loops.py b/examples/tracing_loops.py index 15b64a64..327dcf90 100644 --- a/examples/tracing_loops.py +++ b/examples/tracing_loops.py @@ -45,9 +45,7 @@ # The base flux and median flux ratio ``qthresh1`` is 0.0. # The noise threshold in the image with repect to median flux ``qthresh2`` is 3.0 . # For the meaning of these parameters please consult the OCCULT2 article. -loops = trace.occult2( - trace_map.data, nsm1=3, rmin=30, lmin=25, nstruc=1000, ngap=0, qthresh1=0.0, qthresh2=3.0 -) +loops = trace.occult2(trace_map.data, nsm1=3, rmin=30, lmin=25, nstruc=1000, ngap=0, qthresh1=0.0, qthresh2=3.0) ############################################################################### # `~sunkit_image.trace.occult2` returns a list, each element of which is a detected loop. diff --git a/pyproject.toml b/pyproject.toml index a1987264..4dd4bb2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,14 +2,14 @@ requires = [ "extension-helpers", "oldest-supported-numpy", - "setuptools_scm", - "setuptools", + "setuptools>=56,!=61.0.0", + "setuptools_scm[toml]>=6.2", "wheel", ] build-backend = 'setuptools.build_meta' [tool.black] -line-length = 110 +line-length = 120 include = '\.pyi?$' exclude = ''' ( diff --git a/setup.cfg b/setup.cfg index eec91260..c31268d1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,20 +19,20 @@ classifiers = Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Topic :: Scientific/Engineering :: Physics [options] -python_requires = >=3.7 +python_requires = >=3.8 packages = find: include_package_data = True setup_requires = setuptools_scm install_requires = scikit-image>=0.18.0 - sunpy>=3.0.0 + sunpy>=4.0.0 [options.extras_require] tests = diff --git a/sunkit_image/__init__.py b/sunkit_image/__init__.py index 94310195..97f3b8c9 100644 --- a/sunkit_image/__init__.py +++ b/sunkit_image/__init__.py @@ -23,8 +23,6 @@ class UnsupportedPythonError(Exception): if sys.version_info < tuple(int(val) for val in __minimum_python_version__.split(".")): # This has to be .format to keep backwards compatibly. - raise UnsupportedPythonError( - "sunkit_image does not support Python < {}".format(__minimum_python_version__) - ) + raise UnsupportedPythonError("sunkit_image does not support Python < {}".format(__minimum_python_version__)) __all__ = [] diff --git a/sunkit_image/_dev/__init__.py b/sunkit_image/_dev/__init__.py index 19bd3936..fa3fdbaa 100644 --- a/sunkit_image/_dev/__init__.py +++ b/sunkit_image/_dev/__init__.py @@ -1,6 +1,7 @@ """ -This package contains utilities that are only used when developing sunkit_image in a -copy of the source repository. +This package contains utilities that are only used when developing sunkit_image +in a copy of the source repository. + These files are not installed, and should not be assumed to exist at runtime. """ diff --git a/sunkit_image/asda.py b/sunkit_image/asda.py index edeab781..31959966 100644 --- a/sunkit_image/asda.py +++ b/sunkit_image/asda.py @@ -140,9 +140,7 @@ def gamma_values(self): vel = self.gen_vel(index[1], index[0]) # Iterate over the array gamma for d, (i, j) in enumerate( - product( - np.arange(self.r, self.dshape[0] - self.r, 1), np.arange(self.r, self.dshape[1] - self.r, 1) - ) + product(np.arange(self.r, self.dshape[0] - self.r, 1), np.arange(self.r, self.dshape[1] - self.r, 1)) ): self.gamma[i, j, 0], self.gamma[i, j, 1] = calc_gamma(pm, vel[..., d], pnorm, N) # Transpose back vx & vy diff --git a/sunkit_image/coalignment.py b/sunkit_image/coalignment.py index 4abe161b..6a88488b 100644 --- a/sunkit_image/coalignment.py +++ b/sunkit_image/coalignment.py @@ -1,7 +1,7 @@ """ This module provides routines for the co-alignment of images and -`~sunpy.map.mapsequence.MapSequence` objects through both template -matching and corrections due to solar rotation. +`~sunpy.map.mapsequence.MapSequence` objects through both template matching and +corrections due to solar rotation. """ import warnings from copy import deepcopy @@ -101,9 +101,7 @@ def clip_edges(data, yclips: u.pix, xclips: u.pix): nx = data.shape[1] # The purpose of the int below is to ensure integer type since by default # astropy quantities are converted to floats. - return data[ - int(yclips[0].value) : ny - int(yclips[1].value), int(xclips[0].value) : nx - int(xclips[1].value) - ] + return data[int(yclips[0].value) : ny - int(yclips[1].value), int(xclips[0].value) : nx - int(xclips[1].value)] @u.quantity_input @@ -291,7 +289,8 @@ def parabolic_turning_point(y): def check_for_nonfinite_entries(layer_image, template_image): """ - Issue a warning if there is any nonfinite entry in the layer or template images. + Issue a warning if there is any nonfinite entry in the layer or template + images. Parameters ---------- @@ -579,8 +578,8 @@ def mapsequence_coalign_by_match_template( def calculate_solar_rotate_shift(mc, layer_index=0, **kwargs): """ - Calculate the shift that must be applied to each map contained in a mapsequence - in order to compensate for solar rotation. + Calculate the shift that must be applied to each map contained in a + mapsequence in order to compensate for solar rotation. The center of the map is used to calculate the position of each mapsequence layer. Shifts are calculated relative to a specified layer in the mapsequence. @@ -627,9 +626,7 @@ def calculate_solar_rotate_shift(mc, layer_index=0, **kwargs): # Calculate the rotation of the center of the map 'm' at its # observation time to the observation time of the reference layer # indicated by "layer_index". - new_coordinate = solar_rotate_coordinate( - m.center, observer=rotate_to_this_layer.observer_coordinate, **kwargs - ) + new_coordinate = solar_rotate_coordinate(m.center, observer=rotate_to_this_layer.observer_coordinate, **kwargs) xshift_arcseconds[i] = new_coordinate.Tx - rotate_to_this_layer.center.Tx yshift_arcseconds[i] = new_coordinate.Ty - rotate_to_this_layer.center.Ty diff --git a/sunkit_image/tests/figure_hashes_mpl_332_ft_261_sunkit_image_dev_sunpy_300.json b/sunkit_image/tests/figure_hashes_mpl_332_ft_261_sunkit_image_dev_sunpy_300.json deleted file mode 100644 index 88baedf5..00000000 --- a/sunkit_image/tests/figure_hashes_mpl_332_ft_261_sunkit_image_dev_sunpy_300.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sunkit_image.tests.test_enhance.test_mgn": "8fcdf836ebda3405569ae1c73f40132c25f30b5e6408ce1584de1dc54d52b142", - "sunkit_image.tests.test_radial.test_fig_fnrgf": "f0e5b9c7b725aab30b3e7ed103bc4dd9728dafb02ed1b0f59045ed6d0c2f5626", - "sunkit_image.tests.test_radial.test_fig_nrgf": "6867843c6f7c143501f07fbcd04c4b22d093dca37f4f7f691d1cacab62d6dfb4", - "sunkit_image.tests.test_trace.test_occult2_fig": "c5ff1416cb51dc51ad1705174e5b13f8cb02486dc3c58fd79dc1b80534f6caf5" -} diff --git a/sunkit_image/tests/figure_hashes_mpl_332_ft_261_sunkit_image_dev_sunpy_400.json b/sunkit_image/tests/figure_hashes_mpl_332_ft_261_sunkit_image_dev_sunpy_400.json new file mode 100644 index 00000000..e0e4162e --- /dev/null +++ b/sunkit_image/tests/figure_hashes_mpl_332_ft_261_sunkit_image_dev_sunpy_400.json @@ -0,0 +1,6 @@ +{ + "sunkit_image.tests.test_enhance.test_mgn": "ab39d3330a967a6f34fb53043aa820665e87c4a73002381883b9516d2983228d", + "sunkit_image.tests.test_radial.test_fig_nrgf": "a0efb4aa94724bf1b2ff97466decb6edcc1394c704315f5b16dbf458d9c1df84", + "sunkit_image.tests.test_radial.test_fig_fnrgf": "4a653738b96abebac537ebba5aadedce02f3c03dd13cf12de836600c800a650e", + "sunkit_image.tests.test_trace.test_occult2_fig": "c5ff1416cb51dc51ad1705174e5b13f8cb02486dc3c58fd79dc1b80534f6caf5" +} diff --git a/sunkit_image/tests/helpers.py b/sunkit_image/tests/helpers.py index 950e413f..b059c9f4 100644 --- a/sunkit_image/tests/helpers.py +++ b/sunkit_image/tests/helpers.py @@ -25,9 +25,9 @@ def get_hash_library_name(): def figure_test(test_function): """ A decorator which marks the test as comparing the hash of the returned - figure to the hash library in the repository. - A `matplotlib.figure.Figure` object should be returned or ``plt.gcf()`` - will be called to get the figure object to compare to. + figure to the hash library in the repository. A `matplotlib.figure.Figure` + object should be returned or ``plt.gcf()`` will be called to get the figure + object to compare to. Examples -------- diff --git a/sunkit_image/tests/test_asda.py b/sunkit_image/tests/test_asda.py index 4be2a680..4fca7eea 100644 --- a/sunkit_image/tests/test_asda.py +++ b/sunkit_image/tests/test_asda.py @@ -23,16 +23,12 @@ def test_asda_artificial(): with pytest.raises(ValueError, match="Keyword 'factor' must be an integer"): lo = asda.Lamb_Oseen(vmax=vmax, rmax=rmax, ratio_vradial=ratio, factor=1.2, r=1) - with pytest.warns( - UserWarning, match="One of the input parameters is missing," + "setting both to 'None'" - ): + with pytest.warns(UserWarning, match="One of the input parameters is missing," + "setting both to 'None'"): lo = asda.Lamb_Oseen(vmax=vmax, rmax=rmax, gamma=0.5, ratio_vradial=ratio, factor=1) lo = asda.Lamb_Oseen(vmax=vmax, rmax=rmax, ratio_vradial=ratio, factor=1) # Generate vx and vy - with pytest.warns( - UserWarning, match="One of the input parameters is missing, setting " + " both to 'None'" - ): + with pytest.warns(UserWarning, match="One of the input parameters is missing, setting " + " both to 'None'"): vx, vy = lo.get_vxvy(x_range=[-100, 100, 200], y_range=[-100, 100, 200], x=np.meshgrid) vx, vy = lo.get_vxvy(x_range=[-100, 100, 200], y_range=[-100, 100, 200]) diff --git a/sunkit_image/tests/test_coalignment.py b/sunkit_image/tests/test_coalignment.py index d3ad48f8..5c647c09 100644 --- a/sunkit_image/tests/test_coalignment.py +++ b/sunkit_image/tests/test_coalignment.py @@ -92,16 +92,12 @@ def test_check_for_nonfinite_entries(): a[i] = non_number b = a.reshape(3, 3) - with pytest.warns( - SunpyUserWarning, match="The layer image has nonfinite entries." - ) as warning_list: + with pytest.warns(SunpyUserWarning, match="The layer image has nonfinite entries.") as warning_list: check_for_nonfinite_entries(b, np.ones((3, 3))) assert len(warning_list) == 1 - with pytest.warns( - SunpyUserWarning, match="The template image has nonfinite entries." - ) as warning_list: + with pytest.warns(SunpyUserWarning, match="The template image has nonfinite entries.") as warning_list: check_for_nonfinite_entries(np.ones((3, 3)), b) assert len(warning_list) == 1 @@ -162,9 +158,7 @@ def test_find_best_match_location(aia171_test_map_layer, aia171_test_template, a result = match_template_to_layer(aia171_test_map_layer, aia171_test_template) match_location = u.Quantity(find_best_match_location(result)) - assert_allclose( - match_location.value, np.array(result.shape) / 2.0 - 0.5 + aia171_test_shift, rtol=1e-3, atol=0 - ) + assert_allclose(match_location.value, np.array(result.shape) / 2.0 - 0.5 + aia171_test_shift, rtol=1e-3, atol=0) def test_lower_clip(aia171_test_clipping): @@ -214,10 +208,8 @@ def aia171_test_mc_pixel_displacements(): @pytest.fixture def aia171_mc_arcsec_displacements(aia171_test_mc_pixel_displacements, aia171_test_map): return { - "x": np.asarray([0.0, aia171_test_mc_pixel_displacements[1] * aia171_test_map.scale[0].value]) - * u.arcsec, - "y": np.asarray([0.0, aia171_test_mc_pixel_displacements[0] * aia171_test_map.scale[1].value]) - * u.arcsec, + "x": np.asarray([0.0, aia171_test_mc_pixel_displacements[1] * aia171_test_map.scale[0].value]) * u.arcsec, + "y": np.asarray([0.0, aia171_test_mc_pixel_displacements[0] * aia171_test_map.scale[1].value]) * u.arcsec, } @@ -381,9 +373,7 @@ def test_apply_shifts(aia171_test_map): # Test that keywords are correctly passed # Test for an individual keyword - test_mc = apply_shifts( - mc, astropy_displacements["y"], astropy_displacements["x"], clip=False, cval=np.nan - ) + test_mc = apply_shifts(mc, astropy_displacements["y"], astropy_displacements["x"], clip=False, cval=np.nan) assert np.all(np.logical_not(np.isfinite(test_mc[1].data[:, -1]))) # Test for a combination of keywords, and that changing the interpolation @@ -397,9 +387,7 @@ def test_apply_shifts(aia171_test_map): @pytest.fixture def aia171_test_submap(aia171_test_map): - return aia171_test_map.submap( - SkyCoord(((0, 0), (400, 500)) * u.arcsec, frame=aia171_test_map.coordinate_frame) - ) + return aia171_test_map.submap(SkyCoord(((0, 0), (400, 500)) * u.arcsec, frame=aia171_test_map.coordinate_frame)) @pytest.fixture @@ -430,23 +418,15 @@ def test_calculate_solar_rotate_shift( ): # Test that the default works test_output = calculate_solar_rotate_shift(aia171_test_mapsequence) - assert_allclose( - test_output["x"].to("arcsec").value, known_displacements_layer_index0["x"], rtol=5e-2, atol=1e-5 - ) - assert_allclose( - test_output["y"].to("arcsec").value, known_displacements_layer_index0["y"], rtol=5e-2, atol=1e-5 - ) + assert_allclose(test_output["x"].to("arcsec").value, known_displacements_layer_index0["x"], rtol=5e-2, atol=1e-5) + assert_allclose(test_output["y"].to("arcsec").value, known_displacements_layer_index0["y"], rtol=5e-2, atol=1e-5) # Test that the rotation relative to a nonzero layer_index works test_output = calculate_solar_rotate_shift(aia171_test_mapsequence, layer_index=1) print(test_output["x"].to("arcsec").value) print(test_output["y"].to("arcsec").value) - assert_allclose( - test_output["x"].to("arcsec").value, known_displacements_layer_index1["x"], rtol=5e-2, atol=1e-5 - ) - assert_allclose( - test_output["y"].to("arcsec").value, known_displacements_layer_index1["y"], rtol=5e-2, atol=1e-5 - ) + assert_allclose(test_output["x"].to("arcsec").value, known_displacements_layer_index1["x"], rtol=5e-2, atol=1e-5) + assert_allclose(test_output["y"].to("arcsec").value, known_displacements_layer_index1["y"], rtol=5e-2, atol=1e-5) def test_mapsequence_solar_derotate(aia171_test_mapsequence, aia171_test_submap): diff --git a/sunkit_image/tests/test_radial.py b/sunkit_image/tests/test_radial.py index 5749ed9f..024cb0a1 100644 --- a/sunkit_image/tests/test_radial.py +++ b/sunkit_image/tests/test_radial.py @@ -290,9 +290,7 @@ def test_intensity_enhance(map_test1): enhancement[map_r < normalization_radius] = 1 with pytest.raises(ValueError, match="The fit range must be strictly increasing."): - rad.intensity_enhance( - smap=map_test1, radial_bin_edges=radial_bin_edges, scale=scale, fit_range=fit_range[::-1] - ) + rad.intensity_enhance(smap=map_test1, radial_bin_edges=radial_bin_edges, scale=scale, fit_range=fit_range[::-1]) assert np.allclose( enhancement * map_test1.data, diff --git a/sunkit_image/tests/test_time_lag.py b/sunkit_image/tests/test_time_lag.py index 4e42194f..dfb1a252 100644 --- a/sunkit_image/tests/test_time_lag.py +++ b/sunkit_image/tests/test_time_lag.py @@ -7,9 +7,7 @@ from sunkit_image.time_lag import cross_correlation, get_lags, max_cross_correlation, time_lag -@pytest.mark.parametrize( - "shape_in,shape_out", [((20, 5, 5), (39, 5, 5)), ((100, 10), (199, 10)), ((1000,), (1999,))] -) +@pytest.mark.parametrize("shape_in,shape_out", [((20, 5, 5), (39, 5, 5)), ((100, 10), (199, 10)), ((1000,), (1999,))]) def test_cross_correlation_array_shapes(shape_in, shape_out): s_a = np.random.rand(*shape_in) s_b = np.random.rand(*shape_in) diff --git a/sunkit_image/tests/test_trace.py b/sunkit_image/tests/test_trace.py index 2d38f05d..be254a4a 100644 --- a/sunkit_image/tests/test_trace.py +++ b/sunkit_image/tests/test_trace.py @@ -236,17 +236,13 @@ def test_erase_loop_in_image(image, test_map): result = erase_loop_in_image(image, istart, jstart, width, xloop, yloop) - expect = np.array( - [[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]] - ) + expect = np.array([[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]]) assert np.allclose(expect, result) result = erase_loop_in_image(test_map, istart, jstart, width, xloop, yloop) - expect = np.array( - [[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]] - ) + expect = np.array([[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]]) assert np.allclose(expect, result) @@ -321,9 +317,7 @@ def parameters_add_loop(): lengths = np.zeros((np1), dtype=np.float32) for ip in range(1, np1): - lengths[ip] = lengths[ip - 1] + np.sqrt( - (xloop[ip] - xloop[ip - 1]) ** 2 + (yloop[ip] - yloop[ip - 1]) ** 2 - ) + lengths[ip] = lengths[ip - 1] + np.sqrt((xloop[ip] - xloop[ip - 1]) ** 2 + (yloop[ip] - yloop[ip - 1]) ** 2) # The empty structures in which the first loop is stored loops = [] diff --git a/sunkit_image/time_lag.py b/sunkit_image/time_lag.py index 8a3bcd39..7adc8edf 100644 --- a/sunkit_image/time_lag.py +++ b/sunkit_image/time_lag.py @@ -25,8 +25,8 @@ @u.quantity_input def get_lags(time: u.s): """ - Convert an array of evenly spaced times to an array of time lags - evenly spaced between ``-max(time)`` and ``max(time)``. + Convert an array of evenly spaced times to an array of time lags evenly + spaced between ``-max(time)`` and ``max(time)``. """ delta_t = np.diff(time) if not np.allclose(delta_t, delta_t[0]): @@ -236,8 +236,8 @@ def time_lag(signal_a, signal_b, time: u.s, lag_bounds: (u.s, None) = None, **kw @u.quantity_input def max_cross_correlation(signal_a, signal_b, time: u.s, lag_bounds: (u.s, None) = None): """ - Compute the maximum value of the cross-correlation between ``signal_a`` - and ``signal_b``. + Compute the maximum value of the cross-correlation between ``signal_a`` and + ``signal_b``. This is the maximum value of the cross-correlation as a function of lag (computed in :func:`cross_correlation`). This will always be between diff --git a/sunkit_image/trace.py b/sunkit_image/trace.py index b78d641f..e8572b18 100644 --- a/sunkit_image/trace.py +++ b/sunkit_image/trace.py @@ -209,9 +209,7 @@ def occult2(image, nsm1, rmin, lmin, nstruc, ngap, qthresh1, qthresh2): looplen = 0 if np1 >= 2: for ip in range(1, np1): - s[ip] = s[ip - 1] + np.sqrt( - (xloop[ip] - xloop[ip - 1]) ** 2 + (yloop[ip] - yloop[ip - 1]) ** 2 - ) + s[ip] = s[ip - 1] + np.sqrt((xloop[ip] - xloop[ip - 1]) ** 2 + (yloop[ip] - yloop[ip - 1]) ** 2) looplen = s[np1 - 1] # SKIP STRUCT: Only those loops are returned whose length is greater than the minimum @@ -548,9 +546,9 @@ def curvature_radius(image, rmin, xl, yl, zl, al, ir, ip, nlen, idir): ib2 = int(min(ir[ip] + 1, rad_segments - 1)) # See Eqn. 6 in the paper. Getting the values of all the valid radii - rad_i = rmin / ( - -1.0 + 2.0 * np.arange(ib1, ib2 + 1, dtype=np.float32) / np.float32(rad_segments - 1) - ).reshape((1, -1)) + rad_i = rmin / (-1.0 + 2.0 * np.arange(ib1, ib2 + 1, dtype=np.float32) / np.float32(rad_segments - 1)).reshape( + (1, -1) + ) # See Eqn 16. beta0 = al[ip] + np.float32(np.pi / 2) diff --git a/sunkit_image/utils/tests/test_utils.py b/sunkit_image/utils/tests/test_utils.py index 3ae0308d..8aeea2f9 100644 --- a/sunkit_image/utils/tests/test_utils.py +++ b/sunkit_image/utils/tests/test_utils.py @@ -134,9 +134,7 @@ def test_get_radial_intensity_summary(smap): warnings.simplefilter("ignore", category=RuntimeWarning) expected = np.asarray([summary(smap.data[lower_edge[i] * upper_edge[i]]) for i in range(0, nbins)]) - assert np.allclose( - utils.get_radial_intensity_summary(smap=smap, radial_bin_edges=radial_bin_edges), expected - ) + assert np.allclose(utils.get_radial_intensity_summary(smap=smap, radial_bin_edges=radial_bin_edges), expected) def test_calculate_gamma(): diff --git a/sunkit_image/version.py b/sunkit_image/version.py index ca665b0b..bf0f9144 100644 --- a/sunkit_image/version.py +++ b/sunkit_image/version.py @@ -9,9 +9,7 @@ except Exception: import warnings - warnings.warn( - f'could not determine {__name__.split(".")[0]} package version; this indicates a broken installation' - ) + warnings.warn(f'could not determine {__name__.split(".")[0]} package version; this indicates a broken installation') del warnings version = "0.0.0" diff --git a/tox.ini b/tox.ini index d256280e..ae824505 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,10 @@ [tox] envlist = - py{37,38,39,310}{,-oldestdeps,-devdeps,-online,-figure,-conda} + py{38,39,310}{,-oldestdeps,-devdeps,-online,-figure,-conda} build_docs codestyle requires = - setuptools >= 30.3.0 + setuptools >=56, !=61.0.0 pip >= 19.3.1 tox-pypi-filter >= 0.12 isolated_build = true @@ -18,14 +18,6 @@ whitelist_externals= # Run the tests in a temporary directory to make sure that we don't import # sunkit_image from the source tree changedir = .tmp/{envname} -# tox environments are constructued with so-called 'factors' (or terms) -# separated by hyphens, e.g. test-devdeps-cov. Lines below starting with factor: -# will only take effect if that factor is included in the environment name. To -# see a list of example environments that can be run, along with a description, -# run: -# -# tox -l -v -# description = run tests devdeps: with the latest developer version of key dependencies