From 512b9fa2e355b70852d58cdec82c545bbc34e462 Mon Sep 17 00:00:00 2001 From: SeanSDarcy2001 Date: Wed, 24 Nov 2021 18:57:33 -0500 Subject: [PATCH 1/6] save method --- deepdrr/annotations/line_annotation.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/deepdrr/annotations/line_annotation.py b/deepdrr/annotations/line_annotation.py index e57cba0a..8d9e7ceb 100644 --- a/deepdrr/annotations/line_annotation.py +++ b/deepdrr/annotations/line_annotation.py @@ -65,7 +65,12 @@ def from_markup(cls, path: str, volume: AnyVolume) -> LineAnnotation: return cls(*points, volume) - def save(self, path: str): + #sean 11/23/21 + def save(self, path: str, fileName: str): + savePath = path + '/' + fileName + '.json' + with open(savePath, 'w') as outfile: + json.dump(self, outfile) + # todo(sean): save markups with color options based on the following template # markup = { # "@schema": "https://raw.githubusercontent.com/slicer/slicer/master/Modules/Loadable/Markups/Resources/Schema/markups-schema-v1.0.0.json#", From fd716dc72c89c57c4153ca1c7f8100db1e7f111a Mon Sep 17 00:00:00 2001 From: SeanSDarcy2001 Date: Wed, 24 Nov 2021 20:22:04 -0500 Subject: [PATCH 2/6] save method 1st iteration with markup template. TO DO: test and debug --- deepdrr/annotations/line_annotation.py | 212 +++++++++++++------------ 1 file changed, 108 insertions(+), 104 deletions(-) diff --git a/deepdrr/annotations/line_annotation.py b/deepdrr/annotations/line_annotation.py index 8d9e7ceb..4ab3eadb 100644 --- a/deepdrr/annotations/line_annotation.py +++ b/deepdrr/annotations/line_annotation.py @@ -66,112 +66,116 @@ def from_markup(cls, path: str, volume: AnyVolume) -> LineAnnotation: return cls(*points, volume) #sean 11/23/21 - def save(self, path: str, fileName: str): + def save(self, path: str, fileName: str, breachDetected: bool): + startPoint = self.startpoint + endPoint = self.endpoint + + #determine line color based on cortical breach detected + if breachDetected : + #RGB red if breach + lineColor = [1.0, 0.0, 0.0] + else : + #RGB green if no breach + lineColor = [0.0, 1.0, 0.0] + + # todo(sean): save markups with color options based on the following template + markup = { + "@schema": "https://raw.githubusercontent.com/slicer/slicer/master/Modules/Loadable/Markups/Resources/Schema/markups-schema-v1.0.0.json#", + "markups": [ + { + "type": "Line", + "coordinateSystem": "LPS", + "locked": false, + "labelFormat": "%N-%d", + "controlPoints": [ + { + "id": "1", + "label": "entry", + "description": "", + "associatedNodeID": "", + "position": startPoint, + "orientation": [ + -1.0, + -0.0, + -0.0, + -0.0, + -1.0, + -0.0, + 0.0, + 0.0, + 1.0, + ], + "selected": true, + "locked": false, + "visibility": true, + "positionStatus": "defined", + }, + { + "id": "2", + "label": "exit", + "description": "", + "associatedNodeID": "", + "position": endPoint, + "orientation": [ + -1.0, + -0.0, + -0.0, + -0.0, + -1.0, + -0.0, + 0.0, + 0.0, + 1.0, + ], + "selected": true, + "locked": false, + "visibility": true, + "positionStatus": "defined", + }, + ], + "measurements": [ + { + "name": "length", + "enabled": true, + "value": 124.90054351814699, + "printFormat": "%-#4.4gmm", + } + ], + "display": { + "visibility": true, + "opacity": 1.0, + "color": lineColor, + "selectedColor": lineColor, + "activeColor": lineColor, + "propertiesLabelVisibility": true, + "pointLabelsVisibility": true, + "textScale": 3.0, + "glyphType": "Sphere3D", + "glyphScale": 5.800000000000001, + "glyphSize": 5.0, + "useGlyphScale": true, + "sliceProjection": false, + "sliceProjectionUseFiducialColor": true, + "sliceProjectionOutlinedBehindSlicePlane": false, + "sliceProjectionColor": [1.0, 1.0, 1.0], + "sliceProjectionOpacity": 0.6, + "lineThickness": 0.2, + "lineColorFadingStart": 1.0, + "lineColorFadingEnd": 10.0, + "lineColorFadingSaturation": 1.0, + "lineColorFadingHueOffset": 0.0, + "handlesInteractive": false, + "snapMode": "toVisibleSurface", + }, + } + ], + } + + #the actual saving savePath = path + '/' + fileName + '.json' with open(savePath, 'w') as outfile: - json.dump(self, outfile) - - # todo(sean): save markups with color options based on the following template - # markup = { - # "@schema": "https://raw.githubusercontent.com/slicer/slicer/master/Modules/Loadable/Markups/Resources/Schema/markups-schema-v1.0.0.json#", - # "markups": [ - # { - # "type": "Line", - # "coordinateSystem": "LPS", - # "locked": false, - # "labelFormat": "%N-%d", - # "controlPoints": [ - # { - # "id": "1", - # "label": "entry", - # "description": "", - # "associatedNodeID": "", - # "position": [ - # 3.980233907699585, - # -40.96451187133789, - # -1392.0523681640626, - # ], - # "orientation": [ - # -1.0, - # -0.0, - # -0.0, - # -0.0, - # -1.0, - # -0.0, - # 0.0, - # 0.0, - # 1.0, - # ], - # "selected": true, - # "locked": false, - # "visibility": true, - # "positionStatus": "defined", - # }, - # { - # "id": "2", - # "label": "exit", - # "description": "", - # "associatedNodeID": "", - # "position": [ - # 100.19214630126953, - # -2.4773364067077638, - # -1322.3232421875, - # ], - # "orientation": [ - # -1.0, - # -0.0, - # -0.0, - # -0.0, - # -1.0, - # -0.0, - # 0.0, - # 0.0, - # 1.0, - # ], - # "selected": true, - # "locked": false, - # "visibility": true, - # "positionStatus": "defined", - # }, - # ], - # "measurements": [ - # { - # "name": "length", - # "enabled": true, - # "value": 124.90054351814699, - # "printFormat": "%-#4.4gmm", - # } - # ], - # "display": { - # "visibility": true, - # "opacity": 1.0, - # "color": [0.5, 0.5, 0.5], - # "selectedColor": [1.0, 0.5000076295109484, 0.5000076295109484], - # "activeColor": [0.4, 1.0, 0.0], - # "propertiesLabelVisibility": true, - # "pointLabelsVisibility": true, - # "textScale": 3.0, - # "glyphType": "Sphere3D", - # "glyphScale": 5.800000000000001, - # "glyphSize": 5.0, - # "useGlyphScale": true, - # "sliceProjection": false, - # "sliceProjectionUseFiducialColor": true, - # "sliceProjectionOutlinedBehindSlicePlane": false, - # "sliceProjectionColor": [1.0, 1.0, 1.0], - # "sliceProjectionOpacity": 0.6, - # "lineThickness": 0.2, - # "lineColorFadingStart": 1.0, - # "lineColorFadingEnd": 10.0, - # "lineColorFadingSaturation": 1.0, - # "lineColorFadingHueOffset": 0.0, - # "handlesInteractive": false, - # "snapMode": "toVisibleSurface", - # }, - # } - # ], - # } - + json.dump(markup, outfile) + raise NotImplementedError @property From 5762ef2e7615eafcd025346d572b16dc7dc7fcef Mon Sep 17 00:00:00 2001 From: SeanSDarcy2001 Date: Wed, 24 Nov 2021 20:39:57 -0500 Subject: [PATCH 3/6] removed path parameter, path assigned based on breachDetected param --- deepdrr/annotations/line_annotation.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/deepdrr/annotations/line_annotation.py b/deepdrr/annotations/line_annotation.py index 4ab3eadb..fe693051 100644 --- a/deepdrr/annotations/line_annotation.py +++ b/deepdrr/annotations/line_annotation.py @@ -66,17 +66,19 @@ def from_markup(cls, path: str, volume: AnyVolume) -> LineAnnotation: return cls(*points, volume) #sean 11/23/21 - def save(self, path: str, fileName: str, breachDetected: bool): + def save(self, fileName: str, breachDetected: bool): startPoint = self.startpoint endPoint = self.endpoint - #determine line color based on cortical breach detected + #determine line color and path based on cortical breach detected if breachDetected : #RGB red if breach lineColor = [1.0, 0.0, 0.0] + path = './savedLineAnnotations/breachDetected' else : #RGB green if no breach lineColor = [0.0, 1.0, 0.0] + path = './savedLineAnnotations/noBreachDetected' # todo(sean): save markups with color options based on the following template markup = { From 919e6a439cc7dd8f056f7ce4711a05c5105d2ad8 Mon Sep 17 00:00:00 2001 From: SeanSDarcy2001 Date: Thu, 25 Nov 2021 23:23:13 -0500 Subject: [PATCH 4/6] added startPt and endPt geo point parameters to save method --- deepdrr/annotations/line_annotation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deepdrr/annotations/line_annotation.py b/deepdrr/annotations/line_annotation.py index fe693051..99afbb68 100644 --- a/deepdrr/annotations/line_annotation.py +++ b/deepdrr/annotations/line_annotation.py @@ -66,9 +66,9 @@ def from_markup(cls, path: str, volume: AnyVolume) -> LineAnnotation: return cls(*points, volume) #sean 11/23/21 - def save(self, fileName: str, breachDetected: bool): - startPoint = self.startpoint - endPoint = self.endpoint + def save(self, fileName: str, breachDetected: bool, startPt: geo, endPt: geo): + start = startPt + end = endPt #determine line color and path based on cortical breach detected if breachDetected : @@ -95,7 +95,7 @@ def save(self, fileName: str, breachDetected: bool): "label": "entry", "description": "", "associatedNodeID": "", - "position": startPoint, + "position": start, "orientation": [ -1.0, -0.0, @@ -117,7 +117,7 @@ def save(self, fileName: str, breachDetected: bool): "label": "exit", "description": "", "associatedNodeID": "", - "position": endPoint, + "position": end, "orientation": [ -1.0, -0.0, From 08e13283e12d68a583aacf8429d9ae97ee5731f7 Mon Sep 17 00:00:00 2001 From: SeanSDarcy2001 Date: Thu, 2 Dec 2021 12:24:28 -0500 Subject: [PATCH 5/6] removed NotImplementedError --- deepdrr/annotations/line_annotation.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/deepdrr/annotations/line_annotation.py b/deepdrr/annotations/line_annotation.py index 99afbb68..b88d430c 100644 --- a/deepdrr/annotations/line_annotation.py +++ b/deepdrr/annotations/line_annotation.py @@ -177,8 +177,6 @@ def save(self, fileName: str, breachDetected: bool, startPt: geo, endPt: geo): savePath = path + '/' + fileName + '.json' with open(savePath, 'w') as outfile: json.dump(markup, outfile) - - raise NotImplementedError @property def startpoint_in_world(self) -> geo.Point: From b38f1f932559f1a53de1171a1ad643c531dadb15 Mon Sep 17 00:00:00 2001 From: "Benjamin D. Killeen" Date: Thu, 2 Dec 2021 15:14:25 -0500 Subject: [PATCH 6/6] code review --- deepdrr/annotations/line_annotation.py | 217 ++++++++++++------------- 1 file changed, 104 insertions(+), 113 deletions(-) diff --git a/deepdrr/annotations/line_annotation.py b/deepdrr/annotations/line_annotation.py index b88d430c..81e9d7ca 100644 --- a/deepdrr/annotations/line_annotation.py +++ b/deepdrr/annotations/line_annotation.py @@ -1,13 +1,13 @@ from __future__ import annotations import logging -from typing import Optional +from typing import List, Optional from pathlib import Path import numpy as np import json import pyvista as pv -from .. import geo +from .. import geo, utils from ..vol import Volume, AnyVolume logger = logging.getLogger(__name__) @@ -65,118 +65,109 @@ def from_markup(cls, path: str, volume: AnyVolume) -> LineAnnotation: return cls(*points, volume) - #sean 11/23/21 - def save(self, fileName: str, breachDetected: bool, startPt: geo, endPt: geo): - start = startPt - end = endPt - - #determine line color and path based on cortical breach detected - if breachDetected : - #RGB red if breach - lineColor = [1.0, 0.0, 0.0] - path = './savedLineAnnotations/breachDetected' - else : - #RGB green if no breach - lineColor = [0.0, 1.0, 0.0] - path = './savedLineAnnotations/noBreachDetected' - - # todo(sean): save markups with color options based on the following template + def save(self, path: str, color: List[float] = [0.5, 0.5, 0.5]): + """Save the Line annotation to a mrk.json file, which can be opened by 3D Slicer. + + Args: + path (str): Output path to the file. + color (List[int], optional): The color of the saved annotation. + """ + path = Path(path).expanduser() + markup = { - "@schema": "https://raw.githubusercontent.com/slicer/slicer/master/Modules/Loadable/Markups/Resources/Schema/markups-schema-v1.0.0.json#", - "markups": [ - { - "type": "Line", - "coordinateSystem": "LPS", - "locked": false, - "labelFormat": "%N-%d", - "controlPoints": [ - { - "id": "1", - "label": "entry", - "description": "", - "associatedNodeID": "", - "position": start, - "orientation": [ - -1.0, - -0.0, - -0.0, - -0.0, - -1.0, - -0.0, - 0.0, - 0.0, - 1.0, - ], - "selected": true, - "locked": false, - "visibility": true, - "positionStatus": "defined", - }, - { - "id": "2", - "label": "exit", - "description": "", - "associatedNodeID": "", - "position": end, - "orientation": [ - -1.0, - -0.0, - -0.0, - -0.0, - -1.0, - -0.0, - 0.0, - 0.0, - 1.0, - ], - "selected": true, - "locked": false, - "visibility": true, - "positionStatus": "defined", - }, - ], - "measurements": [ - { - "name": "length", - "enabled": true, - "value": 124.90054351814699, - "printFormat": "%-#4.4gmm", - } - ], - "display": { - "visibility": true, - "opacity": 1.0, - "color": lineColor, - "selectedColor": lineColor, - "activeColor": lineColor, - "propertiesLabelVisibility": true, - "pointLabelsVisibility": true, - "textScale": 3.0, - "glyphType": "Sphere3D", - "glyphScale": 5.800000000000001, - "glyphSize": 5.0, - "useGlyphScale": true, - "sliceProjection": false, - "sliceProjectionUseFiducialColor": true, - "sliceProjectionOutlinedBehindSlicePlane": false, - "sliceProjectionColor": [1.0, 1.0, 1.0], - "sliceProjectionOpacity": 0.6, - "lineThickness": 0.2, - "lineColorFadingStart": 1.0, - "lineColorFadingEnd": 10.0, - "lineColorFadingSaturation": 1.0, - "lineColorFadingHueOffset": 0.0, - "handlesInteractive": false, - "snapMode": "toVisibleSurface", - }, - } - ], - } - - #the actual saving - savePath = path + '/' + fileName + '.json' - with open(savePath, 'w') as outfile: - json.dump(markup, outfile) + "@schema": "https://raw.githubusercontent.com/slicer/slicer/master/Modules/Loadable/Markups/Resources/Schema/markups-schema-v1.0.0.json#", + "markups": [ + { + "type": "Line", + "coordinateSystem": self.volume.anatomical_coordinate_system, + "locked": True, + "labelFormat": "%N-%d", + "controlPoints": [ + { + "id": "1", + "label": "entry", + "description": "", + "associatedNodeID": "", + "position": utils.jsonable(self.startpoint), + "orientation": [ + -1.0, + -0.0, + -0.0, + -0.0, + -1.0, + -0.0, + 0.0, + 0.0, + 1.0, + ], + "selected": True, + "locked": False, + "visibility": True, + "positionStatus": "defined", + }, + { + "id": "2", + "label": "exit", + "description": "", + "associatedNodeID": "", + "position": utils.jsonable(self.endpoint), + "orientation": [ + -1.0, + -0.0, + -0.0, + -0.0, + -1.0, + -0.0, + 0.0, + 0.0, + 1.0, + ], + "selected": True, + "locked": False, + "visibility": True, + "positionStatus": "defined", + }, + ], + "measurements": [ + { + "name": "length", + "enabled": True, + "value": 124.90054351814699, + "printFormat": "%-#4.4gmm", + } + ], + "display": { + "visibility": True, + "opacity": 1.0, + "color": color, + "selectedColor": [1.0, 0.5000076295109484, 0.5000076295109484], + "activeColor": [0.4, 1.0, 0.0], + "propertiesLabelVisibility": True, + "pointLabelsVisibility": True, + "textScale": 3.0, + "glyphType": "Sphere3D", + "glyphScale": 5.800000000000001, + "glyphSize": 5.0, + "useGlyphScale": True, + "sliceProjection": False, + "sliceProjectionUseFiducialColor": True, + "sliceProjectionOutlinedBehindSlicePlane": False, + "sliceProjectionColor": [1.0, 1.0, 1.0], + "sliceProjectionOpacity": 0.6, + "lineThickness": 0.2, + "lineColorFadingStart": 1.0, + "lineColorFadingEnd": 10.0, + "lineColorFadingSaturation": 1.0, + "lineColorFadingHueOffset": 0.0, + "handlesInteractive": False, + "snapMode": "toVisibleSurface", + }, + } + ], + } + + with open(path, "w") as file: + json.dump(markup, file) @property def startpoint_in_world(self) -> geo.Point: