|
| 1 | +import numpy as np |
| 2 | + |
1 | 3 | from dask_setup import get_dask_client |
2 | 4 | from zarrnii import ZarrNii |
3 | 5 | from zarrnii.analysis import compute_otsu_thresholds |
|
8 | 10 | if __name__ == "__main__": |
9 | 11 | with get_dask_client(snakemake.config["dask_scheduler"], snakemake.threads): |
10 | 12 |
|
| 13 | + zarrnii_kwargs = snakemake.params.zarrnii_kwargs |
| 14 | + pct_lo, pct_hi = snakemake.params.hist_percentile_range |
| 15 | + bin_width = snakemake.params.hist_bin_width |
| 16 | + |
| 17 | + # load a downsampled version to estimate the percentile-based range |
| 18 | + print("estimating intensity range from downsampled image...") |
| 19 | + znimg_ds = None |
| 20 | + for ds_level in [5, 4, 3, 2, 1]: |
| 21 | + try: |
| 22 | + candidate = ZarrNii.from_ome_zarr( |
| 23 | + snakemake.input.corrected, level=ds_level, **zarrnii_kwargs |
| 24 | + ) |
| 25 | + znimg_ds = candidate |
| 26 | + break |
| 27 | + except Exception: |
| 28 | + pass |
| 29 | + |
| 30 | + if znimg_ds is None: |
| 31 | + znimg_ds = ZarrNii.from_ome_zarr( |
| 32 | + snakemake.input.corrected, **zarrnii_kwargs |
| 33 | + ) |
| 34 | + |
| 35 | + data_ds = znimg_ds.data.compute().ravel().astype(np.float32) |
| 36 | + range_lo = float(np.percentile(data_ds, pct_lo)) |
| 37 | + range_hi = float(np.percentile(data_ds, pct_hi)) |
| 38 | + print( |
| 39 | + f" 📊 percentile range [{pct_lo}%, {pct_hi}%]: [{range_lo:.3f}, {range_hi:.3f}]" |
| 40 | + ) |
| 41 | + |
| 42 | + # compute number of bins from bin width |
| 43 | + n_bins = max(2, int(np.ceil((range_hi - range_lo) / bin_width))) |
| 44 | + print(f" 📊 bins: {n_bins} (bin width: {bin_width})") |
| 45 | + |
11 | 46 | # we use the default level=0, since we are reading in the n4 output, which is already downsampled if level was >0 |
12 | 47 | znimg = ZarrNii.from_ome_zarr( |
13 | | - snakemake.input.corrected, **snakemake.params.zarrnii_kwargs |
| 48 | + snakemake.input.corrected, **zarrnii_kwargs |
14 | 49 | ) |
15 | 50 |
|
16 | | - # first calculate histogram - using preset bins to avoid issues where bins are too large |
17 | | - # because of high intensity outliers |
| 51 | + # calculate histogram using percentile-based range and bin-width-derived bin count |
18 | 52 | (hist_counts, bin_edges) = znimg.compute_histogram( |
19 | | - bins=snakemake.params.hist_bins, range=snakemake.params.hist_range |
| 53 | + bins=n_bins, range=[range_lo, range_hi] |
20 | 54 | ) |
21 | 55 |
|
22 | 56 | # get otsu thresholds (uses histogram) |
|
0 commit comments