dsa-helpers 0.4.dev5__tar.gz → 0.5.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. dsa_helpers-0.5.dev0/.gitignore +11 -0
  2. {dsa_helpers-0.4.dev5/dsa_helpers.egg-info → dsa_helpers-0.5.dev0}/PKG-INFO +1 -1
  3. dsa_helpers-0.5.dev0/dsa_helpers/__init__.py +16 -0
  4. dsa_helpers-0.5.dev0/dsa_helpers/dash/__init__.py +3 -0
  5. dsa_helpers-0.5.dev0/dsa_helpers/dash/dash_paperdragon_utils.py +76 -0
  6. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/image_utils.py +13 -10
  7. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/metrics/binary_dice_coefficient_metric.py +4 -2
  8. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/object_detection/__init__.py +1 -1
  9. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0/dsa_helpers.egg-info}/PKG-INFO +1 -1
  10. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers.egg-info/SOURCES.txt +1 -1
  11. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/pyproject.toml +1 -1
  12. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/requirements.txt +4 -0
  13. dsa_helpers-0.4.dev5/.gitignore +0 -11
  14. dsa_helpers-0.4.dev5/dsa_helpers/__init__.py +0 -8
  15. dsa_helpers-0.4.dev5/dsa_helpers/dash/__init__.py +0 -1
  16. dsa_helpers-0.4.dev5/dsa_helpers/login.py +0 -36
  17. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/LICENSE +0 -0
  18. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/README.md +0 -0
  19. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/app.py +0 -0
  20. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/dash/header.py +0 -0
  21. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/dash/header_callbacks.py +0 -0
  22. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/girder_utils.py +0 -0
  23. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/imread.py +0 -0
  24. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/imwrite.py +0 -0
  25. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/__init__.py +0 -0
  26. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/datasets/SegFormerSegmentationDataset.py +0 -0
  27. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/datasets/__init__.py +0 -0
  28. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/datasets/utils.py +0 -0
  29. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/metrics/__init__.py +0 -0
  30. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +0 -0
  31. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/object_detection/tile_image.py +0 -0
  32. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/object_detection/utils.py +0 -0
  33. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/transforms/__init__.py +0 -0
  34. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/ml/transforms/segformer_transforms.py +0 -0
  35. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/mongo_utils.py +0 -0
  36. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers/utils.py +0 -0
  37. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers.egg-info/dependency_links.txt +0 -0
  38. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers.egg-info/requires.txt +0 -0
  39. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/dsa_helpers.egg-info/top_level.txt +0 -0
  40. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/setup.cfg +0 -0
  41. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/tests/app/Dockerfile +0 -0
  42. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/tests/app/app.py +0 -0
  43. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/tests/docker-compose.yaml +0 -0
  44. {dsa_helpers-0.4.dev5 → dsa_helpers-0.5.dev0}/tests/test.ipynb +0 -0
@@ -0,0 +1,11 @@
1
+ # Python environment directories.
2
+ env/
3
+ pyenv/
4
+
5
+ *.pyc
6
+ *.egg-info
7
+ dist/
8
+ .env
9
+
10
+ # Ignore data directory created for testing the package.
11
+ tests/data/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsa_helpers
3
- Version: 0.4.dev5
3
+ Version: 0.5.dev0
4
4
  Summary: Utility functions for working with the DSA girder client.
5
5
  Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
6
  Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
