pma-python 2.0.0.181__tar.gz → 2.0.0.183__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.
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/PKG-INFO +1 -1
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/README.md +5 -5
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/core.py +33 -17
- pma_python-2.0.0.183/pma_python/version.py +1 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python.egg-info/PKG-INFO +1 -1
- pma_python-2.0.0.181/pma_python/version.py +0 -1
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/long_desc.txt +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/__init__.py +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/control.py +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/core_admin.py +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/pma.py +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/pma_core_client.py +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python/view.py +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python.egg-info/SOURCES.txt +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python.egg-info/dependency_links.txt +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python.egg-info/not-zip-safe +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python.egg-info/requires.txt +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/pma_python.egg-info/top_level.txt +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/setup.cfg +0 -0
- {pma_python-2.0.0.181 → pma_python-2.0.0.183}/setup.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# pma_python
|
|
2
|
-
pma_python is a Python wrapper library for PMA.
|
|
2
|
+
pma_python is a Python wrapper library for PMA.core ([https://www.pathomation.com](https://www.pathomation.com)),
|
|
3
3
|
a universal viewer by Pathomation for whole slide imaging and microscopy.
|
|
4
4
|
|
|
5
|
-
YOU NEED TO HAVE PMA.
|
|
5
|
+
YOU NEED TO HAVE PMA.core (or PMA.START) RUNNING IN ORDER TO USE THIS
|
|
6
6
|
LIBRARY. PMA_PYTHON IS NOT A STAND-ALONE LIBRARY FOR WSI.
|
|
7
7
|
|
|
8
8
|
If you're working with
|
|
@@ -16,10 +16,10 @@ select those provided for you)
|
|
|
16
16
|
just wish there was a way to now automatically evaluate it on
|
|
17
17
|
100s of slides (batch processing)
|
|
18
18
|
|
|
19
|
-
and you're doing all of this in Python, then PMA.start and
|
|
19
|
+
and you're doing all of this in Python, then PMA.core (or PMA.start) and
|
|
20
20
|
pma_python are for you!
|
|
21
21
|
|
|
22
|
-
PMA.start can be downloaded
|
|
22
|
+
PMA.start can be downloaded from [https://www.pathomation.com/pmastart](https://www.pathomation.com/pmastart)
|
|
23
23
|
|
|
24
24
|
With pma_python, you can inspect and navigate any type of
|
|
25
25
|
microscopic imaging file format available. Whether you have
|
|
@@ -51,7 +51,7 @@ The following vendor formats are currently supported:
|
|
|
51
51
|
* Perkin Elmer (.qptiff)
|
|
52
52
|
|
|
53
53
|
The most up to date list with supported file formats can be found at
|
|
54
|
-
http://
|
|
54
|
+
[http://www.pathomation.com/formats](https://www.pathomation.com/formats)
|
|
55
55
|
|
|
56
56
|
## Installation from source
|
|
57
57
|
To install from pypi
|
|
@@ -599,6 +599,7 @@ def analyse_corresponding_slides(sessionPathDict, recursive=False, includeFinger
|
|
|
599
599
|
"""
|
|
600
600
|
Return a pandas DataFrame that indicates which slides exist on which PMA.core instances
|
|
601
601
|
:param dict sessionPathDict: a dictionary that looks e.g. like
|
|
602
|
+
|
|
602
603
|
{DevSessionID: rootDirAndPath1, ProdSessionID: rootDirAndPath2 }
|
|
603
604
|
:param bool recursive: indicates whether the method should look in sub-directories or not
|
|
604
605
|
"""
|
|
@@ -825,10 +826,12 @@ def get_zoomlevels_dict(slideRef, sessionID=None, min_number_of_tiles=0):
|
|
|
825
826
|
"""
|
|
826
827
|
Obtain a dictionary with the number of tiles per zoomlevel.
|
|
827
828
|
Information is returned as (x, y, n) tuples per zoomlevel, with
|
|
829
|
+
|
|
828
830
|
x = number of horizontal tiles,
|
|
829
831
|
y = number of vertical tiles,
|
|
830
832
|
n = total number of tiles at specified zoomlevel (x * y)
|
|
831
|
-
|
|
833
|
+
|
|
834
|
+
Use min_number_of_tiles argument to specify that you're only interested in zoomlevels that include at least a given number of tiles
|
|
832
835
|
"""
|
|
833
836
|
zoomlevels = list(range(0, get_max_zoomlevel(slideRef, sessionID) + 1))
|
|
834
837
|
dimensions = [
|
|
@@ -1728,7 +1731,8 @@ def add_annotations(slideRef, classification, notes, anns, color="#000000", laye
|
|
|
1728
1731
|
:return: An integer representing the annotation id
|
|
1729
1732
|
:rtype: int
|
|
1730
1733
|
|
|
1731
|
-
Example
|
|
1734
|
+
Example::
|
|
1735
|
+
|
|
1732
1736
|
anns = []
|
|
1733
1737
|
annotation = {
|
|
1734
1738
|
"geometry": string,
|
|
@@ -1897,7 +1901,30 @@ def get_annotation_distance(slideRef, layerID, annotationID, sessionID=None, ver
|
|
|
1897
1901
|
# **************************************#
|
|
1898
1902
|
# === Uploader === #
|
|
1899
1903
|
# **************************************#
|
|
1904
|
+
FOUR_GB = 4 * 1024 * 1024 * 1024
|
|
1900
1905
|
FIVE_GB = 5 * 1024 * 1024 * 1024
|
|
1906
|
+
|
|
1907
|
+
def _get_slide_package_size(slide_path: str) -> tuple[int, int]:
|
|
1908
|
+
"""Return total bytes and maximum single-file bytes for a slide package."""
|
|
1909
|
+
total_size = 0
|
|
1910
|
+
max_size = 0
|
|
1911
|
+
|
|
1912
|
+
files = [slide_path]
|
|
1913
|
+
slide_name_no_ext = os.path.splitext(os.path.basename(slide_path))[0]
|
|
1914
|
+
slide_dir = os.path.join(os.path.dirname(slide_path), slide_name_no_ext)
|
|
1915
|
+
|
|
1916
|
+
if os.path.isdir(slide_dir):
|
|
1917
|
+
for root, _, filenames in os.walk(slide_dir):
|
|
1918
|
+
for filename in filenames:
|
|
1919
|
+
files.append(os.path.join(root, filename))
|
|
1920
|
+
|
|
1921
|
+
for filepath in files:
|
|
1922
|
+
size = os.stat(filepath).st_size
|
|
1923
|
+
total_size += size
|
|
1924
|
+
max_size = max(max_size, size)
|
|
1925
|
+
|
|
1926
|
+
return total_size, max_size
|
|
1927
|
+
|
|
1901
1928
|
async def upload(
|
|
1902
1929
|
*,
|
|
1903
1930
|
pma_core_url: str,
|
|
@@ -1921,21 +1948,10 @@ async def upload(
|
|
|
1921
1948
|
# ================================
|
|
1922
1949
|
# CALCULATE TOTAL SLIDE SIZE
|
|
1923
1950
|
# ================================
|
|
1924
|
-
total_size =
|
|
1925
|
-
|
|
1926
|
-
# main file size
|
|
1927
|
-
total_size += os.stat(slide_path).st_size
|
|
1928
|
-
|
|
1929
|
-
# possible slide folder (multi-files slides)
|
|
1930
|
-
slide_name_no_ext = os.path.splitext(os.path.basename(slide_path))[0]
|
|
1931
|
-
slide_dir = os.path.join(os.path.dirname(slide_path), slide_name_no_ext)
|
|
1932
|
-
|
|
1933
|
-
if os.path.isdir(slide_dir):
|
|
1934
|
-
for root, _, files in os.walk(slide_dir):
|
|
1935
|
-
for f in files:
|
|
1936
|
-
total_size += os.stat(os.path.join(root, f)).st_size
|
|
1951
|
+
total_size, max_file_size = _get_slide_package_size(slide_path)
|
|
1937
1952
|
|
|
1938
1953
|
print("Total slide size:", round(total_size / (1024 ** 3), 2), "GB")
|
|
1954
|
+
print("Largest single file:", round(max_file_size / (1024 ** 3), 2), "GB")
|
|
1939
1955
|
|
|
1940
1956
|
# ================================
|
|
1941
1957
|
# CHECK UPLOAD TYPE (PRE-FLIGHT)
|
|
@@ -1977,8 +1993,8 @@ async def upload(
|
|
|
1977
1993
|
progress_callback=progress_callback
|
|
1978
1994
|
)
|
|
1979
1995
|
|
|
1980
|
-
# Otherwise
|
|
1981
|
-
if total_size < FIVE_GB:
|
|
1996
|
+
# Otherwise choose based on total package size or safe single-request cap
|
|
1997
|
+
if total_size < FOUR_GB and max_file_size < FIVE_GB:
|
|
1982
1998
|
print("Using SMALL file uploader")
|
|
1983
1999
|
|
|
1984
2000
|
return upload_legacy(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.0.0.183'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.0.0.181'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|