pma-python 2.0.0.166__tar.gz → 2.0.0.168__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.2
2
2
  Name: pma_python
3
- Version: 2.0.0.166
3
+ Version: 2.0.0.168
4
4
  Summary: Universal viewing of digital microscopy, whole slide imaging and digital pathology data
5
5
  Home-page: http://github.com/pathomation/pma_python
6
6
  Author: Pathomation
@@ -994,6 +994,39 @@ def get_macro_image(slideRef, width=None, height=None, sessionID=None):
994
994
  _pma_amount_of_data_downloaded[sessionID] += len(r.content)
995
995
  return img
996
996
 
997
+ def get_tile_url(slideRef, x=0, y=0, zoomlevel=None, zstack=0, sessionID=None, format="jpg", quality=100):
998
+ """
999
+ Get a single tile at position (x, y)
1000
+ Format can be 'jpg' or 'png'
1001
+ Quality is an integer value and varies from 0 (as much compression as possible; not recommended) to 100 (100%, no compression)
1002
+ """
1003
+ sessionID = _pma_session_id(sessionID)
1004
+ if (slideRef.startswith("/")):
1005
+ slideRef = slideRef[1:]
1006
+ if (zoomlevel is None):
1007
+ zoomlevel = 0 # get_max_zoomlevel(slideRef, sessionID)
1008
+
1009
+ url = _pma_url(sessionID) + "tile"
1010
+ if url is None:
1011
+ raise Exception("Unable to determine the PMA.core instance belonging to " + str(sessionID))
1012
+
1013
+ params = {
1014
+ "sessionID": sessionID,
1015
+ "channels": 0,
1016
+ "timeframe": 0,
1017
+ "layer": int(round(zstack)),
1018
+ "pathOrUid": slideRef,
1019
+ "x": int(round(x)),
1020
+ "y": int(round(y)),
1021
+ "z": int(round(zoomlevel)),
1022
+ "format": format,
1023
+ "quality": quality,
1024
+ "cache": str(_pma_usecachewhenretrievingtiles).lower()
1025
+ }
1026
+
1027
+ r = requests.get(url, params=params)
1028
+ return r.request.url
1029
+
997
1030
  def get_tile(slideRef, x=0, y=0, zoomlevel=None, zstack=0, sessionID=None, format="jpg", quality=100):
998
1031
  """
999
1032
  Get a single tile at position (x, y)
@@ -1597,8 +1630,18 @@ def download(slideRef, save_directory=None, sessionID=None):
1597
1630
  print("{0:.0%}".format(progress))
1598
1631
  prev = progress
1599
1632
 
1633
+ def dummy_annotation():
1634
+ """Returns a dictionary with the right keys and default values filled out already to be used as input for add_annotation() and add_annotations
1635
+ """
1636
+ return { "classification": "",
1637
+ "notes": "",
1638
+ "geometry": "", # shapely?
1639
+ "color": "",
1640
+ "fillColor": "",
1641
+ "lineThickness": 1}
1600
1642
 
1601
- def add_annotation(slideRef, classification, notes, geometry, color="#000000", layerID=0, sessionID=None, fillColor = "#cccccc", opacity = 0.4, outlineOpacity = 1.0):
1643
+ #def add_annotation(slideRef, classification, notes, ann, color="#000000", layerID=0, sessionID=None, fillColor = "#cccccc", opacity = 0.4, outlineOpacity = 1.0):
1644
+ def add_annotation(slideRef, classification, notes, ann, color="#000000", layerID=0, sessionID=None):
1602
1645
  """Adds an anotation to a slide with the specified parameters
1603
1646
 
1604
1647
  :param slideRef: The slide path to add annotation to