@@ -0,0 +1,16 @@
1
+ # Shadow imports.
2
+ from .imread import imread
3
+ from .imwrite import imwrite
4
+ from . import girder_utils, image_utils, dash, ml, mongo_utils, utils
5
+
6
+ # Modules that should be available.
7
+ __all__ = [
8
+ "girder_utils",
9
+ "image_utils",
10
+ "dash",
11
+ "ml",
12
+ "imread",
13
+ "imwrite",
14
+ "mongo_utils",
15
+ "utils",
16
+ ]
@@ -0,0 +1,3 @@
1
+ from . import header
2
+
3
+ __all__ = ["dash_paperdragon_utils", "header_callbacks", "header"]
@@ -0,0 +1,76 @@
1
+ def format_ann_docs_for_paperjs(
2
+ geojson_ann_docs: list[dict], return_as_input_to_paper: bool = False
3
+ ) -> list[dict]:
4
+ """Format DSA annotations in the geojson format into a format that paperdragon
5
+ can read and show as polygons.
6
+
7
+ Args:
8
+ geojson_ann_docs (list[dict]): A list of geojson annotation documents.
9
+ return_as_input_to_paper (bool): Whether to return the formatted documents as
10
+ input to paper. Defaults to False.
11
+
12
+ Returns:
13
+ list[dict]: A list of formatted annotation documents for paperjs. Note that
14
+ it will return an empty list if the documents could not be formatted.
15
+
16
+ """
17
+ # NOTE: hard-coded to only do the first doc.
18
+ formatted_docs = []
19
+
20
+ # Loop through each annotation document.
21
+ for ann_doc in geojson_ann_docs:
22
+ # Grab the features of this document, contains the polygon info.
23
+ features_to_include = []
24
+
25
+ for feature in ann_doc["features"]:
26
+ geometry = feature["geometry"]
27
+ if geometry["type"] == "Polygon":
28
+ properties = feature["properties"]
29
+ properties["rescale"] = {"strokeWidth": properties["lineWidth"]}
30
+ properties["strokeColor"] = properties["lineColor"]
31
+ properties["source"] = "dsa"
32
+
33
+ # Paperjs only supports multipolygons.
34
+ geometry["type"] = "MultiPolygon"
35
+
36
+ coordinates = geometry["coordinates"]
37
+
38
+ adjusted_coordinates = [
39
+ [[[int(coord) for coord in point[:2]] for point in coordinates[0]]]
40
+ ]
41
+
42
+ geometry["coordinates"] = adjusted_coordinates
43
+
44
+ features_to_include.append(feature)
45
+
46
+ if len(features_to_include):
47
+ formatted_docs.append(features_to_include)
48
+
49
+ if return_as_input_to_paper:
50
+ return get_input_to_paper_dict(formatted_docs)
51
+
52
+ return formatted_docs
53
+
54
+
55
+ def get_input_to_paper_dict(formatted_docs: list[dict] | None = None) -> dict:
56
+ """Get the input to paper dictionary.
57
+
58
+ Args:
59
+ formatted_docs (list[dict]): A list of formatted annotation documents for paperjs.
60
+
61
+ Returns:
62
+ dict: The input to paper dictionary.
63
+
64
+ """
65
+ input_to_paper = [{"type": "clearItems"}]
66
+
67
+ if formatted_docs is not None and len(formatted_docs):
68
+ for doc in formatted_docs:
69
+ input_to_paper.append(
70
+ {
71
+ "type": "drawItems",
72
+ "itemList": doc,
73
+ }
74
+ )
75
+
76
+ return {"actions": input_to_paper}
@@ -13,6 +13,7 @@ def tile_image(
13
13
  stride: int | None = None,
14
14
  fill: int | tuple = (255, 255, 255),
15
15
  prepend_name: str = "",
16
+ overwrite: bool = False,
16
17
  ) -> pd.DataFrame:
