Repository: BBQuercus/deepBlink (language: python)

Issue:
Error when using both probability and radius parameters
Hi, thanks for making this super useful tool! Just wanted to let you know I encountered a minor bug that occurs when you try to use both the probability and radius parameters simultaneously when predicting (ie: `deepblink predict --model model.h5 --input img.tiff -r 1 -p 0.9`). Running using both parameters causes it to throw the following error:

> Traceback (most recent call last):
File "/mnt/envs/dev-nkeener/bin/deepblink", line 33, in
sys.exit(load_entry_point('deepblink==0.1.3', 'console_scripts', 'deepblink')())
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_main.py", line 115, in main
handler()
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_predict.py", line 71, in call
self.predict_adaptive(fname_in, image)
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_predict.py", line 193, in predict_adaptive
curr_df = self.predict_single(single_image, pixel_size)
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_predict.py", line 165, in predict_single
df["i"] = get_intensities(image, coords, self.radius)
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/inference.py", line 105, in get_intensities
for r, c in coordinate_list:
ValueError: too many values to unpack (expected 2)

This is because `coordinate_list` in the `get_intensities()` function in inference.py can have either 2 or 3 columns depending on if you used the probability parameter so that function will need to be adjusted to handle the variable number of columns.  

Error when using both probability and radius parameters
Hi, thanks for making this super useful tool! Just wanted to let you know I encountered a minor bug that occurs when you try to use both the probability and radius parameters simultaneously when predicting (ie: `deepblink predict --model model.h5 --input img.tiff -r 1 -p 0.9`). Running using both parameters causes it to throw the following error:

> Traceback (most recent call last):
File "/mnt/envs/dev-nkeener/bin/deepblink", line 33, in
sys.exit(load_entry_point('deepblink==0.1.3', 'console_scripts', 'deepblink')())
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_main.py", line 115, in main
handler()
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_predict.py", line 71, in call
self.predict_adaptive(fname_in, image)
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_predict.py", line 193, in predict_adaptive
curr_df = self.predict_single(single_image, pixel_size)
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/cli/_predict.py", line 165, in predict_single
df["i"] = get_intensities(image, coords, self.radius)
File "/mnt/envs/dev-nkeener/lib/python3.7/site-packages/deepblink/inference.py", line 105, in get_intensities
for r, c in coordinate_list:
ValueError: too many values to unpack (expected 2)

This is because `coordinate_list` in the `get_intensities()` function in inference.py can have either 2 or 3 columns depending on if you used the probability parameter so that function will need to be adjusted to handle the variable number of columns.  



Discussion / hints:
Hey. Thanks for letting us know! I was able to reproduce the error. We'll try to get it fixed by early next week.
Thank you!
Hey. Thanks for letting us know! I was able to reproduce the error. We'll try to get it fixed by early next week.
Thank you!

Fix patch:
diff --git a/.gitignore b/.gitignore
index 81b8000..c41e1e3 100755
--- a/.gitignore
+++ b/.gitignore
@@ -76,7 +76,7 @@ docs/_build
 # Training
 *.npz
 *.h5
-!model512x512.h5
+!model.h5
 wandb/
 Fiji.app/
 
