dsa-helpers 0.4.dev2__py3-none-any.whl → 0.4.dev4__py3-none-any.whl

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.
dsa_helpers/__init__.py CHANGED
@@ -5,4 +5,4 @@ from .imwrite import imwrite
5
5
  # Modules that should be available.
6
6
  # from . import girder_utils, image_utils, dash
7
7
 
8
- __all__ = ["girder_utils", "image_utils", "dash"]
8
+ __all__ = ["girder_utils", "image_utils", "dash", "ml"]
@@ -1,2 +1,2 @@
1
1
  # Modules that can be imported.
2
- __all__ = ["object_detection"]
2
+ __all__ = ["object_detection", "datasets", "metrics", "transforms"]
@@ -0,0 +1,33 @@
1
+ from torch.utils.data import Dataset
2
+ import pandas as pd
3
+ from PIL import Image
4
+ import numpy as np
5
+
6
+
7
+ class SegFormerSegmentationDataset(Dataset):
8
+ """PyTorch dataset class for semantic segmentation using HuggingFaces SegFormer
9
+ model.
10
+
11
+ """
12
+
13
+ def __init__(self, df: pd.DataFrame):
14
+ """Initiate an instance of the segmentation dataset.
15
+
16
+ Args:
17
+ df (pandas.DataFrame): A pandas DataFrame with columns "fp" and "mask_fp".
18
+
19
+ """
20
+ self.image_files = df["fp"].tolist()
21
+ self.mask_files = df["mask_fp"].tolist()
22
+ self.df = df # store potential metadata
23
+
24
+ def __len__(self):
25
+ return len(self.image_files)
26
+
27
+ def __getitem__(self, idx):
28
+ # Get the filepath to the image and its mask.
29
+ image_path = self.image_files[idx]
30
+ mask_path = self.mask_files[idx]
31
+
32
+ # Return image & mask as PIL images in a dictionary.
33
+ return {"pixel_values": Image.open(image_path), "label": Image.open(mask_path)}
@@ -0,0 +1,3 @@
1
+ from .SegFormerSegmentationDataset import SegFormerSegmentationDataset
2
+
3
+ __all__ = ["SegFormerSegmentationDataset", "utils"]
@@ -0,0 +1,42 @@
1
+ # Utility functions, usualy for creating Datasets in specific formats.
2
+ import pandas as pd
3
+ from .SegFormerSegmentationDataset import SegFormerSegmentationDataset
4
+ from datasets import Dataset, Features, Image
5
+
6
+
7
+ def dataset_generator(dataset):
8
+ """Yield a dataset."""
9
+ for item in dataset:
10
+ yield item
11
+
12
+
13
+ def create_segformer_segmentation_dataset(
14
+ df: pd.DataFrame | str, low_memory: bool = True, transforms=None
15
+ ):
16
+ """Create a SegFormer segmentation dataset from a DataFrame.
17
+
18
+ Args:
19
+ df (pd.DataFrame | str): A pandas DataFrame with columns "fp" and "mask_fp" or a
20
+ path to a CSV file.
21
+ low_memory (bool): Whether to read the CSV file in low memory mode.
22
+ transforms: A function that takes in a batch of samples (dictionary with
23
+ pixel_values and label keys) and returns a transformed batch.
24
+
25
+ Returns:
26
+ A Dataset object to be used for HuggingFaces SegFormer model training.
27
+
28
+ """
29
+ if isinstance(df, str):
30
+ df = pd.read_csv(df, low_memory=low_memory)
31
+
32
+ dataset = SegFormerSegmentationDataset(df)
33
+
34
+ dataset = Dataset.from_generator(
35
+ generator=lambda: dataset_generator(dataset),
36
+ features=Features({"pixel_values": Image(), "label": Image()}), # Example shape
37
+ )
38
+
39
+ if transforms is not None:
40
+ dataset = dataset.set_transform(transforms)
41
+
42
+ return dataset
@@ -0,0 +1,3 @@
1
+ from .binary_dice_coefficient_metric import binary_dice_coefficient_metric
2
+
3
+ __all__ = ["binary_dice_coefficient_metric"]
@@ -0,0 +1,22 @@
1
+ import torch
2
+ from torch import nn
3
+ from ...utils import binary_dice_coefficient
4
+
5
+
6
+ def binary_dice_coefficient_metric(eval_pred):
7
+ with torch.no_grad():
8
+ logits, labels = eval_pred # assumed both are numpy
9
+
10
+ logits_tensor = torch.from_numpy(logits)
11
+
12
+ # Scale the logits to the size of the label.
13
+ logits_tensor = nn.functional.interpolate(
14
+ logits_tensor,
15
+ size=labels.shape[-2:],
16
+ mode="bilinear",
17
+ align_corners=False,
18
+ ).argmax(dim=1)
19
+
20
+ pred_labels = logits_tensor.detach().cpu().numpy()
21
+
22
+ return {"dice_coefficient": binary_dice_coefficient(pred_labels, labels)}
@@ -0,0 +1 @@
1
+ __all__ = ["segformer_transforms"]
@@ -0,0 +1,23 @@
1
+ from transformers import SegformerImageProcessor
2
+ from torchvision.transforms import ColorJitter
3
+
4
+
5
+ def train_transforms(example_batch):
6
+ """Default transforms for training images."""
7
+ processor = SegformerImageProcessor() # required for using SegFormer model.
8
+ jitter = ColorJitter(brightness=0.25, contrast=0.25, saturation=0.25, hue=0.1)
9
+
10
+ images = [jitter(x) for x in example_batch["pixel_values"]]
11
+ labels = [x for x in example_batch["label"]]
12
+ inputs = processor(images, labels)
13
+ return inputs
14
+
15
+
16
+ def val_transforms(example_batch):
17
+ """Default transforms for validation images."""
18
+ processor = SegformerImageProcessor() # required for using SegFormer model.
19
+
20
+ images = [x for x in example_batch["pixel_values"]]
21
+ labels = [x for x in example_batch["label"]]
22
+ inputs = processor(images, labels)
23
+ return inputs
@@ -89,10 +89,8 @@ def add_many_to_collection(
89
89
 
90
90
  operations = []
91
91
 
92
- for item in items:
93
- operations.append(
94
- pymongo.UpdateOne({"_id": item[key]}, {"$set": item}, upsert=True)
95
- )
92
+ for _id, item in items.items():
93
+ operations.append(pymongo.UpdateOne({"_id": _id}, {"$set": item}, upsert=True))
96
94
 
97
95
  for chunk in chunks(operations):
98
96
  _ = mongo_collection.bulk_write(chunk)
dsa_helpers/utils.py ADDED
@@ -0,0 +1,28 @@
1
+ # Basic utility functions.
2
+ import numpy as np
3
+
4
+
5
+ def binary_dice_coefficient(mask1: np.ndarray, mask2: np.ndarray) -> float:
6
+ """Calculate the dice coefficient between two binary masks.
7
+
8
+ Args:
9
+ mask1 (np.ndarray): A binary mask.
10
+ mask2 (np.ndarray): A binary mask.
11
+
12
+ Returns:
13
+ float: The dice coefficient between the two masks.
14
+
15
+ """
16
+ # Convert the masks to binary.
17
+ mask1 = mask1 > 0
18
+ mask2 = mask2 > 0
19
+
20
+ # Calculate dice.
21
+ intersection = np.sum(mask1 * mask2)
22
+
23
+ sum_masks = np.sum(mask1) + np.sum(mask2)
24
+
25
+ if sum_masks == 0:
26
+ return 1.0 # Both masks are empty
27
+
28
+ return 2.0 * intersection / sum_masks
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsa_helpers
3
- Version: 0.4.dev2
3
+ Version: 0.4.dev4
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>
@@ -22,6 +22,10 @@ Requires-Dist: dash
22
22
  Requires-Dist: dash-bootstrap-components
23
23
  Requires-Dist: shapely
24
24
  Requires-Dist: geopandas
25
+ Requires-Dist: torch
26
+ Requires-Dist: datasets
27
+ Requires-Dist: transformers
28
+ Requires-Dist: torchvision
25
29
 
26
30
  # Digital Slide Archive (DSA) Helpers
27
31
  Digital Slide Archive Python utility library.
@@ -36,9 +40,11 @@ This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
36
40
  1. Install requirements for building and distributing package:
37
41
  ```
38
42
  $ python3 -m pip install --upgrade build # for building package
39
- $ python3 -m pip install --upgrade build # for uploading to PyPI
43
+ $ python3 -m pip install --upgrade twine # for uploading to PyPI
40
44
  ```
41
45
  2. When ready to build:
42
46
  - Modify "pyproject.toml" file, change the "version" key to a different value than a version already pushed.
43
47
  - Run ```$ python3 -m build```. This will create a dist directory and put your new wheel and tar distribution files there.
44
48
  3. To install locally for development: ```$ pip3 install dist/dsa_helpers-*.whl```, choosing the wheel version you want to test.
49
+ 4. Upload to PyPI using twine: ```python3 -m twine upload --repository pypi dist/*```
50
+ * You can specify specific files to upload, the line above pushes everything in dist directory.
@@ -0,0 +1,28 @@
1
+ dsa_helpers/__init__.py,sha256=-fAJdwc5u8G-Bbfkc1yh_zDktLXuPfQBoI8KqgVyCOw,216
2
+ dsa_helpers/girder_utils.py,sha256=wzxJ3f_sjuCxfoP4V5KlbSy-B3ej0MEDxVWM6PxCprQ,11377
3
+ dsa_helpers/image_utils.py,sha256=6VUteE_0MfFoRNHt4E2v7pb8XoSjbBxwdhNCk9Gzmgs,1757
4
+ dsa_helpers/imread.py,sha256=jPr6hO4TOtGphENJQWLLtTaQ377yAwLe4F9jSAehJXQ,885
5
+ dsa_helpers/imwrite.py,sha256=eQI8VGn7M35_85QMPrNqGgS66iQn9YboCS50tigAE8s,1159
6
+ dsa_helpers/login.py,sha256=-QyVLW9fKywiPUQCPWxF1BIsufAOqMizDM062nUbupA,1147
7
+ dsa_helpers/mongo_utils.py,sha256=x-66p8DQHYA-mhLnAFKaTcDea43dlSD6bYVf9nQiJds,4679
8
+ dsa_helpers/utils.py,sha256=6_IcUOJHmBZDjVIMbsjEJ4tEpisj48QxvjdyL6OZu88,667
9
+ dsa_helpers/dash/__init__.py,sha256=tNGwvi7Rgr_cSYT7qbbB3Y0mlBZ0pFEA5WFPXjQpugE,21
10
+ dsa_helpers/dash/header.py,sha256=6AsI4npuxhE2_zOZf8OKlkkEkXJze_-fSvMA3OoMucM,4898
11
+ dsa_helpers/dash/header_callbacks.py,sha256=tpf2PU8cgGsecQTWCByxq-Q_v_wUoRikozxRn3brB_4,3256
12
+ dsa_helpers/ml/__init__.py,sha256=AsT-mCmtyYaL7QgHpko1ZOYCbV9Q07PSCs4IpgzME98,100
13
+ dsa_helpers/ml/datasets/SegFormerSegmentationDataset.py,sha256=KVMYQx60OTOslKv0SDKsJbhf8zWkJMG0Ux65mPONJWo,993
14
+ dsa_helpers/ml/datasets/__init__.py,sha256=NZu-iv5uw9VnUIAR5KGOcWrOsAGdqEwO2PrKoWVJdHo,124
15
+ dsa_helpers/ml/datasets/utils.py,sha256=DJedFRav1QPt9_9O8bpTv_oughmfQltHad4IlzOgfwo,1380
16
+ dsa_helpers/ml/metrics/__init__.py,sha256=UemU9cjAi1fGEmurFWbJ8cOoJ8ybzyyQAVmB-joyNi4,121
17
+ dsa_helpers/ml/metrics/binary_dice_coefficient_metric.py,sha256=AA29jG8qnGGvREXSdJba8SVursaNTrLopiJnHZs9EZ4,662
18
+ dsa_helpers/ml/object_detection/__init__.py,sha256=StdNYGjQ3dcJfr5uvUCdWi_XiZpkKMqWNL2EbHBh4Pk,140
19
+ dsa_helpers/ml/object_detection/get_pearce_roi_images.py,sha256=bHV-GpCcm_t8_RaA-TQs3M8E2zI2Q6rrEc0etPV5PGI,4466
20
+ dsa_helpers/ml/object_detection/tile_image.py,sha256=GR6kmhtWVlZOmmoybyw_amew9UdZCj68PWL80kqkdQ4,4492
21
+ dsa_helpers/ml/object_detection/utils.py,sha256=OOwljZTinMHk106-GS2qYXcQTrH7OwO7v9G9SBfTu9E,3273
22
+ dsa_helpers/ml/transforms/__init__.py,sha256=O5pTx287amnPwNhXHY6wT0q5YQxryA3WFm-QRYlm9Ls,35
23
+ dsa_helpers/ml/transforms/segformer_transforms.py,sha256=jn8Mi1GN2dUG7qeEnVnjgsgfIdF_mDGIxvNv_M8pSH8,853
24
+ dsa_helpers-0.4.dev4.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
25
+ dsa_helpers-0.4.dev4.dist-info/METADATA,sha256=y7EoghsThMVnyBpDLW9Cm6BaZixytUGN_GBajCRyhHI,2100
26
+ dsa_helpers-0.4.dev4.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
27
+ dsa_helpers-0.4.dev4.dist-info/top_level.txt,sha256=BmAEDVvDa1MJlSUFHWzx73UKec3o1K6dFUd9tHwgHGo,12
28
+ dsa_helpers-0.4.dev4.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- dsa_helpers/__init__.py,sha256=LriYvuDNhcz1kCSk4hqAVIZAmk2qFDPrdZmA2LK8vkU,210
2
- dsa_helpers/girder_utils.py,sha256=wzxJ3f_sjuCxfoP4V5KlbSy-B3ej0MEDxVWM6PxCprQ,11377
3
- dsa_helpers/image_utils.py,sha256=6VUteE_0MfFoRNHt4E2v7pb8XoSjbBxwdhNCk9Gzmgs,1757
4
- dsa_helpers/imread.py,sha256=jPr6hO4TOtGphENJQWLLtTaQ377yAwLe4F9jSAehJXQ,885
5
- dsa_helpers/imwrite.py,sha256=eQI8VGn7M35_85QMPrNqGgS66iQn9YboCS50tigAE8s,1159
6
- dsa_helpers/login.py,sha256=-QyVLW9fKywiPUQCPWxF1BIsufAOqMizDM062nUbupA,1147
7
- dsa_helpers/mongo_utils.py,sha256=Y3vkhGXpGAbPoDIcv6dZfVoHgmIW64AB6EDMkgMFc5w,4694
8
- dsa_helpers/dash/__init__.py,sha256=tNGwvi7Rgr_cSYT7qbbB3Y0mlBZ0pFEA5WFPXjQpugE,21
9
- dsa_helpers/dash/header.py,sha256=6AsI4npuxhE2_zOZf8OKlkkEkXJze_-fSvMA3OoMucM,4898
10
- dsa_helpers/dash/header_callbacks.py,sha256=tpf2PU8cgGsecQTWCByxq-Q_v_wUoRikozxRn3brB_4,3256
11
- dsa_helpers/ml/__init__.py,sha256=0LbEDNSy6jGcUnAglJQDC_3FSNKinB2Cr561UglWIUs,63
12
- dsa_helpers/ml/object_detection/__init__.py,sha256=StdNYGjQ3dcJfr5uvUCdWi_XiZpkKMqWNL2EbHBh4Pk,140
13
- dsa_helpers/ml/object_detection/get_pearce_roi_images.py,sha256=bHV-GpCcm_t8_RaA-TQs3M8E2zI2Q6rrEc0etPV5PGI,4466
14
- dsa_helpers/ml/object_detection/tile_image.py,sha256=GR6kmhtWVlZOmmoybyw_amew9UdZCj68PWL80kqkdQ4,4492
15
- dsa_helpers/ml/object_detection/utils.py,sha256=OOwljZTinMHk106-GS2qYXcQTrH7OwO7v9G9SBfTu9E,3273
16
- dsa_helpers-0.4.dev2.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
17
- dsa_helpers-0.4.dev2.dist-info/METADATA,sha256=MrL5fGz0rfDcslkjzQJOj0OgZzF9e26gBtsu6FBQCoU,1814
18
- dsa_helpers-0.4.dev2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
19
- dsa_helpers-0.4.dev2.dist-info/top_level.txt,sha256=BmAEDVvDa1MJlSUFHWzx73UKec3o1K6dFUd9tHwgHGo,12
20
- dsa_helpers-0.4.dev2.dist-info/RECORD,,