17
18
  """Tile an image into smaller images.
18
19
 
@@ -25,6 +26,8 @@ def tile_image(
25
26
  fill (int | tuple, optional): The fill value for tiles over the edges.
26
27
  Defaults to (255, 255, 255).
27
28
  prepend_name (str, optional): A string to prepend to the tile names.
29
+ overwrite (bool, optional): Whether to overwrite existing images.
30
+ Defaults to False.
28
31
 
29
32
  Returns:
30
33
  pandas.DataFrame: A DataFrame with the tile locations.
@@ -38,9 +41,7 @@ def tile_image(
38
41
 
39
42
  # Pad the image to avoid tiles not of the right size.
40
43
  save_loc = Path(save_loc)
41
-
42
- if not save_loc.exists():
43
- save_loc.mkdir(parents=True)
44
+ save_loc.mkdir(parents=True, exist_ok=True)
44
45
 
45
46
  if stride is None:
46
47
  stride = tile_size
@@ -50,16 +51,18 @@ def tile_image(
50
51
  xys = [(x, y) for x in range(0, w, stride) for y in range(0, h, stride)]
51
52
 
52
53
  for xy in xys:
54
+ # Get the top left and bottom right coordinates of the tile.
53
55
  x, y = xy
54
- # Get the tile from the image.
55
- tile_img = img[x : x + tile_size, y : y + tile_size]
56
56
 
57
- save_fp = str(save_loc.joinpath(f"{prepend_name}x-{x}y-{y}.png"))
57
+ # Filepath for saving tile.
58
+ save_fp = save_loc / f"{prepend_name}_x{x}y{y}tilesize{tile_size}.png"
58
59
 
59
- imwrite(save_fp, tile_img)
60
+ if not save_fp.is_file() or overwrite:
61
+ # Get the tile from the image.
62
+ tile_img = img[y : y + tile_size, x : x + tile_size]
60
63
 
61
- df_data.append([save_fp, x, y])
64
+ imwrite(save_fp, tile_img)
62
65
 
63
- df = pd.DataFrame(df_data, columns=["fp", "x", "y"])
66
+ df_data.append([save_fp, x, y, tile_size])
64
67
 
65
- return df
68
+ return pd.DataFrame(df_data, columns=["fp", "x", "y", "tile_size"])
@@ -7,7 +7,8 @@ def binary_dice_coefficient_metric(eval_pred):
7
7
  with torch.no_grad():
8
8
  logits, labels = eval_pred # assumed both are numpy
9
9
 
10
- logits_tensor = torch.from_numpy(logits)
10
+ logits_tensor = torch.from_numpy(logits).cpu()
11
+ labels_tensor = torch.from_numpy(labels).cpu()
11
12
 
12
13
  # Scale the logits to the size of the label.
13
14
  logits_tensor = nn.functional.interpolate(
@@ -17,6 +18,7 @@ def binary_dice_coefficient_metric(eval_pred):
17
18
  align_corners=False,
18
19
  ).argmax(dim=1)
19
20
 
20
- pred_labels = logits_tensor.detach().cpu().numpy()
21
+ pred_labels = logits_tensor.detach().numpy()
22
+ labels = labels_tensor.numpy()
21
23
 
22
24
  return {"dice_coefficient": binary_dice_coefficient(pred_labels, labels)}
@@ -2,4 +2,4 @@
2
2
  from .get_pearce_roi_images import get_pearce_roi_images
3
3
  from .tile_image import tile_image
4
4
 
5
- __all__ = ["utils"]
5
+ __all__ = ["utils", "get_pearce_roi_images", "tile_image"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsa_helpers
3
- Version: 0.4.dev5
3
+ Version: 0.5.dev0
4
4
  Summary: Utility functions for working with the DSA girder client.
5
5
  Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
6
  Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
@@ -9,7 +9,6 @@ dsa_helpers/girder_utils.py
9
9
  dsa_helpers/image_utils.py
10
10
  dsa_helpers/imread.py
11
11
  dsa_helpers/imwrite.py
12
- dsa_helpers/login.py
13
12
  dsa_helpers/mongo_utils.py
14
13
  dsa_helpers/utils.py
15
14
  dsa_helpers.egg-info/PKG-INFO
@@ -18,6 +17,7 @@ dsa_helpers.egg-info/dependency_links.txt
18
17
  dsa_helpers.egg-info/requires.txt
19
18
  dsa_helpers.egg-info/top_level.txt
20
19
  dsa_helpers/dash/__init__.py
20
+ dsa_helpers/dash/dash_paperdragon_utils.py
21
21
  dsa_helpers/dash/header.py
22
22
  dsa_helpers/dash/header_callbacks.py
23
23
  dsa_helpers/ml/__init__.py
@@ -35,7 +35,7 @@ classifiers = [
35
35
  "License :: OSI Approved :: MIT License",
36
36
  ]
37
37
  keywords = ["dsa", "girder", "girder_client"]
38
- version = "v0.4dev5"
38
+ version = "v0.5dev0"
39
39
 
40
40
  [project.urls]
41
41
  Repository = "https://github.com/Gutman-Lab/dsa-python-utils"
@@ -1,3 +1,7 @@
1
+ # For developing the package locally.
2
+ build
3
+ twine
4
+
1
5
  girder-client
2
6
  numpy
3
7
  setuptools
@@ -1,11 +0,0 @@
1
- # Python environment directories.
2
- env/
3
- pyenv/
4
-
5
- # Do not push the version file.
6
- dsa_utils/_version.py
7
-
8
- *.pyc
9
- *.egg-info
10
- dist/
11
- .env
@@ -1,8 +0,0 @@
1
- # Shadow imports.
2
- from .imread import imread
3
- from .imwrite import imwrite
4
-
5
- # Modules that should be available.
6
- # from . import girder_utils, image_utils, dash
7
-
8
- __all__ = ["girder_utils", "image_utils", "dash", "ml"]
@@ -1 +0,0 @@
1
- from . import header
@@ -1,36 +0,0 @@
1
- # Login / authenticate function for the girder client.
2
- from girder_client import GirderClient
3
-
4
-
5
- def login(
6
- api_url: str,
7
- login_or_email: str | None = None,
8
- password: str | None = None,
9
- api_key: str | None = None,
10
- ) -> GirderClient:
11
- """Authenticate a girder client with the given credentials or interactively
12
- if none is given.
13
-
14
- Args:
15
- api_url (str): The DSA girder API url.
16
- login_or_email (str | None): The login or email. Defaults to None.
17
- password (str | None): Password for login / email. Defaults to None.
18
- api_key (str | None): The api key to authenticate with. Defaults to None.
19
-
20
- Returns:
21
- girder_client.GirderClient: The authenticated girder client.
22
-
23
- """
24
- gc = GirderClient(apiUrl=api_url)
25
-
26
- if api_key is None:
27
- if login_or_email is None:
28
- _ = gc.authenticate(interactive=True)
29
- elif password is None:
30
- _ = gc.authenticate(username=login_or_email, interactive=True)
31
- else:
32
- _ = gc.authenticate(username=login_or_email, password=password)
33
- else:
34
- _ = gc.authenticate(apiKey=api_key)
35
-
36
- return gc
File without changes
File without changes
File without changes
File without changes