peng-lab / BaSiCPy

MIT License
62 stars 20 forks source link

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

Open donovanr opened 1 year ago

donovanr commented 1 year ago

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 ```python 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 ```python # 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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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?