Skip to content

Commit 97479d4

Browse files
committed
cq: update warnings with automatic stack_level
1 parent 3796aa0 commit 97479d4

17 files changed

+101
-45
lines changed

lumicks/pylake/detail/confocal.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from .image import reconstruct_image, reconstruct_image_sum
1010
from .mixin import PhotonCounts, ExcitationLaserPower
11-
from .utilities import method_cache, could_sum_overflow
11+
from .utilities import method_cache, find_stack_level, could_sum_overflow
1212
from ..adjustments import no_adjustment
1313
from .imaging_mixins import TiffExport
1414

@@ -348,7 +348,8 @@ def _tiff_image_metadata(self) -> dict:
348348
except NotImplementedError:
349349
warnings.warn(
350350
f"Pixel times are not defined for this {self.__class__.__name__}. "
351-
"The corresponding metadata in the output file is set to `None`."
351+
"The corresponding metadata in the output file is set to `None`.",
352+
stacklevel=find_stack_level(),
352353
)
353354
pixel_time_seconds = None
354355

lumicks/pylake/detail/image.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import numpy as np
66

7+
from .utilities import find_stack_level
8+
79

810
class InfowaveCode(enum.IntEnum):
911
discard = 0 # this data sample does not contain useful information
@@ -195,7 +197,9 @@ def histogram_rows(image, pixels_per_bin, pixel_width):
195197
remainder = n_rows % pixels_per_bin
196198
if remainder != 0:
197199
warnings.warn(
198-
f"{n_rows} pixels is not divisible by {pixels_per_bin}, final bin only contains {remainder} pixels"
200+
f"{n_rows} pixels is not divisible by {pixels_per_bin}, final bin only contains "
201+
f"{remainder} pixels",
202+
stacklevel=find_stack_level(),
199203
)
200204
pad = np.zeros((pixels_per_bin - remainder, image.shape[1]))
201205
image = np.vstack((image, pad))

lumicks/pylake/detail/utilities.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import math
2-
import contextlib
3-
import pathlib
42
import inspect
3+
import pathlib
4+
import contextlib
55

66
import numpy as np
77
import cachetools

lumicks/pylake/detail/widefield.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import numpy as np
99
import tifffile
1010

11+
from .utilities import find_stack_level
1112
from ..adjustments import no_adjustment
1213

1314

@@ -161,7 +162,7 @@ def __init__(self, tiff_files, align_requested, roi=None, tether=None):
161162
# warn on file open if alignment is requested, but not possible
162163
# stacklevel=4 corresponds to ImageStack.__init__()
163164
if self._description._alignment.has_problem:
164-
warnings.warn(self._description._alignment.status.value, stacklevel=4)
165+
warnings.warn(self._description._alignment.status.value, stacklevel=find_stack_level())
165166

166167
if roi is None:
167168
self._roi = Roi(0, self._description.width, 0, self._description.height)

lumicks/pylake/file.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from .calibration import ForceCalibration
1616
from .detail.mixin import Force, PhotonCounts, DownsampledFD, PhotonTimeTags, BaselineCorrectedForce
1717
from .detail.h5_helper import write_h5
18+
from .detail.utilities import find_stack_level
1819

1920
__all__ = ["File"]
2021

@@ -260,7 +261,7 @@ def try_from_dataset(*args):
260261
try:
261262
return cls.from_dataset(*args)
262263
except Exception as e:
263-
warnings.warn(e.args[0])
264+
warnings.warn(e.args[0], stacklevel=find_stack_level())
264265
return None
265266

266267
if field not in self.h5:

lumicks/pylake/fitting/detail/derivative_manipulation.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import numpy as np
44
import scipy
55

6+
from ...detail.utilities import find_stack_level
7+
68