@@ -1607,24 +1650,24 @@ def add_annotation(slideRef, classification, notes, geometry, color="#000000", l
1607
1650
  :type classification: str
1608
1651
  :param notes: A string for free text notes to be associated with this annotation
1609
1652
  :type notes: str
1610
- :param geometry: A Well-Known Text (WKT) representation of the geometry of this annotation
1611
- :type geometry: str
1653
+ :param ann: A Well-Known Text (WKT) representation of the geometry of this annotation; can be a dictionary as well
1654
+ :type geometry: str, dict
1612
1655
  :param color: An HTML color, defaults to "#000000"
1613
1656
  :type color: str, optional
1614
1657
  :param layerID: The layer id to attach this annotation to, defaults to 0
1615
1658
  :type layerID: int, optional
1616
1659
  :param sessionID: The PMA.core session id, defaults to None for autodetection
1617
1660
  :type sessionID: str, optional
1618
- :param fillColor: The fill color for the annotation if any
1619
- :type fillColor: str, optional
1620
- :param opacity: The fill opacity for the annotation
1621
- :type opacity: number, optional
1622
- :param outlineOpacity: The outline opacity for the annotation if any
1623
- :type outlineOpacity: number, optional
1624
1661
  :raises ValueError: If the server response is not in a known format
1625
1662
  :return: An integer representing the annotation id
1626
1663
  :rtype: int
1627
1664
  """
1665
+ # :param fillColor: The fill color for the annotation if any
1666
+ # :type fillColor: str, optional
1667
+ # :param opacity: The fill opacity for the annotation
1668
+ # :type opacity: number, optional
1669
+ # :param outlineOpacity: The outline opacity for the annotation if any
1670
+ # :type outlineOpacity: number, optional
1628
1671
  sessionID = _pma_session_id(sessionID)
1629
1672
  if (sessionID == _pma_pmacoreliteSessionID):
1630
1673
  if is_lite():
@@ -1632,6 +1675,12 @@ def add_annotation(slideRef, classification, notes, geometry, color="#000000", l
1632
1675
  else:
1633
1676
  raise ValueError("PMA.core.lite not found, and besides; it doesn't support adding annotations.")
1634
1677
 
1678
+ if not (type(ann) is dict):
1679
+ geo = ann
1680
+ ann = dummy_annotation()
1681
+ ann["geometry"] = geo
1682
+ ann["color"] = color
1683
+
1635
1684
  url = _pma_api_url(sessionID) + "AddAnnotation"
1636
1685
 
1637
1686
  data = {
@@ -1640,8 +1689,8 @@ def add_annotation(slideRef, classification, notes, geometry, color="#000000", l
1640
1689
  "classification": classification,
1641
1690
  "layerID": layerID,
1642
1691
  "notes": notes,
1643
- "geometry": geometry,
1644
- "color": color
1692
+ "geometry": ann["geometry"],
1693
+ "color": ann["color"]
1645
1694
  }
1646
1695
 
1647
1696
  if pma._pma_debug == True:
@@ -1651,6 +1700,93 @@ def add_annotation(slideRef, classification, notes, geometry, color="#000000", l
1651
1700
  json = r.json()
1652
1701
  return json
1653
1702
 
1703
+ #def add_annotations(slideRef, classification, notes, anns, color="#000000", layerID=0, sessionID=None, fillColor = "#cccccc", opacity = 0.4, outlineOpacity = 1.0):
1704
+ def add_annotations(slideRef, classification, notes, anns, color="#000000", layerID=0, sessionID=None):
1705
+ """Adds multiple anotations to a slide with the specified parameters
1706
+
1707
+ :param slideRef: The slide path to add annotation to
1708
+ :type slideRef: str
1709
+ :param classification: A string representing the class of this annotation (tumor, necrosis etc)
1710
+ :type classification: str
1711
+ :param notes: A string for free text notes to be associated with this annotation
1712
+ :type notes: str
1713
+ :param anns: A list of Well-Known Text (WKT) representation of the geometry of this annotation
1714
+ :type anns: list
1715
+ :param color: An HTML color, defaults to "#000000"; you can specify a separate color for each annotation individually as well
1716
+ :type color: str, optional
1717
+ :param layerID: The layer id to attach this annotation to, defaults to 0
1718
+ :type layerID: int, optional
1719
+ :param sessionID: The PMA.core session id, defaults to None for autodetection
1720
+ :type sessionID: str, optional
1721
+ :raises ValueError: If the server response is not in a known format
1722
+ :return: An integer representing the annotation id
1723
+ :rtype: int
1724
+ """
1725
+ # :param fillColor: The fill color for the annotation if any
1726
+ # :type fillColor: str, optional
1727
+ # :param opacity: The fill opacity for the annotation
1728
+ # :type opacity: number, optional
1729
+ # :param outlineOpacity: The outline opacity for the annotation if any
1730
+ # :type outlineOpacity: number, optional
1731
+
1732
+ if not (type(anns) is list):
1733
+ anns = [anns]
1734
+
1735
+ sessionID = _pma_session_id(sessionID)
1736
+ if (sessionID == _pma_pmacoreliteSessionID):
1737
+ if is_lite():
1738
+ raise ValueError("PMA.core.lite found running, but doesn't support adding annotations.")
1739
+ else:
1740
+ raise ValueError("PMA.core.lite not found, and besides; it doesn't support adding annotations.")
1741
+
1742
+ json_all_added_annotations = []
1743
+ for ann in anns:
1744
+
1745
+ if not (type(ann) is dict):
1746
+ geo = ann
1747
+ ann = dummy_annotation()
1748
+ ann["geometry"] = geo
1749
+ ann["color"] = "#3333FF"
1750
+
1751
+ json_single_annotation = {
1752
+ "Classification": classification,
1753
+ "LayerID": layerID,
1754
+ "Notes": notes,
1755
+ "Geometry": ann["geometry"],
1756
+ "Color": ann["color"],
1757
+ "FillColor": ann["fillColor"],
1758
+ "LineThickness": ann["lineThickness"]
1759
+ }
1760
+ json_all_added_annotations.append(json_single_annotation)
1761
+
1762
+ url = _pma_api_url(sessionID) + "AddAnnotation"
1763
+
1764
+ data = {
1765
+ "sessionID": sessionID,
1766
+ "pathOrUid": slideRef,
1767
+ "deleted": [],
1768
+ "updated": [],
1769
+ "added": json_all_added_annotations
1770
+ }
1771
+
1772
+ url = c.core_url + "/api/json/SaveAnnotations"
1773
+
1774
+ # data = {
1775
+ # "sessionID": sessionID,
1776
+ # "pathOrUid": slideRef,
1777
+ # "classification": classification,
1778
+ # "layerID": layerID,
1779
+ # "notes": notes,
1780
+ # "geometry": geometry,
1781
+ # "color": color
1782
+ # }
1783
+
1784
+ if pma._pma_debug == True:
1785
+ print("url =", url)
1786
+
1787
+ r = requests.post(url, json=data)
1788
+ json = r.json()
1789
+ return json
1654
1790
 
1655
1791
  def clear_all_annotations(slideRef, sessionID=None):
1656
1792
  sessionID = _pma_session_id(sessionID)
@@ -0,0 +1 @@
1
+ __version__ = '2.0.0.168'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.2
2
2
  Name: pma-python
3
- Version: 2.0.0.166
3
+ Version: 2.0.0.168
4
4
  Summary: Universal viewing of digital microscopy, whole slide imaging and digital pathology data
5
5
  Home-page: http://github.com/pathomation/pma_python
6
6
  Author: Pathomation
@@ -1 +0,0 @@
1
- __version__ = '2.0.0.166'
File without changes
File without changes
File without changes