Skip to content

Commit

Permalink
Merge pull request #20 from DavidStirling/compart-4-2-8-ai-test
Browse files Browse the repository at this point in the history
Update to 4.2.8 & migrate internal bio-formats
  • Loading branch information
emilroz authored Oct 24, 2024
2 parents 8a252f0 + 17781ed commit 2af1ec7
Show file tree
Hide file tree
Showing 18 changed files with 75 additions and 70 deletions.
47 changes: 20 additions & 27 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macos-12, windows-2019 ]
os: [ macos-13, windows-2019 ]
python-version: [ "3.8" ]
fail-fast: false
steps:
Expand All @@ -21,7 +21,7 @@ jobs:
name: Install Java
with:
distribution: "temurin"
java-version: "11" # The JDK version to make available on the path.
java-version: "11.0.20+8" # The JDK version to make available on the path.
java-package: jdk
architecture: x64

Expand All @@ -47,28 +47,24 @@ jobs:
brew install [email protected]
brew link [email protected]
pip install mysqlclient==2.0.3
pip install centrosome==1.2.2 --no-cache-dir --no-build-isolation
git clone https://github.com/glencoesoftware/core.git
cd core
git checkout compat-4-2
pip install --editable . --upgrade --no-use-pep517
cd ..
pip install --editable . --no-use-pep517
pip install https://github.com/glencoesoftware/core/releases/download/v4.2.80001/cellprofiler_core-4.2.8-py3-none-any.whl
pip install .
pip install https://github.com/DavidStirling/prokaryote/releases/download/v2.4.5/prokaryote-2.4.5.tar.gz --no-cache-dir --no-build-isolation
pip install https://github.com/DavidStirling/python-bioformats/releases/download/v4.1.10001/python_bioformats-4.1.10001-py3-none-any.whl
- env:
JDK_HOME: ${{ env.JAVA_HOME }}
CPPFLAGS: -I/usr/local/opt/[email protected]/include
LDFLAGS: "-L/usr/local/opt/[email protected]/lib -L/usr/local/opt/openssl/lib"
if: startsWith(matrix.os, 'windows')
name: Windows dependency install
run: |
python -m pip install --upgrade pip setuptools wheel
pip install mysqlclient==2.0.3
pip install centrosome==1.2.2 --no-cache-dir --no-build-isolation
git clone https://github.com/glencoesoftware/core.git
cd core
git checkout compat-4-2
pip install --editable . --upgrade --no-use-pep517
cd ..
pip install --editable . --no-use-pep517
pip install https://github.com/glencoesoftware/core/releases/download/v4.2.80001/cellprofiler_core-4.2.8-py3-none-any.whl
pip install .
pip install wxpython==4.1.1
pip install https://github.com/DavidStirling/prokaryote/releases/download/v2.4.5/prokaryote-2.4.5.tar.gz --no-cache-dir --no-build-isolation
pip install https://github.com/DavidStirling/python-bioformats/releases/download/v4.1.10001/python_bioformats-4.1.10001-py3-none-any.whl
- name: Install plugins
run: |
pip install torch==2.2.1
Expand All @@ -85,29 +81,26 @@ jobs:
run: |
pyinstaller distribution/windows/cellprofiler.spec
rm ./dist/CellProfiler/jvm.dll
iscc /dMyAppVersion="4.2.60001-ai" "distribution/windows/cellprofiler.iss"
iscc /dMyAppVersion="4.2.80001-ai" "distribution/windows/cellprofiler.iss"
- if: startsWith(matrix.os, 'macos')
name: MacOS pyinstaller build and package
run: |
pyinstaller -y ./distribution/macos/CellProfiler.spec
- if: startsWith(matrix.os, 'macos')
name: MacOS dmg package
continue-on-error: true
run: |
cd dist
echo Creating DMG
create-dmg 'CellProfiler+AI.app' --dmg-title "CellProfiler+AI.dmg"
name: MacOS tar package
run: tar -cvf CellProfiler+AI.tar CellProfiler+AI.app
working-directory: ./dist
- if: startsWith(matrix.os, 'macos')
uses: actions/upload-artifact@v4
name: MacOS dmg upload
name: MacOS tar upload
with:
name: CellProfiler-macOS-4.2.60001-ai.dmg
path: ./dist/*.dmg
name: CellProfiler-macOS-4.2.80001-ai.tar
path: ./dist/*.tar
- if: startsWith(matrix.os, 'windows')
uses: actions/upload-artifact@v4
name: Windows artifact upload
with:
name: CellProfiler-Windows-4.2.60001-ai.exe
name: CellProfiler-Windows-4.2.80001-ai.exe
path: ./distribution/windows/Output/*.exe
upload:
name: upload
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![CellProfiler](cellprofiler/data/images/splash.png)

[![Version](https://img.shields.io/badge/version-4.2.6-green.svg)](https://cellprofiler.org/releases)
[![Docs](https://img.shields.io/badge/documentation-4.2.6-brightgreen.svg)](https://cellprofiler-manual.s3.amazonaws.com/CellProfiler-4.2.6/index.html)
[![Version](https://img.shields.io/badge/version-4.2.8-green.svg)](https://cellprofiler.org/releases)
[![Docs](https://img.shields.io/badge/documentation-4.2.8-brightgreen.svg)](https://cellprofiler-manual.s3.amazonaws.com/CellProfiler-4.2.8/index.html)
[![Image.sc forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftag%2Fcellprofiler.json&query=%24.topic_list.tags.0.topic_count&colorB=brightgreen&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tag/cellprofiler)

**CellProfiler** is a free open-source software designed to enable biologists without training in computer vision or programming to quantitatively measure phenotypes from thousands of images automatically. More information can be found in the [CellProfiler Wiki](https://github.com/CellProfiler/CellProfiler/wiki).
Expand Down
2 changes: 1 addition & 1 deletion cellprofiler/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__test__ = False

__version__ = "4.2.60001"
__version__ = "4.2.80001"
6 changes: 4 additions & 2 deletions cellprofiler/gui/checkupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@


def check_update(parent, force=False):
if not force and not check_date():
if not force:
return
try:
response = requests.get("https://api.github.com/repos/cellprofiler/cellprofiler/releases/latest", timeout=0.25)
response = requests.get("https://api.github.com/repos/glencoesoftware/cellprofiler/releases/latest", timeout=0.25)
except:
response = False
message = "CellProfiler was unable to connect to GitHub to check for updates"
Expand All @@ -19,6 +19,8 @@ def check_update(parent, force=False):
response = response.json()
if status == 200 and 'name' in response:
latest_version = response['name'][1:]
if '-' in latest_version:
latest_version = latest_version.split('-')[0]
if current_version < latest_version or len(current_version) != len(latest_version):
body_text = response['body']
if len(body_text) > 1000:
Expand Down
2 changes: 1 addition & 1 deletion cellprofiler/modules/classifyobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ def run_two_measurements(self, workspace):

if self.show_window:
workspace.display_data.in_high_class = in_high_class
workspace.display_data.labels = (objects.segmented,)
workspace.display_data.labels = objects.segmented
workspace.display_data.saved_values = saved_values

def display_two_measurements(self, workspace, figure):
Expand Down
4 changes: 4 additions & 0 deletions cellprofiler/modules/flagimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,10 @@ def load_classifier(self, measurement_group):
d[path_] = joblib.load(path_)
return d[path_]

def get_dictionary_for_worker(self):
# Sklearn models can't be serialized, so workers will need to read them from disk.
return {}

def get_classifier(self, measurement_group):
return self.load_classifier(measurement_group)[0]

Expand Down
14 changes: 13 additions & 1 deletion cellprofiler/modules/measureimageoverlap.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,9 @@ def run(self, workspace):

# In volumetric case the 3D image stack gets converted to a long 2D image and gets analyzed
if ground_truth_image.volumetric:

orig_shape = ground_truth_pixels.shape

ground_truth_pixels = ground_truth_pixels.reshape(
-1, ground_truth_pixels.shape[-1]
)
Expand Down Expand Up @@ -451,6 +454,15 @@ def run(self, workspace):
)

if self.show_window:

workspace.display_data.dimensions = test_image.dimensions

if ground_truth_image.volumetric:
true_positives = true_positives.reshape(orig_shape)
true_negatives = true_negatives.reshape(orig_shape)
false_positives = false_positives.reshape(orig_shape)
false_negatives = false_negatives.reshape(orig_shape)

workspace.display_data.true_positives = true_positives

workspace.display_data.true_negatives = true_negatives
Expand Down Expand Up @@ -741,7 +753,7 @@ def get_weights(self, i, j, labels_mask):

def display(self, workspace, figure):
"""Display the image confusion matrix & statistics"""
figure.set_subplots((3, 2))
figure.set_subplots((3, 2),dimensions=workspace.display_data.dimensions)

for x, y, image, label in (
(0, 0, workspace.display_data.true_positives, "True positives"),
Expand Down
2 changes: 1 addition & 1 deletion cellprofiler/modules/measureimagequality.py
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ def get_measurement_scales(
if image_names in self.images_to_process(
image_group, None, pipeline
):
result += [scale_group.scale]
result += [scale_group.scale.value]
return result
if measurement.startswith(F_THRESHOLD):
result = []
Expand Down
4 changes: 2 additions & 2 deletions cellprofiler/modules/measureimageskeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ def get_measurements(self, pipeline, object_name, category):

if object_name == "Image" and category == "Skeleton":
return [
"Skeleton_Branches_{}".format(name),
"Skeleton_Endpoints_{}".format(name),
"Branches",
"Endpoints"
]

return []
Expand Down
5 changes: 3 additions & 2 deletions cellprofiler/modules/measureobjectneighbors.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,9 @@ def run(self, workspace):
neighbor_has_pixels = has_pixels
else:
_, neighbor_numbers = neighbor_objects.relate_labels(
neighbor_labels, neighbor_objects.small_removed_segmented
neighbor_labels, neighbor_kept_labels
)
neighbor_has_pixels = numpy.bincount(neighbor_labels.ravel())[1:] > 0
neighbor_has_pixels = numpy.bincount(neighbor_kept_labels.ravel())[1:] > 0
neighbor_count = numpy.zeros((nobjects,))
pixel_count = numpy.zeros((nobjects,))
first_object_number = numpy.zeros((nobjects,), int)
Expand Down Expand Up @@ -703,6 +703,7 @@ def run(self, workspace):
)

labels = kept_labels
neighbor_labels = neighbor_kept_labels

neighbor_count_image = numpy.zeros(labels.shape, int)
object_mask = objects.segmented != 0
Expand Down
2 changes: 1 addition & 1 deletion cellprofiler/modules/runimagejmacro.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def run(self, workspace):

cmd += [self.stringify_metadata(tempdir)]

result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, errors='backslashreplace')
for image_group in self.image_groups_out:
if not os.path.exists(os.path.join(tempdir, image_group.input_filename.value)):
# Cleanup the error logs for display, we want to remove less-useful lines to keep it succinct.
Expand Down
4 changes: 4 additions & 0 deletions cellprofiler/modules/threshold.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,10 @@ def get_local_threshold(self, image, mask, volumetric):
elif numpy.all(image_data == image_data[0]):
local_threshold = numpy.full_like(image_data, image_data[0])

elif numpy.all((image_data == 0) | numpy.isnan(image_data)):
#test if all values are a mixture of 0 or nan
local_threshold = numpy.zeros_like(image_data)

elif self.threshold_operation == TM_LI:
local_threshold = self._run_local_threshold(
image_data,
Expand Down
1 change: 1 addition & 0 deletions distribution/macos/CellProfiler.spec
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ hiddenimports += PyInstaller.utils.hooks.collect_submodules("wx")
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler.gui')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler.modules')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler_core')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler_core.modules')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('skimage.io._plugins')
hiddenimports += PyInstaller.utils.hooks.collect_submodules("skimage.feature")
Expand Down
1 change: 1 addition & 0 deletions distribution/windows/CellProfiler.spec
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ hiddenimports = []

hiddenimports += PyInstaller.utils.hooks.collect_submodules('centrosome')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler.modules')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler_core')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler_core.modules')
hiddenimports += PyInstaller.utils.hooks.collect_submodules('cellprofiler.utilities')
hiddenimports += PyInstaller.utils.hooks.collect_submodules("scipy")
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
# The short X.Y version.
version = "4.2"
# The full version, including alpha/beta/rc tags.
release = "4.2.6"
release = "4.2.8"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
20 changes: 3 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
[tool.black]
exclude = '''
(
/(
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| build
| dist
)/
)
'''
target_version = ['py38']
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
21 changes: 11 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,21 @@ def package_data():
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Scientific/Engineering :: Bio-Informatics",
"Topic :: Scientific/Engineering :: Image Recognition",
"Topic :: Scientific/Engineering",
],
entry_points={"console_scripts": ["cellprofiler=cellprofiler.__main__:main"]},
extras_require={
"build": ["black", "pre-commit", "pyinstaller", "twine"],
"docs": ["Sphinx>=3.1.1", "sphinx-rtd-theme>=0.5.0"],
"test": ["pytest>=3.3.2,<4"],
"build": ["pyinstaller", "twine"],
"docs": ["Sphinx>=3.1.1", "sphinx-rtd-theme>=0.5.0", "markupsafe<2.0.1"],
"test": ["pytest~=7.4.1"],
},
install_requires=[
"boto3==1.14.23",
"cellprofiler-core",
"centrosome==1.2.2",
"boto3>=1.12.28",
"cellprofiler-core==4.2.8",
"centrosome~=1.2.3",
"docutils==0.15.2",
"h5py==3.6.0",
"imageio==2.34.0",
Expand All @@ -79,17 +80,17 @@ def package_data():
"opencv-python-headless==4.5.3.56",
"Pillow==8.3.2",
"prokaryote==2.4.4",
"python-bioformats==4.0.7",
"python-javabridge==4.0.3",
"python-bioformats~=4.1.0",
"python-javabridge==4.0.4",
"pyzmq==22.3.0",
"sentry-sdk==0.18.0",
"requests==2.22",
"scikit-image==0.18.3",
"scikit-learn==0.24.1",
"scipy==1.9.0",
"six",
"tifffile==2023.2.3",
"wxPython==4.2.1",
"tifffile<2022.4.22",
"wxPython>=4.1.0,<5",
],
license="BSD",
name="CellProfiler",
Expand Down
4 changes: 2 additions & 2 deletions tests/modules/test_measureimageskeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_get_measurement_columns(module, pipeline):
def test_get_measurements_image_skeleton(module, pipeline):
module.skeleton_name.value = "example"

expected_measurements = ["Skeleton_Branches_example", "Skeleton_Endpoints_example"]
expected_measurements = ["Branches", "Endpoints"]

measurements = module.get_measurements(
pipeline, "Image", "Skeleton"
Expand Down Expand Up @@ -127,7 +127,7 @@ def test_get_measurement_images(module, pipeline):
pipeline,
"Image",
"Skeleton",
"Skeleton_Branches_example",
"Branches",
)

assert images == expected_images
Expand Down

0 comments on commit 2af1ec7

Please sign in to comment.