Skip to content

Commit 98e3fcf

Browse files
authored
Merge pull request #56 from BrainLesion/config
updated to config branch, addded config example notebook
2 parents 2cd7bbb + 63089e7 commit 98e3fcf

4 files changed

Lines changed: 583 additions & 53 deletions

File tree

panoptica/example_config.ipynb

Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Use Case: Matched Instances Input\n"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"## Install Dependencies"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": 1,
20+
"metadata": {},
21+
"outputs": [
22+
{
23+
"name": "stdout",
24+
"output_type": "stream",
25+
"text": [
26+
"Requirement already satisfied: panoptica in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from -r requirements.txt (line 1)) (0.6.6.post13.dev0+a2f5dd3)\n",
27+
"Requirement already satisfied: auxiliary in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from -r requirements.txt (line 2)) (0.0.42)\n",
28+
"Requirement already satisfied: rich in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from -r requirements.txt (line 3)) (13.6.0)\n",
29+
"Requirement already satisfied: numpy in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from -r requirements.txt (line 4)) (1.25.2)\n",
30+
"Requirement already satisfied: connected-components-3d<4.0.0,>=3.12.3 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from panoptica->-r requirements.txt (line 1)) (3.12.3)\n",
31+
"Requirement already satisfied: ruamel.yaml<0.19.0,>=0.18.6 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from panoptica->-r requirements.txt (line 1)) (0.18.6)\n",
32+
"Requirement already satisfied: scikit-image<0.23.0,>=0.22.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from panoptica->-r requirements.txt (line 1)) (0.22.0)\n",
33+
"Requirement already satisfied: scipy<2.0.0,>=1.7.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from panoptica->-r requirements.txt (line 1)) (1.11.2)\n",
34+
"Requirement already satisfied: nibabel>=3.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from auxiliary->-r requirements.txt (line 2)) (5.1.0)\n",
35+
"Requirement already satisfied: path>=16.10.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from auxiliary->-r requirements.txt (line 2)) (17.0.0)\n",
36+
"Requirement already satisfied: pathlib>=1.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from auxiliary->-r requirements.txt (line 2)) (1.0.1)\n",
37+
"Requirement already satisfied: pillow>=10.0.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from auxiliary->-r requirements.txt (line 2)) (10.0.0)\n",
38+
"Requirement already satisfied: tifffile>=2023.8.25 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from auxiliary->-r requirements.txt (line 2)) (2023.8.30)\n",
39+
"Requirement already satisfied: markdown-it-py>=2.2.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from rich->-r requirements.txt (line 3)) (3.0.0)\n",
40+
"Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from rich->-r requirements.txt (line 3)) (2.17.2)\n",
41+
"Requirement already satisfied: mdurl~=0.1 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from markdown-it-py>=2.2.0->rich->-r requirements.txt (line 3)) (0.1.2)\n",
42+
"Requirement already satisfied: packaging>=17 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from nibabel>=3.0->auxiliary->-r requirements.txt (line 2)) (23.1)\n",
43+
"Requirement already satisfied: ruamel.yaml.clib>=0.2.7 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from ruamel.yaml<0.19.0,>=0.18.6->panoptica->-r requirements.txt (line 1)) (0.2.8)\n",
44+
"Requirement already satisfied: networkx>=2.8 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from scikit-image<0.23.0,>=0.22.0->panoptica->-r requirements.txt (line 1)) (3.1)\n",
45+
"Requirement already satisfied: imageio>=2.27 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from scikit-image<0.23.0,>=0.22.0->panoptica->-r requirements.txt (line 1)) (2.31.3)\n",
46+
"Requirement already satisfied: lazy_loader>=0.3 in /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages (from scikit-image<0.23.0,>=0.22.0->panoptica->-r requirements.txt (line 1)) (0.3)\n"
47+
]
48+
}
49+
],
50+
"source": [
51+
"!pip install -r requirements.txt"
52+
]
53+
},
54+
{
55+
"cell_type": "markdown",
56+
"metadata": {},
57+
"source": [
58+
"## Setup Imports"
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": 2,
64+
"metadata": {},
65+
"outputs": [],
66+
"source": [
67+
"import numpy as np\n",
68+
"from auxiliary.nifti.io import read_nifti\n",
69+
"from rich import print as pprint\n",
70+
"from panoptica import InputType, Panoptica_Evaluator\n",
71+
"from panoptica.metrics import Metric"
72+
]
73+
},
74+
{
75+
"cell_type": "markdown",
76+
"metadata": {},
77+
"source": [
78+
"## Load Data"
79+
]
80+
},
81+
{
82+
"cell_type": "markdown",
83+
"metadata": {},
84+
"source": [
85+
"To demonstrate we use a reference and predicition of spine a segmentation with matched instances.\n",
86+
"\n",
87+
"\n",
88+
"![matched_figure](figures/matched_instance.png)"
89+
]
90+
},
91+
{
92+
"cell_type": "code",
93+
"execution_count": 3,
94+
"metadata": {},
95+
"outputs": [
96+
{
97+
"data": {
98+
"text/plain": [
99+
"(array([ 0, 2, 3, 4, 5, 6, 7, 8, 26, 102, 103, 104, 105,\n",
100+
" 106, 107, 108, 202, 203, 204, 205, 206, 207, 208], dtype=uint8),\n",
101+
" array([ 0, 2, 3, 4, 5, 6, 7, 8, 26, 102, 103, 104, 105,\n",
102+
" 106, 107, 108, 202, 203, 204, 205, 206, 207, 208], dtype=uint8))"
103+
]
104+
},
105+
"execution_count": 3,
106+
"metadata": {},
107+
"output_type": "execute_result"
108+
}
109+
],
110+
"source": [
111+
"ref_masks = read_nifti(\"./spine_seg/matched_instance/ref.nii.gz\")\n",
112+
"pred_masks = read_nifti(\"./spine_seg/matched_instance/pred.nii.gz\")\n",
113+
"\n",
114+
"# labels are matching\n",
115+
"np.unique(ref_masks), np.unique(pred_masks)"
116+
]
117+
},
118+
{
119+
"cell_type": "markdown",
120+
"metadata": {},
121+
"source": [
122+
"## Build Evaluator object"
123+
]
124+
},
125+
{
126+
"cell_type": "code",
127+
"execution_count": 4,
128+
"metadata": {},
129+
"outputs": [
130+
{
131+
"data": {
132+
"text/html": [
133+
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #00ff00; text-decoration-color: #00ff00\">────────────────────────────────────────── </span>Thank you for using <span style=\"font-weight: bold\">panoptica</span><span style=\"color: #00ff00; text-decoration-color: #00ff00\"> ──────────────────────────────────────────</span>\n",
134+
"</pre>\n"
135+
],
136+
"text/plain": [
137+
"\u001b[92m────────────────────────────────────────── \u001b[0mThank you for using \u001b[1mpanoptica\u001b[0m\u001b[92m ──────────────────────────────────────────\u001b[0m\n"
138+
]
139+
},
140+
"metadata": {},
141+
"output_type": "display_data"
142+
},
143+
{
144+
"data": {
145+
"text/html": [
146+
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"> Please support our development by citing \n",
147+
"</pre>\n"
148+
],
149+
"text/plain": [
150+
" Please support our development by citing \n"
151+
]
152+
},
153+
"metadata": {},
154+
"output_type": "display_data"
155+
},
156+
{
157+
"data": {
158+
"text/html": [
159+
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"> <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://github.com/BrainLesion/panoptica#citation</span> -- Thank you! \n",
160+
"</pre>\n"
161+
],
162+
"text/plain": [
163+
" \u001b[4;94mhttps://github.com/BrainLesion/panoptica#citation\u001b[0m -- Thank you! \n"
164+
]
165+
},
166+
"metadata": {},
167+
"output_type": "display_data"
168+
},
169+
{
170+
"data": {
171+
"text/html": [
172+
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #00ff00; text-decoration-color: #00ff00\">───────────────────────────────────────────────────────────────────────────────────────────────────────────────────</span>\n",
173+
"</pre>\n"
174+
],
175+
"text/plain": [
176+
"\u001b[92m───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n"
177+
]
178+
},
179+
"metadata": {},
180+
"output_type": "display_data"
181+
},
182+
{
183+
"data": {
184+
"text/html": [
185+
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
186+
"</pre>\n"
187+
],
188+
"text/plain": [
189+
"\n"
190+
]
191+
},
192+
"metadata": {},
193+
"output_type": "display_data"
194+
},
195+
{
196+
"name": "stdout",
197+
"output_type": "stream",
198+
"text": [
199+
"Panoptic: Start Evaluation\n",
200+
"-- Got MatchedInstancePair, will evaluate instances\n"
201+
]
202+
}
203+
],
204+
"source": [
205+
"evaluator = Panoptica_Evaluator(\n",
206+
" expected_input=InputType.MATCHED_INSTANCE,\n",
207+
" decision_metric=Metric.IOU,\n",
208+
" decision_threshold=0.5,\n",
209+
")\n",
210+
"\n",
211+
"result, debug_data = evaluator.evaluate(pred_masks, ref_masks)[\"ungrouped\"]"
212+
]
213+
},
214+
{
215+
"cell_type": "markdown",
216+
"metadata": {},
217+
"source": [
218+
"## Inspect Results\n",
219+
"The results object allows access to individual metrics and provides helper methods for further processing"
220+
]
221+
},
222+
{
223+
"cell_type": "code",
224+
"execution_count": 5,
225+
"metadata": {},
226+
"outputs": [
227+
{
228+
"name": "stdout",
229+
"output_type": "stream",
230+
"text": [
231+
"\n",
232+
"+++ MATCHING +++\n",
233+
"Number of instances in reference (num_ref_instances): 22\n",
234+
"Number of instances in prediction (num_pred_instances): 22\n",
235+
"True Positives (tp): 22\n",
236+
"False Positives (fp): 0\n",
237+
"False Negatives (fn): 0\n",
238+
"Recognition Quality / F1-Score (rq): 1.0\n",
239+
"\n",
240+
"+++ GLOBAL +++\n",
241+
"Global Binary Dice (global_bin_dsc): 0.9744370224078394\n",
242+
"Global Binary Centerline Dice (global_bin_cldsc): 0.9637064011802574\n",
243+
"Global Binary Average Symmetric Surface Distance (global_bin_assd): 0.1499152780072207\n",
244+
"Global Binary Relative Volume Difference (global_bin_rvd): -0.0006011763989268869\n",
245+
"\n",
246+
"+++ INSTANCE +++\n",
247+
"Segmentation Quality IoU (sq): 0.8328184295330796 +- 0.15186064004517466\n",
248+
"Panoptic Quality IoU (pq): 0.8328184295330796\n",
249+
"Segmentation Quality Dsc (sq_dsc): 0.900292616009954 +- 0.10253566174957332\n",
250+
"Panoptic Quality Dsc (pq_dsc): 0.900292616009954\n",
251+
"Segmentation Quality Assd (sq_assd): 0.250331887879225 +- 0.07696680402317076\n",
252+
"Segmentation Quality Relative Volume Difference (sq_rvd): 0.0028133049062930553 +- 0.034518928495505724\n",
253+
"\n"
254+
]
255+
}
256+
],
257+
"source": [
258+
"# print all results\n",
259+
"print(result)"
260+
]
261+
},
262+
{
263+
"cell_type": "markdown",
264+
"metadata": {},
265+
"source": [
266+
"## Save Evaluator as config\n",
267+
"\n",
268+
"You can save your settings and arguments for nearly all panoptica-related objects as yaml configs"
269+
]
270+
},
271+
{
272+
"cell_type": "code",
273+
"execution_count": 6,
274+
"metadata": {},
275+
"outputs": [
276+
{
277+
"name": "stdout",
278+
"output_type": "stream",
279+
"text": [
280+
"Saved config into /opt/anaconda3/envs/seg11panoptdev/lib/python3.11/site-packages/panoptica/test_config.yaml\n"
281+
]
282+
}
283+
],
284+
"source": [
285+
"evaluator.save_to_config_by_name(\"test_config\")"
286+
]
287+
},
288+
{
289+
"cell_type": "markdown",
290+
"metadata": {},
291+
"source": [
292+
"## Load Configs\n",
293+
"\n",
294+
"You can simply load the same object by using its class.load_config:\n",
295+
"\n",
296+
"Notably: \n",
297+
"\n",
298+
"- load_from_config() uses an absolute path, while\n",
299+
"- load_from_config_by_name() uses some default path\n",
300+
"\n",
301+
"The same is true for saving configs:\n",
302+
"\n",
303+
"- save_to_config() saves to a given absolute path, while\n",
304+
"- save_to_config_by_name() uses a default path"
305+
]
306+
},
307+
{
308+
"cell_type": "code",
309+
"execution_count": 7,
310+
"metadata": {},
311+
"outputs": [
312+
{
313+
"name": "stdout",
314+
"output_type": "stream",
315+
"text": [
316+
"<panoptica.panoptica_evaluator.Panoptica_Evaluator object at 0x7fbe999a9c90>\n"
317+
]
318+
}
319+
],
320+
"source": [
321+
"eval = Panoptica_Evaluator.load_from_config_name(\"test_config\")\n",
322+
"print(eval)"
323+
]
324+
},
325+
{
326+
"cell_type": "code",
327+
"execution_count": 8,
328+
"metadata": {},
329+
"outputs": [
330+
{
331+
"name": "stdout",
332+
"output_type": "stream",
333+
"text": [
334+
"Panoptic: Start Evaluation\n",
335+
"-- Got MatchedInstancePair, will evaluate instances\n",
336+
"\n",
337+
"+++ MATCHING +++\n",
338+
"Number of instances in reference (num_ref_instances): 22\n",
339+
"Number of instances in prediction (num_pred_instances): 22\n",
340+
"True Positives (tp): 22\n",
341+
"False Positives (fp): 0\n",
342+
"False Negatives (fn): 0\n",
343+
"Recognition Quality / F1-Score (rq): 1.0\n",
344+
"\n",
345+
"+++ GLOBAL +++\n",
346+
"Global Binary Dice (global_bin_dsc): 0.9744370224078394\n",
347+
"Global Binary Centerline Dice (global_bin_cldsc): 0.9637064011802574\n",
348+
"Global Binary Average Symmetric Surface Distance (global_bin_assd): 0.1499152780072207\n",
349+
"Global Binary Relative Volume Difference (global_bin_rvd): -0.0006011763989268869\n",
350+
"\n",
351+
"+++ INSTANCE +++\n",
352+
"Segmentation Quality IoU (sq): 0.8328184295330796 +- 0.15186064004517466\n",
353+
"Panoptic Quality IoU (pq): 0.8328184295330796\n",
354+
"Segmentation Quality Dsc (sq_dsc): 0.900292616009954 +- 0.10253566174957332\n",
355+
"Panoptic Quality Dsc (pq_dsc): 0.900292616009954\n",
356+
"Segmentation Quality Assd (sq_assd): 0.250331887879225 +- 0.07696680402317076\n",
357+
"Segmentation Quality Relative Volume Difference (sq_rvd): 0.0028133049062930553 +- 0.034518928495505724\n",
358+
"\n"
359+
]
360+
}
361+
],
362+
"source": [
363+
"# Now use it as normal\n",
364+
"result, debug_data = evaluator.evaluate(pred_masks, ref_masks)[\"ungrouped\"]\n",
365+
"print(result) # yields same results as the evaluator object manually constructed"
366+
]
367+
},
368+
{
369+
"cell_type": "code",
370+
"execution_count": null,
371+
"metadata": {},
372+
"outputs": [],
373+
"source": []
374+
}
375+
],
376+
"metadata": {
377+
"kernelspec": {
378+
"display_name": "helm",
379+
"language": "python",
380+
"name": "python3"
381+
},
382+
"language_info": {
383+
"codemirror_mode": {
384+
"name": "ipython",
385+
"version": 3
386+
},
387+
"file_extension": ".py",
388+
"mimetype": "text/x-python",
389+
"name": "python",
390+
"nbconvert_exporter": "python",
391+
"pygments_lexer": "ipython3",
392+
"version": "3.11.6"
393+
}
394+
},
395+
"nbformat": 4,
396+
"nbformat_minor": 2
397+
}

0 commit comments

Comments
 (0)