diff --git a/deepblink/cli/_predict.py b/deepblink/cli/_predict.py
index ce2ba45..ebabf8f 100644
--- a/deepblink/cli/_predict.py
+++ b/deepblink/cli/_predict.py
@@ -158,11 +158,11 @@ def predict_single(
 
         coords = predict(image, self.model, self.probability)
         df = pd.DataFrame(coords, columns=columns)
+        if self.radius is not None:
+            df["i"] = get_intensities(image, coords[..., :2], self.radius)
+
         df[column_x] *= pixel_size[0]
         df[column_y] *= pixel_size[1]
-
-        if self.radius is not None:
-            df["i"] = get_intensities(image, coords, self.radius)
         return df
 
     def predict_adaptive(self, fname_in: str, image: np.ndarray) -> None:
diff --git a/tox.ini b/tox.ini
index 52045a2..0ad1d85 100644
--- a/tox.ini
+++ b/tox.ini
@@ -51,6 +51,7 @@ commands =
 
 [testenv:style]
 deps =
+	click==8.0.2
     black==19.10b0
     mypy
     types-requests


Test patch:
diff --git a/tests/data/model.h5 b/tests/data/model.h5
new file mode 100644
index 0000000..d345d38
Binary files /dev/null and b/tests/data/model.h5 differ
diff --git a/tests/test_cli.py b/tests/test_cli.py
index d7c8244..50aedb3 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -4,17 +4,21 @@
 import argparse
 import logging
 import os
+import platform
 
 import numpy as np
 import pandas as pd
+import pytest
 
 from deepblink.cli._config import HandleConfig
 from deepblink.cli._create import HandleCreate
+from deepblink.cli._predict import HandlePredict
 from deepblink.cli._main import arg_parser
 
 
 LOGGER = logging.Logger("None")
 
+
 # TODO cover more in-depth functionality like commands etc.
 def test_parse_args():
     parser = arg_parser()
@@ -67,3 +71,72 @@ def test_create():
         assert df["c"].min() >= 0
         assert df["r"].max() <= max_size
         assert df["c"].max() <= max_size
+
+
+# TODO test batch prediction
+@pytest.fixture(scope="session")
+def predict_handler():
+    handler = HandlePredict(
+        arg_input=os.path.join(os.path.dirname(__file__), "./data/image_pixel.tif"),
+        arg_model=os.path.join(os.path.dirname(__file__), "./data/model.h5"),
+        arg_output=None,
+        arg_radius=None,
+        arg_shape=None,
+        arg_probability=None,
+        arg_pixel_size=None,
+        logger=LOGGER,
+    )
+    return handler
+
+
+@pytest.fixture(scope="session")
+def filename_predict_output():
+    return os.path.join(os.path.dirname(__file__), "./data/image_pixel.csv")
+
+
+def test_predict_different_name(predict_handler):
+    filename_special = os.path.join(os.getcwd(), "image_pixel.csv")
+    predict_handler.raw_output = os.getcwd()
+    predict_handler()
+    assert os.path.exists(filename_special)
+    os.remove(filename_special)
+    predict_handler.raw_output = None
+
+
+# Test radius and no output -> same name as input
+def test_predict_radius_and_output(predict_handler, filename_predict_output):
+    predict_handler.radius = 1
+    predict_handler()
+    assert os.path.exists(filename_predict_output)
+    with open(filename_predict_output, "r") as f:
+        assert f.readline().strip() == "y [px],x [px],i"
+    os.remove(filename_predict_output)
+    predict_handler.radius = None
+
+
+def test_predict_probability_and_pixel_size(predict_handler, filename_predict_output):
+    predict_handler.pixel_size = 2.3
+    predict_handler.probability = 0.9
+    predict_handler()
+    with open(filename_predict_output, "r") as f:
+        if platform.system() != "Windows":
+            assert f.readline().strip() == "y [\u00B5m],x [\u00B5m],p"
+    os.remove(filename_predict_output)
+    predict_handler.pixel_size = None
+    predict_handler.probability = None
+
+
+def test_predict_all_options(predict_handler, filename_predict_output):
+    predict_handler.pixel_size = 2.3
+    predict_handler.probability = 0.9
+    predict_handler.radius = 3
+    predict_handler.raw_shape = "(x,y)"
+    predict_handler()
+    with open(filename_predict_output, "r") as f:
+        if platform.system() != "Windows":
+            assert f.readline().strip() == "y [\u00B5m],x [\u00B5m],p,i"
+    os.remove(filename_predict_output)
+    predict_handler.pixel_size = None
+    predict_handler.probability = None
+    predict_handler.radius = None
+    predict_handler.raw_shape = None