|
15 | 15 | import re |
16 | 16 | import shutil |
17 | 17 | import tempfile |
| 18 | +import warnings |
18 | 19 | from pathlib import PosixPath |
19 | 20 | from typing import TYPE_CHECKING, Literal |
20 | 21 |
|
@@ -198,7 +199,7 @@ def __init__( |
198 | 199 | if not os.path.isdir(self.project_location): |
199 | 200 | os.makedirs(self.project_location) |
200 | 201 | else: |
201 | | - Warning("There is already a directory in the location path") |
| 202 | + warnings.warn("There is already a directory in the location path", stacklevel=2) |
202 | 203 |
|
203 | 204 | # === setup sdata reader/writer === |
204 | 205 | self.filehandler = sdata_filehandler( |
@@ -499,8 +500,9 @@ def _check_image_dtype(self, image: np.ndarray) -> None: |
499 | 500 | """ |
500 | 501 |
|
501 | 502 | if not image.dtype == self.DEFAULT_IMAGE_DTYPE: |
502 | | - Warning( |
503 | | - f"Image dtype is not {self.DEFAULT_IMAGE_DTYPE} but insteadt {image.dtype}. The workflow expects images to be of dtype {self.DEFAULT_IMAGE_DTYPE}. Proceeding with the incorrect dtype can lead to unexpected results." |
| 503 | + warnings.warn( |
| 504 | + f"Image dtype is not {self.DEFAULT_IMAGE_DTYPE} but insteadt {image.dtype}. The workflow expects images to be of dtype {self.DEFAULT_IMAGE_DTYPE}. Proceeding with the incorrect dtype can lead to unexpected results.", |
| 505 | + stacklevel=2, |
504 | 506 | ) |
505 | 507 | self.log( |
506 | 508 | f"Image dtype is not {self.DEFAULT_IMAGE_DTYPE} but insteadt {image.dtype}. The workflow expects images to be of dtype {self.DEFAULT_IMAGE_DTYPE}. Proceeding with the incorrect dtype can lead to unexpected results." |
@@ -638,7 +640,10 @@ def close_interactive_viewer(self): |
638 | 640 |
|
639 | 641 | def _check_for_interactive_session(self): |
640 | 642 | if self.interactive is not None: |
641 | | - Warning("Interactive viewer is still open. Will automatically close before proceeding with processing.") |
| 643 | + warnings.warn( |
| 644 | + "Interactive viewer is still open. Will automatically close before proceeding with processing.", |
| 645 | + stacklevel=2, |
| 646 | + ) |
642 | 647 | self.close_interactive_viewer() |
643 | 648 |
|
644 | 649 | #### Functions to visualize results #### |
@@ -1452,8 +1457,9 @@ def load_input_from_sdata( |
1452 | 1457 | table = sdata_input[table_elem] |
1453 | 1458 | rename_columns = {} |
1454 | 1459 | if self.DEFAULT_CELL_ID_NAME in table.obs: |
1455 | | - Warning( |
1456 | | - f"Column {self.DEFAULT_CELL_ID_NAME} already exists in table. Renaming to `f{self.DEFAULT_CELL_ID_NAME}_orig` to preserve compatibility with scPortrait workflow." |
| 1460 | + warnings.warn( |
| 1461 | + f"Column {self.DEFAULT_CELL_ID_NAME} already exists in table. Renaming to `f{self.DEFAULT_CELL_ID_NAME}_orig` to preserve compatibility with scPortrait workflow.", |
| 1462 | + stacklevel=2, |
1457 | 1463 | ) |
1458 | 1464 | rename_columns[self.DEFAULT_CELL_ID_NAME] = f"{self.DEFAULT_CELL_ID_NAME}_orig" |
1459 | 1465 | self.log( |
@@ -1495,11 +1501,31 @@ def load_input_from_sdata( |
1495 | 1501 |
|
1496 | 1502 | self.filehandler._add_centers(segmentation_label=self.cyto_seg_name) |
1497 | 1503 |
|
| 1504 | + # read the sdata object from file to ensure we have access to all newly written elements |
| 1505 | + sdata = SpatialData.read(self.sdata_path) |
| 1506 | + |
1498 | 1507 | # ensure that if both an nucleus and cytosol segmentation mask are loaded that they match |
1499 | 1508 | if self.nuc_seg_status and self.cyto_seg_status: |
1500 | | - ids_nuc = set(sdata[f"{self.DEFAULT_CENTERS_NAME}_{self.nuc_seg_name}"].index.values) |
1501 | | - ids_cyto = set(sdata[f"{self.DEFAULT_CENTERS_NAME}_{self.cyto_seg_name}"].index.values) |
1502 | | - assert ids_nuc == ids_cyto, "Nucleus and cytosol segmentation masks do not match." |
| 1509 | + ids_nuc = set(sdata["centers_seg_all_nucleus"].index.compute().values) |
| 1510 | + ids_cyto = set(sdata["centers_seg_all_cytosol"].index.compute().values) |
| 1511 | + |
| 1512 | + if ids_nuc.issubset(ids_cyto): |
| 1513 | + if not ids_nuc == ids_cyto: |
| 1514 | + warnings.warn( |
| 1515 | + "Nucleus segmentation mask is a subset of cytosol segmentation mask, but they do not match exactly. \n This means that cells exist which do not have a nucleus mask but do have a cytosol mask. \n Please be careful when configuring your extraction workflow.", |
| 1516 | + stacklevel=2, |
| 1517 | + ) |
| 1518 | + |
| 1519 | + elif ids_cyto.issubset(ids_nuc): |
| 1520 | + if not ids_cyto == ids_nuc: |
| 1521 | + warnings.warn( |
| 1522 | + "Cytosol segmentation mask is a subset of nucleus segmentation mask, but they do not match exactly. \n This means cells exist which do not have a cytosol mask but do have a nucleus mask. \n Please be careful when configuring your extraction workflow.", |
| 1523 | + stacklevel=2, |
| 1524 | + ) |
| 1525 | + else: |
| 1526 | + raise ValueError( |
| 1527 | + "Nucleus and cytosol segmentation masks do not match. This is unexpected and should be investigated." |
| 1528 | + ) |
1503 | 1529 |
|
1504 | 1530 | self.get_project_status() |
1505 | 1531 |
|
|
0 commit comments