Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correcting a set of 2D images gives an error: WARNING:basicpy.basicpy:Reweighting did not converge #104

Open
donovanr opened this issue Oct 3, 2022 · 3 comments

Comments

@donovanr
Copy link

donovanr commented Oct 3, 2022

Hi, I'm interested in using BaSiCPy on cell painting data (2D static images, one channel at a time), but I'm running into some trouble, which is that I can't get the fit() method to converge.

I'm using a numpy array as input, but that was just an educated guess based on some of the notebooks -- it looks like you're in the process of making some changes to the code / documentation?

Anyway, here's what I tried:

Load data:

images = dict(df_small[["ImageStackName", "AICSImageRawPath"]].values)
warnings.filterwarnings(action='once')
images = {k:AICSImage(v).get_image_data("YX", C=1) for k,v in images.items()}
images = {k:skimage.img_as_float(v) for k,v in images.items()}
images = np.stack(list(images.values())).astype(np.float32)

At this point there are 8 images, all in an array of shape images.shape = (8, 1104, 1104), with np.all(np.isfinite(images)) returning True.

When I try to run the illumination correction:

basic = BaSiC(get_darkfield=True, lambda_flatfield_coef=10)
basic.fit(images)

I just get a non-convergence warning, and all nans for the darkfield and all zeros for the flatfield. I tired instantiating the basic object with some different parameters, but nothing seemed to help. Any suggestions?

Full error message
INFO:basicpy.basicpy:Initializing BaSiC 140117717795456 with parameters: 
get_darkfield: True

INFO:basicpy.basicpy:=== BaSiC fit started ===
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
INFO:basicpy.basicpy:reweighting iteration 0
INFO:basicpy.basicpy:single-step optimization score: 9.616014722269028e-07.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 0 finished.
INFO:basicpy.basicpy:reweighting iteration 1
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 1 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.462442509829998 seconds
INFO:basicpy.basicpy:reweighting iteration 2
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 2 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.4833310060203075 seconds
INFO:basicpy.basicpy:reweighting iteration 3
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 3 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.4939699675887823 seconds
INFO:basicpy.basicpy:reweighting iteration 4
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 4 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.50440825894475 seconds
INFO:basicpy.basicpy:reweighting iteration 5
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 5 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.5148190148174763 seconds
INFO:basicpy.basicpy:reweighting iteration 6
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 6 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.525381213054061 seconds
INFO:basicpy.basicpy:reweighting iteration 7
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 7 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.535923656076193 seconds
INFO:basicpy.basicpy:reweighting iteration 8
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 8 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.546493735164404 seconds
INFO:basicpy.basicpy:reweighting iteration 9
INFO:basicpy.basicpy:single-step optimization score: nan.
INFO:basicpy.basicpy:mean of S: 0.0.
INFO:basicpy.basicpy:Iteration 9 finished.
INFO:basicpy.basicpy:reweighting score: nan
INFO:basicpy.basicpy:elapsed time: 3.5569557193666697 seconds
WARNING:basicpy.basicpy:Reweighting did not converge.
/nfs_home/users/rzdm/mambaforge/envs/jumpcp_dev/lib/python3.9/site-packages/skimage/transform/_warps.py:725: RuntimeWarning: All-NaN slice encountered
min_val = min_func(input_image)
/nfs_home/users/rzdm/mambaforge/envs/jumpcp_dev/lib/python3.9/site-packages/skimage/transform/_warps.py:729: RuntimeWarning: All-NaN slice encountered
max_val = max_func(input_image)
INFO:basicpy.basicpy:=== BaSiC fit finished in 3.7635780666023493 seconds ===
Full python code
# imports
from pathlib import Path
import basicpy
import numpy as np
import pandas as pd
import skimage
from aicsimageio import AICSImage

# load data / metadata
DATA_PAR_DIR = Path(
    "/nfs_home/projects/departments/cdd/data/rzdm/jumpcp_U2OS/output_data/AIUN_smORF_U2OS_exp1/Plate_11/"
)
df_images = pd.read_csv(DATA_PAR_DIR / "field_image_manifest.csv")[
    ["ImageStackName", "AICSImageRawPath"]
].drop_duplicates()
df_meta = pd.read_csv(DATA_PAR_DIR / "metadata.csv")
df_meta.Name = df_meta.Name.str.replace(r"d[0-9].TIFF$", "", regex=True)
df_meta = df_meta.rename(columns={"Name": "ImageStackName"})
df = df_meta.merge(df_images)

# work with just one well
wells = df.WellId.sample(1)
df_small = df[df.WellId.isin(wells)].reset_index(drop=True).copy()

# load images
images = dict(df_small[["ImageStackName", "AICSImageRawPath"]].values)
images = {k:AICSImage(v).get_image_data("YX", C=0) for k,v in images.items()}
images = {k:skimage.img_as_float(v) for k,v in images.items()}
images = np.stack(list(images.values())).astype(np.float32)

# illumination correction
basic = basicpy.BaSiC(get_darkfield=True)
basic.fit(images)

P.S. I tried to see if the code would run correctly on the WSI data set, but the hash of the download has changed and threw an error when I tried to download it.

@donovanr
Copy link
Author

donovanr commented Oct 6, 2022

After some digging into the tests on the dev branch, I believe the issue I was having is cause by the input array dtype. Am I correct in assuming that the fit method wants a uint16 array? The NaN / nonconvergent behaviour vanishes when I hit the array with skimage's img_as_uint before passing it to fit(). If so, that might be a useful thing to have as an error message, either refusing to proceed without an input of the right dtype, or converting it for the user (with an accompanying message).

@drippypale
Copy link

I encountered the same problem even though my input image tensor is of dtype=uint16. Any other solution for the "WARNING:basicpy.basicpy:Reweighting did not converge." warning?

@lopollar
Copy link

I encountered the same issue, and my flatfield image gave all Nan's.
However, this happens when I run the analysis on a certain subset of my data. If I run BaSic on another subset of the same dataset, even containing some of the same tiles, it doesn't give this convergence error.
It also gives this error when only looking at one tile. Is there a minimum amount of tiles required?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants