From 325e29c8236bbf2887ef43fd914fa217b2b8f14a Mon Sep 17 00:00:00 2001 From: Shane Maloney Date: Tue, 12 Mar 2024 15:42:04 +0000 Subject: [PATCH 1/5] Initial repo and code setup --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 92c08c4..6046a24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,6 @@ dependencies = [ 'mahotas', 'scikit-image', 'opencv-python' - ] dynamic = ["version"] From d5ac37c98d9c5a5e4c99ddb834b219242196029e Mon Sep 17 00:00:00 2001 From: Shane Maloney Date: Thu, 13 Jun 2024 11:00:46 +0100 Subject: [PATCH 2/5] Code formatting, better tests and small refactor --- .pre-commit-config.yaml | 7 + .ruff.toml | 10 +- chimerapy/chimera.py | 242 ++++++++++++---------------- chimerapy/tests/test_ch_summary.txt | 26 +++ chimerapy/tests/test_chimera.py | 24 ++- pyproject.toml | 11 +- tox.ini | 2 +- 7 files changed, 166 insertions(+), 156 deletions(-) create mode 100644 chimerapy/tests/test_ch_summary.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 59d7541..8952969 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,13 @@ repos: hooks: - id: ruff args: ["--fix"] + # Run the formatter. + - id: ruff-format + - repo: https://github.com/PyCQA/isort + rev: 5.13.2 + hooks: + - id: isort + exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*)$" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: diff --git a/.ruff.toml b/.ruff.toml index 007308e..6e881e3 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -20,20 +20,20 @@ extend-ignore = [ "PT023", # Always use () on pytest decorators ] -[flake8-tidy-imports] -[flake8-tidy-imports.banned-api] +[lint.flake8-tidy-imports] +[lint.flake8-tidy-imports.banned-api] "warnings.warn".msg = "Use sunpy specific warning helpers warn_* from sunpy.utils.exceptions" -[per-file-ignores] +[lint.per-file-ignores] # Part of configuration, not a package. "setup.py" = ["INP001"] "conftest.py" = ["INP001"] # Implicit-namespace-package. The examples are not a package. -"docs/*.py" = ["INP001"] +"docs/*.py" = ["INP001", "E402"] "__init__.py" = ["E402", "F401", "F403"] "test_*.py" = ["B011", "D", "E402", "PGH001", "S101"] # Need to import clients to register them, but don't use them in file "CHIMERApy/net/__init__.py" = ["F811"] -[pydocstyle] +[lint.pydocstyle] convention = "numpy" diff --git a/chimerapy/chimera.py b/chimerapy/chimera.py index e1b8723..4609259 100644 --- a/chimerapy/chimera.py +++ b/chimerapy/chimera.py @@ -3,21 +3,20 @@ """ -from astropy import wcs -from astropy.io import fits -from astropy.modeling.models import Gaussian2D -from skimage.util import img_as_ubyte +import glob +import sys import astropy.units as u - import cv2 -import glob import mahotas import matplotlib.pyplot as plt import numpy as np import scipy.interpolate import sunpy.map -import sys +from astropy import wcs +from astropy.io import fits +from astropy.modeling.models import Gaussian2D +from skimage.util import img_as_ubyte def chimera_legacy(): @@ -28,10 +27,23 @@ def chimera_legacy(): im211 = glob.glob(file_path + "*211*.fts.gz") imhmi = glob.glob(file_path + "*hmi*.fts.gz") + circ, data, datb, datc, dattoarc, hedb, iarr, props, rs, slate, center, xgrid, ygrid = chimera( + im171, im193, im211, imhmi + ) + + # =====sets ident back to max value of iarr====== + + # ident = ident - 1 + np.savetxt("ch_summary.txt", props, fmt="%s") + + plot_tricolor(data, datb, datc, xgrid, ygrid, slate) + plot_mask(slate, iarr, circ, rs, dattoarc, center, xgrid, ygrid, hedb) + + +def chimera(im171, im193, im211, imhmi): if im171 == [] or im193 == [] or im211 == [] or imhmi == []: print("Not all required files present") sys.exit() - # =====Reads in data and resizes images===== x = np.arange(0, 1024) * 4 hdu_number = 0 @@ -39,34 +51,26 @@ def chimera_legacy(): data = fits.getdata(im171[0], ext=0) / (heda["EXPTIME"]) dn = scipy.interpolate.interp2d(x, x, data) data = dn(np.arange(0, 4096), np.arange(0, 4096)) - hedb = fits.getheader(im193[0], hdu_number) datb = fits.getdata(im193[0], ext=0) / (hedb["EXPTIME"]) dn = scipy.interpolate.interp2d(x, x, datb) datb = dn(np.arange(0, 4096), np.arange(0, 4096)) - hedc = fits.getheader(im211[0], hdu_number) datc = fits.getdata(im211[0], ext=0) / (hedc["EXPTIME"]) dn = scipy.interpolate.interp2d(x, x, datc) datc = dn(np.arange(0, 4096), np.arange(0, 4096)) - hedm = fits.getheader(imhmi[0], hdu_number) datm = fits.getdata(imhmi[0], ext=0) # dn = scipy.interpolate.interp2d(np.arange(4096), np.arange(4096), datm) # datm = dn(np.arange(0, 1024)*4, np.arange(0, 1024)*4) - if hedm["crota1"] > 90: datm = np.rot90(np.rot90(datm)) - # =====Specifies solar radius and calculates conversion value of pixel to arcsec===== - s = np.shape(data) rs = heda["rsun"] - if hedb["ctype1"] != "solar_x ": hedb["ctype1"] = "solar_x " hedb["ctype2"] = "solar_y " - if heda["cdelt1"] > 1: heda["cdelt1"], heda["cdelt2"], heda["crpix1"], heda["crpix2"] = ( heda["cdelt1"] / 4.0, @@ -86,35 +90,26 @@ def chimera_legacy(): hedc["crpix1"] * 4.0, hedc["crpix2"] * 4.0, ) - dattoarc = heda["cdelt1"] - conver = (s[0] / 2) * dattoarc / hedm["cdelt1"] - (s[1] / 2) convermul = dattoarc / hedm["cdelt1"] - # =====Alternative coordinate systems===== - hdul = fits.open(im171[0]) - hdul[0].header['CUNIT1'] = 'arcsec' - hdul[0].header['CUNIT2'] = 'arcsec' + hdul[0].header["CUNIT1"] = "arcsec" + hdul[0].header["CUNIT2"] = "arcsec" aia = sunpy.map.Map(hdul[0].data, hdul[0].header) adj = 4096.0 / aia.dimensions[0].value x, y = (np.meshgrid(*[np.arange(adj * v.value) for v in aia.dimensions]) * u.pixel) / adj hpc = aia.pixel_to_world(x, y) hg = hpc.transform_to(sunpy.coordinates.frames.HeliographicStonyhurst) - csys = wcs.WCS(hedb) - # =======setting up arrays to be used============ - ident = 1 iarr = np.zeros((s[0], s[1]), dtype=np.byte) offarr, slate = np.array(iarr), np.array(iarr) bmcool = np.zeros((s[0], s[1]), dtype=np.float32) cand, bmmix, bmhot = np.array(bmcool), np.array(bmcool), np.array(bmcool) circ = np.zeros((s[0], s[1]), dtype=int) - # =======creation of a 2d gaussian for magnetic cut offs=========== - r = (s[1] / 2.0) - 450 xgrid, ygrid = np.meshgrid(np.arange(s[0]), np.arange(s[1])) center = [int(s[1] / 2.0), int(s[1] / 2.0)] @@ -122,9 +117,7 @@ def chimera_legacy(): y, x = np.mgrid[0:4096, 0:4096] garr = Gaussian2D(1, s[0] / 2, s[1] / 2, 2000 / 2.3548, 2000 / 2.3548)(x, y) garr[w] = 1.0 - # ======creation of array for CH properties========== - props = np.zeros((26, 30), dtype=" 2.7)] = 2.7 t1[np.where(t1 < 1.4)] = 1.4 t1[np.where(t1 > 3.0)] = 3.0 t2[np.where(t2 < 1.2)] = 1.2 t2[np.where(t2 > 3.9)] = 3.9 - t0 = np.array(((t0 - 0.8) / (2.7 - 0.8)) * 255, dtype=np.float32) t1 = np.array(((t1 - 1.4) / (3.0 - 1.4)) * 255, dtype=np.float32) t2 = np.array(((t2 - 1.2) / (3.9 - 1.2)) * 255, dtype=np.float32) - # ====create 3 segmented bitmasks===== - with np.errstate(divide="ignore", invalid="ignore"): bmmix[np.where(t2 / t0 >= ((np.mean(data) * 0.6357) / (np.mean(datc))))] = 1 bmhot[np.where(t0 + t1 < (0.7 * (np.mean(datb) + np.mean(datc))))] = 1 bmcool[np.where(t2 / t1 >= ((np.mean(data) * 1.5102) / (np.mean(datb))))] = 1 - # ====logical conjunction of 3 segmentations======= - cand = bmcool * bmmix * bmhot - # ====plot tricolour image with lon/lat conotours======= - # ======removes off detector mis-identifications========== - r = (s[1] / 2.0) - 100 w = np.where((xgrid - center[0]) ** 2 + (ygrid - center[1]) ** 2 <= r**2) circ[w] = 1.0 cand = cand * circ - - # =======Seperates on-disk and off-limb CHs=============== - + # =======Separates on-disk and off-limb CHs=============== circ[:] = 0 r = (rs / dattoarc) - 10 w = np.where((xgrid - center[0]) ** 2 + (ygrid - center[1]) ** 2 <= r**2) @@ -237,31 +215,20 @@ def chimera_legacy(): w = np.where((xgrid - center[0]) ** 2 + (ygrid - center[1]) ** 2 >= r**2) circ[w] = 1.0 cand = cand * circ - # ====open file for property storage===== - # =====contours the identified datapoints======= - cand = np.array(cand, dtype=np.uint8) cont, heir = cv2.findContours(cand, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - # ======sorts contours by size============ - sizes = [] for i in range(len(cont)): sizes = np.append(sizes, len(cont[i])) - reord = sizes.ravel().argsort()[::-1] - tmp = list(cont) - for i in range(len(cont)): tmp[i] = cont[reord[i]] - cont = list(tmp) - # =====cycles through contours========= - for i in range(len(cont)): x = np.append(x, len(cont[i])) @@ -277,7 +244,7 @@ def chimera_legacy(): if arcar > 1000: # =====finds centroid======= - chpts = len(cont[i]) + # chpts = len(cont[i]) cent = [np.mean(cont[i][:, 0, 0]), np.mean(cont[i][:, 0, 1])] # ===remove quiet sun regions encompassed by coronal holes====== @@ -309,11 +276,15 @@ def chimera_legacy(): if (((arccent[0] ** 2) + (arccent[1] ** 2)) > (rs**2)) or ( np.sum(np.array(csys.all_pix2world(cont[i][0, 0, 0], cont[i][0, 0, 1], 0)) ** 2) > (rs**2) ): - mahotas.polygon.fill_polygon(np.array(list(zip(cont[i][:, 0, 1], cont[i][:, 0, 0]))), offarr) + mahotas.polygon.fill_polygon( + np.array(list(zip(cont[i][:, 0, 1], cont[i][:, 0, 0]))), offarr + ) else: # =====classifies on disk coronal holes======= - mahotas.polygon.fill_polygon(np.array(list(zip(cont[i][:, 0, 1], cont[i][:, 0, 0]))), slate) + mahotas.polygon.fill_polygon( + np.array(list(zip(cont[i][:, 0, 1], cont[i][:, 0, 0]))), slate + ) poslin = np.where(slate == 1) slate[:] = 0 @@ -338,7 +309,7 @@ def chimera_legacy(): wh1 = np.where(npix[1] > 0) wh2 = np.where(npix[1] < 0) - # =====magnetic cut offs dependant on area========= + # =====magnetic cut offs dependent on area========= if ( np.absolute((np.sum(npix[0][wh1]) - np.sum(npix[0][wh2])) / np.sqrt(np.sum(npix[0]))) @@ -355,8 +326,12 @@ def chimera_legacy(): # ====create an accurate center point======= - ypos = np.sum((poslin[0]) * np.absolute(hg.lat[poslin])) / np.sum(np.absolute(hg.lat[poslin])) - xpos = np.sum((poslin[1]) * np.absolute(hg.lon[poslin])) / np.sum(np.absolute(hg.lon[poslin])) + ypos = np.sum((poslin[0]) * np.absolute(hg.lat[poslin])) / np.sum( + np.absolute(hg.lat[poslin]) + ) + xpos = np.sum((poslin[1]) * np.absolute(hg.lon[poslin])) / np.sum( + np.absolute(hg.lon[poslin]) + ) arccent = csys.all_pix2world(xpos, ypos, 0) @@ -371,47 +346,47 @@ def chimera_legacy(): truarcar = trupixar * (dattoarc**2) trummar = truarcar * ((6.96e08 / rs) ** 2) - # ====find CH extent in lattitude and longitude======== + # ====find CH extent in latitude and longitude======== - maxxlat = hg.lat[ - cont[i][np.where(cont[i][:, 0, 0] == np.max(cont[i][:, 0, 0]))[0][0], 0, 1], - np.max(cont[i][:, 0, 0]), - ] + # maxxlat = hg.lat[ + # cont[i][np.where(cont[i][:, 0, 0] == np.max(cont[i][:, 0, 0]))[0][0], 0, 1], + # np.max(cont[i][:, 0, 0]), + # ] maxxlon = hg.lon[ cont[i][np.where(cont[i][:, 0, 0] == np.max(cont[i][:, 0, 0]))[0][0], 0, 1], np.max(cont[i][:, 0, 0]), ] - maxylat = hg.lat[ - np.max(cont[i][:, 0, 1]), - cont[i][np.where(cont[i][:, 0, 1] == np.max(cont[i][:, 0, 1]))[0][0], 0, 0], - ] - maxylon = hg.lon[ - np.max(cont[i][:, 0, 1]), - cont[i][np.where(cont[i][:, 0, 1] == np.max(cont[i][:, 0, 1]))[0][0], 0, 0], - ] - minxlat = hg.lat[ - cont[i][np.where(cont[i][:, 0, 0] == np.min(cont[i][:, 0, 0]))[0][0], 0, 1], - np.min(cont[i][:, 0, 0]), - ] + # maxylat = hg.lat[ + # np.max(cont[i][:, 0, 1]), + # cont[i][np.where(cont[i][:, 0, 1] == np.max(cont[i][:, 0, 1]))[0][0], 0, 0], + # ] + # maxylon = hg.lon[ + # np.max(cont[i][:, 0, 1]), + # cont[i][np.where(cont[i][:, 0, 1] == np.max(cont[i][:, 0, 1]))[0][0], 0, 0], + # ] + # minxlat = hg.lat[ + # cont[i][np.where(cont[i][:, 0, 0] == np.min(cont[i][:, 0, 0]))[0][0], 0, 1], + # np.min(cont[i][:, 0, 0]), + # ] minxlon = hg.lon[ cont[i][np.where(cont[i][:, 0, 0] == np.min(cont[i][:, 0, 0]))[0][0], 0, 1], np.min(cont[i][:, 0, 0]), ] - minylat = hg.lat[ - np.min(cont[i][:, 0, 1]), - cont[i][np.where(cont[i][:, 0, 1] == np.min(cont[i][:, 0, 1]))[0][0], 0, 0], - ] - minylon = hg.lon[ - np.min(cont[i][:, 0, 1]), - cont[i][np.where(cont[i][:, 0, 1] == np.min(cont[i][:, 0, 1]))[0][0], 0, 0], - ] + # minylat = hg.lat[ + # np.min(cont[i][:, 0, 1]), + # cont[i][np.where(cont[i][:, 0, 1] == np.min(cont[i][:, 0, 1]))[0][0], 0, 0], + # ] + # minylon = hg.lon[ + # np.min(cont[i][:, 0, 1]), + # cont[i][np.where(cont[i][:, 0, 1] == np.min(cont[i][:, 0, 1]))[0][0], 0, 0], + # ] # =====CH centroid in lat/lon======= centlat = hg.lat[int(ypos), int(xpos)] centlon = hg.lon[int(ypos), int(xpos)] - # ====caluclate the mean magnetic field===== + # ====calculate the mean magnetic field===== mB = np.mean(datm[pos[:, 0], pos[:, 1]]) mBpos = np.sum(npix[0][wh1] * npix[1][wh1]) / np.sum(npix[0][wh1]) @@ -494,68 +469,53 @@ def chimera_legacy(): # =====sets up code for next possible coronal hole===== ident = ident + 1 + return circ, data, datb, datc, dattoarc, hedb, iarr, props, rs, slate, center, xgrid, ygrid - # =====sets ident back to max value of iarr====== - ident = ident - 1 - np.savetxt("ch_summary.txt", props, fmt="%s") - - # ====create image in output folder======= - # from scipy.misc import bytescale - - - def rescale01(arr, cmin=None, cmax=None, a=0, b=1): - if cmin or cmax: - arr = np.clip(arr, cmin, cmax) - return (b - a) * ((arr - np.min(arr)) / (np.max(arr) - np.min(arr))) + a - - - def plot_tricolor(): - tricolorarray = np.zeros((4096, 4096, 3)) +def rescale01(arr, cmin=None, cmax=None, a=0, b=1): + if cmin or cmax: + arr = np.clip(arr, cmin, cmax) + return (b - a) * ((arr - np.min(arr)) / (np.max(arr) - np.min(arr))) + a - data_a = img_as_ubyte(rescale01(np.log10(data), cmin=1.2, cmax=3.9)) - data_b = img_as_ubyte(rescale01(np.log10(datb), cmin=1.4, cmax=3.0)) - data_c = img_as_ubyte(rescale01(np.log10(datc), cmin=0.8, cmax=2.7)) - tricolorarray[..., 0] = data_c / np.max(data_c) - tricolorarray[..., 1] = data_b / np.max(data_b) - tricolorarray[..., 2] = data_a / np.max(data_a) +def plot_tricolor(data, datb, datc, xgrid, ygrid, slate): + tricolorarray = np.zeros((4096, 4096, 3)) - fig, ax = plt.subplots(figsize=(10, 10)) + data_a = img_as_ubyte(rescale01(np.log10(data), cmin=1.2, cmax=3.9)) + data_b = img_as_ubyte(rescale01(np.log10(datb), cmin=1.4, cmax=3.0)) + data_c = img_as_ubyte(rescale01(np.log10(datc), cmin=0.8, cmax=2.7)) - plt.imshow(tricolorarray, origin="lower") # , extent = ) - plt.contour(xgrid, ygrid, slate, colors="white", linewidths=0.5) - plt.savefig("tricolor.png") - plt.close() + tricolorarray[..., 0] = data_c / np.max(data_c) + tricolorarray[..., 1] = data_b / np.max(data_b) + tricolorarray[..., 2] = data_a / np.max(data_a) + fig, ax = plt.subplots(figsize=(10, 10)) - def plot_mask(slate=slate): - chs = np.where(iarr > 0) - slate[chs] = 1 - slate = np.array(slate, dtype=np.uint8) - cont, heir = cv2.findContours(slate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + plt.imshow(tricolorarray, origin="lower") # , extent = ) + plt.contour(xgrid, ygrid, slate, colors="white", linewidths=0.5) + plt.savefig("tricolor.png") + plt.close() - circ[:] = 0 - r = rs / dattoarc - w = np.where((xgrid - center[0]) ** 2 + (ygrid - center[1]) ** 2 <= r**2) - circ[w] = 1.0 - plt.figure(figsize=(10, 10)) - plt.xlim(143, 4014) - plt.ylim(143, 4014) - plt.scatter(chs[1], chs[0], marker="s", s=0.0205, c="black", cmap="viridis", edgecolor="none", alpha=0.2) - plt.gca().set_aspect("equal", adjustable="box") - plt.axis("off") - plt.contour(xgrid, ygrid, slate, colors="black", linewidths=0.5) - plt.contour(xgrid, ygrid, circ, colors="black", linewidths=1.0) +def plot_mask(slate, iarr, circ, rs, dattoarc, center, xgrid, ygrid, hedb): + chs = np.where(iarr > 0) + slate[chs] = 1 + slate = np.array(slate, dtype=np.uint8) + # cont, heir = cv2.findContours(slate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - plt.savefig("CH_mask_" + hedb["DATE"] + ".png", transparent=True) - plt.close() - - - # ====stores all CH properties in a text file===== - - plot_tricolor() - plot_mask() + circ[:] = 0 + r = rs / dattoarc + w = np.where((xgrid - center[0]) ** 2 + (ygrid - center[1]) ** 2 <= r**2) + circ[w] = 1.0 - # ====EOF==== + plt.figure(figsize=(10, 10)) + plt.xlim(143, 4014) + plt.ylim(143, 4014) + plt.scatter(chs[1], chs[0], marker="s", s=0.0205, c="black", cmap="viridis", edgecolor="none", alpha=0.2) + plt.gca().set_aspect("equal", adjustable="box") + plt.axis("off") + plt.contour(xgrid, ygrid, slate, colors="black", linewidths=0.5) + plt.contour(xgrid, ygrid, circ, colors="black", linewidths=1.0) + + plt.savefig("CH_mask_" + hedb["DATE"] + ".png", transparent=True) + plt.close() diff --git a/chimerapy/tests/test_ch_summary.txt b/chimerapy/tests/test_ch_summary.txt new file mode 100644 index 0000000..5fc9e14 --- /dev/null +++ b/chimerapy/tests/test_ch_summary.txt @@ -0,0 +1,26 @@ +ID num 1 2 3 4 +XCEN " -199.0 -720.0 -131.0 231.0 +YCEN " 801.0 371.0 -123.0 -904.0 +CENTROID H° E27N63 E57N27 E8S0 W36S65 +X_EB " -534.0 -821.0 -213.0 85.0 +Y_EB " 746.0 333.0 -189.0 -939.0 +X_WB " 326.0 -502.0 -47.0 361.0 +Y_WB " 688.0 269.0 -17.0 -878.0 +X_NB " -27.0 -713.0 -137.0 283.0 +Y_NB " 949.0 609.0 34.0 -861.0 +X_SB " -289.0 -778.0 -133.0 88.0 +Y_SB " 594.0 173.0 -275.0 -946.0 +WIDTH H° E71-W34 E69-E34 E13-E3 W17-W58 +WIDTH° ° 105 35 10 41 +AREA Mm^2 1.7e+05 5.7e+04 1.3e+04 2.3e+04 +AREA% % 5.8 2.0 0.8 0.3 + G 0.5 2.6 2.0 -0.8 + G 6.8 9.8 12.5 5.7 + G -5.9 -5.9 -5.3 -7.5 +BMAX G 247.0 421.0 615.0 35.0 +BMIN G -150.0 -110.0 -108.0 -161.0 +TOT_B+ G 1.5e+06 7.8e+05 2.8e+05 6.6e+04 +TOT_B- G -1.2e+06 -3.8e+05 -1.4e+05 -8.6e+04 + Mx 9.6e+32 1.4e+33 2.6e+32 -1.8e+32 + Mx 1.2e+34 5.6e+33 1.6e+33 1.3e+33 + Mx -1.0e+34 -3.3e+33 -6.8e+32 -1.7e+33 diff --git a/chimerapy/tests/test_chimera.py b/chimerapy/tests/test_chimera.py index ef21a7e..c6e5952 100644 --- a/chimerapy/tests/test_chimera.py +++ b/chimerapy/tests/test_chimera.py @@ -1,17 +1,29 @@ import os +from pathlib import Path -from chimerapy.chimera import chimera_legacy from parfive import Downloader +from chimerapy.chimera import chimera_legacy + INPUT_FILES = { - 'aia171': 'https://solarmonitor.org/data/2016/09/22/fits/saia/saia_00171_fd_20160922_103010.fts.gz', - 'aia193': 'https://solarmonitor.org/data/2016/09/22/fits/saia/saia_00193_fd_20160922_103041.fts.gz', - 'aia211': 'https://solarmonitor.org/data/2016/09/22/fits/saia/saia_00211_fd_20160922_103046.fts.gz', - 'hmi_mag': 'https://solarmonitor.org/data/2016/09/22/fits/shmi/shmi_maglc_fd_20160922_094640.fts.gz' + "aia171": "https://solarmonitor.org/data/2016/09/22/fits/saia/saia_00171_fd_20160922_103010.fts.gz", + "aia193": "https://solarmonitor.org/data/2016/09/22/fits/saia/saia_00193_fd_20160922_103041.fts.gz", + "aia211": "https://solarmonitor.org/data/2016/09/22/fits/saia/saia_00211_fd_20160922_103046.fts.gz", + "hmi_mag": "https://solarmonitor.org/data/2016/09/22/fits/shmi/shmi_maglc_fd_20160922_094640.fts.gz", } def test_chimera(tmp_path): - files = Downloader.simple_download(INPUT_FILES.values(), path=tmp_path) + Downloader.simple_download(INPUT_FILES.values(), path=tmp_path) os.chdir(tmp_path) chimera_legacy() + + test_summary_file = Path(__file__).parent / 'test_ch_summary.txt' + with test_summary_file.open('r') as f: + test_summary_text = f.read() + + ch_summary_file = tmp_path / "ch_summary.txt" + with ch_summary_file.open("r") as f: + ch_summary_text = f.read() + + assert ch_summary_text == test_summary_text diff --git a/pyproject.toml b/pyproject.toml index 6046a24..d2295f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,10 +12,10 @@ readme = "README.rst" requires-python = ">=3.9" license = { file = "licenses/LICENSE.rst", content-type = "text/plain" } dependencies = [ - 'sunpy[net,map]', - 'mahotas', + 'sunpy[net,map]>=5.1.0', + 'mahotas>=1.4.0', 'scikit-image', - 'opencv-python' + 'opencv-python', ] dynamic = ["version"] @@ -30,6 +30,7 @@ docs = [ "sphinx-automodapi", "tomli; python_version <\"3.11\"", ] +dev = ["chimerapy[docs,tests]"] [project.urls] repository = "chimerapy.readthedocs.io" @@ -87,3 +88,7 @@ exclude_lines = [ # Don't complain about IPython completion helper "def _ipython_key_completions_", ] + +[tool.codespell] +skip = '*.fits,*.fts,*.header,*.json,*.xsh,*cache*,*egg*,*extern*,.git,.idea,.tox,_build,*truncated,*.svg,.asv_env,.history' +ignore-words-list = 'alog, nd, nin, ot, te, upto, afile, reord' diff --git a/tox.ini b/tox.ini index c226b1f..5daf780 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ min_version = 4.0 requires = tox-pypi-filter>=0.14 envlist = - py{39,310} + py{39,310,311,312} build_docs [testenv] From 2d907181c8d212add3774c9fbce977c7b0b2dfbe Mon Sep 17 00:00:00 2001 From: Shane Maloney Date: Thu, 13 Jun 2024 11:03:25 +0100 Subject: [PATCH 3/5] pre-commit --- chimerapy/tests/test_chimera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chimerapy/tests/test_chimera.py b/chimerapy/tests/test_chimera.py index c6e5952..e08da98 100644 --- a/chimerapy/tests/test_chimera.py +++ b/chimerapy/tests/test_chimera.py @@ -18,8 +18,8 @@ def test_chimera(tmp_path): os.chdir(tmp_path) chimera_legacy() - test_summary_file = Path(__file__).parent / 'test_ch_summary.txt' - with test_summary_file.open('r') as f: + test_summary_file = Path(__file__).parent / "test_ch_summary.txt" + with test_summary_file.open("r") as f: test_summary_text = f.read() ch_summary_file = tmp_path / "ch_summary.txt" From b575000e5e0c14c0cf232a757ed5b31992884e37 Mon Sep 17 00:00:00 2001 From: Shane Maloney Date: Thu, 13 Jun 2024 13:23:25 +0100 Subject: [PATCH 4/5] Fix test on windows --- chimerapy/tests/test_chimera.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chimerapy/tests/test_chimera.py b/chimerapy/tests/test_chimera.py index e08da98..4fd0eaf 100644 --- a/chimerapy/tests/test_chimera.py +++ b/chimerapy/tests/test_chimera.py @@ -26,4 +26,4 @@ def test_chimera(tmp_path): with ch_summary_file.open("r") as f: ch_summary_text = f.read() - assert ch_summary_text == test_summary_text + assert ascii(ch_summary_text) == ascii(test_summary_text) From 13debe7feda7d479955972998ff9dc88b7f94cda Mon Sep 17 00:00:00 2001 From: Shane Maloney Date: Thu, 13 Jun 2024 13:47:05 +0100 Subject: [PATCH 5/5] Remove odd charcters from output and update test data --- chimerapy/chimera.py | 8 ++++---- chimerapy/tests/test_ch_summary.txt | 6 +++--- chimerapy/tests/test_chimera.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/chimerapy/chimera.py b/chimerapy/chimera.py index 4609259..4462553 100644 --- a/chimerapy/chimera.py +++ b/chimerapy/chimera.py @@ -133,7 +133,7 @@ def chimera(im171, im193, im211, imhmi): "X_SB", "Y_SB", "WIDTH", - "WIDTH°", + "WIDTH", "AREA", "AREA%", "", @@ -151,7 +151,7 @@ def chimera(im171, im193, im211, imhmi): "num", '"', '"', - "H°", + "H deg", '"', '"', '"', @@ -160,8 +160,8 @@ def chimera(im171, im193, im211, imhmi): '"', '"', '"', - "H°", - "°", + "H deg", + "deg", "Mm^2", "%", "G", diff --git a/chimerapy/tests/test_ch_summary.txt b/chimerapy/tests/test_ch_summary.txt index 5fc9e14..21cb14a 100644 --- a/chimerapy/tests/test_ch_summary.txt +++ b/chimerapy/tests/test_ch_summary.txt @@ -1,7 +1,7 @@ ID num 1 2 3 4 XCEN " -199.0 -720.0 -131.0 231.0 YCEN " 801.0 371.0 -123.0 -904.0 -CENTROID H° E27N63 E57N27 E8S0 W36S65 +CENTROID H deg E27N63 E57N27 E8S0 W36S65 X_EB " -534.0 -821.0 -213.0 85.0 Y_EB " 746.0 333.0 -189.0 -939.0 X_WB " 326.0 -502.0 -47.0 361.0 @@ -10,8 +10,8 @@ X_NB " -27.0 -713.0 -137.0 283.0 Y_NB " 949.0 609.0 34.0 -861.0 X_SB " -289.0 -778.0 -133.0 88.0 Y_SB " 594.0 173.0 -275.0 -946.0 -WIDTH H° E71-W34 E69-E34 E13-E3 W17-W58 -WIDTH° ° 105 35 10 41 +WIDTH H deg E71-W34 E69-E34 E13-E3 W17-W58 +WIDTH deg 105 35 10 41 AREA Mm^2 1.7e+05 5.7e+04 1.3e+04 2.3e+04 AREA% % 5.8 2.0 0.8 0.3 G 0.5 2.6 2.0 -0.8 diff --git a/chimerapy/tests/test_chimera.py b/chimerapy/tests/test_chimera.py index 4fd0eaf..e08da98 100644 --- a/chimerapy/tests/test_chimera.py +++ b/chimerapy/tests/test_chimera.py @@ -26,4 +26,4 @@ def test_chimera(tmp_path): with ch_summary_file.open("r") as f: ch_summary_text = f.read() - assert ascii(ch_summary_text) == ascii(test_summary_text) + assert ch_summary_text == test_summary_text