79
def numerical_diff(fn, x, dx=1e-6):
810
return (fn(x + dx) - fn(x - dx)) / (2.0 * dx)
@@ -126,7 +128,8 @@ def invert_function_interpolation(
126128
except Exception as e:
127129
warnings.warn(
128130
f"Interpolation failed. Cause: {e}. Falling back to brute force evaluation. "
129-
f"Results should be fine, but slower."
131+
f"Results should be fine, but slower.",
132+
stacklevel=find_stack_level(),
130133
)
131134
result[interpolated_idx] = manual_inversion(d[interpolated_idx], initial)
132135
else:

lumicks/pylake/fitting/detail/model_implementation.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from .utilities import latex_frac, latex_sqrt, solve_formatter, solve_formatter_tex
66
from ..parameters import Parameter
7+
from ...detail.utilities import find_stack_level
78
from .derivative_manipulation import invert_function, invert_jacobian, invert_function_interpolation
89

910

@@ -103,8 +104,10 @@ def wlc_marko_siggia_force(d, Lp, Lc, kT):
103104

104105
if np.any(d > Lc):
105106
warnings.warn(
106-
"Marko Siggia model is only defined properly up to the contour length (d = Lc)",
107-
RuntimeWarning,
107+
RuntimeWarning(
108+
"Marko Siggia model is only defined properly up to the contour length (d = Lc)"
109+
),
110+
stacklevel=find_stack_level(),
108111
)
109112

110113
d_div_Lc = d / Lc

lumicks/pylake/force_calibration/power_spectrum.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import numpy as np
66
import matplotlib.pyplot as plt
77

8-
from lumicks.pylake.detail.utilities import downsample
8+
from lumicks.pylake.detail.utilities import downsample, find_stack_level
99

1010

1111
class PowerSpectrum:
@@ -53,7 +53,10 @@ def squared_fft(d):
5353
int(np.round(window_seconds * sample_rate)) if window_seconds else len(data)
5454
)
5555
if num_points_per_window > len(data):
56-
warnings.warn(RuntimeWarning("Longer window than data duration: not using windowing."))
56+
warnings.warn(
57+
RuntimeWarning("Longer window than data duration: not using windowing."),
58+
stacklevel=find_stack_level(),
59+
)
5760
num_points_per_window = len(data)
5861

5962
squared_fft_chunks = [

lumicks/pylake/force_calibration/touchdown.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import scipy
66
import matplotlib.pyplot as plt
77

8-
from lumicks.pylake.detail.utilities import downsample
8+
from lumicks.pylake.detail.utilities import downsample, find_stack_level
99

1010

1111
def mack_model(
@@ -83,7 +83,8 @@ def f_test(sse_restricted, sse_unrestricted, num_data, num_pars_difference, num_
8383
RuntimeWarning(
8484
"Denominator in F-Test is zero. "
8585
"This may be caused by using noise-free data or fewer than 4 data points."
86-
)
86+
),
87+
stacklevel=find_stack_level(),
8788
)
8889
return 0.0
8990
else:
@@ -309,15 +310,17 @@ def touchdown(
309310
RuntimeWarning(
310311
"Insufficient data available to reliably fit touchdown curve. We need at least two "
311312
"oscillations to reliably fit the interference pattern."
312-
)
313+
),
314+
stacklevel=find_stack_level(),
313315
)
314316
focal_shift = None
315317

316318
if p_value > maximum_p_value:
317319
warnings.warn(
318320
RuntimeWarning(
319321
"Surface detection failed (piecewise linear fit not better than linear fit)"
320-
)
322+
),
323+
stacklevel=find_stack_level(),
321324
)
322325
surface_position = None
323326

lumicks/pylake/group.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import h5py
44

55
from .channel import channel_class
6+
from .detail.utilities import find_stack_level
67

78

89
class Group:
@@ -34,9 +35,11 @@ def __getitem__(self, item):
3435
redirect_location, redirect_class = self._lk_file.redirect_list.get(item_type, (None, None))
3536
if redirect_location and not redirect_class:
3637
warnings.warn(
37-
f"Direct access to this field is deprecated. Use file.{redirect_location} "
38-
"instead. In case raw access is needed, go through the fn.h5 directly.",
39-
FutureWarning,
38+
FutureWarning(
39+
f"Direct access to this field is deprecated. Use file.{redirect_location} "
40+
"instead. In case raw access is needed, go through the fn.h5 directly.",
41+
),
42+
stacklevel=find_stack_level(),
4043
)
4144

4245
if type(thing) is h5py.Group:

