Skip to content

Commit

Permalink
Update ruff configuration so that it runs on all files in the reposit…
Browse files Browse the repository at this point in the history
…ory.
  • Loading branch information
MetinSa committed Apr 19, 2024
1 parent 50efecf commit 44b3cc0
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 113 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ jobs:
source $VENV
mypy ./zodipy
- name: Lint with ruff
- name: Check linting with ruff
run: |
source $VENV
ruff ./zodipy
ruff check
- name: Check formating with ruff
run: |
source $VENV
ruff format --check ./zodipy
ruff format --check
- name: Test with pytest
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Note that developers using Python 3.12 will need to upgrade their pip versions w
The following tools should be run from the root of the repository with no errors. (These are ran automatically as part of the CI workflows on GitHub, but should be tested locally first)

- [pytest](https://docs.pytest.org/en/8.0.x/): Tests are run with pytest by simply running `pytest` in the command line in the root of the repository.
- [ruff](https://github.com/astral-sh/ruff): Formating and linting is done with `ruff` by simply running `ruff check zodipy/` and `ruff format zodipy/` in the command line in the root of the repository.
- [ruff](https://github.com/astral-sh/ruff): Formating and linting is done with `ruff` by simply running `ruff check` and `ruff format` in the command line in the root of the repository.
- [mypy](https://mypy-lang.org/): Type checking is done with `mypy` by simply running `mypy zodipy/` in the root of the repository.

Remeber to add tests when implementing new features to maintain a high code coverage.
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/get_bandpass_integrated_emission.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

hp.mollview(
emission_central_freq,
title=f"Center frequency",
title="Center frequency",
unit="MJy/sr",
cmap="afmhot",
norm="log",
Expand Down
10 changes: 7 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ lint.ignore = [
"D107",
"ANN101",
"PLR0913",
"ISC001"
"ISC001",
"S311",
]
exclude = ["tests/*", "docs/*"]
lint.pydocstyle.convention = "google"
# exclude = ["docs/*"]
lint.pydocstyle.convention = "google"
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"]
"docs/*" = ["INP001", "T201", "S101"]
62 changes: 17 additions & 45 deletions tests/_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
MIN_FREQ = u.Quantity(10, u.GHz)
MAX_FREQ = u.Quantity(0.1, u.micron).to(u.GHz, equivalencies=u.spectral())
N_FREQS = 1000
FREQ_LOG_RANGE = np.geomspace(
np.log(MIN_FREQ.value), np.log(MAX_FREQ.value), N_FREQS
).tolist()
FREQ_LOG_RANGE = np.geomspace(np.log(MIN_FREQ.value), np.log(MAX_FREQ.value), N_FREQS).tolist()

MIN_DATE = datetime.datetime(year=1900, month=1, day=1)
MAX_DATE = datetime.datetime(year=2100, month=1, day=1)
Expand Down Expand Up @@ -74,9 +72,7 @@ def time(draw: DrawFn) -> Time:

@composite
def nside(draw: Callable[[SearchStrategy[int]], int]) -> int:
return draw(
integers(min_value=MIN_NSIDE_EXP, max_value=MAX_NSIDE_EXP).map(partial(pow, 2))
)
return draw(integers(min_value=MIN_NSIDE_EXP, max_value=MAX_NSIDE_EXP).map(partial(pow, 2)))


@composite
Expand All @@ -93,9 +89,7 @@ def pixels(draw: DrawFn, nside: int) -> int | list[int] | npt.NDArray[np.integer


@composite
def angles(
draw: DrawFn, lonlat: bool = False
) -> tuple[u.Quantity[u.deg], u.Quantity[u.deg]]:
def angles(draw: DrawFn, lonlat: bool = False) -> tuple[u.Quantity[u.deg], u.Quantity[u.deg]]:
if lonlat:
theta_strategy = floats(min_value=0, max_value=360)
phi_strategy = floats(min_value=-90, max_value=90)
Expand All @@ -105,9 +99,9 @@ def angles(

shape = draw(integers(min_value=1, max_value=MAX_ANGELS_LEN))

theta_array_strategy = arrays(
dtype=float, shape=shape, elements=theta_strategy
).map(partial(u.Quantity, unit=u.deg))
theta_array_strategy = arrays(dtype=float, shape=shape, elements=theta_strategy).map(
partial(u.Quantity, unit=u.deg)
)
phi_array_strategy = arrays(dtype=float, shape=shape, elements=phi_strategy).map(
partial(u.Quantity, unit=u.deg)
)
Expand All @@ -116,16 +110,9 @@ def angles(


@composite
def freq(
draw: DrawFn, model: zodipy.Zodipy
) -> u.Quantity[u.GHz] | u.Quantity[u.micron]:

def freq(draw: DrawFn, model: zodipy.Zodipy) -> u.Quantity[u.GHz] | u.Quantity[u.micron]:
if model.extrapolate:
return draw(
sampled_from(FREQ_LOG_RANGE)
.map(np.exp)
.map(partial(u.Quantity, unit=u.GHz))
)
return draw(sampled_from(FREQ_LOG_RANGE).map(np.exp).map(partial(u.Quantity, unit=u.GHz)))

min_freq = model._ipd_model.spectrum[0]
max_freq = model._ipd_model.spectrum[-1]
Expand All @@ -140,9 +127,7 @@ def freq(


@composite
def random_freq(
draw: DrawFn, unit: u.Unit | None = None, bandpass: bool = False
) -> u.Quantity:
def random_freq(draw: DrawFn, unit: u.Unit | None = None, bandpass: bool = False) -> u.Quantity:
random_freq = draw(
sampled_from(FREQ_LOG_RANGE).map(np.exp).map(partial(u.Quantity, unit=u.GHz))
)
Expand All @@ -156,10 +141,9 @@ def random_freq(
if bandpass:
shape = draw(integers(min_value=2, max_value=100))
sigma = draw(floats(min_value=0.1, max_value=0.3))
freq_range = np.linspace(
return np.linspace(
random_freq - random_freq * sigma, random_freq + random_freq * sigma, shape
)
return freq_range

return random_freq

Expand All @@ -178,40 +162,30 @@ def normalize_array(
list_stategy = lists(weights_strategy, min_size=freqs.size, max_size=freqs.size)
array_strategy = arrays(dtype=float, shape=freqs.size, elements=weights_strategy)

return draw(
one_of(list_stategy, array_strategy).map(partial(normalize_array, freqs=freqs))
)
return draw(one_of(list_stategy, array_strategy).map(partial(normalize_array, freqs=freqs)))


@composite
def obs(draw: DrawFn, model: zodipy.Zodipy, obs_time: Time) -> str:
def get_obs_dist(obs: str, obs_time: Time) -> u.Quantity[u.AU]:
if obs == "semb-l2":
obs_pos = (
get_body("earth", obs_time)
.transform_to(HeliocentricMeanEcliptic)
.cartesian.xyz
get_body("earth", obs_time).transform_to(HeliocentricMeanEcliptic).cartesian.xyz
)
obs_pos += 0.01 * u.AU
else:
obs_pos = (
get_body(obs, obs_time)
.transform_to(HeliocentricMeanEcliptic)
.cartesian.xyz
)
obs_pos = get_body(obs, obs_time).transform_to(HeliocentricMeanEcliptic).cartesian.xyz
return u.Quantity(np.linalg.norm(obs_pos.value), u.AU)

los_dist_cut = min(
[COMPONENT_CUTOFFS[comp][1] for comp in model._ipd_model.comps.keys()],
[COMPONENT_CUTOFFS[comp][1] for comp in model._ipd_model.comps],
)
if isinstance(los_dist_cut, dict):
los_dist_cut = min(list(los_dist_cut.values()))

obs_list = model.supported_observers
return draw(
sampled_from(obs_list).filter(
lambda obs: los_dist_cut > get_obs_dist(obs, obs_time).value
)
sampled_from(obs_list).filter(lambda obs: los_dist_cut > get_obs_dist(obs, obs_time).value)
)


Expand All @@ -231,10 +205,8 @@ def any_obs(draw: DrawFn, model: zodipy.Zodipy) -> str:
@composite
def model(draw: DrawFn, **static_params: dict[str, Any]) -> zodipy.Zodipy:
strategies = MODEL_STRATEGY_MAPPINGS.copy()
for key in static_params.keys():
for key in static_params:
if key in strategies:
strategies.pop(key)

return draw(
builds(partial(zodipy.Zodipy, **static_params), **strategies)
)
return draw(builds(partial(zodipy.Zodipy, **static_params), **strategies))
54 changes: 19 additions & 35 deletions tests/test_get_emission.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def test_get_emission_pix(
data: DataObject,
) -> None:
"""Property test for get_emission_pix."""

observer = data.draw(obs(model, time))
frequency = data.draw(freq(model))
pix = data.draw(pixels(nside))
Expand All @@ -58,7 +57,6 @@ def test_get_binned_emission_pix(
data: DataObject,
) -> None:
"""Property test for get_binned_emission_pix."""

observer = data.draw(obs(model, time))
frequency = data.draw(freq(model))
pix = data.draw(pixels(nside))
Expand All @@ -82,7 +80,6 @@ def test_get_emission_ang(
data: DataObject,
) -> None:
"""Property test for get_emission_ang."""

theta, phi = angles

observer = data.draw(obs(model, time))
Expand All @@ -108,7 +105,6 @@ def test_get_binned_emission_ang(
data: DataObject,
) -> None:
"""Property test for get_binned_emission_pix."""

theta, phi = angles

observer = data.draw(obs(model, time))
Expand All @@ -134,11 +130,7 @@ def test_invalid_freq(
nside: int,
data: DataObject,
) -> None:
"""
Property test checking for unsupported spectral range in models where extrapolation is
set to False.
"""

"""Property test checking for unsupported spectral range."""
theta, phi = angles
observer = data.draw(obs(model, time))
pix = data.draw(pixels(nside))
Expand Down Expand Up @@ -186,23 +178,20 @@ def test_invalid_freq(


def test_compare_to_dirbe_idl() -> None:
"""
Tests that ZodiPy is able to reproduce tabulated emission from the DIRBE Zoidacal Light
"""Tests that ZodiPy reproduces the DIRBE software.
Zodipy should be able to reproduce the tabulated emission from the DIRBE Zoidacal Light
Prediction Software with a maximum difference of 0.1%.
"""

model = Zodipy("dirbe")
for freq, tabulated_emission in TABULATED_DIRBE_EMISSION.items():
freq *= u.micron
for frequency, tabulated_emission in TABULATED_DIRBE_EMISSION.items():
for idx, (day, lon, lat) in enumerate(zip(DAYS, LON, LAT)):
time = DIRBE_START_DAY + TimeDelta(day - 1, format="jd")
lon *= u.deg
lat *= u.deg

emission = model.get_emission_ang(
freq,
theta=lon,
phi=lat,
frequency * u.micron,
theta=lon * u.deg,
phi=lat * u.deg,
lonlat=True,
obs="earth",
obs_time=time,
Expand All @@ -219,10 +208,7 @@ def test_invalid_pixel(
random_integer: int,
data: DataObject,
) -> None:
"""
Tests that an error is raised when an invalid pixel is passed to get_emission_pix.
"""

"""Tests that an error is raised when an invalid pixel is passed to get_emission_pix."""
frequency = data.draw(freq(model))
observer = data.draw(obs(model, time))
npix = hp.nside2npix(nside)
Expand All @@ -245,12 +231,13 @@ def test_invalid_pixel(
obs=observer,
)


def test_multiprocessing() -> None:
"""
Testing that model with multiprocessing enabled returns the same value as
"""Tests multiprocessing with for zodipy.
Tests that model with multiprocessing enabled returns the same value as
without multiprocessing.
"""

model = Zodipy()
model_parallel = Zodipy(n_proc=4)

Expand Down Expand Up @@ -330,11 +317,9 @@ def test_multiprocessing() -> None:

assert np.allclose(emission_binned_ang.value, emission_binned_ang_parallel.value)

def test_inner_radial_cutoff_multiprocessing() -> None:
"""
Testing that model with inner radial cutoffs can be parallelized.
"""

def test_inner_radial_cutoff_multiprocessing() -> None:
"""Testing that model with inner radial cutoffs can be parallelized."""
model = Zodipy("RRM-experimental")
model_parallel = Zodipy("RRM-experimental", n_proc=4)

Expand All @@ -360,6 +345,7 @@ def test_inner_radial_cutoff_multiprocessing() -> None:
)
assert np.allclose(emission_pix, emission_pix_parallel)


@given(
model(extrapolate=True),
time(),
Expand Down Expand Up @@ -411,7 +397,6 @@ def test_weights(
data: DataObject,
) -> None:
"""Property test for bandpass weights."""

theta, phi = angles
observer = data.draw(obs(model, time))
bp_weights = data.draw(weights(freqs))
Expand All @@ -428,16 +413,14 @@ def test_weights(


def test_custom_weights() -> None:
"""Tests bandpass integration with custom weights."""
model = Zodipy()
time = Time("2020-01-01")
nside = 32
pix = np.arange(hp.nside2npix(nside))
central_freq = 25
sigma_freq = 3
freqs = (
np.linspace(central_freq - sigma_freq, central_freq + sigma_freq, 100)
* u.micron
)
freqs = np.linspace(central_freq - sigma_freq, central_freq + sigma_freq, 100) * u.micron
weights = np.random.randn(len(freqs))
weights /= np.trapz(weights, freqs.value)

Expand All @@ -452,6 +435,7 @@ def test_custom_weights() -> None:


def test_custom_obs_pos() -> None:
"""Tests a user specified observer position."""
model = Zodipy()
time = Time("2020-01-01")
nside = 64
Expand Down
8 changes: 6 additions & 2 deletions tests/test_model_registry.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
from hypothesis import given
import hypothesis.strategies as st
import pytest
from hypothesis import given

from zodipy import model_registry

ALL_MODELS = model_registry.models


@given(st.sampled_from(ALL_MODELS))
def test_get_model(model) -> None:
def test_get_model(model: str) -> None:
"""Tests that the model can be retrieved."""
model_registry.get_model(model)


def test_get_model_raises_error() -> None:
"""Tests that an error is raised when the model is not found."""
with pytest.raises(ValueError):
model_registry.get_model("metins_model")


def test_register_model() -> None:
"""Tests that a model can be registered."""
DIRBE_model = model_registry.get_model("DIRBE")
DIRBE_model.T_0 += 250
model_registry.register_model("metins_model", DIRBE_model)


def test_register_model_raises_error() -> None:
"""Tests that an error is raised when the model is already registered."""
with pytest.raises(ValueError):
model_registry.register_model("DIRBE", model_registry.get_model("DIRBE"))
Loading

0 comments on commit 44b3cc0

Please sign in to comment.