Skip to content

Commit

Permalink
stricter linting
Browse files Browse the repository at this point in the history
  • Loading branch information
tjlane committed Aug 22, 2024
1 parent a676ce8 commit 6f44f09
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 41 deletions.
40 changes: 25 additions & 15 deletions meteor/tv.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,43 @@ def tv_denoise_difference_map(
) -> rs.DataSet | tuple[rs.DataSet, TvDenoiseResult]:
"""Single-pass TV denoising of a difference map.
Automatically selects the optimal level of regularization (the TV lambda parameter) by maximizing the negentropy of the denoised map. Two modes can be used to dictate which candidate values of lambda are assessed:
Automatically selects the optimal level of regularization (the TV lambda parameter) by
maximizing the negentropy of the denoised map. Two modes can be used to dictate which
candidate values of lambda are assessed:
1. By default (`lambda_values_to_scan=None`), the golden-section search algorithm selects a lambda value according to the bounds and convergence criteria set in meteor.settings.
2. Alternatively, an explicit list of lambda values to assess can be provided using `lambda_values_to_scan`.
1. By default (`lambda_values_to_scan=None`), the golden-section search algorithm selects
a lambda value according to the bounds and convergence criteria set in meteor.settings.
2. Alternatively, an explicit list of lambda values to assess can be provided using
`lambda_values_to_scan`.
Parameters
----------
difference_map_coefficients : rs.DataSet
The input dataset containing the difference map coefficients (amplitude and phase) that will be used to compute the
difference map.
The input dataset containing the difference map coefficients (amplitude and phase)
that will be used to compute the difference map.
full_output : bool, optional
If `True`, the function returns both the denoised map coefficients and a `TvDenoiseResult` object containing the optimal
lambda and the associated negentropy. If `False`, only the denoised map coefficients are returned. Default is `False`.
If `True`, the function returns both the denoised map coefficients and a `TvDenoiseResult`
object containing the optimal lambda and the associated negentropy. If `False`, only
the denoised map coefficients are returned. Default is `False`.
difference_map_amplitude_column : str, optional
The column name in `difference_map_coefficients` that contains the amplitude values for the difference map. Default is "DF".
The column name in `difference_map_coefficients` that contains the amplitude values for
the difference map. Default is "DF".
difference_map_phase_column : str, optional
The column name in `difference_map_coefficients` that contains the phase values for the difference map. Default is "PHIC".
The column name in `difference_map_coefficients` that contains the phase values for the
difference map. Default is "PHIC".
lambda_values_to_scan : Sequence[float] | None, optional
A sequence of lambda values to explicitly scan for determining the optimal value. If `None`, the function uses the
golden-section search method to determine the optimal lambda. Default is `None`.
A sequence of lambda values to explicitly scan for determining the optimal value. If
`None`, the function uses the golden-section search method to determine the optimal
lambda. Default is `None`.
Returns
-------
rs.DataSet | tuple[rs.DataSet, TvDenoiseResult]
If `full_output` is `False`, returns a `rs.DataSet` containing the denoised map coefficients.
If `full_output` is `False`, returns a `rs.DataSet`, the denoised map coefficients.
If `full_output` is `True`, returns a tuple containing:
- `rs.DataSet`: The denoised map coefficients.
- `TvDenoiseResult`: An object containing the optimal lambda and the corresponding negentropy.
- `TvDenoiseResult`: An object w/ the optimal lambda and the corresponding negentropy.
Raises
------
Expand All @@ -104,9 +112,11 @@ def tv_denoise_difference_map(
Notes
-----
- The function is designed to maximize the negentropy of the denoised map, which is a measure of the map's "randomness."
- The function is designed to maximize the negentropy of the denoised map, which is a
measure of the map's "randomness."
Higher negentropy generally corresponds to a more informative and less noisy map.
- The golden-section search is a robust method for optimizing unimodal functions, particularly suited for scenarios where
- The golden-section search is a robust method for optimizing unimodal functions,
particularly suited for scenarios where
an explicit list of candidate values is not provided.
Example
Expand Down
11 changes: 5 additions & 6 deletions meteor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@


def resolution_limits(dataset: rs.DataSet) -> tuple[float, float]:
dHKL = dataset.compute_dHKL()["dHKL"]
return dHKL.max(), dHKL.min()
d_hkl = dataset.compute_dHKL()["dHKL"]
return d_hkl.max(), d_hkl.min()


def cut_resolution(
Expand All @@ -16,11 +16,11 @@ def cut_resolution(
dmax_limit: float | None = None,
dmin_limit: float | None = None,
) -> rs.DataSet:
dHKL = dataset.compute_dHKL()["dHKL"]
d_hkl = dataset.compute_dHKL()["dHKL"]
if dmax_limit:
dataset = dataset.loc[(dHKL <= dmax_limit)]
dataset = dataset.loc[(d_hkl <= dmax_limit)]
if dmin_limit:
dataset = dataset.loc[(dHKL >= dmin_limit)]
dataset = dataset.loc[(d_hkl >= dmin_limit)]
return dataset


Expand Down Expand Up @@ -51,7 +51,6 @@ def canonicalize_amplitudes(
phase_label: str,
inplace: bool = False,
) -> rs.DataSet | None:

if not inplace:
dataset = dataset.copy(deep=True)

Expand Down
7 changes: 4 additions & 3 deletions meteor/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def negentropy(samples: np.ndarray, tolerance: float = 0.1) -> float:
Args:
----
samples (np.ndarray): A numpy array of sample data for which to calculate the negentropy.
tolerance (float): A tolerance level for checking if the negentropy is suspiciously negative.
tolerance (float): Tolerance level determining if the negentropy is suspiciously negative.
Defaults to 0.01.
Returns:
Expand All @@ -38,12 +38,13 @@ def negentropy(samples: np.ndarray, tolerance: float = 0.1) -> float:
"""
std = np.std(samples.flatten())
if std <= 0.0:
return np.inf
return -np.inf