lumicks/pylake/kymo.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .detail.confocal import ScanAxis, ScanMetaData, ConfocalImage
1616
from .detail.plotting import get_axes, show_image
1717
from .detail.timeindex import to_timestamp
18-
from .detail.utilities import method_cache
18+
from .detail.utilities import method_cache, find_stack_level
1919

2020

2121
def _default_line_time_factory(self: "Kymo"):
@@ -292,8 +292,10 @@ def _fix_incorrect_start(self):
292292
self.start = seek_timestamp_next_line(self.infowave[self.start :])
293293
self._cache = {}
294294
warnings.warn(
295-
"Start of the kymograph was truncated. Omitting the truncated first line.",
296-
RuntimeWarning,
295+
RuntimeWarning(
296+
"Start of the kymograph was truncated. Omitting the truncated first line."
297+
),
298+
stacklevel=find_stack_level(),
297299
)
298300

299301
def _to_spatial(self, data):
@@ -488,7 +490,10 @@ def set_aspect_ratio(axis, ar):
488490
)
489491

490492
warnings.warn(
491-
RuntimeWarning("Using downsampled force since high frequency force is unavailable.")
493+
RuntimeWarning(
494+
"Using downsampled force since high frequency force is unavailable."
495+
),
496+
stacklevel=find_stack_level(),
492497
)
493498

494499
time_ranges = self.line_timestamp_ranges(include_dead_time=False)

lumicks/pylake/kymotracker/detail/msd_estimation.py

+15-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import numpy.typing as npt
77
import matplotlib.pyplot as plt
88

9+
from ...detail.utilities import find_stack_level
10+
911

1012
@dataclass(frozen=True)
1113
class DiffusionEstimate:
@@ -471,7 +473,10 @@ def _diffusion_gls(lag_idx, mean_squared_displacements, num_points, tolerance=1e
471473

472474
def fallback(warning_message):
473475
"""Fallback method if the GLS fails"""
474-
warnings.warn(RuntimeWarning(f"{warning_message} Reverting to two-point OLS."))
476+
warnings.warn(
477+
RuntimeWarning(f"{warning_message} Reverting to two-point OLS."),
478+
stacklevel=find_stack_level(),
479+
)
475480
return _diffusion_ols(lag_idx[:2], mean_squared_displacements[:2], num_points)
476481

477482
# Since the covariance matrix depends on the parameters for the intercept and slope, we obtain
@@ -599,7 +604,7 @@ def estimate_diffusion_constant_simple(
599604
"`help(lk.refine_tracks_centroid)` or `help(lk.refine_tracks_gaussian)` for "
600605
"more information."
601606
),
602-
stacklevel=2,
607+
stacklevel=find_stack_level(),
603608
)
604609

605610
frame_lags, msd = calculate_msd(frame_idx, coordinate, max_lag)
@@ -717,7 +722,8 @@ def determine_optimal_points(frame_idx, coordinate, max_iterations=100):
717722
RuntimeWarning(
718723
"Your tracks have missing frames. Note that this can lead to a suboptimal "
719724
"estimate of the optimal number of lags when using OLS."
720-
)
725+
),
726+
stacklevel=find_stack_level(),
721727
)
722728

723729
num_slope = max(2, len(coordinate) // 10) # Need at least two points for a linear regression!
@@ -743,7 +749,8 @@ def determine_optimal_points(frame_idx, coordinate, max_iterations=100):
743749
return num_slope, num_intercept
744750

745751
warnings.warn(
746-
RuntimeWarning("Warning, maximum number of iterations exceeded. Returning best solution.")
752+
RuntimeWarning("Warning, maximum number of iterations exceeded. Returning best solution."),
753+
stacklevel=find_stack_level(),
747754
)
748755
return num_slope, num_intercept
749756

@@ -1122,7 +1129,8 @@ def _determine_optimal_points_ensemble(frame_lags, msds, n_coord, max_iterations
11221129
return num_slope
11231130

11241131
warnings.warn(
1125-
RuntimeWarning("Warning, maximum number of iterations exceeded. Returning best solution.")
1132+
RuntimeWarning("Warning, maximum number of iterations exceeded. Returning best solution."),
1133+
stacklevel=find_stack_level(),
11261134
)
11271135

11281136
return num_slope
@@ -1136,7 +1144,8 @@ def ensemble_ols(kymotracks, max_lag):
11361144
warnings.warn(
11371145
RuntimeWarning(
11381146
"Your tracks have missing frames. Note that this can lead to a suboptimal estimates"
1139-
)
1147+
),
1148+
stacklevel=find_stack_level(),
11401149
)
11411150

11421151
optimal_lags = (

lumicks/pylake/kymotracker/kymotrack.py

+16-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from copy import copy
55

66
from ..__about__ import __version__
7-
from ..detail.utilities import replace_key_aliases
7+
from ..detail.utilities import find_stack_level, replace_key_aliases
88
from .detail.peakfinding import _sum_track_signal
99
from ..population.dwelltime import DwelltimeModel
1010
from .detail.msd_estimation import *
@@ -191,7 +191,7 @@ def import_kymotrackgroup_from_csv(filename, kymo, channel, delimiter=";"):
191191
"File contains non-integer time indices; round-off errors may have occurred "
192192
"when loading the data"
193193
),
194-
stacklevel=2,
194+
stacklevel=find_stack_level(),
195195
)
196196

