From 84ea65d8404ff5a9ec794a4c1dcaa6239fa9e3d5 Mon Sep 17 00:00:00 2001 From: bilalcodehub Date: Sat, 29 Mar 2025 00:59:54 +0000 Subject: [PATCH 1/8] Added read_labels_from_file and changed init_datastore to parse CSV labels with JSON attributes passed via cvat_labels_file --- sample-apps/endoscopy/main.py | 48 ++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/sample-apps/endoscopy/main.py b/sample-apps/endoscopy/main.py index 258b5cb20..bebb238ee 100644 --- a/sample-apps/endoscopy/main.py +++ b/sample-apps/endoscopy/main.py @@ -96,9 +96,55 @@ def __init__(self, app_dir, studies, conf): ) self.downloading = False + def read_labels_from_file(self, file_path: str) -> List[Dict[str, Union[str, int, list]]]: + labels = [] + + try: + with open(file_path, mode='r') as csvfile: + reader = csv.DictReader(csvfile) + + for row in reader: + # Check for required fields + if "name" in row and "id" in row and "color" in row: + attributes = [] + # Process the attributes if they exist and are not empty + if "attributes" in row and row["attributes"].strip(): + try: + attributes = json.loads(row["attributes"].strip()) + except json.JSONDecodeError as e: + logger.warning(f"Could not parse attributes JSON for row {row}: {e}") + + entry = { + "name": row["name"], + "id": int(row["id"]), + "color": row["color"], + "type": "any", + "attributes": attributes + } + labels.append(entry) + else: + logger.warning(f"Skipping row due to missing fields: {row}") + + logger.info(f"Loaded {len(labels)} labels from {file_path}") + except FileNotFoundError: + logger.error(f"Label file {file_path} not found!") + except Exception as e: + logger.error(f"Error reading label file {file_path}: {e}") + + return labels + def init_datastore(self) -> Datastore: if settings.MONAI_LABEL_DATASTORE_URL and settings.MONAI_LABEL_DATASTORE.lower() == "cvat": logger.info(f"Using CVAT: {self.studies}") + # First try to get labels directly from the configuration + labels = self.conf.get("cvat_labels") + # If cvat_labels_file is specified and not null, read labels from that file + cvat_labels_file = self.conf.get("cvat_labels_file") + if cvat_labels_file: + try: + labels = self.read_labels_from_file(cvat_labels_file) + except Exception as e: + logger.error(f"Error reading CVAT labels file {cvat_labels_file}: {e}") return CVATDatastore( datastore_path=self.studies, api_url=settings.MONAI_LABEL_DATASTORE_URL, @@ -107,7 +153,7 @@ def init_datastore(self) -> Datastore: project=self.conf.get("cvat_project", "MONAILabel"), task_prefix=self.conf.get("cvat_task_prefix", "ActiveLearning_Iteration"), image_quality=int(self.conf.get("cvat_image_quality", "70")), - labels=self.conf.get("cvat_labels"), + labels=labels, normalize_label=strtobool(self.conf.get("cvat_normalize_label", "true")), segment_size=int(self.conf.get("cvat_segment_size", "1")), extensions=settings.MONAI_LABEL_DATASTORE_FILE_EXT, From 6cdf0947a4ad7a7a1eb2be52900480b73c852e74 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 29 Mar 2025 01:09:29 +0000 Subject: [PATCH 2/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sample-apps/endoscopy/main.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sample-apps/endoscopy/main.py b/sample-apps/endoscopy/main.py index bebb238ee..274a368b6 100644 --- a/sample-apps/endoscopy/main.py +++ b/sample-apps/endoscopy/main.py @@ -98,11 +98,11 @@ def __init__(self, app_dir, studies, conf): def read_labels_from_file(self, file_path: str) -> List[Dict[str, Union[str, int, list]]]: labels = [] - + try: - with open(file_path, mode='r') as csvfile: + with open(file_path) as csvfile: reader = csv.DictReader(csvfile) - + for row in reader: # Check for required fields if "name" in row and "id" in row and "color" in row: @@ -113,26 +113,26 @@ def read_labels_from_file(self, file_path: str) -> List[Dict[str, Union[str, int attributes = json.loads(row["attributes"].strip()) except json.JSONDecodeError as e: logger.warning(f"Could not parse attributes JSON for row {row}: {e}") - + entry = { "name": row["name"], "id": int(row["id"]), "color": row["color"], "type": "any", - "attributes": attributes + "attributes": attributes, } labels.append(entry) else: logger.warning(f"Skipping row due to missing fields: {row}") - + logger.info(f"Loaded {len(labels)} labels from {file_path}") except FileNotFoundError: logger.error(f"Label file {file_path} not found!") except Exception as e: logger.error(f"Error reading label file {file_path}: {e}") - + return labels - + def init_datastore(self) -> Datastore: if settings.MONAI_LABEL_DATASTORE_URL and settings.MONAI_LABEL_DATASTORE.lower() == "cvat": logger.info(f"Using CVAT: {self.studies}") From 879c9b59a260cde3de30bbf5f66192251d74509a Mon Sep 17 00:00:00 2001 From: bilalcodehub Date: Tue, 1 Apr 2025 23:39:35 +0000 Subject: [PATCH 3/8] Fix: corrected issues from previous PR submission related to imports Signed-off-by: Muhammad Bilal --- sample-apps/endoscopy/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sample-apps/endoscopy/main.py b/sample-apps/endoscopy/main.py index 274a368b6..1057fda85 100644 --- a/sample-apps/endoscopy/main.py +++ b/sample-apps/endoscopy/main.py @@ -12,7 +12,9 @@ import logging import os from datetime import timedelta -from typing import Dict +from typing import List, Dict, Union +import csv +import json import lib.configs import numpy as np From 802e6ae44dbb679c12ac1a2cf759954c9376b12b Mon Sep 17 00:00:00 2001 From: bilalcodehub Date: Wed, 2 Apr 2025 00:25:37 +0000 Subject: [PATCH 4/8] Fix: corrected issues from previous PR submission Signed-off-by: Muhammad Bilal --- sample-apps/endoscopy/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sample-apps/endoscopy/main.py b/sample-apps/endoscopy/main.py index 1057fda85..961b51c7d 100644 --- a/sample-apps/endoscopy/main.py +++ b/sample-apps/endoscopy/main.py @@ -11,10 +11,10 @@ import logging import os -from datetime import timedelta -from typing import List, Dict, Union import csv import json +from datetime import timedelta +from typing import List, Dict, Union import lib.configs import numpy as np From da270d015bf65bc6a1cdf94bf7f76d0e5636f50d Mon Sep 17 00:00:00 2001 From: bilalcodehub Date: Wed, 2 Apr 2025 01:00:34 +0000 Subject: [PATCH 5/8] Fix: Add setuptools>=61 for Windows build compatibility with girder-client Signed-off-by: bilalcodehub --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 9ed558867..81b63522a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,6 +29,8 @@ pydicom-seg==0.4.1 pynetdicom==2.0.2 pynrrd==1.0.0 numpymaxflow==0.0.7 +setuptools>=61 +setuptools-scm<8.0.0 girder-client==3.2.3 ninja==1.11.1.1 einops==0.7.0 From 1302a7857c59883e524b8305f459617bf1a6d85d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 01:04:22 +0000 Subject: [PATCH 6/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sample-apps/endoscopy/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sample-apps/endoscopy/main.py b/sample-apps/endoscopy/main.py index 961b51c7d..dd07dbf28 100644 --- a/sample-apps/endoscopy/main.py +++ b/sample-apps/endoscopy/main.py @@ -9,12 +9,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging -import os import csv import json +import logging +import os from datetime import timedelta -from typing import List, Dict, Union +from typing import Dict, List, Union import lib.configs import numpy as np From 8bad0d3d76d2dca14fdd87206b12401ebe858b14 Mon Sep 17 00:00:00 2001 From: bilalcodehub Date: Wed, 2 Apr 2025 01:20:55 +0000 Subject: [PATCH 7/8] Fix: upgrade setuptools early in CI to avoid girder-client error on Windows Signed-off-by: bilalcodehub --- .github/workflows/pythonapp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index e832da531..e476efef9 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -45,7 +45,7 @@ jobs: rm -rf /opt/hostedtoolcache - name: Install dependencies run: | - python -m pip install --upgrade pip wheel + python -m pip install --upgrade pip setuptools wheel pip install -r requirements.txt build: From 32400d6fbc991dedb0269b2ca20915b68e79b94b Mon Sep 17 00:00:00 2001 From: bilalcodehub Date: Wed, 2 Apr 2025 01:51:46 +0000 Subject: [PATCH 8/8] Fix: resolve mypy type error in endoscopy main.py Signed-off-by: bilalcodehub --- sample-apps/endoscopy/main.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sample-apps/endoscopy/main.py b/sample-apps/endoscopy/main.py index dd07dbf28..2cb360e36 100644 --- a/sample-apps/endoscopy/main.py +++ b/sample-apps/endoscopy/main.py @@ -138,8 +138,9 @@ def read_labels_from_file(self, file_path: str) -> List[Dict[str, Union[str, int def init_datastore(self) -> Datastore: if settings.MONAI_LABEL_DATASTORE_URL and settings.MONAI_LABEL_DATASTORE.lower() == "cvat": logger.info(f"Using CVAT: {self.studies}") - # First try to get labels directly from the configuration - labels = self.conf.get("cvat_labels") + + labels: List[Dict[str, Union[str, int, list]]] = [] + # If cvat_labels_file is specified and not null, read labels from that file cvat_labels_file = self.conf.get("cvat_labels_file") if cvat_labels_file: @@ -147,6 +148,14 @@ def init_datastore(self) -> Datastore: labels = self.read_labels_from_file(cvat_labels_file) except Exception as e: logger.error(f"Error reading CVAT labels file {cvat_labels_file}: {e}") + else: + label_str = self.conf.get("cvat_labels") + if label_str: + try: + labels = json.loads(label_str) + except Exception as e: + logger.error(f"Error parsing cvat_labels config: {e}") + return CVATDatastore( datastore_path=self.studies, api_url=settings.MONAI_LABEL_DATASTORE_URL,