neg_e = 0.5 * np.log(2.0 * np.pi * std**2) + 0.5 - differential_entropy(samples.flatten())
if not neg_e >= -tolerance:
raise ValueError(
f"negentropy is a relatively big negative number {neg_e} that exceeds the tolerance {tolerance} -- something may have gone wrong"
f"negentropy is a large negative number {neg_e}, exceeds the tolerance {tolerance}"
" -- something may have gone wrong"
)

return neg_e
10 changes: 5 additions & 5 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import gemmi
import numpy as np
import pytest
import reciprocalspaceship as rs
from pytest import fixture

from meteor.utils import canonicalize_amplitudes


@fixture()
@pytest.fixture()

Check failure on line 9 in test/conftest.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Ruff (PT001)

test/conftest.py:9:1: PT001 Use `@pytest.fixture` over `@pytest.fixture()`
def random_difference_map() -> rs.DataSet:
resolution = 1.0
cell = gemmi.UnitCell(10.0, 10.0, 10.0, 90.0, 90.0, 90.0)
space_group = gemmi.SpaceGroup(1)
Hall = rs.utils.generate_reciprocal_asu(cell, space_group, resolution, anomalous=False)
hall = rs.utils.generate_reciprocal_asu(cell, space_group, resolution, anomalous=False)

h, k, l = Hall.T
h, k, l = hall.T # noqa: E741
number_of_reflections = len(h)

ds = rs.DataSet(
{
"H": h,
Expand Down
9 changes: 4 additions & 5 deletions test/unit/test_tv.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import Sequence

import gemmi
import numpy as np
import reciprocalspaceship as rs
import pytest
from typing import Sequence
import reciprocalspaceship as rs

from meteor import tv
from meteor.utils import compute_coefficients_from_map, compute_map_from_coefficients
Expand Down Expand Up @@ -135,7 +136,7 @@ def test_tv_denoise_difference_map(
denoised_map, result = tv.tv_denoise_difference_map(
difference_map_coefficients=noisy_map,
lambda_values_to_scan=lambda_values_to_scan,
full_output=True
full_output=True,
)
rms_after_denoising = rms_between_coefficients(noise_free_map, denoised_map)
# assert rms_after_denoising < rms_before_denoising
Expand All @@ -162,5 +163,3 @@ def test_tv_denoise_difference_map(
map_sampling=1,
)
testmap.write_ccp4_map("denoised.ccp4")


12 changes: 5 additions & 7 deletions test/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_resolution_limits(random_difference_map: rs.DataSet) -> None:


@pytest.mark.parametrize(
"dmax_limit, dmin_limit",
("dmax_limit", "dmin_limit"),
[
(None, None),
(None, 2.0),
Expand Down Expand Up @@ -88,8 +88,9 @@ def test_compute_map_from_coefficients(random_difference_map: rs.DataSet) -> Non


@pytest.mark.parametrize("map_sampling", [1, 2, 2.25, 3, 5])
def test_map_to_coefficients_round_trip(map_sampling: int, random_difference_map: rs.DataSet) -> None:

def test_map_to_coefficients_round_trip(
map_sampling: int, random_difference_map: rs.DataSet
) -> None:
# TODO fix this
amplitude_label = "DF"
phase_label = "PHIC"
Expand All @@ -111,9 +112,6 @@ def test_map_to_coefficients_round_trip(map_sampling: int, random_difference_map
)

utils.canonicalize_amplitudes(
output_coefficients,
amplitude_label=amplitude_label,
phase_label=phase_label,
inplace=True
output_coefficients, amplitude_label=amplitude_label, phase_label=phase_label, inplace=True
)
pd.testing.assert_frame_equal(left=random_difference_map, right=output_coefficients, atol=0.5)

0 comments on commit 6f44f09

Please sign in to comment.