197197
def create_track(time, coord, min_length=None):
@@ -551,7 +551,7 @@ def sample_from_image(self, num_pixels, reduce=np.sum, *, correct_origin=None):
551551
"ensure backward compatibility. To silence this warning use "
552552
"`correct_origin=False`."
553553
),
554-
stacklevel=2,
554+
stacklevel=find_stack_level(),
555555
)
556556

557557
# Time and coordinates are being cast to an integer since we use them to index into a data
@@ -863,7 +863,8 @@ def estimate_diffusion(
863863
RuntimeWarning(
864864
"Motion blur cannot be taken into account for this type of Kymo. As a "
865865
"consequence, not all estimates will be available."
866-
)
866+
),
867+
stacklevel=find_stack_level(),
867868
)
868869
blur = np.nan
869870

@@ -1574,7 +1575,8 @@ def fit_binding_times(
15741575
"warning, but use the deprecated behavior use `observed_minimum=True`. To "
15751576
"enable the recommended method of estimating the minimum observable dwell "
15761577
"time use `observed_minimum=False`."
1577-
)
1578+
),
1579+
stacklevel=find_stack_level(),
15781580
)
15791581
observed_minimum = True
15801582

@@ -1589,7 +1591,8 @@ def fit_binding_times(
15891591
"version of Pylake (`2.0.0`), using the discrete model will become the "
15901592
"default. Until then, the continuous model is still used for backward "
15911593
"compatibility."
1592-
)
1594+
),
1595+
stack_level=find_stack_level(),
15931596
)
15941597
discrete_model = False
15951598

@@ -1618,7 +1621,7 @@ def fit_binding_times(
16181621
"dropped from the analysis. If you wish to not see this warning, filter the "
16191622
"tracks with `lk.filter_tracks` with a minimum length of 2 samples."
16201623
),
1621-
stacklevel=2,
1624+
stacklevel=find_stack_level(),
16221625
)
16231626

16241627
if dwelltimes.size == 0:
@@ -1802,10 +1805,11 @@ def estimate_diffusion(self, method, *args, min_length=None, **kwargs):
18021805

18031806
if n_discarded and min_length is None:
18041807
warnings.warn(
1805-
f"{n_discarded} tracks were shorter than the specified min_length "
1806-
"and discarded from the analysis.",
1807-
RuntimeWarning,
1808-
stacklevel=2,
1808+
RuntimeWarning(
1809+
f"{n_discarded} tracks were shorter than the specified min_length and "
1810+
f"discarded from the analysis.",
1811+
),
1812+
stacklevel=find_stack_level(),
18091813
)
18101814

18111815
return [k.estimate_diffusion(method, *args, **kwargs) for k in filtered_tracks]
@@ -1866,6 +1870,7 @@ def ensemble_diffusion(self, method, *, max_lag=None):
18661870
"Localization variances cannot be reliably calculated for an ensemble of "
18671871
"tracks from kymographs with different line times or pixel sizes."
18681872
),
1873+
stacklevel=find_stack_level(),
18691874
)
18701875
is_valid = False
18711876
return ensemble_cve(self, calculate_localization_var=is_valid)

0 commit comments

Comments
 (0)