Bayer-Group / paquo

PAthological QUpath Obsession - QuPath and Python conversations
GNU General Public License v3.0
104 stars 16 forks source link

No valid installation of QuPath #107

Closed swaradgat19 closed 11 months ago

swaradgat19 commented 11 months ago

qupath.py:

from __future__ import annotations

import json
from pathlib import Path
import subprocess
import os
import toml

def configure_qupath():

    try:
        from paquo.projects import QuPathProject
    except Exception as e:
        print(f"Couldn't find Qupath project with error: {e}")

        choice = input("""QuPath can be configured by setting the 'qupath_dir' 
                        field in '.paquo.toml'. You can also manually enter the path
                        to your local QuPath installation. Do you want to enter manually?
                        Y[yes] or n[no]:
        """)

        if choice is None or choice == 'n' or choice != 'Y':
            pass
        elif choice == 'Y':
            ### Converting the string to Path doesnt work. Gives TypeError: str expected, not PosixPath
            qupath_directory = input("Please enter the exact path where QuPath is installed: ")

            if Path(qupath_directory).exists():
                os.environ["PAQUO_QUPATH_DIR"] = str(qupath_directory)
            else:
                print(f"QuPath Directory not found. Try again!")

def add_image_and_geojson(
    qupath_proj: QuPathProject, *, image_path: Path | str, geojson_path: Path | str
) -> None:
    with open(geojson_path) as f:
        # FIXME: check that a 'features' key is present and raise a useful error if not
        geojson_features = json.load(f)["features"]

    entry = qupath_proj.add_image(image_path)
    # FIXME: test that the 'load_geojson' function exists. If not, raise a useful error
    entry.hierarchy.load_geojson(geojson_features)  # type: ignore

# Store a list of matched slides and geojson files. Linking the slides and geojson in
# this way prevents a potential mismatch by simply listing directories and relying on
# the order to be the same.

def make_qupath_project(wsi_dir, results_dir):

    configure_qupath()
    from paquo.projects import QuPathProject
    print("Imported paquo successfully!")
    QUPATH_PROJECT_DIRECTORY = "QuPathProject"

    slides_and_geojsons = [
    ("/home/sggat/wsinfer/wsinfer/SlideImages/CMU-2.svs", "/home/sggat/wsinfer/wsinfer/Results/model-outputs-geojson/CMU-2.json"),
]
    with QuPathProject(QUPATH_PROJECT_DIRECTORY, mode="w") as qp:
        for image_path, geojson_path in slides_and_geojsons:
            try:
                add_image_and_geojson(qp, image_path=image_path, geojson_path=geojson_path)
            except Exception as e:
                print(f"Failed to add image/geojson with error:: {e}")
    print("Successfully created QuPath Project!")

I am calling the make_qupath_project(wsi_dir, results_dir) from another python file with the appropriate arguments. When I run that python file, I am getting the following errors:

Couldn't find Qupath project with error: no valid qupath installation found
QuPath can be configured by setting the 'qupath_dir' 
                        field in '.paquo.toml'. You can also manually enter the path
                        to your local QuPath installation. Do you want to enter manually?
                        Y[yes] or n[no]:
        Y
Please enter the exact path where QuPath is installed: /home/sggat/QuPath
Command executed successfully.
Traceback (most recent call last):
  File "/home/sggat/miniforge3/bin/wsinfer", line 8, in <module>
    sys.exit(cli())
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/sggat/wsinfer/wsinfer/cli/infer.py", line 391, in run
    make_qupath_project(wsi_dir, results_dir)
  File "/home/sggat/wsinfer/wsinfer/qupath.py", line 78, in make_qupath_project
    from paquo.projects import QuPathProject
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/paquo/projects.py", line 23, in <module>
    from paquo._logging import get_logger
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/paquo/_logging.py", line 13, in <module>
    from paquo.java import ByteArrayOutputStream
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/paquo/java.py", line 32, in <module>
    qupath_version = start_jvm(finder_kwargs=to_kwargs(settings))
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/paquo/jpype_backend.py", line 198, in start_jvm
    app_dir, runtime_dir, jvm_path, jvm_options = finder(**finder_kwargs)
  File "/home/sggat/miniforge3/lib/python3.10/site-packages/paquo/jpype_backend.py", line 111, in find_qupath
    raise ValueError("no valid qupath installation found")
ValueError: no valid qupath installation found

The environment variable PAQUO_QUPATH_DIR is successfully getting set in configure_path function. Why am I unable to import from paquo.projects import QuPathProject even after setting the environment variable? Could you comment as to why this is happening?

ap-- commented 11 months ago

When the first import of QuPathProject fails, paquo.settings is already loaded and configured. When you then change the environment variable, the old setting keeps on being used when searching for QuPath.

You might be able to work around this issue by calling paquo.settings.reload() after setting the environment variable to force reloading the configuration.

swaradgat19 commented 11 months ago

This worked for me. Thank you for your prompt response! @ap--

ap-- commented 11 months ago

Glad I could help 😃